1
votes

I have a clojure project that depends on a Java library, that does not work, when it gets included in an uberjar. (It needs different XML descriptors using the same filename in different JAR files.)

Everything I find on using Docker with leiningen depends on building and packaging a uberjar. That's also how I built all clojure Docker images so far.

Is there any leiningen plugin out there, that understands to package a Docker image using several jar files like io.fabric8/docker-maven-plugin does?

1
An uberjar is language independent. So you can build one with Clojure code in it using any build tool. Generally I prefer lein to SBT, but for creating uberjars I've had more success with SBT plugins than lein plugins. For example in your case github.com/marcuslonnberg/sbt-docker might help you. - Chris Murphy
@ChrisMurphy Thanks for your suggestion. My problem is, that a library that I'm using doesn't work when repackaged to a uber-jar. I have to package my container with the original jar file and then reference this jar in the classpath when starting the application.–When I'm doing this manually it works. It also works when I package with docker-maven-plugin as this plugin does not repackage the jars. The problem with maven is, that emacs/cider does not support maven. - Matthias Wimmer

1 Answers

0
votes

Whenever packaging (uberjar, war) the big file that is created contains .class files and a directory structure. Where are these XML files supposed to be (class)loaded from? You can experiment with packing manually. After all it (whether uberjar, war or jar) is just a zip file.

When you know exactly the layout you need SBT is flexible enough to insure you can package from the many input jar files. Unfortunately lein plugins will do things like always overwrite duplicates, and you can't control the packaging behaviour. I can't remember exactly the inflexibilities, but I couldn't control how the packaging process went, what decisions were made.

For doing it manually I use a Linux something called Archive Manager, which I found to be much better than what I used when on Windows. Doing it manually may be all you need. The downside of SBT of course being that you have to learn it, which includes a bit of Scala.

It needs different XML descriptors using the same filename in different JAR files.

Just thinking about this, is it that you need to append the contents of each file that is in a different jar into the one file that is in the uberjar? You can try it out. If it works and you need to package up often enough that manually creating and renaming a zip file every time becomes a pain, then I believe that SBT will be your best bet.

I have to package my container with the original jar file and then reference this jar in the classpath when starting the application

The classloader loads classes rather than jars. It is the container's job to unpackage all the things you give it, such as .class files, (uber)jars, wars. Any program that dynamically loads from the classpath is loading either classes or resources (things like .xml files). I suppose a .jar file could be a resource, in which case you would put the jar file in the uberjar. So it is still possible to package it up.