Question

I have an application that allows, using an abstract class, people to write their own implementations. I load these implementations as .class-files from a directory. Currently, I have this solution:

File classDir = new File("/users/myproject/classes/");

URL[] url = { classDir.toURI().toURL() };
URLClassLoader urlLoader = new URLClassLoader(url);

String filename;
for (File file : classDir.listFiles()) {
    filename = string.getFilenameWithoutExtension(file);
    if (filename.equals(".") || filename.equals("..") || filename.startsWith("."))
        continue;

AbstractClass instance = (AbstractClass)urlLoader
    .loadClass("org.mypackage." + filename)
    .getConstructor(ConfigUtil.class, DatabaseUtil.class, StringUtil.class)
    .newInstance(config, database, string));

    instance.doSomething();
}

As you see - I need to specify the package the classes are located in in order to correctly load them. Omitting the package, I get an

 java.lang.NoClassDefFoundError:
     MyClass (wrong name: org/mypackage/MyClass)

error.

Now, from a architectural POV, I think it is very ill-designed that classes other people designed have to be compiled to MY package when loading them.

So I ask you: Is there a way I can load classes form the file system without having to specify the package they reside in?

Was it helpful?

Solution

Yes; implement an interface (or use an annotation).

Then use any class-scanning library (there are lots of SO questions about this, like this one) to load the particular class in question. Searching for "Java class scanning" or "Java plugin mechanism" will help.

You might also just want to use the Java Plugin Framework and avoid some effort. Although it's not clear to me that it's maintained any more, I know people are still using it.

OTHER TIPS

You can use the ServiceProvider to load implementations which you don't know.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top