我需要获取由JVM加载的所有Java软件包的名称。这是为了显示一个像在IDE中发现的软件包浏览器。通过访问ClassLoader类的受保护“包”字段,我可以获取当前类加载器及其祖先的包列表。但我无法获得由其他webapps加载的包,因为他们有他们自己的类加载器。我正在Weblogic服务器上测试此代码如何获取由JVM加载的所有软件包名称的列表
回答
您需要使用getParent()
遍历类加载器的树,找到所有扩展ClassLoader的类,找到所有当前实例(调试API应该在这里帮助)。但是,由于安全策略,Web服务器可能无法工作(Web应用程序不允许彼此窥视)。
对于Tomcat,可以选择在加载它们时记录所有类。这几乎减慢了服务器的速度,但它可能是开发服务器上的一个选项。
这就是说,我很好奇你为什么需要这个。最简单的解决方案是列出您的应用程序带来的所有JAR文件,并带上jar tvf
并去掉路径的最后部分(类文件)。
Weblogic安全模型的预期行为是您无法访问其他Web应用程序的类加载器。这不是你能够解决的问题 - 请参阅this article了解更多信息。
我也想知道他在做什么。也许他正试图找到一种方法来扫描其他人的网络应用程序的安全漏洞? – 2009-06-22 12:18:15
他可能试图找出哪些库正在被多个webapps使用,所以他可以将这些库分成共享区域。 JMX经理无法找到这类信息吗? – ThaDon 2009-06-22 15:26:13
我能想到做到这一点的唯一方法就是修改每个web应用程序,以便您可以发送每个请求加载他们的类信息。然后,您可以创建一个新的Web应用程序,结合现有Web应用程序的响应进行显示。
如果你在一些不错的用户界面中不需要这些信息,那么Sun JVM有一些-XX虚拟机选项可以告诉你关于类加载的情况。
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
我没那么熟悉的JRockit但我会感到惊讶,如果它没有类似的选项。
好吧我设法让这个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) {
}
}
- 1. Python,MonkeyRunner。如何在所有列表软件包中找到软件包名称?
- 2. 获取软件包名称
- 3. 如何获取软件包所有版本的列表?
- 4. 获取JVM中所有类加载器的列表
- 5. 通过软件包名称执行软件包名称以获取Sql Server存储的软件包
- 6. 从软件包名称中获取应用程序名称
- 7. 如何读取由休眠生成的所有表名称?
- 8. 如何从sdkmanager --list获取完整软件包名称?
- 9. 如何从共享首选项获取软件包名称?
- 10. 如何使用黑莓获取软件包名称
- 11. 如何获取C#中所有加载类型的列表?
- 12. 如何获取所有当前加载的程序集列表?
- 13. Android - 该软件包与现有软件包的名称冲突
- 14. 与现有软件包相同名称的软件包冲突
- 15. 如何从我的软件的所有打开的表单中获取列表?
- 16. 获取表中所有字段名称的列表
- 17. 如何列出在ipython会话中加载的所有名称?
- 18. 加载软件包内容后不使用它们的名称
- 19. 获取阵列中所有文件/文件夹的名称
- 20. jqgrid获取所有网格列名称
- 21. 获取通用类型参数的软件包名称
- 22. 获取默认图像openner的软件包名称
- 23. 列出软件包的所有子软件包
- 24. 获取包含负值的列的列名称列表
- 25. 如何列出多个apks的软件包名称?
- 26. 获取AppDomain中所有可用名称空间的列表
- 27. 获取项目中定义的所有灯具名称列表
- 28. 获取内容提供商中所有名称的列表
- 29. 获取SpreadSheetLight Excel工作表中所有列的名称
- 30. XSLT:如何获取所有使用的名称空间的列表
Package.getPackages()会更传统。 – 2009-06-22 12:26:21