3

基本的に、私はjarがバンドルをアクティブ化または開始せずに任意の数のインターフェースを実装しているかどうかを発見したいと思います。コンテナーと同じように、バンドルをアクティブ化せずに、APIからmeta-infからメタデータを読み取ることは可能ですか?

OSGiを使用して、多数のインターフェースが公開されるプラグインをサポートしたいのですが、ユーザーがバンドルなどをアクティブ化せずにアップロードしたときに、バンドルによって実装されるインターフェースを知りたいです。

4

2 に答える 2

2

バンドルが提供するサービスを発見することは不可能だと思います。なぜなら、これは Java コードの内部から発生する可能性があり、それに関するメタデータがないからです。もちろん、Declarative Services を使用する場合は、メタデータ ファイルがあります。また、バンドルはサービス インターフェイスをインポート (または提供) する必要があります。

バンドルをアクティブ化せずにインポートおよびエクスポートする Java パッケージを調べることができます。インストールする (解決しない、アクティブ化しない) 場合は、クエリを実行できます。結局、Felix または Equinox シェルはそれらのパッケージを一覧表示できます。

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

    // ...
}
于 2009-04-25T00:58:52.423 に答える
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();
    }
      }
  }
于 2010-04-06T08:27:02.767 に答える