2011-01-28 2 views
7

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

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

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

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

ответ

5

Если вы сделаете эти банки в 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

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

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

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

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

+0

Это звучит как правильный способ сделать это (+1) –

+0

Спасибо. Это похоже на хороший подход. Однако у меня все еще есть проблемы. Мне удалось загрузить пакет. Но Class.forName («MyClass») по-прежнему вызывает исключение ClassNotFound. Я указал пакет, который содержит класс в выражении экспорта манифеста – Maria

+0

. Я отредактировал исходный ответ с более подробной информацией о загрузке классов после установки пакетов. –

1

Недавно я сделал это для плагина Eclipse:

Вот Характерный код

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"); 
Смежные вопросы