1

I'm making an app that run all the methods inside the classes that has the @Window annotation, but for now I've got this:

    Class<App> obj = App.class;
    Object t = null;
    try {
        t = obj.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    if (obj.isAnnotationPresent(Window.class)) {
        for (Method method : obj.getMethods()) {
            if (method.isAnnotationPresent(Window.Run.class)) {
                try {
                    method.invoke(t, new Object[] {});
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                }
            }

        }

    }

but it works only if I know the class name. How can I detect all the classes inside the project without external API?

shb
  • 5,957
  • 2
  • 15
  • 32
Bonfra
  • 297
  • 1
  • 11
  • You may should take a look here: https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection – Frighi Jul 30 '18 at 22:37
  • @Frighi yes i have already seen that but it uses external API and it's ok there is no problem. I just wanted to recreate it without them. – Bonfra Jul 30 '18 at 22:42
  • @Frighi but there is apparently no easy way so probably i'll use that – Bonfra Jul 30 '18 at 22:43

2 Answers2

0

So yes it was difficult but i did it without any API

private static List<Class<?>> findClasses(File directory, String packageName) {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    if (!directory.exists())
        return classes;

    File[] files = directory.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            assert !file.getName().contains(".");
            classes.addAll(findClasses(file,
                    (!packageName.equals("") ? packageName + "." : packageName) + file.getName()));
        } else if (file.getName().endsWith(".class"))
            try {
                classes.add(Class
                        .forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
            } catch (ClassNotFoundException e) {
                System.err.println(e.getMessage());
            }
    }
    return classes;
}

this returns all classes inside a package like TREE command in CMD (if you insert "" as packagne name this will return all classes inside the project).

public static Class<?>[] getClasses(String packageName) {

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    assert classLoader != null;
    String path = packageName.replace('.', '/');
    Enumeration<URL> resources = null;
    try {
        resources = classLoader.getResources(path);
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
    List<File> dirs = new ArrayList<File>();
    while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        dirs.add(new File(resource.getFile()));
    }
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (File directory : dirs)
        classes.addAll(findClasses(directory, packageName));

    return classes.toArray(new Class[classes.size()]);

}

then this method extract all classes from a package using findClasses() method.

Bonfra
  • 297
  • 1
  • 11
-1

I don't think there is a very easy way to do this or in fact even if it's worth it creating your own custom implementation.

I don't see why you would not want to use an external dependency to do so. I have came across the same exact problem a few months ago, and I simply elected to use the reflections API to do my job. You can check more on this here: https://github.com/ronmamo/reflections.

Aside, from that you could potentially look into creating a utility that will scan the various packages of your project looking for the classes and methods annotated with that annotation but as mentioned before, this would lead you into creating something very similar like the library mentioned above.

Aside from that you could potentially look into an annotation post processor (that is creating your own) but I haven't tried this approach nor can I tell you if fits your requirements.

Bottom line is, unless there is a very very restrictive need that dictates that you cannot use a third party library, I don't see any reason that might require you to re-invent the wheel.

akortex
  • 5,067
  • 2
  • 25
  • 57