Добавление банок в плагин Eclipse во время выполнения - PullRequest
7 голосов
/ 28 января 2011

Я работаю над плагином Eclipse, которому нужны классы, которые не известны во время компиляции. Классы отправляются по сети в виде файлов JAR. Я хотел бы динамически загружать эти классы во время выполнения.

Я попробовал подход, указанный здесь: http://blog.imaginea.com/making-applications-work-together-in-eclipse/

К сожалению, это не дает желаемого эффекта. Хотя классы загружаются, я не могу использовать их вне функции, в которую я их загружал. Я предполагаю, что это как-то связано с использованием разных загрузчиков классов.

Любая помощь приветствуется. Даже если вы скажете мне, что это невозможно, поэтому я знаю, что мне не нужно смотреть дальше.

Ответы [ 2 ]

5 голосов
/ 28 января 2011

Если вы сделаете эти jar-файлы в пакеты OSGi (то есть дадите им MANIFEST.MF), то вы можете установить их динамически во время выполнения OSGi.

Если вы добавите активатор пакета в свой плагин, вы можете сохранить org.osgi.framework.BundleContext, а затем сделать следующее:

  Bundle [] newBundle = new Bundle[] { bundleContext.install(location, newJarInputStream) };
  packageAdmin.refreshPackages( newBundle );
  packageAdmin.resolveBundles( newBundle); 

packageAdmin является экземпляром org.osgi.service.packageAdmin.PackageAdmin, который является услугой, которую вы можете приобрести с помощью BundleContext#getService

Новые jar-файлы могут быть целыми пакетами сами по себе, или они также могут быть фрагментами пакетов, в которых ваш плагин является хостом. Если они являются фрагментами вашего пакета, тогда ваш пакет (BundleContext#getBundle()) необходимо будет включить в массив, передаваемый в refreshPackages и resolBundles.

(редактирование загрузки классов) Class.forName из кода вашего плагина найдет классы во вновь установленных пакетах, только если у вашего плагина есть зависимости, которые будут удовлетворены новыми пакетами после их разрешения.

  • Один из способов сделать это - необязательный Import-Package в манифесте вашего плагина. В этом случае ваш плагин должен быть включен в массив, переданный refreshPackages.
  • Другим вариантом будет использование оператора DynamicImport-Package в манифесте вашего плагина. Динамический импорт разрешается во время загрузки класса

Другой вариант - использовать Bundle.loadClass (вместо Class.forName) в объектах комплекта для вновь установленных комплектов. При этом используется загрузчик классов нового пакета, поэтому сам плагин не должен зависеть от новых пакетов.

2 голосов
/ 28 января 2011

Я недавно сделал это для плагина для затмения:

Вот выдающийся код

URL[] urls = new URL[]{ new URL("jar", "", "file:" + jarFile.getAbsolutePath() + "!/")};
URLClassLoader cl = URLClassLoader.newInstance(urls, this.getClass().getClassLoader());
Class<?> loadedClass = cl.loadClass("com.whatever.SomeClass");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...