Search code examples
javadllclasspathjpackage

Defining a custom classpath (and binaries folder) for jpackage executables


I am trying to create a Windows EXE / MSI file for my Java application using jpackage. By and large, this works, however I am running into some issues for which I require some help:

  1. Defining a custom classpath: I went through the documentation that states how to add a custom classpath. The documentation does two things: it uses the variable $APPDIR and it uses a : separator. However, when I pass this directive to jpackage:
--java-options "-cp \$APPDIR/config:\$APPDIR/lib\gson-2.10.1.jar:\$APPDIR/lib\xmlbeans-5.1.1.jar:\$APPDIR/lib\mssql-jdbc-12.4.0.jre8.jar:\$APPDIR/MyApp.jar"

... I get this in the CFG file:

java-options=-Djpackage.app-version=1.0
java-options=-cp
java-options=\/config:\/lib\gson-2.10.1.jar:\/lib\xmlbeans-5.1.1.jar:\/lib\mssql-jdbc-12.4.0.jre8.jar:\/MyApp.jar

As you can see, the reference to APPDIR is removed. Consequently, I get an error when I try to run my executable:

Error: Could not find or load main class path.to.my.MainClass
Caused by: java.lang.ClassNotFoundException: path.to.my.MainClass

The separator slashes don't matter - / and \ have the same effect. If I remove the --java-options, the paths are pulled from my --input directive, and the MainClass is resolved. However, I don't get to see the config directory in my classpath. I know that there is an alternative posted here, but I would like to use the classpath feature if possible.

  1. Using a folder for DLLs One of my jar files is for MS SQL, where I want to use Active Directory authentication. This requires me to have a specific DLL in the path (i.e. in the Environment Variable Path). Is there a way I can make the generated runtime executable look at a specific folder for this?

Solution

  • Defining a custom classpath

    The command from the documentation is for a unix shell/platform (as evidenced also by the use of : in the class path). On Windows, you need to use ; as a path separator.

    You also need to prevent the expansion of the $APPDIR as a shell variable. In the unix shell this is done by escaping the $ with \, on Windows in powershell for instance, you can use a single quoted string (which avoids variable expansion):

    --java-options '-cp $APPDIR\config;$APPDIR\lib\gson-2.10.1.jar;$APPDIR\lib\xmlbeans-5.1.1.jar;$APPDIR\lib\mssql-jdbc-12.4.0.jre8.jar;$APPDIR\MyApp.jar'
    

    If I use this, it creates a .cfg file with:

    java-options=-cp
    java-options=$APPDIR\config;$APPDIR\lib\gson-2.10.1.jar;$APPDIR\lib\xmlbeans-5.1.1.jar;$APPDIR\lib\mssql-jdbc-12.4.0.jre8.jar;$APPDIR\MyApp.jar
    

    Which is what you want.


    For the native MS SQL library, you should also be able to use --java-options to set the -Djava.library.path:

    --java-options '-Djava.library.path=$APPDIR'
    

    Then just put the DLL file into the folder you pass to --input, and the application should be able to load it using System.loadLibrary from there.