Search code examples
clojureleiningenuberjar

leiningen uberjar - add external jar at runtime


I am trying to see how I can add a directory and an external jar to the classpath when making a leiningen uberjar.

The reason is that I need to distribute a jar but some dependencies (jdbc driver for example) cannot be compiled into the uberjar due to licencing restrictions.

I would also like to provide certain external resources such as properties for logging and configuration external to the jar.

Normally in java or spring boot I would use the appropriate command line option to change the classpath. However -cp does not find the jar etc

Is there a way to do this or an appropriate plugin? Thanks in advance


Solution

  • You can add the jar as a resource in the :dev profile. Then it is added to the classpath. The dev profile is for the local development and not packaged into the uberjar.

    :profiles {
             :uberjar {:aot :all}
             :dev {:resource-paths ["no-redist/commercial-jdbc-driver.jar"]}}
    

    At 'production' time with the uberjar you need set the classpath then manually:

    java -cp no-redist/commercial-jdbc-driver.jar;your-app-uber-jar.jar main.namespace
    

    Afaik when using the -jar flag, it uses the dependencies in the jar file, whatever is linked and referred to in there. Combining -cp and -jar might not work.

    Another way is to refer to the no-distributable jar file in the jar manifest (META-INF/MANIFEST.MF):

    Class-Path: no-redist/commercial-jdbc-driver.jar
    

    The the java -jar your-app-uber-jar.jar would look for the jar in the folder no-redist/commercial-jdbc-driver.jar in the local directory. Add this in leinigen like:

    :manifest {"Class-Path" "no-redist/commercial-jdbc-driver.jar"}