Java classpath on command line may exceed OS limits

Description

On some operating systems (Windows in particular), using a large classpath may exceed maximum command-line arg or length limits. On Windows, this results in Program 'java.exe' failed to run: The filename or extension is too long.

Cause: The CLI builds a command line execution that includes the classpath as a string, and the classpath may be arbitrarily large.

Alternative considered:

One older approach is to create a "pathing jar" - a jar file which has a Class-Path: entry in its MANIFEST.MD and no other content (this is an old applet feature). Java can then be invoked via java ... -classpath pathing.jar clojure.main. This relies on old applet features and requires making a jar on the fly, so is not a good approach.

Approach:

The Clojure CLI always has a .cp file with the classpath information in the cache by the time it executes the user’s Java command line. Java supports specifying the classpath in a file with -cp @cpfile.txtand we should be able to do this as the normal operation.

Things to investigate:

  • Sometimes we combine ad-hoc entries (like the -X exec jar) - can that be done with the @ syntax?

  • Is it useful for debugging to see the full classpath on the command line? If so, maybe we still support that with an option. We already have -Spath flag to see the classpath being used.

  • Did (the clojure port of the bash script) already do this for Windows users?

    • yes, but by putting the computed classpath into a new file - instead we should really use the .cp file we already have in the cache

Environment

Windows

Attachments

2

Activity

Show:

Michiel Borkent May 18, 2023 at 3:03 PM

The github repo you linked in this issue no longer exists and I don’t have a good way to repro this on Windows. Do you perhaps have a full deps.edn + clj invocation which triggers this problem?

Michiel Borkent November 13, 2021 at 12:53 PM

Perhaps the tools.deps.alpha uberjar that the CLI calls can write the java version to a file in .cpcache and then the CLI script can also do the @classpath-file.txt thing if appropriate.

This way we don't have to shell out to java to see the version.

or perhaps it can become part of an existing file, e.g. the basis (but that would probably mean that the CLI would have to be able to parse .edn) 

Alex Miller November 16, 2020 at 7:07 PM

A better solution to this would be to use the java built-in support for specifying the classpath in a file with -cp @cpfile.txt. clj always has such a file already so this should be easy to implement in the script.

Tim Gilbert July 31, 2019 at 8:19 PM
Edited

Rebased the clojure-side patch from t.d.a master on github (patch is viewable on github here: https://github.com/clojure/tools.deps.alpha/compare/master...timgilbert:pathing-jar?expand=1)

Tim Gilbert March 25, 2019 at 4:15 PM

Oops! This newer 0002 patch fixes a syntax error around $ForceCP in the previous brew-install patch.

Details

Assignee

Reporter

Labels

Priority

Created March 8, 2019 at 10:13 PM
Updated November 11, 2024 at 3:04 PM