-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows classpath length issue #18
Comments
First came across mention of this feature at: https://stackoverflow.com/a/54270831 where there is some explanation. The following quote is from the official docs at: https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111
So to use this functionality, it looks like an external file is necessary. The official docs have a number of examples and the stackoverflow post has an example. |
Hmm, inspecting the output of the Java 11 graal 19.3.0's native-image, I don't see the @-file support listed:
Whereas for
May be there isn't any support for this in native-image... |
Did some brief testing and didn't get the sense that @-files are supported. Have also asked at the graalvm slack's #native-image. |
Apparently, other approaches include:
Whether native-image has any support for these... |
Brief testing of the pathing jar approach suggests it might work. For testing purposes, I tried Then created the following file / folder hierarchy:
Put the following in Manifest.mf:
Created pathing.jar by:
Then invoked:
(Everything after the first line is just the ordinary stuff clj-kondo needs to be built, so I think we can ignore it for this discussion.) This created a working clj-kondo. On a side note, as if this isn't enough yak-shaving, there is apparently a line length limitation in manifest files...which apparently can be worked around by: https://stackoverflow.com/a/3057862 For reference, other bits at the same and previous SO pages may contain even more caveats... One caveat is that the paths listed as part of the value for Class-Path: need to be relative. May be that's not too bad. Exactly how to format the value may also be an issue: |
Perhaps the other approach (classpath wildcard) might not be too bad since Windows 10 has support for symlinks (I think). May be a temporary directory could be made, filled with symlinks to each .jar item that is desired for the classpath and the non-jar items can be specified normally:
...
via: https://docs.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html#Understanding (The link actually points to the section immediately after the relevant one, so scrolling up might help.) |
One more approach that has turned up is to use the CLASSPATH environment variable. That sounds the simplest, According to: https://devblogs.microsoft.com/oldnewthing/20100203-00/?p=15083
So it appears possible that depending on what other environment variables are set to, using the CLASSPATH environment variable could be an improvement. |
May be trying to use symlinks is worth considering. I'm not exactly sure what the requirements are, but found this from some time back:
and:
via: https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/ May be "Developer Mode" needs to be enabled. Even if that's necessary, may be it's not such a bad requirement, given that |
Below are some concrete numbers for the project I had difficulty with.
|
I got confirmation from Paul Wögerer on #native-image that there isn't currently support for @-files in native-image. |
It could be that the clj / clojure tooling on Windows is experiencing this issue. If it turns out there's a way for the classpath to get shortened either before clj / clojure receives it, or before clj / clojure launches its final jvm, may be clj.native-image will inherit a short enough classpath. Then, may be native-image will launch without problems. |
An attempt at a summary of the state of classpath-and-windows-length-limits-do-not-get-along-work-around-functionality available in native-image:
So, how can one of the usable bits be applied? The uberjar method has a track record. Where I've seen it, the uberjar is constructed via Leiningen. I would prefer a solution that doesn't use that. May be there is an alternate tool that could be used to a similar end. Not sure if depstar or uberdeps are enough -- more options may be available at: https://github.com/clojure/tools.deps.alpha/wiki/Tools#packaging As mentioned in a comment above (#18 (comment)), the manifest file has some limitations to it. I don't know if that's something that can be surmounted. On the surface, it makes the pathing.jar approach not-so-attractive. Due to symlinks being available on developer-mode-enabled Windows 10 machines, that in combination with the classpath wildcard functionality, seems promising. (This doesn't appear to be doable in Java 8 or Java 11 directly: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8218418 -- so shelling out to mklink might be a work-around, for code or a tool when running on Windows) |
To expand a bit on the "promising" idea, it might work like this:
Notes:
|
Supposing there was code or a tool to accomplish the symlink + classpath wildcard idea, it might be used as follows:
Not sure yet how to invoke clj.native-image via an alias in a convenient way. That is, invokding Something like:
seems like it could work, but it's certainly not as nice. May be that's not worth worrying about. |
On Windows 10, I compared the .cp file created via Oddly enough, the native-image classpath is quite a bit longer (~7500 bytes vs ~250 bytes). I fabricated an invocation of A similar fabricated invocation using the content of the .cp file from the
I will try to compare the two classpaths. |
It looks like invoking Specifically, (something close to, if not) the following:
(Obtained via |
@sogaiu I'm having the same issue and I'm currently stuck. I cannot use Leiningen because it doesn't work with cljfx and uberjar and I cannot use deps.edn because of this issue. I haven't had any issues with Leiningen and lein-native-image plugin. |
I don't think a solution was arrived at that made it into clj.native-image. IIRC, the compilation being done in the same process as clj.native-image running can lead to this situation. It's been a while but I think it had to do with overlaps between clj.native-image's dependencies and those of one's project: #20 As mentioned in #20, I worked around this once by using an older version of clj.native-image. Whether that sort of thing works might be project-specific though. Not sure if it would help for your case, but one thing that came about from these investigations was this: https://github.com/sogaiu/clj-pathing-jar Sorry if this is a bit fragmented -- don't have the context loaded up 😅 |
Hello! I have just faced the same issue and it seems that graal now supports arguments file. oracle/graal#2443 Will it help with resolving the issue? |
So I ran into this issue, and solved it by writing the classpath argument to a file as mentioned above https://github.com/skynet-gh/skylobby/blob/53a56f8/dev/clj/graal/native_image.clj#L20-L27 |
@sogaiu reported an issue on Windows where the classpath is hitting some length limit.
For Java 9 and up, it's possible to specify a classpath file (that contains the classpath argument) rather than passing the classpath itself as an argument. It might be possible to workaround the length issue with that.
The text was updated successfully, but these errors were encountered: