0

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

4

1 回答 1

0

编写你自己的类加载器,它的父类是包的类加载器,而不是试图侵入现有的类加载器。

于 2014-05-19T16:43:29.277 回答