0

JVM によってロードされたすべての Java パッケージの名前を取得する必要があります。これは、IDE に見られるようなパッケージ ブラウザーを表示するためです。ClassLoader クラスの保護された「packages」フィールドにアクセスすることで、現在のクラスローダーとその祖先のパッケージ リストを取得できます。しかし、独自のクラスローダーを持っているため、他の webapps によって読み込まれたパッケージを取得できません。これをWeblogicサーバーでテストしています

4

4 に答える 4

1

Weblogic セキュリティ モデルの予想される動作は、他の Web アプリケーションのクラス ローダーにアクセスできないことです。これは実際には回避できるものではありません。詳細については、この記事を参照してください。

于 2009-06-22T12:16:07.163 に答える
0

わかりました。これをWeblogicで機能させることができました。ここでも、特定のWebLogicサーバーにデプロイされているすべてのアプリケーションでJavaパッケージ名を取得することを目的としていました。なんで?私には理由がありました:)

まず、デプロイされたすべてのアプリのear、war、またはjarファイルの場所を取得する必要があります。これを行うには、WebLogicからAppDeployment MBeanを取得し、以下に示すように繰り返します。

    Set<ObjectName> set = utils.getConfigMBeansByType("AppDeployment");
    for (ObjectName objectName : set) {
        String name = objectName.getKeyProperty("Name");            

        if (!appCache.contains(name)) {
            //System.out.println("Config bean: " + objectName);
            Object path = utils.getPropertyValue(objectName,
                    "AbsoluteSourcePath");
            //System.out.println("Path: " + path);
            if(path != null){
                PackageFinder finder = new PackageFinder();
                packages.addAll(finder.findPackages(path.toString()));
            }
            appCache.add(name);
        }
    }

上記のコードでは、war、ear、jar、またはexplodedフォルダーへのパスを取得し、それをPackageFinderクラスのfindPakagesメソッドに渡します。このメソッドはすべての作業を実行します。

 public Set<String> findPackages(String path){
    File file = new File(path);
    if(file.exists() && file.isFile()){
        InputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(file));
            if(path.toLowerCase().endsWith(".war")){
                processWar(in);
            }else if(path.toLowerCase().endsWith(".ear")){
                processEar(in);
            }/*
    Rest of the method body removed, I guess you get the idea 
    */              
    return packageNames;

}


public void processJar(InputStream in){
    ZipInputStream zin = null;
    try {
        zin = new ZipInputStream(in);
        ZipEntry entry;
        while((entry = zin.getNextEntry()) != null){
            if(entry.getName().endsWith(".class")){
                addPackage(entry.getName());
            }
        }
    } catch (Exception e) {
    }
}
于 2009-11-06T03:22:31.123 に答える
0

これを行うために私が考えることができる唯一の方法は、ロードされたクラス情報のリクエストをそれぞれに送信できるように、各Webアプリを変更することです。次に、既存のWebアプリからの応答を組み合わせて表示する新しいWebアプリを作成できます。

いくつかの優れたUIでこの情報が必要ない場合、Sun JVMには、クラスのロードに関して何が起こっているかを示す-XXvmオプションがいくつかあります。

http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

私はJRockitにあまり詳しくありませんが、同様のオプションがなかったとしたら驚きます。

于 2009-06-22T12:36:35.217 に答える
0

を使用してクラスローダーのツリーをgetParent()たどり、ClassLoader を拡張するすべてのクラスを見つけ、現在のすべてのインスタンスを見つける必要があります (ここではデバッグ API が役立ちます)。ただし、セキュリティ ポリシー (Web アプリは相互に覗き見ることは許可されていません) のため、おそらく Web サーバーでは機能しません。

Tomcat の場合、ロード時にすべてのクラスをログに記録するオプションがあります。これによりサーバーの速度がかなり低下しますが、開発サーバーではオプションになる可能性があります。

そうは言っても、なぜあなたがそれを必要とするのか、私はかなり興味があります。最も簡単な解決策は、アプリが持ち込むすべての JAR ファイルを一覧表示しjar tvf、パスの最後の部分 (クラス ファイル) を削除することです。

于 2009-06-22T12:15:08.490 に答える