【发布时间】:2012-12-26 13:57:15
【问题描述】:
- 在我的
/tomcat/lib目录中,我有SharedClass类(因此与所有网络应用程序共享)。 - 在我的网络应用程序的
WEB-INF/lib中,我有课程LocalClass。 -
SharedClass引用了LocalClass。
在我的网络应用程序中,我尝试创建 SharedClass 的实例,但失败并显示以下消息:
NoClassDefFoundError: LocalClass.
由于SharedClass 是共享的,而LocalClass 是我的网络应用程序的本地,我希望它可以工作,但它没有。
我怀疑SharedClass 是由Tomcat 父类加载器加载的,LocalClass 是由Web App 类加载器加载的。由于SharedClass 是由父级加载的,我假设它的所有依赖项也必须由父级加载。因此,父级找不到LocalClass 并抛出错误。
这有意义吗?有没有办法解决这个问题(无需编写我自己的类加载器)?
【问题讨论】:
-
在所有编辑之后,
SharedClass似乎直接引用了它LocalClass。在这种情况下,我展示的上下文类加载器技巧将不起作用,您需要将 JAR 打包在一起。 -
所以如果我理解正确的话,一旦
SharedClass被父类加载器加载,它就被该类加载器“拥有”。因此,它引用的任何其他类,即使它们直到稍后才加载(例如,当调用方法时)仍将由 Parent 加载,而 Web App Classloader 将永远没有机会加载它们?如果我也使用反射来加载依赖类,这是真的吗? -
如果
X.class.getClassLoader() == X.class.getClassLoader(),X只是X的一个实例。父类加载器无法解析子类加载器中的类型,即使可以,它也只能看到其中一个。 感谢 Tomcat 不支持 parent-last 类加载器 - 那是一大堆错误。 -
@dough:没有。 SharedClass 由 Tomcat 类加载器加载,而 LocalClass 无法被该类加载器访问:它不在 Tomcat 类路径中。
-
@dough - 由于 JB Nizet 所说的原因,简单的反射不起作用。您可以使用上下文类加载器加载类,然后使用反射来调用它的方法。 但这是一个非常糟糕的主意。
标签: java class tomcat web-applications classloader