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
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"}
Related
I defined :resource-paths in profile.clj to include some special jar (vertica jdbc) file. and then I run lein uberjar: trying to pack that jar file into the standalone jar file, but after I run it, and uncompressed it, I can't find that vertica jdbc file.
Leiningen can create jar files, but the only place it picks them up from is your maven repository (under an .m2 directory on your machine). Once your special jar is in maven you need to refer to it as a dependency in your project.clj file.
If your jar file was in clojars this would be quite easy - just put in a dependency - lein will fetch it into your maven repository. On the other hand if it was your own source code you would first need to lein install from the directory of that source code project.
However I'm guessing your file is just a jar file you have, which is not an artifact in clojars. In this case you can install it into your maven repository using this maven command (here assuming my-deps.jar is your file):
mvn install:install-file -Dfile=./my-deps.jar -DgroupId=my-deps -DartifactId=my-deps -Dversion=1.0.0 -Dpackaging=jar
You can then refer to it as a dependency in the uberjar project, and then lein uberjar.
Edit - if you don't want to use raw maven commands then consider using this leiningen library that abstracts them away for you: https://github.com/kumarshantanu/lein-localrepo.
An alternative is to add to project.clj:
:repositories {"local" "file:lib"}
Create a lib directory in your project and add the jar there.
Add the lib reference in the :dependencies tag in project.clj.
This lib directory has the same structure as .m2/repository but is inside your project and local to your project
I am building a MIDI application with Clojure and Leiningen, and I am including some example MIDI files in the resources directory for testing on the REPL. However, I would like to exclude these resources when using lein uberjar. I am not sure if this is possible, or if the best place for test files such as these is in the resources directory. I couldn't find anything specific to this... is there a way to exclude with uberjar-exclusions in project.clj?
The correct approach to your problem would be to have a separate resource directory for development purposes, and have it configured separately in your dev profile in leiningen.
:profiles {:dev {:resource-paths ["dummy-data"] ...
Remember settings get merged into existing ones, so you don't need to specify the standard resources path.
Look at the sample project here, and profiles doc here.
When using lein 2.2, trying to put jar files in /lib does not work.
I tried and it doesn't seems to work but plenty of docs out there says this way still works.
The lib directory functionality was removed in Leiningen v2.0, in favor of a repository (repeatability).
To add free floating jars to a project, you will need to either deploy your dependency to Clojars or a Maven repository. The Maven repository can be as simple as a directory in your project folder.
Please see the answer to this question if you need the jar in a project local folder:
How do I use checked-in jars with leiningen
You do not need to use maven to access a local jar file in Leiningen v2.0
Just use syntax like this in your project.clj:
:resource-paths [ "local-jars/*" ]
and then place your *.jar files in the local-jars subdirectory of your project.
Please see this blog: http://www.troyastorino.com/tidbits/lein2-local-jars
I use Emacs and nrepl.el for Clojure development and I want to include a JAR file (a proprietary JDBC driver that isn't available on Leiningen/Maven) on the classpath for playing around in the REPL.
I have no intention of releasing this JAR as part of a project. I am just writing some utility functions for my own use so I would rather not make it work with Leiningen/Maven at all and just stick with the classpath.
Is it possible to add a jar manually to the set of dependencies that nrepl-jack-in uses?
It is possible, but not through nrepl.el, as it offloads classpath management to Leiningen.
You can use mvn deploy:deploy-file to deploy the JAR file into your local Maven repository. After that just add the identifier to :dependencies in project.clj and Leiningen will then pick it up just fine.
If that seems like too much manual work, check out lein-localrepo plugin: https://github.com/kumarshantanu/lein-localrepo.
Note that everyone who contributes to your project will need to do this manually. See https://github.com/technomancy/leiningen/wiki/Repeatability for extended discussion on why going this way is often a bad idea and goes against the grain of Leiningen. If you're working in a team, setting up a private repository is the best solution in the long run.
Everytime I do a lein new I seem to get a copy of the clojure jar in the lib folder of that project. I thought that jars deps were copied to .m2/repository. Why is the clojure jar duplicated for every lein project?
This only happens with Leiningen 1. The reason for this (I think) was to allow tools to inspect the dependencies easily. With Leiningen 2, this is no longer an issue because it uses the pomegranate library (which is a wrapper for Aether) to manage dependencies. It allows for more robust dependency management, and therefore Leiningen can just link to the dependencies from your local Maven repository.
Jars are cached in your .m2 repo. However, to use them in your project, they need to be on your project's classpath, usually in your project/lib directory. Caching in your local Maven repo just saves you a download from the server.