如何在不安装/激活的情况下发现OSGi包导出的类型?

时间:2009-04-24 12:09:42

标签: osgi

基本上我想发现jar是否在激活或启动bundle时实现了任意数量的接口。是否有可能从容器中读取meta-inf中的元数据,就像容器一样,但没有激活包?

我想使用OSGi来支持将发布大量接口的插件,我想知道当用户上传而不激活捆绑包时,捆绑包实现了哪些接口。

2 个答案:

答案 0 :(得分:2)

我认为不可能发现捆绑包将提供哪些服务,因为这可能发生在Java代码内部,而没有任何关于它的元数据。当然,如果您使用Declarative Services,则会有一个元数据文件。此外,捆绑包需要导入(或提供)服务接口,这可能会给你一个提示(但不是更多)。

您可以检查捆绑包导入和导出的Java包而不激活它。 如果您愿意安装(不解析,不激活)它,您可以查询它。毕竟Felix或Equinox shell可以列出这些包。

这是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);

    // ...
}

答案 1 :(得分:2)

你可以试试下面的东西。使用bundle.findResource(...)方法在导出的包中找到“.class”文件。

 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();
    }
      }
  }