Bundle.loadClass() возвращает экземпляр класса без полей или методов

#java #osgi #classloader #equinox #apache-felix

#java #osgi #загрузчик классов #равноденствие #apache-felix

Вопрос:

Я хочу программно создать фреймворк OSGi, загрузить с ним пакет и загрузить класс из этого пакета. Когда я вызываю Bundle.loadClass() , я получаю Class запрос, для всех полей методов конструктора установлено значение null. У него есть только имя. Я не могу получить доступ к каким-либо общедоступным методам и т. Д. Я пробовал как Equinox, так и Felix с тем же результатом.

Пакет MANIFEST :

 Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Activator: org.osgitest.osgitest.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Name: OSGi Test
Bundle-SymbolicName: org.osgitest.osgitest
Bundle-Version: 1.0
Import-Package: org.osgi.framework
Export-Package: org.osgitest.osgitest.test
  

Настройка фреймворка:

 FrameworkFactory ff = new EquinoxFactory();
Map<String, String> config = new HashMap<String, String>(1);
config.put("org.osgi.framework.storage.clean", "onFirstInit");
Framework framework = ff.newFramework(config);
framework.init();
framework.start();
  

и

 FrameworkFactory ff = new org.apache.felix.framework.FrameworkFactory();
Map<String, String> config = new HashMap<String, String>(1);
config.put("org.osgi.framework.storage.clean", "onFirstInit");
Framework framework = ff.newFramework(config);
framework.init();
framework.start();
  

Загрузка пакета:

 Bundle testBundle = framework.getBundleContext().installBundle("file:C:\org-osgitest-osgitest.jar");
testBundle.start();
Class<?> classOne = testBundle.loadClass("org.osgitest.osgitest.test.ClassOne");
Class<?> activator = testBundle.loadClass("org.osgitest.osgitest.Activator");
  

Class Экземпляр Activator содержит ссылку на конструктор, но не содержит общедоступных методов. Он имеет public void start(BundleContext c) и public void stop(BundleContext c) .

Как я могу загрузить правильный Class ? Что я делаю не так? Спасибо за любую помощь.

Ответ №1:

Class использует какую-то ленивую инициализацию. Class экземпляр будет заполнен методами / полями только после выполнения getMethods etc . Вот почему я ничего не смог увидеть в отладчике.

Я попытался вызвать public static void main(String[] args) и не привел свой String[] к Object . Таким образом, это было интерпретировано как Object[] , и JVM искал метод с сигнатурой (args[0].class, args[1].class, ... , args[n].class) . Вот почему мой метод не был найден.

Ответ №2:

Поскольку пакет представляет собой jar, вы пытались загрузить класс в обычном режиме пути к классу? OSGi просто определяет загрузчики классов. Виртуальная машина по-прежнему отвечает за создание объектов класса из байт-кодов. Поэтому я не понимаю, как платформа OSGi может «удалить» элементы из объекта класса.