java 没有ClassDefFoundError 但Class 存在并且可用

java NoClassDefFoundError but Class is there and Usable

我有一个非常奇怪的(对我来说)问题。我使用充气城堡 de-/crypt Web 应用程序中的一些邮件。重新部署我的应用程序后出现此异常

java.lang.NoClassDefFoundError: org/bouncycastle/jcajce/spec/SkeinParameterSpec at org.bouncycastle.jcajce.provider.symmetric.util.BaseMac.engineInit(Unknown Source) at javax.crypto.Mac.init(Mac.java:443) at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.calculatePbeMac(Unknown Source) at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad(Unknown Source) at java.security.KeyStore.load(KeyStore.java:1445) at my.application.Class.getDecryptedContent(my.application.Class.java:401) at my.application.Class.decrypt(my.application.Class.java:91) at my.application.Class.getKvConnectMail(my.application.Class.java:320) at my.application.Class.processEinClick(my.application.Class.java:198) at my.application.Class.shedule(my.application.Class.java:44) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273) at org.springframework.scheduling.support.MethodInvokingRunnable.run(MethodInvokingRunnable.java:65) at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51) at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

所以我认为我的应用程序的 WEB-INF/lib 文件夹中缺少该库,但它在那里。

奇怪的是:如果我直接将 Class 与此 Codesnipped 一起使用,则 Snipped 会正确无误地执行。

LOGGER.error("Class!!!: " + SkeinParameterSpec.class.getName());
SkeinParameterSpec spec = new SkeinParameterSpec();
LOGGER.error("Instance!!!: " + spec.toString());
LOGGER.error("Instanceof: " + (spec instanceof SkeinParameterSpec));

但是库 Class org.bouncycastle.jcajce.provider.symmetric.util.BaseMac 使用与我截取的代码几乎相同的代码以上述异常结束。

有人可以帮助我理解为什么会这样吗?

P.S.: 这只会在重新部署后发生,如果重新启动整个 Tomcat every thinks works.

更新 1: 我忘了说我使用 Liferay。但是我的WebApplication是一个普通的WebApplication,与Liferay没有任何关系。

但是:经过一番调查,我发现 Liferay 有一些库 (/tomcat/webapps/ROOT/lib)。还有旧版本的 Bouncycastle。是否有可能我的 WebApplication 使用了这个库,错误是 Liferay 的库和 CustomClassLoaders?

的结果

解法: 请参阅 'inigo skimmer' 正确答案的评论。

我想 class 路径上可能有另一个版本的 bouncycastle lib(可能在 Tomcat/lib 文件夹中)或者其他一些先加载但不包含的 jar 需要想要 class.

原因可能是 BouncyCastle 注册了当前的 ClassLoader,并且在您重新启动 Web 应用程序时卸载了。您应该在 JRE 本身中注册 BouncyCastle。参见 NoClassDefFoundError on BouncyCastle class