【发布时间】:2013-09-16 17:57:48
【问题描述】:
我正在尝试为 Java 编写一个简单的插件架构(它扩展了我们现有的一些功能,这就是我没有使用合适的插件库的原因)
我的战争中有一个基类(使用 JBoss 部署):
package org.example.components;
public abstract class ComponentBase {
// Base code
}
我有一个 jar custom-components.jar 包含一些自定义组件代码:
package org.example.components.custom;
public class CustomComponent extends ComponentBase {
// Custom code
}
通过一些魔法,我的战争中的插件代码获得了 CustomComponent 类的名称并执行以下操作:
Class classToRegister = Class.forName("org.example.components.custom.CustomComponent");
但是,这会抛出一个NoClassDefFoundError,说它找不到org.example.components.ComponentBase。
Caused by: java.lang.NoClassDefFoundError: org/example/components/ComponentBase
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.jboss.mx.loading.RepositoryClassLoader.findClassLocally(RepositoryClassLoader.java:690)
at org.jboss.mx.loading.RepositoryClassLoader.findClass(RepositoryClassLoader.java:670)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassLocally(RepositoryClassLoader.java:200)
at org.jboss.mx.loading.ClassLoadingTask$ThreadTask.run(ClassLoadingTask.java:131)
at org.jboss.mx.loading.LoadMgr3.nextTask(LoadMgr3.java:399)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:527)
at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:627)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1345)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
... 259 more
Caused by: java.lang.ClassNotFoundException: No ClassLoaders found for: org/example/components/ComponentBase
at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:212)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:521)
at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:415)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 297 more
ComponentBase 加载正常,因为我可以在没有错误的情况下执行Class.forName('org.example.components.ComponentBase')。初始化CustomComponent 时是否使用了不同的类加载器?我尝试显式传入一个类加载器,但我得到了同样的错误。
【问题讨论】:
-
“它”是谁?你可以发布堆栈跟踪吗?还有:stackoverflow.com/questions/3957637/…
-
Class.forName抛出异常。我已经编辑了帖子以使其更清晰。 -
ServiceLoader类在这种情况下不会有太大用处,因为找到CustomComponent类名的“魔术”基于 bean 配置和与现有匹配的注释的混合工作内部会议。没有一组固定的基类可供ServiceLoader查找。 -
custom-components.jar 在哪里?在你的战争 WEB-INF/lib 中?
-
custom-components.jar就在类路径的某个位置。
标签: java plugins reflection classloader