9

I'm currently using reflection to get all loaded classes from the classes field in ClassLoader and then checking if getPackage is equal to the package I'm searching for. One problem I'm having with this is that the classes aren't getting loaded by the ClassLoader but I have no way to load them myself using Class.forName because I won't know the name of the classes since they are dynamically loaded and always changing. One thing the classes all have in common is that they extend Module. How would I go about loading all the classes from a package?

Thanks in advance.

Jordan Doyle
  • 2,976
  • 4
  • 22
  • 38
  • http://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection seems to answer this – iluxa Oct 25 '13 at 11:20
  • @iluxa I can get all the classes in the package, but only if they are loaded – Jordan Doyle Oct 25 '13 at 11:21
  • 1
    explained [here](http://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection/520344#520344) – mithrandir Oct 25 '13 at 11:23
  • Yup, and it's indeed a problem. It seems you need to figure out your classpath, go through it, inspect the Jar files etc. Nothing you can do cheaply. – iluxa Oct 25 '13 at 11:23
  • There is a Reflections API https://code.google.com/p/reflections/ which does this pretty well. I have personally used it to reflect over packages to find subtypes of a class when no meaningful use has happened on that class, and the class loader has not loaded them yet. I believe it functions like iluxa has suggested, by evaluating the working directory / jar contents. – Mark W Dec 04 '13 at 16:55
  • If you are using a newer jdk now, [this answer](http://stackoverflow.com/a/28833044/2711488) will hint you to a solution. – Holger May 13 '15 at 16:13

1 Answers1

1

Using the reflections API it works for sure. If it doesn't you might set it up the wrong way. I just made up this example and it prints all of the classes in the package independently from any classloader.

package com.test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.MemberUsageScanner;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.MethodParameterNamesScanner;
import org.reflections.scanners.MethodParameterScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

public class Runner {

    public static void main(String[] args) {
        Reflections reflections = new Reflections();
        FilterBuilder TestModelFilter = new FilterBuilder().include("com.test.*");

        reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(Arrays.asList(ClasspathHelper.forClass(Runner.class))).filterInputsBy(TestModelFilter)
                .setScanners(new SubTypesScanner(false), new TypeAnnotationsScanner(), new FieldAnnotationsScanner(),
                        new MethodAnnotationsScanner(), new MethodParameterScanner(), new MethodParameterNamesScanner(),
                        new MemberUsageScanner()));

        Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);
        System.out.println(allClasses);
        for (Iterator it = allClasses.iterator(); it.hasNext();) {
            Class<? extends Object> clazz = (Class<? extends Object>) it.next();
            System.out.println(clazz.getCanonicalName());
        }
    }

}

I added all the imports by intention, so you can see what API it uses. Does this work for you?

Kenyakorn Ketsombut
  • 2,072
  • 2
  • 26
  • 43