如何从类路径中读取Java包中的所有类?

时间:2022-05-20 07:00:53

I need to read classes contained in a Java package. Those classes are in classpath. I need to do this task from a Java program directly. Do you know a simple way to do?

我需要读取Java包中包含的类。这些类在classpath中。我需要直接从Java程序执行此任务。你知道一个简单的方法吗?

List<Class> classes = readClassesFrom("my.package")

16 个解决方案

#1


42  

If you have Spring in you classpath then the following will do it.

如果您在类路径中有Spring,那么以下将执行此操作。

Find all classes in a package that are annotated with XmlRootElement:

查找使用XmlRootElement注释的包中的所有类:

private List<Class> findMyTypes(String basePackage) throws IOException, ClassNotFoundException
{
    ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);

    List<Class> candidates = new ArrayList<Class>();
    String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                               resolveBasePackage(basePackage) + "/" + "**/*.class";
    Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
    for (Resource resource : resources) {
        if (resource.isReadable()) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            if (isCandidate(metadataReader)) {
                candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
            }
        }
    }
    return candidates;
}

private String resolveBasePackage(String basePackage) {
    return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
}

private boolean isCandidate(MetadataReader metadataReader) throws ClassNotFoundException
{
    try {
        Class c = Class.forName(metadataReader.getClassMetadata().getClassName());
        if (c.getAnnotation(XmlRootElement.class) != null) {
            return true;
        }
    }
    catch(Throwable e){
    }
    return false;
}

#2


29  

You could use the Reflections Project described here

您可以使用此处描述的Reflections项目

It's quite complete and easy to use.

它非常完整且易于使用。

Brief description from the above website:

以上网站的简要说明:

Reflections scans your classpath, indexes the metadata, allows you to query it on runtime and may save and collect that information for many modules within your project.

Reflections扫描您的类路径,索引元数据,允许您在运行时查询它,并可以保存和收集项目中许多模块的信息。

Example:

例:

Reflections reflections = new Reflections(
    new ConfigurationBuilder()
        .setUrls(ClasspathHelper.forJavaClassPath())
);
Set<Class<?>> types = reflections.getTypesAnnotatedWith(Scannable.class);

#3


24  

I use this one, it works with files or jar archives

我使用这个,它适用于文件或jar档案

public static ArrayList<String>getClassNamesFromPackage(String packageName) throws IOException{
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL packageURL;
    ArrayList<String> names = new ArrayList<String>();;

    packageName = packageName.replace(".", "/");
    packageURL = classLoader.getResource(packageName);

    if(packageURL.getProtocol().equals("jar")){
        String jarFileName;
        JarFile jf ;
        Enumeration<JarEntry> jarEntries;
        String entryName;

        // build jar file name, then loop through zipped entries
        jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
        jarFileName = jarFileName.substring(5,jarFileName.indexOf("!"));
        System.out.println(">"+jarFileName);
        jf = new JarFile(jarFileName);
        jarEntries = jf.entries();
        while(jarEntries.hasMoreElements()){
            entryName = jarEntries.nextElement().getName();
            if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){
                entryName = entryName.substring(packageName.length(),entryName.lastIndexOf('.'));
                names.add(entryName);
            }
        }

    // loop through files in classpath
    }else{
    URI uri = new URI(packageURL.toString());
    File folder = new File(uri.getPath());
        // won't work with path which contains blank (%20)
        // File folder = new File(packageURL.getFile()); 
        File[] contenuti = folder.listFiles();
        String entryName;
        for(File actual: contenuti){
            entryName = actual.getName();
            entryName = entryName.substring(0, entryName.lastIndexOf('.'));
            names.add(entryName);
        }
    }
    return names;
}

#4


10  

Spring has implemented an excellent classpath search function in the PathMatchingResourcePatternResolver. If you use the classpath*: prefix, you can find all the resources, including classes in a given hierarchy, and even filter them if you want. Then you can use the children of AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter and AssignableTypeFilter to filter those resources either on class level annotations or on interfaces they implement.

Spring在PathMatchingResourcePatternResolver中实现了一个出色的类路径搜索功能。如果使用classpath *:前缀,则可以找到所有资源,包括给定层次结构中的类,甚至可以根据需要过滤它们。然后,您可以使用AbstractTypeHierarchyTraversingFilter,AnnotationTypeFilter和AssignableTypeFilter的子项在类级别注释或它们实现的接口上过滤这些资源。

#5


8  

Java 1.6.0_24:

Java 1.6.0_24:

public static File[] getPackageContent(String packageName) throws IOException{
    ArrayList<File> list = new ArrayList<File>();
    Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
                            .getResources(packageName);
    while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        File dir = new File(url.getFile());
        for (File f : dir.listFiles()) {
            list.add(f);
        }
    }
    return list.toArray(new File[]{});
}

This solution was tested within the EJB environment.

此解决方案在EJB环境中进行了测试。

#6


6  

Scannotation and Reflections use class path scanning approach:

Scannotation和Reflections使用类路径扫描方法:

Reflections reflections = new Reflections("my.package");
Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);

Another approach is to use Java Pluggable Annotation Processing API to write annotation processor which will collect all annotated classes at compile time and build the index file for runtime use. This mechanism is implemented in ClassIndex library:

另一种方法是使用Java Pluggable Annotation Processing API来编写注释处理器,该处理器将在编译时收集所有带注释的类,并构建索引文件以供运行时使用。此机制在ClassIndex库中实现:

Iterable<Class> classes = ClassIndex.getPackageClasses("my.package");

#7


3  

That functionality is still suspiciously missing from the Java reflection API as far as I know. You can get a package object by just doing this:

据我所知,Java反射API仍然可疑地遗漏了这个功能。你可以通过这样做得到一个包对象:

Package packageObj = Package.getPackage("my.package");

But as you probably noticed, that won't let you list the classes in that package. As of right now, you have to take sort of a more filesystem-oriented approach.

但是您可能已经注意到,这不会让您列出该包中的类。截至目前,您必须采取更多面向文件系统的方法。

I found some sample implementations in this post

我在这篇文章中找到了一些示例实现

I'm not 100% sure these methods will work when your classes are buried in JAR files, but I hope one of those does it for you.

当你的类被隐藏在JAR文件中时,我并不是100%确定这些方法是可行的,但我希望其中一个能为你做到这一点。

I agree with @skaffman...if you have another way of going about this, I'd recommend doing that instead.

我同意@skaffman ......如果你有另一种方法可以解决这个问题,我建议你这样做。

#8


3  

You could try my library FastClasspathScanner. Scanning the classpath is not as simple as checking the java.class.path property, and recursively scanning for classes there, because there are many ways that the classpath can be specified (e.g. you can add Class-Path entries to a jarfile's manifest). Using Class.forName() actually initializes the class, which may not be what you want, etc. FastClasspathScanner handles these complexities for you.

您可以尝试我的库FastClasspathScanner。扫描类路径并不像检查java.class.path属性那样简单,并且在那里递归扫描类,因为可以通过多种方式指定类路径(例如,您可以将类路径条目添加到jarfile的清单中)。使用Class.forName()实际上初始化类,这可能不是你想要的,等等.FastClasspathScanner为你处理这些复杂性。

To enumerate all classes in a package, do the following:

要枚举包中的所有类,请执行以下操作:

String packageName = "my.package";
Set<String> classNames = new FastClassPathScanner(packageName)
    .scan()
    .getNamesOfAllClasses();
String packageNamePrefix = packageName + ".";
for (String className : classNames) {
    if (className.startsWith(packageNamePrefix) {
        System.out.println("Found class: " + className);
   }
}

You need the check if (className.startsWith(packageNamePrefix) because if a class refers to another class (e.g. as a superclass), and it's outside the whitelisted package prefix my.package, it will be included in the set returned by .getNamesOfAllClasses().

你需要检查if(className.startsWith(packageNamePrefix),因为如果一个类引用另一个类(例如作为超类),并且它在白名单包前缀my.package之外,它将包含在.getNamesOfAllClasses返回的集合中( )。

#9


2  

I happen to have implemented it, and it works in most cases. Since it is long, I put it in a file here.

我碰巧实现了它,它在大多数情况下都有效。由于它很长,我把它放在一个文件中。

The idea is to find the location of the class source file which is available in most cases (a known exception are JVM class files -- as far as I've tested). If the code is in a directory, scan through all files and only spot class files. If the code is in a JAR file, scan all entries.

我们的想法是找到在大多数情况下可用的类源文件的位置(已知的例外是JVM类文件 - 据我测试过)。如果代码在目录中,则扫描所有文件并仅查找类文件。如果代码位于JAR文件中,请扫描所有条目。

This method can only be used when:

此方法只能在以下情况下使用:

  1. You have a class that is in the same package you want to discover, This class is called a SeedClass. For example, if you want to list all classes in 'java.io', the seed class may be java.io.File.

    您有一个与要发现的包相同的类,此类称为SeedClass。例如,如果要列出'java.io'中的所有类,则种子类可以是java.io.File。

  2. Your classes are in a directory or in a JAR file it has source file information (not source code file, but just source file). As far as I've tried, it work almost 100% except the JVM class (those classes come with the JVM).

    您的类位于目录或JAR文件中,它具有源文件信息(不是源代码文件,而只是源文件)。据我所知,除了JVM类(这些类附带JVM)之外,它几乎100%工作。

  3. Your program must have permission to access ProtectionDomain of those classes. If your program is loaded locally, there should be no problem.

    您的程序必须具有访问这些类的ProtectionDomain的权限。如果你的程序在本地加载,应该没有问题。

I've tested the program only for my regular usage, so it may still have problem.

我已经测试了该程序仅用于我的常规用法,所以它可能仍有问题。

I hope this helps.

我希望这有帮助。

#10


2  

eXtcos looks promising. Imagine you want to find all the classes that:

eXtcos看起来很有前景。想象一下,你想要找到所有类:

  1. Extend from class "Component", and store them
  2. 从类“Component”扩展,并存储它们
  3. Are annotated with "MyComponent", and
  4. 用“MyComponent”注释,和
  5. Are in the “common” package.
  6. 是在“共同”的包。

With eXtcos this is as simple as

使用eXtcos,这很简单

ClasspathScanner scanner = new ClasspathScanner();
final Set<Class> classStore = new ArraySet<Class>();

Set<Class> classes = scanner.getClasses(new ClassQuery() {
    protected void query() {
        select().
        from(“common”).
        andStore(thoseExtending(Component.class).into(classStore)).
        returning(allAnnotatedWith(MyComponent.class));
    }
});

#11


2  

  1. Bill Burke has written a (nice article about class scanning] and then he wrote Scannotation.

    比尔伯克写了一篇(关于班级扫描的好文章)然后他写了Scannotation。

  2. Hibernate has this already written:

    Hibernate已经写了这个:

    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.NativeScanner
    • org.hibernate.ejb.packaging.NativeScanner
  3. CDI might solve this, but don't know - haven't investigated fully yet

    CDI可能会解决这个问题,但不知道 - 尚未完全调查

.

@Inject Instance< MyClass> x;
...
x.iterator() 

Also for annotations:

也用于注释:

abstract class MyAnnotationQualifier
extends AnnotationLiteral<Entity> implements Entity {}

#12


1  

Here is another option, slight modification to another answer in above/below:

这是另一个选项,稍微修改上面/下面的另一个答案:

Reflections reflections = new Reflections("com.example.project.package", 
    new SubTypesScanner(false));
Set<Class<? extends Object>> allClasses = 
    reflections.getSubTypesOf(Object.class);

#13


0  

Back when applets were common place, one might have a URL on the classpath. When the classloader required a class, it would search all the locations on the classpath, including http resources. Because you can have things like URLs and directories on the classpath, there is no easy way to get a definitive list of the classes.

当applet很常见时,可能会在类路径上有一个URL。当类加载器需要一个类时,它将搜索类路径上的所有位置,包括http资源。因为你可以在类路径上拥有URL和目录之类的东西,所以没有简单的方法来获得类的确定列表。

However, you can get pretty close. Some of the Spring libraries are doing this now. You can get all the jar's on the classpath, and open them up like files. You can then take this list of files, and create a data structure containing your classes.

但是,你可以非常接近。一些Spring库现在正在这样做。你可以在类路径中获取所有jar,并像文件一样打开它们。然后,您可以获取此文件列表,并创建包含您的类的数据结构。

#14


0  

The project ldapbeans provides a class Scanner that do this.

项目ldapbeans提供了一个类扫描器来执行此操作。

#15


0  

use dependency maven:

使用依赖maven:

groupId: net.sf.extcos
artifactId: extcos
version: 0.4b

then use this code :

然后使用此代码:

ComponentScanner scanner = new ComponentScanner();
        Set classes = scanner.getClasses(new ComponentQuery() {
            @Override
            protected void query() {
                select().from("com.leyton").returning(allExtending(DynamicForm.class));
            }
        });

#16


-2  

Brent - the reason the association is one way has to do with the fact that any class on any component of your CLASSPATH can declare itself in any package (except for java/javax). Thus there just is no mapping of ALL the classes in a given "package" because nobody knows nor can know. You could update a jar file tomorrow and remove or add classes. It's like trying to get a list of all people named John/Jon/Johan in all the countries of the world - none of us is omniscient therefore none of us will ever have the correct answer.

Brent - 关联是一种方式的原因与CLASSPATH的任何组件上的任何类都可以在任何包中声明自己(java / javax除外)这一事实有关。因此,在给定的“包”中没有所有类的映射,因为没有人知道也不知道。您可以明天更新jar文件并删除或添加类。这就像试图获得世界上所有国家中名为John / Jon / Johan的所有人的名单 - 我们都不是无所不知的,因此我们都不会得到正确的答案。

#1


42  

If you have Spring in you classpath then the following will do it.

如果您在类路径中有Spring,那么以下将执行此操作。

Find all classes in a package that are annotated with XmlRootElement:

查找使用XmlRootElement注释的包中的所有类:

private List<Class> findMyTypes(String basePackage) throws IOException, ClassNotFoundException
{
    ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);

    List<Class> candidates = new ArrayList<Class>();
    String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                               resolveBasePackage(basePackage) + "/" + "**/*.class";
    Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
    for (Resource resource : resources) {
        if (resource.isReadable()) {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            if (isCandidate(metadataReader)) {
                candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
            }
        }
    }
    return candidates;
}

private String resolveBasePackage(String basePackage) {
    return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
}

private boolean isCandidate(MetadataReader metadataReader) throws ClassNotFoundException
{
    try {
        Class c = Class.forName(metadataReader.getClassMetadata().getClassName());
        if (c.getAnnotation(XmlRootElement.class) != null) {
            return true;
        }
    }
    catch(Throwable e){
    }
    return false;
}

#2


29  

You could use the Reflections Project described here

您可以使用此处描述的Reflections项目

It's quite complete and easy to use.

它非常完整且易于使用。

Brief description from the above website:

以上网站的简要说明:

Reflections scans your classpath, indexes the metadata, allows you to query it on runtime and may save and collect that information for many modules within your project.

Reflections扫描您的类路径,索引元数据,允许您在运行时查询它,并可以保存和收集项目中许多模块的信息。

Example:

例:

Reflections reflections = new Reflections(
    new ConfigurationBuilder()
        .setUrls(ClasspathHelper.forJavaClassPath())
);
Set<Class<?>> types = reflections.getTypesAnnotatedWith(Scannable.class);

#3


24  

I use this one, it works with files or jar archives

我使用这个,它适用于文件或jar档案

public static ArrayList<String>getClassNamesFromPackage(String packageName) throws IOException{
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL packageURL;
    ArrayList<String> names = new ArrayList<String>();;

    packageName = packageName.replace(".", "/");
    packageURL = classLoader.getResource(packageName);

    if(packageURL.getProtocol().equals("jar")){
        String jarFileName;
        JarFile jf ;
        Enumeration<JarEntry> jarEntries;
        String entryName;

        // build jar file name, then loop through zipped entries
        jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
        jarFileName = jarFileName.substring(5,jarFileName.indexOf("!"));
        System.out.println(">"+jarFileName);
        jf = new JarFile(jarFileName);
        jarEntries = jf.entries();
        while(jarEntries.hasMoreElements()){
            entryName = jarEntries.nextElement().getName();
            if(entryName.startsWith(packageName) && entryName.length()>packageName.length()+5){
                entryName = entryName.substring(packageName.length(),entryName.lastIndexOf('.'));
                names.add(entryName);
            }
        }

    // loop through files in classpath
    }else{
    URI uri = new URI(packageURL.toString());
    File folder = new File(uri.getPath());
        // won't work with path which contains blank (%20)
        // File folder = new File(packageURL.getFile()); 
        File[] contenuti = folder.listFiles();
        String entryName;
        for(File actual: contenuti){
            entryName = actual.getName();
            entryName = entryName.substring(0, entryName.lastIndexOf('.'));
            names.add(entryName);
        }
    }
    return names;
}

#4


10  

Spring has implemented an excellent classpath search function in the PathMatchingResourcePatternResolver. If you use the classpath*: prefix, you can find all the resources, including classes in a given hierarchy, and even filter them if you want. Then you can use the children of AbstractTypeHierarchyTraversingFilter, AnnotationTypeFilter and AssignableTypeFilter to filter those resources either on class level annotations or on interfaces they implement.

Spring在PathMatchingResourcePatternResolver中实现了一个出色的类路径搜索功能。如果使用classpath *:前缀,则可以找到所有资源,包括给定层次结构中的类,甚至可以根据需要过滤它们。然后,您可以使用AbstractTypeHierarchyTraversingFilter,AnnotationTypeFilter和AssignableTypeFilter的子项在类级别注释或它们实现的接口上过滤这些资源。

#5


8  

Java 1.6.0_24:

Java 1.6.0_24:

public static File[] getPackageContent(String packageName) throws IOException{
    ArrayList<File> list = new ArrayList<File>();
    Enumeration<URL> urls = Thread.currentThread().getContextClassLoader()
                            .getResources(packageName);
    while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        File dir = new File(url.getFile());
        for (File f : dir.listFiles()) {
            list.add(f);
        }
    }
    return list.toArray(new File[]{});
}

This solution was tested within the EJB environment.

此解决方案在EJB环境中进行了测试。

#6


6  

Scannotation and Reflections use class path scanning approach:

Scannotation和Reflections使用类路径扫描方法:

Reflections reflections = new Reflections("my.package");
Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);

Another approach is to use Java Pluggable Annotation Processing API to write annotation processor which will collect all annotated classes at compile time and build the index file for runtime use. This mechanism is implemented in ClassIndex library:

另一种方法是使用Java Pluggable Annotation Processing API来编写注释处理器,该处理器将在编译时收集所有带注释的类,并构建索引文件以供运行时使用。此机制在ClassIndex库中实现:

Iterable<Class> classes = ClassIndex.getPackageClasses("my.package");

#7


3  

That functionality is still suspiciously missing from the Java reflection API as far as I know. You can get a package object by just doing this:

据我所知,Java反射API仍然可疑地遗漏了这个功能。你可以通过这样做得到一个包对象:

Package packageObj = Package.getPackage("my.package");

But as you probably noticed, that won't let you list the classes in that package. As of right now, you have to take sort of a more filesystem-oriented approach.

但是您可能已经注意到,这不会让您列出该包中的类。截至目前,您必须采取更多面向文件系统的方法。

I found some sample implementations in this post

我在这篇文章中找到了一些示例实现

I'm not 100% sure these methods will work when your classes are buried in JAR files, but I hope one of those does it for you.

当你的类被隐藏在JAR文件中时,我并不是100%确定这些方法是可行的,但我希望其中一个能为你做到这一点。

I agree with @skaffman...if you have another way of going about this, I'd recommend doing that instead.

我同意@skaffman ......如果你有另一种方法可以解决这个问题,我建议你这样做。

#8


3  

You could try my library FastClasspathScanner. Scanning the classpath is not as simple as checking the java.class.path property, and recursively scanning for classes there, because there are many ways that the classpath can be specified (e.g. you can add Class-Path entries to a jarfile's manifest). Using Class.forName() actually initializes the class, which may not be what you want, etc. FastClasspathScanner handles these complexities for you.

您可以尝试我的库FastClasspathScanner。扫描类路径并不像检查java.class.path属性那样简单,并且在那里递归扫描类,因为可以通过多种方式指定类路径(例如,您可以将类路径条目添加到jarfile的清单中)。使用Class.forName()实际上初始化类,这可能不是你想要的,等等.FastClasspathScanner为你处理这些复杂性。

To enumerate all classes in a package, do the following:

要枚举包中的所有类,请执行以下操作:

String packageName = "my.package";
Set<String> classNames = new FastClassPathScanner(packageName)
    .scan()
    .getNamesOfAllClasses();
String packageNamePrefix = packageName + ".";
for (String className : classNames) {
    if (className.startsWith(packageNamePrefix) {
        System.out.println("Found class: " + className);
   }
}

You need the check if (className.startsWith(packageNamePrefix) because if a class refers to another class (e.g. as a superclass), and it's outside the whitelisted package prefix my.package, it will be included in the set returned by .getNamesOfAllClasses().

你需要检查if(className.startsWith(packageNamePrefix),因为如果一个类引用另一个类(例如作为超类),并且它在白名单包前缀my.package之外,它将包含在.getNamesOfAllClasses返回的集合中( )。

#9


2  

I happen to have implemented it, and it works in most cases. Since it is long, I put it in a file here.

我碰巧实现了它,它在大多数情况下都有效。由于它很长,我把它放在一个文件中。

The idea is to find the location of the class source file which is available in most cases (a known exception are JVM class files -- as far as I've tested). If the code is in a directory, scan through all files and only spot class files. If the code is in a JAR file, scan all entries.

我们的想法是找到在大多数情况下可用的类源文件的位置(已知的例外是JVM类文件 - 据我测试过)。如果代码在目录中,则扫描所有文件并仅查找类文件。如果代码位于JAR文件中,请扫描所有条目。

This method can only be used when:

此方法只能在以下情况下使用:

  1. You have a class that is in the same package you want to discover, This class is called a SeedClass. For example, if you want to list all classes in 'java.io', the seed class may be java.io.File.

    您有一个与要发现的包相同的类,此类称为SeedClass。例如,如果要列出'java.io'中的所有类,则种子类可以是java.io.File。

  2. Your classes are in a directory or in a JAR file it has source file information (not source code file, but just source file). As far as I've tried, it work almost 100% except the JVM class (those classes come with the JVM).

    您的类位于目录或JAR文件中,它具有源文件信息(不是源代码文件,而只是源文件)。据我所知,除了JVM类(这些类附带JVM)之外,它几乎100%工作。

  3. Your program must have permission to access ProtectionDomain of those classes. If your program is loaded locally, there should be no problem.

    您的程序必须具有访问这些类的ProtectionDomain的权限。如果你的程序在本地加载,应该没有问题。

I've tested the program only for my regular usage, so it may still have problem.

我已经测试了该程序仅用于我的常规用法,所以它可能仍有问题。

I hope this helps.

我希望这有帮助。

#10


2  

eXtcos looks promising. Imagine you want to find all the classes that:

eXtcos看起来很有前景。想象一下,你想要找到所有类:

  1. Extend from class "Component", and store them
  2. 从类“Component”扩展,并存储它们
  3. Are annotated with "MyComponent", and
  4. 用“MyComponent”注释,和
  5. Are in the “common” package.
  6. 是在“共同”的包。

With eXtcos this is as simple as

使用eXtcos,这很简单

ClasspathScanner scanner = new ClasspathScanner();
final Set<Class> classStore = new ArraySet<Class>();

Set<Class> classes = scanner.getClasses(new ClassQuery() {
    protected void query() {
        select().
        from(“common”).
        andStore(thoseExtending(Component.class).into(classStore)).
        returning(allAnnotatedWith(MyComponent.class));
    }
});

#11


2  

  1. Bill Burke has written a (nice article about class scanning] and then he wrote Scannotation.

    比尔伯克写了一篇(关于班级扫描的好文章)然后他写了Scannotation。

  2. Hibernate has this already written:

    Hibernate已经写了这个:

    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.NativeScanner
    • org.hibernate.ejb.packaging.NativeScanner
  3. CDI might solve this, but don't know - haven't investigated fully yet

    CDI可能会解决这个问题,但不知道 - 尚未完全调查

.

@Inject Instance< MyClass> x;
...
x.iterator() 

Also for annotations:

也用于注释:

abstract class MyAnnotationQualifier
extends AnnotationLiteral<Entity> implements Entity {}

#12


1  

Here is another option, slight modification to another answer in above/below:

这是另一个选项,稍微修改上面/下面的另一个答案:

Reflections reflections = new Reflections("com.example.project.package", 
    new SubTypesScanner(false));
Set<Class<? extends Object>> allClasses = 
    reflections.getSubTypesOf(Object.class);

#13


0  

Back when applets were common place, one might have a URL on the classpath. When the classloader required a class, it would search all the locations on the classpath, including http resources. Because you can have things like URLs and directories on the classpath, there is no easy way to get a definitive list of the classes.

当applet很常见时,可能会在类路径上有一个URL。当类加载器需要一个类时,它将搜索类路径上的所有位置,包括http资源。因为你可以在类路径上拥有URL和目录之类的东西,所以没有简单的方法来获得类的确定列表。

However, you can get pretty close. Some of the Spring libraries are doing this now. You can get all the jar's on the classpath, and open them up like files. You can then take this list of files, and create a data structure containing your classes.

但是,你可以非常接近。一些Spring库现在正在这样做。你可以在类路径中获取所有jar,并像文件一样打开它们。然后,您可以获取此文件列表,并创建包含您的类的数据结构。

#14


0  

The project ldapbeans provides a class Scanner that do this.

项目ldapbeans提供了一个类扫描器来执行此操作。

#15


0  

use dependency maven:

使用依赖maven:

groupId: net.sf.extcos
artifactId: extcos
version: 0.4b

then use this code :

然后使用此代码:

ComponentScanner scanner = new ComponentScanner();
        Set classes = scanner.getClasses(new ComponentQuery() {
            @Override
            protected void query() {
                select().from("com.leyton").returning(allExtending(DynamicForm.class));
            }
        });

#16


-2  

Brent - the reason the association is one way has to do with the fact that any class on any component of your CLASSPATH can declare itself in any package (except for java/javax). Thus there just is no mapping of ALL the classes in a given "package" because nobody knows nor can know. You could update a jar file tomorrow and remove or add classes. It's like trying to get a list of all people named John/Jon/Johan in all the countries of the world - none of us is omniscient therefore none of us will ever have the correct answer.

Brent - 关联是一种方式的原因与CLASSPATH的任何组件上的任何类都可以在任何包中声明自己(java / javax除外)这一事实有关。因此,在给定的“包”中没有所有类的映射,因为没有人知道也不知道。您可以明天更新jar文件并删除或添加类。这就像试图获得世界上所有国家中名为John / Jon / Johan的所有人的名单 - 我们都不是无所不知的,因此我们都不会得到正确的答案。