2009-06-22 3 views
0

Ich brauche Namen aller Java-Pakete von der JVM geladen. Dies zeigt einen Paket-Browser an, wie er in IDEs zu finden ist. Ich kann die Paketliste des aktuellen Classloaders und seiner Vorgänger abrufen, indem ich auf das geschützte "packages" -Feld der ClassLoader-Klasse zugreife. Aber ich kann die Pakete nicht von anderen Webapps laden, da sie ihre eigenen Klassenlader haben. Ich teste dies auf Weblogic-ServerWie bekomme ich eine Liste aller Paketnamen geladen von der JVM

+0

Package.getPackages() wäre konventioneller. –

Antwort

0

Sie müssen den Baum der Klassenlader gehen mit getParent(), finden Sie alle Klassen, die ClassLoader erweitern, finden Sie alle aktuellen Instanzen (die Debug-API sollte hier helfen). Aber das wird wahrscheinlich wegen der Sicherheitsrichtlinie nicht für Web-Server funktionieren (Web-Apps dürfen sich nicht gegenseitig ansehen).

Für Tomcat gibt es eine Option, alle Klassen beim Laden zu protokollieren. Dies verlangsamt einen Server ziemlich, aber es könnte eine Option auf dem Entwicklungsserver sein.

Das sagte, ich bin ziemlich neugierig, warum Sie das brauchen würden. Die einfachste Lösung wäre, alle JAR-Dateien, die Ihre App mitbringt, mit jar tvf aufzulisten und den letzten Teil des Pfades (die Klassendatei) zu entfernen.

1

Das erwartete Verhalten des Weblogic-Sicherheitsmodells besteht darin, dass Sie keinen Zugriff auf die Klassenladeprogramme der anderen Webanwendungen haben. Dies ist nicht wirklich etwas, das Sie bekommen können - siehe this article für weitere Informationen.

+0

Ich frage mich auch, was er vorhat. Vielleicht versucht er einen Weg zu finden, um Web-Apps anderer Leute auf Sicherheitslücken zu scannen? –

+0

Er könnte herausfinden, welche Bibliotheken von mehreren Webapps verwendet werden, damit er diese in einen gemeinsamen Bereich einbeziehen kann. Können JMX-Manager diese Art von Informationen nicht herausfinden? – ThaDon

+0

Ich bin wirklich nicht sicher - wenn sie es können, posten Sie es, Sie werden definitiv meine Stimme haben. – stevedbrown

0

Die einzige Möglichkeit, dies zu tun, wäre, jede Webapp zu ändern, so dass Sie jeder eine Anfrage für ihre geladenen Klasseninformationen senden können. Sie können dann eine neue Webanwendung erstellen, die die Antworten der vorhandenen Webapps zur Anzeige kombiniert.

Wenn Sie diese Informationen nicht in einer netten Benutzeroberfläche benötigen, dann hat die Sun JVM eine Anzahl von -XX vm Optionen, die Ihnen zeigen, was in Bezug auf das Laden von Klassen vor sich geht.

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

Ich bin nicht so mit JRockit vertraut, aber ich würde überrascht, wenn es nicht ähnliche Optionen hat.

0

Ok, ich habe es geschafft, das funktioniert auf Weblogic. Wiederum war es mein Ziel, Java-Paketnamen in allen Anwendungen zu erhalten, die auf einem bestimmten WebLogic-Server implementiert sind. Warum? Ich hatte meine Gründe :)

Zuerst müssen Sie die Ohr-, Kriegs- oder JAR-Dateistandorte aller bereitgestellten Anwendungen ergreifen. Dazu rufen wir die AppDeployment-MBeans von WebLogic ab und durchlaufen sie wie unten gezeigt.

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

In dem obigen Code, den wir den Weg zum Krieg, Ohr, Glas oder den Explosions Ordner und übergeben sie an die PackageFinder Klasse findPakages Methode erhalten, die die ganze Arbeit.

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) { 
    } 
} 
+0

Hinweis: Dies liefert keine Paketnamen aller geladenen Klassen in der JVM. Es gibt nur alle Paketnamen von Klassen zurück, die mit allen bereitgestellten Apps in einem WebLogic-Server gebündelt sind, was meinen Zweck erfüllt. – maneesh

Verwandte Themen