Java : programmatically determine all of the package names loaded on the classpath

标签 java reflection jar classpath package

关于如何找到当前类路径中存在的包名称列表,有什么建议吗?

这需要在运行时通过在类路径上加载(和执行)的类之一以编程方式完成(即由内而外,而不是由外而内)。


更多详情:

我考虑的一种方法是对类加载器到目前为止加载的每个类使用反射,并从中提取包名称。但是,我的应用程序已经运行了数千个类,因此我需要一种更高效的方法。

我考虑的另一件事类似于找出类路径中的 JAR 文件,然后为每个 JAR 并行列出目录。但是,我不知道这是否可以从应用程序内部实现/如何实现。

奖励积分

任何建议可以按顶级包过滤的方法的人都可以获得奖励积分。例如。显示 com.xyz 下的所有包 ==> com.xyz.*, com.xyz.*.*

谢谢!

最佳答案

如果确实需要挂载和扫描jar文件commons-vfs内置了这个。如果你必须走那条路,这可能会让事情变得更容易一些。

编辑 #1:您可以像这样获取类路径(来自示例 here ):

String strClassPath = System.getProperty("java.class.path");
System.out.println("Classpath is " + strClassPath);

从那里您可以查看本地文件系统类、jar 等。

编辑 #2:这是一个使用 VFS 的解决方案:

import java.util.HashSet;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.VFS;

public class PackageLister {

    private static HashSet< String > packageNames = new HashSet< String >();
    private static String localFilePath;

    /**
     * @param args
     * @throws Throwable
     */
    public static void main( final String[] args ) throws Throwable {
        FileSystemManager fileSystemManager = VFS.getManager();

        String[] pathElements = System.getProperty( "java.class.path" ).split( ";" );
        for( String element : pathElements ) {
            if ( element.endsWith( "jar" ) ) {
                FileObject fileObject = fileSystemManager.resolveFile( "jar://" + element );
                addPackages( fileObject );
            }
            else {
                FileObject fileObject = fileSystemManager.resolveFile( element );
                localFilePath = fileObject.getName().getPath();

                addPackages( fileObject );
            }
        }

        for( String name : packageNames ) {
            System.out.println( name );
        }
    }

    private static void addPackages( final FileObject fileObject ) throws Throwable {
        FileObject[] children = fileObject.getChildren();
        for( FileObject child : children ) {
            if ( !child.getName().getBaseName().equals( "META-INF" ) ) {
                if ( child.getType() == FileType.FOLDER ) {
                    addPackages( child );
                }
                else if ( child.getName().getExtension().equals( "class" ) ) {
                    String parentPath = child.getParent().getName().getPath();
                    parentPath = StringUtils.remove( parentPath, localFilePath );
                    parentPath = StringUtils.removeStart( parentPath, "/" );
                    parentPath = parentPath.replaceAll( "/", "." );

                    packageNames.add( parentPath );
                }
            }
        }
    }
}

关于Java : programmatically determine all of the package names loaded on the classpath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4212088/

相关文章:

java - Lucene:升级旧项目

java - 将十六进制字符串转换为整数

java - OpenCV 无法在 JAR 文件中运行

java - 无法运行具有 .jar 依赖项的 Java 应用程序 - 'Error: Could not find or load main class'

Java 从 eclipse applet 导出 jar 错误

java - 为什么 java.net.SocketInputStream 不存在?

java - Delphi 中通过 Java Bridge 使用 DocumentBuilderFactory 时出现段错误

C#,将字符串变量转换为类变量

java - 有没有办法以声明的顺序从java类中获取私有(private)字段名称

使用反射的 C# 通用 Excel 导出器