我目前遇到了我正在处理的一个小项目的问题。在这个项目中,我试图从配置字符串动态创建类并将其加载到JVM中。在OSGI环境中定义类时ClassFormatError
当我在“正常”环境(单元测试)中执行此操作时,一切正常。但是当我尝试在OSGI环境(Apache Karaf)中创建类时,我收到一个ClassFormatError,其中包含消息“Illegal class name”Ljava/lang/String;“in class ...”。
经过简短的研究,我发现这个问题发生在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方法:它是org.apache.felix.framework.BundleWiringImpl的一个实例。
如果有人能帮助我在这里,这将是伟大的!
问候, 帕斯卡尔
编辑: 我需要在运行时定义类,因为我想避免的样板代码在我的项目,使程序更加一致。
更确切地说,我的项目将是一个RESTful WebService。由于我使用多种技术来存储数据和同步进程(mongoDB,MySQL,activeMQ,...),我想使用Apache骆驼来处理所有不同的技术。 问题是,我不知道在REST上很好地将Camel与Java方法集成在一起(整个方法和类到HTTP请求的映射是使用注释完成的)。 所以对我来说唯一的可能是编写方法,将请求的参数放在骆驼的交换头文件中并将它们发送到路由。 为了避免这种情况,我希望通过在路由定义中定义运行时的这些类来自动执行此过程。
你为什么试图定义类java.lang.String?当然,这已经存在,并由启动类加载器定义?在Java中,只有引导类加载器才被允许定义名称以'java.'开头的类。 –
你能否解释一下为什么你要做自定义类的创建?也许还有更好的方法来实现你想要的OSGi。 –
@NeilBartlett我不想定义java.lang.String。我想定义一个全新的课程,例如一个String类型的输入参数。克里斯蒂安,我更新了这个问题,这样你就可以更准确地了解问题。 – user2764975