【发布时间】:2014-07-06 19:39:26
【问题描述】:
我目前正在处理的一个小项目遇到问题。在这个项目中,我试图从配置字符串动态创建类并将其加载到 JVM 中。
当我在“正常”环境(单元测试)中执行此操作时,一切正常。但是,当我尝试在 OSGI 环境(Apache Karaf)中创建类时,我收到一个 ClassFormatError 消息“非法类名“Ljava/lang/String;”在类中......”。
经过简短的研究后,我发现 java/lang 中的类在系统类加载器未加载时会出现此问题,但在 java 中的类加载,尤其是 OSGi 中,我不是专家.
我认为我访问 defineClass 方法的方式可能对这个问题很感兴趣,所以这里是:
PROTECTION_DOMAIN = (ProtectionDomain) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return RestEndpoint.class.getProtectionDomain();
}
});
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
Class loader = Class.forName("java.lang.ClassLoader");
DEFINE_CLASS = loader.getDeclaredMethod("defineClass",
new Class[]{ String.class,
byte[].class,
Integer.TYPE,
Integer.TYPE,
ProtectionDomain.class });
DEFINE_CLASS.setAccessible(true);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return null;
}
});
最后一条(希望有用的)信息是我在 OSGi 包中运行我的项目时调用 defineClass 方法的 ClassLoader:它是 org.apache.felix.framework.BundleWiringImpl 的一个实例。
如果有人可以在这里帮助我,那就太好了!
您好, 帕斯卡
编辑: 我需要在运行时定义类,因为我想在我的项目中避免样板代码并使程序更加一致。
更准确地说,我的项目将是一个 RESTful WebService。由于我使用多种技术来存储数据和同步进程(mongoDB、MySQL、activeMQ,...),我想使用 Apache camel 来处理所有不同的技术。 问题是我知道不可能将 Camel 与 REST 上的 Java 方法很好地集成(方法和类到 HTTP 请求的整个映射是通过注释完成的)。 所以对我来说唯一的可能性是编写方法,将请求的参数放在 Camel 的交换标头中并将它们发送到路由。 为了避免这种情况,我想通过在运行时从路由定义中定义这些类来自动化这个过程。
【问题讨论】:
-
你为什么要定义类
java.lang.String?肯定已经存在并且由引导类加载器定义?在 Java 中,仅允许引导类加载器定义名称以java.开头的类。 -
你能解释一下你为什么要创建自定义类吗?也许还有更好的方法可以在 OSGi 中实现您想要的。
-
@NeilBartlett 我不想定义 java.lang.String。我想定义一个全新的类,例如String 类型的输入参数。克里斯蒂安,我更新了问题,以便您可以更准确地了解问题。
标签: java osgi classloader karaf