Before I start working on this issue, I’d like to summarize my thoughts so far.
What started as a simple issue turned into a bunch of related suggestions for improvement. I am dumping them below in no particular order:
- Deduplicate the classpath - each jar should appear exactly once
PROS: shorten classpath, make ordering clear
PROPOSING: change he default behavior without further customization options
- Build the CLASSPATH variable incrementally, change the Java invocation not to pass the classmate explicitly
PROS: Can handle up to 32kb classpaths - up from the current 7kb
CONS: Classpath not visible in the process description (i.e. when looking by PS). The 32k boundary can be exceeded when using deeply nested paths.
PROPOSING: Classpath should be built incrementally in all cases, add an option determining whether it should be passed on the actual cmd line.
- Add the notion of working directory and specify the classpath relative to it (rather than absolute paths)
PROS: shorter classpaths, generally useful for some types of apps
CONS: some types of apps benefit from being able to run from anywhere and not tied to a specific working dir
PROPOSING: add an option to specify an app working dir in the distribution - if specified use it, otherwise default to the current behavior
- In relation with the previous suggestion (not directly related to CP), add a ‘resources/config’ directory, containing resources available on the classpath.
PROS: useful for location independent apps for locating configs, etc.
CONS: often an overkill
PROPOSING: add an option to specify an unpacked resources dir in the distribution - if specified use it, otherwise default to the current behavior
- Enumerate only the jars that need explicit ordering and specify the rest using a wildcard classmate. Will require a new property to select the explicit part of the classpath.
PROS: makes the classpaths MUCH shorter, savior when nothing else works, ideally we wouldn’t need explicit ordering at all
CONS: the actual classpath is hidden and the ordering is platform-dependent, can be problematic when troubleshooting classloading problems
PROPOSING: add an option to enable wildcard, and optionally a list of dependencies that should be enumerated explicitly
- Specify the classpath in the manifest relative to the main application JAR and use java -jar to run the app
PROS: eliminates the problem altogether
CONS: classpath is hidden from ps (3), it is difficult to do ad-hoc tweaks to classpath (i.e. add another jar, change ordering, etc.)
PROPOSING: the other approaches may be sufficient, but we could implement this if we consider wildcards without prefix path
So, the proposal so far is to:
deduplicate the classpath + always build the CLASSPATH variable in incremental fashion + add an option whether to pass -cp $CLASSPATH on the command line + add an option to specify an ‘applicationWorkingDir’ in the distribution - if done so, CP entries are relative to that; otherwise use full paths + add an option to specify an ‘applicationResourcesDir’ in the distribution - if done so, it is added to classpath + add an option to use wildcard classpath + add an option to specify an ordered prefix to wildcard classpaths (perhaps an overkill)
add an option to use java -jar launcher and embedded classpath
Please provide feedback, especially if you think that any of these don’t make sense. This is a goldplated proposal and we need to carefully weigh the utility vs. complexity of each feature. I believe the first 3 items are the bare minimum we need.