У меня возникла проблема, которая представляет собой комбинацию «простой» 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 начали программно? Спасибо!
Спасибо @Tassos, это сработало, и я узнал, что я также могу изменить файл .ini, используемый OSGi, чтобы включить эту строку, не имея необходимости менять командную строку. –