2009-04-24 6 views
3

В основном я хочу узнать, реализует ли какое-либо количество интерфейсов какое-либо количество интерфейсов без активации или запуска пучка. Возможно ли считывать метаданные из мета-inf из API так же, как это делает контейнер, но без активации пакета?Как узнать типы, экспортируемые пакетом OSGi без установки/активации?

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

ответ

2

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

Вы можете проверить, какие пакеты Java связывают импорт и экспорт, не активируя его. Если вы хотите установить (не разрешать, не активировать) его, вы можете запросить его. Оболочки Felix или Equinox могут перечислить эти пакеты в конце концов.

Вот relevant source from Felix' shell. Он использует услугу PackageAdmin:

public void execute(String s, PrintStream out, PrintStream err) 
{ 
    // Get package admin service. 
    ServiceReference ref = m_context.getServiceReference(
     org.osgi.service.packageadmin.PackageAdmin.class.getName()); 
    PackageAdmin pa = (ref == null) ? null : 
     (PackageAdmin) m_context.getService(ref); 

    // ... 

    Bundle bundle = m_context.getBundle(bundleId); 
    ExportedPackage[] exports = pa.getExportedPackages(bundle); 

    // ... 
} 
+0

Возможно, услуги были выбором слов, в основном я хотел, чтобы возможность пересекать * все * классы, которые экспортируются из комплекта. Из этого я могу проверить, реализует ли какой-либо класс интерфейс и предпринимает соответствующие действия. У меня было ощущение, что официальные API не предлагают этого, и для этого потребуется использование расширений-исполнителей и т. Д. Проблема с этим, конечно, в том, что эти вещи могут быть изменены и т. Д. –

2

Вы можете попробовать что-то вроде ниже. Найдите файлы «.class» в экспортированных пакетах с помощью метода bundle.findResource (...).

BundleContext context = bundle.getBundleContext(); 
    ServiceReference ref = context.getServiceReference(PackageAdmin.class.getName()); 
    PackageAdmin packageAdmin = (PackageAdmin)context.getService(ref); 
    List<Class> agentClasses = new ArrayList<Class>(); 
    ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(bundle); 
    for(ExportedPackage ePackage : exportedPackages){ 
     String packageName = ePackage.getName(); 
     String packagePath = "/"+packageName.replace('.', '/'); 
     //find all the class files in current exported package 
     Enumeration clazzes = bundle.findEntries(packagePath, "*.class", false); 
     while(clazzes.hasMoreElements()){ 
     URL url = (URL)clazzes.nextElement(); 
     String path = url.getPath(); 
     int index = path.lastIndexOf("/"); 
     int endIndex = path.length()-6;//Strip ".class" substring 
     String className = path.substring(index+1, endIndex); 
     String fullClassName=packageName+"."+className; 
     try { 
    Class clazz = bundle.loadClass(fullClassName); 
    //check whether the class is annotated with Agent tag. 
    if(clazz.isAnnotationPresent(Agent.class)) 
     agentClasses.add(clazz); 
    } catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
    } 
     } 
    } 
+0

Да, но это становится беспорядочным, потому что это означает, что вы должны взглянуть на запустите класс classspath в манифесте, а затем выполните поиск в баночках и любых взорванных каталогах. –