Reputation: 17825
I am getting a NoClassDefFoundError when trying to transmit a soap request with my app.
I've read that NoClassDefFoundError can often be caused by an exception initializing the class in question, but I've looked through the logs and this is the only error reported by the app.
I've been able to log the class name:
val classPath = SubjectPublicKeyInfo::class.java.getResource(SubjectPublicKeyInfo::class.java.simpleName + ".class").toString()
log.info("Class: $classPath")
And verified that the version of bouncy castle is the one expected by my version of Apache CXF:
implementation("org.apache.cxf:apache-cxf:3.3.5")
implementation("org.bouncycastle:bcprov-jdk15on:1.54")
Could it be a problem with a different class loader? Or Tomcat doing ... something strange? Tomcat version is 7.0.76
and Java is java 8.
Exception:
java.lang.NoClassDefFoundError: org/bouncycastle/asn1/x509/SubjectPublicKeyInfo
org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePublic(Unknown Source)
java.security.KeyFactory.generatePublic(KeyFactory.java:334)
sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
sun.security.x509.X509Key.parse(X509Key.java:170)
sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1804)
sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:102)
java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:716)
sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
java.security.KeyStore.load(KeyStore.java:1445)
org.apache.wss4j.common.crypto.Merlin.load(Merlin.java:370)
org.apache.wss4j.common.crypto.Merlin.loadProperties(Merlin.java:228)
org.apache.wss4j.common.crypto.Merlin.<init>(Merlin.java:156)
org.apache.wss4j.common.crypto.CryptoFactory.getInstance(CryptoFactory.java:119)
org.apache.cxf.ws.security.wss4j.WSS4JUtils.loadCryptoFromPropertiesFile(WSS4JUtils.java:300)
org.apache.cxf.ws.security.wss4j.AbstractWSS4JInterceptor.loadCryptoFromPropertiesFile(AbstractWSS4JInterceptor.java:221)
org.apache.wss4j.dom.handler.WSHandler.loadCrypto(WSHandler.java:979)
org.apache.wss4j.dom.handler.WSHandler.loadSignatureCrypto(WSHandler.java:874)
org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:158)
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor.access$100(WSS4JOutInterceptor.java:57)
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessageInternal(WSS4JOutInterceptor.java:275)
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:147)
org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:132)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441)
org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356)
org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)
org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
com.sun.proxy.$Proxy197.bulkRequestTransmitter(Unknown Source)
com.myapp.transmission.irsservices.CXFWebServiceHelper.callTransmitterWebService(CXFWebServiceHelper.java:135)
com.myapp.transmission.controllers.SubmitController.doGet(SubmitController.java:131)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Some additional info as I've looked into it further:
JDK version is:
openjdk version "1.9.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
Using Gradle to build the project. I also have discovered that when running it locally I get a security exception that seems to come later in the process. So I think the class is being properly loaded when run locally, but not on the remote server. But how can I be able to print out the class info both locally and remotely without exception?
Here's the full dependency section of my build.gradle.kts
file (note I've taken out the direct bouncy castle dependency. Same version is pulled in either way):
dependencies {
implementation("org.mongodb:bson:3.6.4")
implementation("org.apache.commons:commons-collections4:4.1")
implementation("commons-fileupload:commons-fileupload:1.3.1")
implementation("commons-io:commons-io:2.4")
implementation("commons-lang:commons-lang:2.3")
implementation("com.google.code.gson:gson:2.3.1")
implementation("com.google.guava:guava:19.0")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.7.0")
implementation("com.fasterxml.jackson.core:jackson-core:2.8.0.rc2")
implementation("com.fasterxml.jackson.core:jackson-databind:2.8.0.rc2")
implementation("ch.qos.logback:logback-classic:1.1.3")
implementation("ch.qos.logback:logback-core:1.1.3")
implementation("org.mongodb:mongodb-driver:3.6.4")
implementation("org.mongodb:mongodb-driver-core:3.6.4")
implementation("org.apache.pdfbox:pdfbox-app:2.0.17")
implementation("org.slf4j:slf4j-api:1.7.7")
implementation("org.apache.xmlbeans:xmlbeans:2.5.0")
implementation("org.apache.cxf:apache-cxf:3.1.18")
implementation("org.jetbrains:annotations:18.0.0")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
providedCompile("javax.servlet:javax.servlet-api:3.1.0")
providedCompile("javax.mail:javax.mail-api:1.6.2")
testImplementation("httpunit:httpunit:1.7")
}
Upvotes: 3
Views: 1757
Reputation: 4139
It looks like a dependency clash between a library in your application and one loaded by Tomcat. Note that all libraries embedded in Tomcat lib
folder prevail over the ones deployed in your app, as Tomcat provide them through its Common Classloader. More detail in officialise doc: https://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
Happy to help !
Upvotes: 2