Building an uberjar with bouncycastle

I’m trying to build 1 executable jar file with all my dependencies. One of my dependencies is bouncycastle. I’ve found multiple solutions, but none have worked for me yet. Here’s what I’ve tried:

Here are my relevant dependencies:

dependencies {
    // ... snip ...
    compile group: 'org.bouncycastle', name: 'bcpg-jdk15on', version: '1.52'
    compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.52'
    // ... snip ...
}

With this config:

jar {
    // thanks: https://stackoverflow.com/questions/22911190/gradle-build-dependancy-throwing-classnotfoundexception/23010014#23010014
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    manifest {
        attributes 'Main-Class': 'my.Main'
    }
}

I get the following exception when running the jar:

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
        at sun.security.util.SignatureFileVerifier.processImpl(Unknown Source)
        at sun.security.util.SignatureFileVerifier.process(Unknown Source)
        at java.util.jar.JarVerifier.processEntry(Unknown Source)
        at java.util.jar.JarVerifier.update(Unknown Source)
        at java.util.jar.JarFile.initializeVerifier(Unknown Source)
        at java.util.jar.JarFile.getInputStream(Unknown Source)
        at sun.misc.URLClassPath$JarLoader$2.getInputStream(Unknown Source)
        at sun.misc.Resource.cachedInputStream(Unknown Source)
        at sun.misc.Resource.getByteBuffer(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Error: A JNI error has occurred, please check your installation and try again

With this config:

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'my.Main'
    }
}

I get a PGPException…

org.bouncycastle.openpgp.PGPException: Exception decrypting key

…with the following underlying exception:

java.lang.SecurityException: JCE cannot authenticate the provider BC

It seems like I’m packaging bouncycastle’s signatures incorrectly, but I’m not sure how I should be doing this when making an uberjar.

So my code above (correct me if I’m wrong) is re-packaging all my dependencies. If that’s the case, I need to figure out how Eclipse’s Export as Runnable Jar File works, because that makes an uberjar that doesn’t break when packaging BC.

http://www.java2s.com/Tutorial/Java/0180__File/Comparetwozipfiles.htm

Hmm. It looks like Eclipse is including the jar files (unmodified) and my build is extracting all the .class files. I’ll have to see if I can do what Eclipse is doing.

It looks like OneJar supports jars within a jar via a custom classloader.

There’s a OneJar gradle plugin at

I’m guessing eclipse is doing something similar. Check the eclipse jar manifest. Is it specifying your class as the Main-Class? My guess no (it’s being proxied through another utility)

Looks like Eclipse has its own loader:

Rsrc-Main-Class: my.Main
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

After some trying, the OneJar plugin got me most of the way there… unfortunately not the whole way:

[Boot] INFO:  setProperties(com.simontuffs.onejar.JarClassLoader@6e0be858)
[Boot] INFO:  using JarClassLoader: com.simontuffs.onejar.JarClassLoader
Exception in thread "main" java.lang.NullPointerException
	at java.lang.String.replace(String.java:2240)
	at com.simontuffs.onejar.JarClassLoader.replaceProps(JarClassLoader.java:501)
	at com.simontuffs.onejar.JarClassLoader.load(JarClassLoader.java:349)
	at com.simontuffs.onejar.JarClassLoader.load(JarClassLoader.java:319)
	at com.simontuffs.onejar.Boot.run(Boot.java:295)
	at com.simontuffs.onejar.Boot.main(Boot.java:161)

I’ll try a few more things and open an issue on the OneJar repo if I think it’s their issue. Thanks for your help!

If you can’t get OneJar working you could just extract JarRsrcLoader.class from the eclipse jar and pack into yours using the same manifest values.

Obviously a bit hacky but if it works i wouldn’t lose any sleep over it :wink:

I opened an issue. I’d rather not hack it :stuck_out_tongue:

A possible alternative to one-jar or the Eclipse export-as-runnable-jar is the spring-boot-loader. I have successfully used it with the Bouncy Castle provider (and, in contrast to one-jar, I didn’t have to do anything clever to make it work). I think I saw that it has a Gradle plugin but I haven’t tried it; I was still just using Maven.

Hi Thomas,
Could you share with me how you used the spring-boot-loader with Bouncy Castle provider. For me, I still run into the issue described in this post. Thanks!