Clojure-generated class names length exceed file-system limit

Description

Class names generated by the Clojure compiler can be arbitrarily long, exceeding the file system's maximum allowed file name length. For example it happens when you nest functions a bit too deeply:

Compiling this produces a java.io.IOException: File name too long exception.

Environment

tested on CentOS 6

Activity

Show:
Alex Miller
July 26, 2018, 3:25 PM

Not going to make any breaking changes. Plan should be to switch second strategy when current strategy doesn’t work.

Ivan Kryvoruchko
July 26, 2018, 10:57 AM

@Alex Miller Hello! Would a patch with Scala-like approach (hashing of name in case it's too long) be considered? As it breaks binary compatibility this workaround would definitely be disabled by default, but it would be possible to enable name hashing by using new compiler option. This approach would definitely help in our particular case, but I'm not sure if it's useful/generic enough to be included in compiler, so I haven't started working on patch yet.

Steve Miner
March 17, 2018, 10:49 PM

Sorry if this comment is off topic, but the original example is a bit confusing to me. Maybe it should be:

That way (trampoline (nestfn 10 "foo")) would return "foo". However, I do get a CompilerException java.lang.StackOverflowError for n=1000 on macOS.

Alex Miller
March 17, 2018, 6:19 PM

Alex - we're not going to output jars. This is at odds with many facets of the Clojure runtime.

Alex Vong
March 17, 2018, 5:50 PM

I come up with a proof-of-concept patch. The compiler now outputs jar instead of class if the class name is longer than 255. The jar name is simply a (left) truncation of the class name.

Suppose *compile-path* is set to "build", then you need to add build/* to your class path, so that the jars can be found.

This patch is only a proof of concept, ideally all classes with long name should be put into one big jar to avoid having to decompress many files. Also, the user should be able to specify *compile-name-max* and *compile-jar-name*. Finally, the code is quite ugly, I should have spitted things into several functions.

Your pinned fields
Click on the next to a field label to start pinning.

Assignee

Unassigned

Reporter

import

Labels

Approval

Triaged

Priority

Critical

Affects versions