我目前正在处理的一个小项目遇到问题。在这个项目中,我试图从配置字符串动态创建类并将其加载到 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 的交换标头中并将它们触发到路由。为了避免这种情况,我想通过在运行时从路由定义中定义这些类来自动化这个过程。