Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Dynamic Factory

I only have about half a year of java experience, so please excuse my lack of knowledge. I tried doing some google searches, and I have some ideas on this, there are just a few holes that I need to fill in.

I am trying to create a 'Dynamic Factory' for a program I am doing. The basis of this is that I want people to be able to insert class files into a folder, and they will be loaded into my factory to create new instances of them later.

This is what I have right now:

import java.util.HashMap;
import java.util.Map;

public class KitManager {

    private Map<String, Class<? extends Kit>> kitMap;

    public KitManager() {
        kitMap = new HashMap<String, Class<? extends Kit>>();
    }

    public Kit makeKit(String kitname) {
        try {
            return kitMap.get(kitname).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }   
}

Now what I am trying to figure out is how to get all the classes inside of a folder, make sure that they extend Kit, and then insert them into the Map to have instances of them created later. This is where I am stuck, I cannot think of a good way to have the classes loaded into the map without having the class names and lookup strings identified somewhere in a config. The idea that I had was to have static code inside each class that would insert itself into the HashMap, but I am not exactly sure how that would work. All I am really asking for is an idea on how to go about accomplishing my goal. (Having a folder that users can input classes into (that extend Kit), and then have those classes dynamically load into my kitMap when my program is loaded)

like image 878
Phiction Avatar asked Nov 01 '22 13:11

Phiction


1 Answers

Hard to give a good answer when the requirements are a bit vague.

From what you say, you could just create a ClassLoader pointing to the directory where users put their classes:

ClassLoader kitClassLoader = new URLClassLoader("file://<path>", KitManager.class.getClassLoader());

To actually find the classes, use a simple directory list method, e.g. java.io.File.listFiles() (using a File instance pointing to the correct path obviously):

File[] candidates = new File("<path>").listFiles();

You can then use the kitClassLoader to actually load a class found:

kitClassLoader.loadClass(className);

Class names you can derive by simply splitting of the ".class" extension from the files found with listFiles(). After loading the class, you can then check that it actually has a default constructor and also if it really implements Kit (if it doesn't, reject it or display an error message).

Thats basically the approach, but it has dire security issues (you have no idea what the classes actually will do when you load them), and it may also introduce problems with dependencies (the classes you load may need additional libraries?).

like image 87
Durandal Avatar answered Nov 09 '22 13:11

Durandal