Just a quick follow-up -- perhaps I am out on an island with this problem, but
if anyone else ever tries to make an executable uber-jar that includes stuff
like
Apache Mina, Sshd, Camel, ActiveMQ, etc. and runs into this problem -- the only
workaround I was able to come up with is to exclude bouncy castle from the
maven shade plugin and make sure it is on the classpath for the executable jar.
This may be completely off-topic, but if someone else is trying to do something
like this, you can configure the shade plugin like below. If you're including
spring, you need the additional transformers so it appends the spring META-INF
stuff and doesn't overwrite it. Now, if you run mvn package, it will make an
executable jar that you can start as long as bcprov jar is in the same
directory...it works.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>LATEST</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${artifactId}-${version}-uberjar</finalName>
<artifactSet>
<!-- we have to exclude bouncycastle
b/c it is signed -->
<excludes>
<exclude>bouncycastle:*</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.example.module.MyMainClassGoesHere</Main-Class>
<!-- add
current dir '.' and conf/ dir to the classpath -->
<Class-Path>.
./bcprov-jdk15-140.jar conf/ conf/bcprov-jdk15-140.jar</Class-Path>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
-----Original Message-----
From: Davis Ford [mailto:[email protected]]
Sent: Friday, September 23, 2011 1:14 PM
To: [email protected]
Subject: "BouncyCastle must be registered as a JCE provider" + maven shade
plugin
Hi all, I use the maven shade plugin
http://maven.apache.org/plugins/maven-shade-plugin/ to create an executable
uber jar of my project so it can just be launched and SFTP connections can be
made to the server.
I use the shade plugin b/c of existing path / classpath clashes when building
the uberjar and it works great. However I had to exclude some signed keys from
it that relate to bouncycastle b/c the shade plugin will fail otherwise.
This is not my pom.xml, but I have configured it similarly:
http://svn.apache.org/repos/asf/directory/apacheds/trunk/all/pom.xml
You'll see it excludes META-INF/BCKEY.SF and META-INF/BCKEY.DSA
If I don't exclude these in the uber-jar, I'll get this exception when I launch
the jar:
Exception in thread "main" 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$000(Unknown Source)
So, I exclude it and the jar starts just fine, but when I go to connect to it
with an SFTP client like FileZilla, I am seeing this problem:
[ NioProcessor-2] DefaultIoFilterChain WARN
Unexpected exception from exceptionCaught handler.
java.lang.IllegalStateException: No session available
at
org.apache.sshd.common.AbstractSessionIoHandler.exceptionCaught(AbstractSessionIoHandler.java:52)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.exceptionCaught(DefaultIoFilterChain.java:697)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextExceptionCaught(DefaultIoFilterChain.java:483)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1100(DefaultIoFilterChain.java:46)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.exceptionCaught(DefaultIoFilterChain.java:791)
at
org.apache.mina.core.filterchain.IoFilterAdapter.exceptionCaught(IoFilterAdapter.java:111)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextExceptionCaught(DefaultIoFilterChain.java:483)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.fireExceptionCaught(DefaultIoFilterChain.java:471)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionCreated(DefaultIoFilterChain.java:359)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.access$700(DefaultIoFilterChain.java:46)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionCreated(DefaultIoFilterChain.java:771)
at
org.apache.mina.core.filterchain.IoFilterAdapter.sessionCreated(IoFilterAdapter.java:79)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionCreated(DefaultIoFilterChain.java:357)
at
org.apache.mina.core.filterchain.DefaultIoFilterChain.fireSessionCreated(DefaultIoFilterChain.java:350)
at
org.apache.mina.core.service.IoServiceListenerSupport.fireSessionCreated(IoServiceListenerSupport.java:211)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.addNow(AbstractPollingIoProcessor.java:536)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.handleNewSessions(AbstractPollingIoProcessor.java:503)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor.access$400(AbstractPollingIoProcessor.java:68)
at
org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1133)
at
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown
Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: BouncyCastle must be registered as
a JCE provider
at
org.apache.sshd.common.keyprovider.FileKeyPairProvider.loadKeys(FileKeyPairProvider.java:78)
at
org.apache.sshd.common.keyprovider.AbstractKeyPairProvider.getKeyTypes(AbstractKeyPairProvider.java:49)
at
org.apache.sshd.server.session.ServerSession.sendKexInit(ServerSession.java:331)
at
org.apache.sshd.server.session.ServerSession.<init>(ServerSession.java:92)
at
org.apache.sshd.server.session.SessionFactory.doCreateSession(SessionFactory.java:43)
at
org.apache.sshd.common.session.AbstractSessionFactory.createSession(AbstractSessionFactory.java:38)
at
org.apache.sshd.common.AbstractSessionIoHandler.sessionCreated(AbstractSessionIoHandler.java:37)
Thus, I am wondering if by excluding those keys, it means the whole process
won't work? My meager understanding of those keys is that they provide a
signature that the jar has not been tampered with. I could be wrong on that,
but can anyone confirm what this code actually does, and why it might be
failing?
FileKeyPairProvider.java
if (!SecurityUtils.isBouncyCastleRegistered()) {
throw new IllegalStateException("BouncyCastle must be registered as
a JCE provider");
}
I suppose the only other possible alternative / workaround is to exclude the
bouncycastle jar from the uber-jar and supply it standalone on the same
classpath