基本的に、私はjarがバンドルをアクティブ化または開始せずに任意の数のインターフェースを実装しているかどうかを発見したいと思います。コンテナーと同じように、バンドルをアクティブ化せずに、APIからmeta-infからメタデータを読み取ることは可能ですか?
OSGiを使用して、多数のインターフェースが公開されるプラグインをサポートしたいのですが、ユーザーがバンドルなどをアクティブ化せずにアップロードしたときに、バンドルによって実装されるインターフェースを知りたいです。
基本的に、私はjarがバンドルをアクティブ化または開始せずに任意の数のインターフェースを実装しているかどうかを発見したいと思います。コンテナーと同じように、バンドルをアクティブ化せずに、APIからmeta-infからメタデータを読み取ることは可能ですか?
OSGiを使用して、多数のインターフェースが公開されるプラグインをサポートしたいのですが、ユーザーがバンドルなどをアクティブ化せずにアップロードしたときに、バンドルによって実装されるインターフェースを知りたいです。
バンドルが提供するサービスを発見することは不可能だと思います。なぜなら、これは 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);
// ...
}
以下のようなものを試すことができます。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();
}
}
}