【问题标题】:NoClassDefFoundError for org.bouncycastle.asn1.x509.SubjectPublicKeyInfo when using Apache CXF使用 Apache CXF 时 org.bouncycastle.asn1.x509.SubjectPublicKeyInfo 的 NoClassDefFoundError
【发布时间】:2020-01-27 18:45:39
【问题描述】:

我在尝试使用我的应用传输肥皂请求时收到 NoClassDefFoundError。

我了解到 NoClassDefFoundError 通常是由初始化相关类的异常引起的,但我查看了日志,这是应用程序报告的唯一错误。

我已经能够记录班级名称:

val classPath = SubjectPublicKeyInfo::class.java.getResource(SubjectPublicKeyInfo::class.java.simpleName + ".class").toString()
log.info("Class: $classPath")

并验证了充气城堡的版本是我的Apache CXF版本所期望的:

implementation("org.apache.cxf:apache-cxf:3.3.5")
implementation("org.bouncycastle:bcprov-jdk15on:1.54")

可能是不同的类加载器有问题吗?或者 Tomcat 正在做……一些奇怪的事情? Tomcat 版本是7.0.76,Java 是 java 8。

例外:

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)

我进一步研究的一些附加信息:

JDK版本是:

openjdk version "1.9.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)

使用 Gradle 构建项目。我还发现,在本地运行它时,我得到了一个似乎在进程后期出现的安全异常。所以我认为这个类在本地运行时被正确加载,但不是在远程服务器上。但是,我怎样才能在本地和远程打印出课程信息而无一例外呢?

这是我的 build.gradle.kts 文件的完整依赖项部分(注意我已经删除了直接充气城堡依赖项。无论哪种方式都拉取相同的版本):

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")
}

【问题讨论】:

  • Java 8 - Oracle、OpenJDK 的分布是什么?什么精确的版本?
  • 1.您是否验证过您的 Webapp 不包含同一个库的两个版本?有时(尤其是使用 Maven 构建)您可能会遇到此类问题。 2.你检查过Tomcat本身提供的库吗?它们是第一手加载的,并且可以在运行时覆盖您自己的应用程序库。 3. Tomcat 实例上除了你自己的应用程序之外,是否还有其他应用程序在运行?在某些情况下,可能会发生分类冲突。
  • 请提供您项目的依赖报告。在您的第一个代码示例中,您的日志语句的确切输出是什么?
  • @KarolDowbecki 这是 Kotlin。
  • @amanin 我解决了!我认为这可能是由于您的问题 #2,但您启发我从头开始重建远程服务器的 Tomcat,这比我预期的要容易并解决了问题。 Tomcat 库中的一个手动修改的库必须导致加载不同版本的 Bouncy Castle。如果您想发布答案,我会奖励您。

标签: java cxf bouncycastle


【解决方案1】:

这看起来像是应用程序中的库与 Tomcat 加载的库之间的依赖冲突。请注意,嵌入在 Tomcat lib 文件夹中的所有库都优于部署在您的应用程序中的库,因为 Tomcat 通过其 Common Classloader 提供它们。更多细节在官方文档中:https://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

乐于助人!

【讨论】:

    猜你喜欢
    • 2011-07-27
    • 2022-01-18
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多