2013-07-24 3 views
0

У меня возникла проблема, которая представляет собой комбинацию «простой» Java, равноденствия и связи между ними. Я прочитал другие связанные вопросы (here, here и there, а также другие веб-сайты, такие как this one и that one), но не смогли найти удовлетворительного (или работающего!) Решения.Получение объекта из Equinox/Eclipse

У меня есть набор плагинов: P1, P2 и P3. P1 экспортирует несколько классов, которые используются P2. P2 дополнительно экспортирует другие классы и интерфейсы, которые используются P3. В частности, P2 определяет и экспортирует интерфейс MyInterface и его реализацию класс MyInterfaceImpl реализует MyInterface. P3 является приложением и, таким образом, содержит класс Launcher реализует IApplication и определяет метод public Object (IApplicationContext). Все прекрасно компилируется. Когда я запускаю Launcher как приложение Eclipse из Eclipse, он работает нормально. Пусковая установка использует MyInterface и MyInterfaceImpl штраф.

Теперь я программно запустить мое приложение, используя следующий (простой) код, который, кажется, чтобы быть «хорошо» способ запуска приложения Equinox/Eclipse, в соответствии с различными сообщений:

void callApplication() { 
    final String[] args = 
     new String[] { 
      "-application", 
      "Launcher", 
      ... }; 
    EclipseStarter.run(args, null); 
} 

Опять же, этот фрагмент кода отлично работает, и я могу «видеть» мой запуск приложения и давать ожидаемые результаты.

Теперь вот моя проблема: я хотел бы получить экземпляр MyInterfaceImpl, созданный моим приложением, работающий в Equinox, обратно внутри «внешнего» Java-кода. Мое наивное решение было вернуть этот объект в начале общественного объекта (IApplicationContext) метода и изменить мой код вызова следующим образом:

MyInterface callApplication() { 
    final String[] args = 
     new String[] { 
      "-application", 
      "Launcher", 
      ... }; 
    return (MyInterface) EclipseStarter.run(args, null); 
} 

Но это наивное решение не работает. Я получаю java.lang.ClassCastException: MyInterfaceImpl не может быть перенесен в MyInterface. Думая об этом, это имеет смысл, потому что, в конце callApplication(), у меня есть две «версии» пар {MyInterface, MyInterfaceImpl}: один из «внешнего» Java кода, загруженного элементом JVM-класс-загрузчик, а другой - от Equinox, загружаемый классом-загрузчиком Equinox. Я изменил мой код для печати класса-погрузчиков возвращенного объекта и MyInterface:

final Object o = EclipseStarter.run(args, null); 
System.out.println(o.getClass().getClassLoader()); 
System.out.println(MyInterface.class.getClassLoader()); 

и, на самом деле, я получил:

[email protected]c[P2:1.5.0(id=413)] 
[email protected] 

Обратите внимание, что класс-погрузчик возвращаемым объект, как говорят, исходит из P2, как и ожидалось, потому что P2 является плагином, который определяет и экспортирует MyInterface и MyInterfaceImpl.

Я пробовал разные способы, чтобы получить «совместимые» пары {MyInterface, MyInterfaceImpl}, но не повезло до сих пор (я всегда получаю один и тот же java.lang.ClassCastException: MyInterfaceImpl не может быть приведен к MyInterface):

  • Я попытался установить свойства -Dorg.osgi.framework.bootdelegation = * -Dorg.osgi.framework.system.packages.extra = MyInterface, MyInterfaceImpl.

  • Я также попытался перехватить DefaultClassLoader в методе пуска().

Итак, мой вопрос: Есть ли способ для программы Java, которая использует некоторые классы, определенные в проекте, который также плагин и который экспортировать эти классы, обмениваться экземплярами этих классы с экземпляром Eclipse начали программно? Спасибо!

ответ

1

А, это сложно. Я бы предложил перестроить ваше приложение и использовать плагины для всего, но это не отвечает на ваш вопрос.

Теперь, что вы хотите сделать, сначала удалите форму определения интерфейса P2 и добавьте ее в ваш оригинальный (не OSGi) JAR, предпочтительно в пакете самостоятельно, допустим, com.example.api. Затем добавьте -Dorg.osgi.framework.system.packages.extra=com.example.api; также добавьте импорт в P2 и P3 для этого пакета.

Надеюсь, это поможет.

+0

Спасибо @Tassos, это сработало, и я узнал, что я также могу изменить файл .ini, используемый OSGi, чтобы включить эту строку, не имея необходимости менять командную строку. –

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

  • Нет связанных вопросов^_^