05 June 2010

Leiningen 1.1.0 bugs

There's a pesky bug in Leiningen 1.1.0 right now. Actually two.

One attacks modules with dashes in their name (you should get a java.lang.NoClassDefFoundError error when you try to java -jar your-app.jar).

The second attacks when your Clojure program depends on a Java signed jar (you should get a Exception in thread "main" java.lang.SecurityException: no manifiestsection for signature file entry some/package/some.class).

Here's the workaround.

Let's say you have a project pesky-bug, and you build it into a standalone application using lein uberjar, which outputs a pesky-bug-standalone.jar.

Jar's are just zipped containers, so open it up as a zipped file. I use the Archive Manager in Ubuntu, which is great for this purpose.

Look for directory META-INF. Inside, there should be a file called MANIFEST.MF.  Both bugs will require you to fix this MANIFEST.MF file.


Workaround for the First Bug
The first bug occurs because the -main function is located in the "main" namespace (ie, pesky-bug.core) in the file pesky_bug/core.clj (declared as main through the :main pesky-bug.core line in the project.clj file).

Leiningen tells Java the namespace is pesky-bug.core but Java doesn't like dashes in module names. It should've been an underscore character!

So open up the MANIFEST.MF file with, eg, gedit.

Look for the line:

Main-Class: pesky-bug.core
and replace it with:

Main-Class: pesky_bug.core

Problem solved. No recompiling necessary.

Workaround for the Second Bug
The second bug occurs when your program depends on a Java jar library that is signed. Leiningen isn't copying over the signatures from that jar file's MANIFEST.MF to yours.  (This is a known issue, but there's a comment there about a fix that's different than the one described here.  So YMMV.)

So for example, let's say you get this error:

Exception in thread "main" java.lang.SecurityException: no manifiest section for signature file entry javax/activation/MimeType.class

Now I know that class comes from the mmemail Clojar package, so I look for it in the lib directory in my project (the specific Clojar package is mmemail-1.0.0 in this case).

I open it up as a zipped file with Archive Manager again and open up META-INF/MANIFEST.MF.  In that file, I see a listing of Name/SHA1-Digest pairs.  I copy every one of those pairs and paste it into my own pesky-bug-standalone.jar's META-INF/MANIFEST.MF.

Problem solved. No recompiling necessary.

Note that to solve the specific problem of not having the signature for javax/activation/MimeType.class, I'd really only have to copy over the Name/SHA1-Digest pair for it (leaving out all the rest of the other pairs). But if I did that, I'll keep getting the "signature file missing" error again and again until I'd have copied over every one of those key/value pairs anyway.

No comments: