2014-05-18 2 views
0

У меня возникают проблемы с небольшим проектом, над которым я работаю. В этом проекте я пытаюсь динамически создавать классы из конфигурации String и загружать их в JVM.ClassFormatError при определении класса в среде OSGI

Когда я делаю это в «нормальной» среде (Unit Tests), все работает нормально. Но когда я пытаюсь создать классы в среде 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; 
     } 
    }); 

Последняя (надеюсь, полезная) часть информации является ClassLoader Я вызывая метод defineClass при запуске моего проекта в комплекте OSGi: это экземпляр org.apache.felix.framework.BundleWiringImpl.

Было бы здорово, если бы кто-то мог помочь мне здесь!

Привет, Pascal

EDIT: мне нужно определить классы во время выполнения, потому что я хочу, чтобы избежать шаблонный код в моем проекте и сделать программу более последовательной.

Чтобы быть более точным, моим проектом будет RESTful WebService. Поскольку я использую несколько технологий для хранения данных и snychronize процессов (mongoDB, MySQL, activeMQ, ...), я хочу использовать верблюд Apache для работы со всеми различными технологиями. Проблема заключается в том, что я не знаю, насколько хорошо знаю Camel с подходом Java к REST (все сопоставление методов и классов с HTTP-запросами выполняется с помощью аннотаций). Таким образом, единственной возможностью для меня было написать методы, которые будут размещать параметры запроса в заголовках обмена Camel и запускать их по маршруту. Чтобы избежать этого, я хотел автоматизировать этот процесс, определив эти классы во время выполнения из определений маршрутов.

+0

Почему вы пытаетесь определить класс 'java.lang.String'? Конечно, это уже существует и определяется загрузчиком загрузки классов? В Java только загрузчивому загрузчику классов разрешено определять классы, имя которых начинается с 'java.'. –

+0

Можете ли вы немного объяснить, почему вы создаете пользовательские классы? Возможно, есть еще лучший способ добиться того, чего вы хотите в OSGi. –

+0

@NeilBartlett Я не хочу определять java.lang.String. Я хочу определить совершенно новый класс, который, например, входной параметр типа String. Кристиан, я обновил вопрос, чтобы вы могли сделать более точную картину проблемы. – user2764975

ответ

0

Напишите свой собственный загрузчик классов, родитель которого является bundle's class loader, вместо того, чтобы пытаться взломать существующий загрузчик классов.

+0

Наконец-то он заработал. Я не думаю, что взлом существующего классаLoader был проблемой, потому что даже после создания моего класса classLoader я столкнулся с той же проблемой, поскольку в создавшемся байт-кодеке была небольшая ошибка, а классы аннотаций javax.ws.rs не были bundle classpath (BND не добавлял их в манифест). Но с помощью пользовательского подхода classLoader это чище, поэтому спасибо за это :). – user2764975

Смежные вопросы