2009-06-22 62 views
0

我需要获取由JVM加载的所有Java软件包的名称。这是为了显示一个像在IDE中发现的软件包浏览器。通过访问ClassLoader类的受保护“包”字段,我可以获取当前类加载器及其祖先的包列表。但我无法获得由其他webapps加载的包,因为他们有他们自己的类加载器。我正在Weblogic服务器上测试此代码如何获取由JVM加载的所有软件包名称的列表

+0

Package.getPackages()会更传统。 – 2009-06-22 12:26:21

回答

0

您需要使用getParent()遍历类加载器的树,找到所有扩展ClassLoader的类,找到所有当前实例(调试API应该在这里帮助)。但是,由于安全策略,Web服务器可能无法工作(Web应用程序不允许彼此窥视)。

对于Tomcat,可以选择在加载它们时记录所有类。这几乎减慢了服务器的速度,但它可能是开发服务器上的一个选项。

这就是说,我很好奇你为什么需要这个。最简单的解决方案是列出您的应用程序带来的所有JAR文件,并带上jar tvf并去掉路径的最后部分(类文件)。

1

Weblogic安全模型的预期行为是您无法访问其他Web应用程序的类加载器。这不是你能够解决的问题 - 请参阅this article了解更多信息。

+0

我也想知道他在做什么。也许他正试图找到一种方法来扫描其他人的网络应用程序的安全漏洞? – 2009-06-22 12:18:15

+0

他可能试图找出哪些库正在被多个webapps使用,所以他可以将这些库分成共享区域。 JMX经理无法找到这类信息吗? – ThaDon 2009-06-22 15:26:13

0

我能想到做到这一点的唯一方法就是修改每个web应用程序,以便您可以发送每个请求加载他们的类信息。然后,您可以创建一个新的Web应用程序,结合现有Web应用程序的响应进行显示。

如果你在一些不错的用户界面中不需要这些信息,那么Sun JVM有一些-XX虚拟机选项可以告诉你关于类加载的情况。

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

我没那么熟悉的JRockit但我会感到惊讶,如果它没有类似的选项。

0

好吧我设法让这个Weblogic工作。我的目标就是在给定的WebLogic服务器上部署的所有应用程序中获取Java包名称。为什么?我有我的理由:)

首先,你必须得到所有部署的应用程序的耳朵,战争或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); 
     } 
    } 

在上面的代码中,我们得到的路径战争,耳,罐或分解的文件夹,并把它传递给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) { 
    } 
} 
相关问题