Search code examples
javajargraalvmgraalvm-native-image

Working GraalVM native-image command line with custom classpath?


I'm on a project that currently builds into 26 jars (+6 if we count the test-only jars). We want to combine them all into a single executable for performance reasons. This is on a windows machine, with graalVM-ce-java11-20.0.0. We're using IntelliJ and gradle. I'm currently just trying to come up with a command line that's work even a little before I try to reproduce it in gradle. Gradle isn't in the picture yet, thus the lack of the appropriate tag.

I've tried everything I can think of to get past my first missing class, to no avail. This strikes me as something basic that I'm too close to and can't see the forest due to all the thrice cursed trees in the way.

I currently have all the jars in the graalvm/bin folder. That should make it easy, right? Not so much.

I'm trying to build jar D, using classes from (among other places), jar A. foo.bar.A.P is the first class it can't find, which kicks it out or to a fallback build.

I've tried a relative path to the directory: native-image -cp ./ -jar D

I've tried a full path to the directory: native-image -cp c:/foo/bar/baz -jar D

I've tried a full path the jar in question: native-image -cp c:/graalvm/bin/A.jar -jar D

I've tried all the aliases for the class path:

  • native-image -cp ... -jar D
  • native-image -classpath ... -jar D
  • native-image --class-path ... -jar D

I've even tried adding a classpath to D.jar's MANIFEST.MF via gradle's jar { manifest { attributes: ( "Class-Path": "..." ) } }. This is right along side the working "Main-Class": "foo.bar.D.baz" attribute in the same place.

Did I just happen on the one directory that native-image automatically ignores (it's own bin folder?) Lets find out! Nope, that didn't help either.

Note that I haven't tried all the possible combinations/permutations here. --class-path with X, Y, but not Z.

What am I missing? If someone could post a known-good command line (ideally for windows), I'd deeply appreciate it.


Solution

  • The first thing to try is to get the command line working without native-image, just using plain java.

    Similar to what the java launchers does, native-image does not support mixing -jar and -cp if you pass -jar, it will override the classpath and the -cp argument will be ignored.

    You avoid using -jar and simply pass the name of the main class:

    native-image -cp ...;D foo.bar.D.baz
    

    (i'm assuming here that D is the full path to your jar)

    The Class-Path attribute in the JAR should work (in which case you don't need to pass -cp) but you need to be careful about how the paths in this attribute are resolved: they will be resolved relative to the location of the jar containing the attribute.