How to load the entire compiled class from a folder?

I have folder operators. In this folder, I compiled the file (one AND 4 interface statement that implements the statement). The goal is to download the entire .class file from this folder and use it in the main program. I use these entries:

    File operatorFile = new File("D:\\operators");
    URL operatorFilePath = operatorFile.toURL();          
    URL[] operatorFilePaths = new URL[]{operatorFilePath};
    ClassLoader operatorsLoader = new URLClassLoader(operatorFilePaths);

 //Plus,Minus,Multiply,Divide are classes that implement operator interface
   Class[] operatorClass = new Class[]{ operatorsLoader.loadClass("Plus"), operatorsLoader.loadClass("Minus"),operatorsLoader.loadClass("Multiply") , operatorsLoader.loadClass("Divide") };

Then I use this element to call the methods of the .class class:

Method methodsInOperator;
Object instance;
String operatorSign;

for(Class operatorCls : operatorClass)
{
   instance = operatorCls.newInstance();
    methodsInOperator = operatorCls.getMethod("getSign", null); 
    operatorSign = (String)methodsInOperator.invoke(instance, null);
                    if(operatorSign.equals(elementInExpression[2]))
                    {
    methodsInOperator = operatorCls.getMethod("calculate", new Class[] { double.class, double.class } ); 
                        output =(double)methodsInOperator.invoke(instance, firstNumber, secondNumber);  
                    }
                }

But below the statute dose does not work dynamically, and if we put another .class file in the folder, then the folder program stops working.

Class[] operatorClass = new Class[]{ operatorsLoader.loadClass("Plus"), operatorsLoader.loadClass("Minus"),operatorsLoader.loadClass("Multiply") , operatorsLoader.loadClass("Divide") };

My goal is to dynamically load all classes and check whether they implement the operator and, in accordance with the getSing () method, select the best class. Can anyone help me?

+4
source share
3 answers

There are two parts:

  • .
  • , /.

, - .

public Class[] getOperators(File operatorFile) throws MalformedURLException, ClassNotFoundException {
    ClassLoader operatorsLoader = new URLClassLoader(new URL[] { operatorFile.toURI().toURL() });

    File[] files = operatorFile.listFiles(new FilenameFilter() {
        @Override public boolean accept(File dir, String name) {
            return name.endsWith(".class");
        }
    });
    ArrayList<Class> operators = new ArrayList<>();
    for (File file : files) {
        String className = file.getName().substring(0, file.getName().length() - 6);
        Class<?> clazz = operatorsLoader.loadClass(className);
        if(OperatorInterface.class.isAssignableFrom(clazz)) {
            operators.add(clazz);
        }
    }
    return operators.toArray(new Class[operators.size()]);
}

, , OpeartorInterface. - , , .

0

SPI- :

  • , ,

java -cp "main.jar; " my.package.MainClass

  1. "META-INF/services"

  2. , . , Operation com.calc "com.calc.Operation"

  3. . , . . "com.calc.Addition", 4- "com.calc.Devision" ..

  4. ServiceLocator :

    ServiceLoader<Operation> operations = ServiceLoader.load(Operation.class);
    Iterator<Operation> ite = operations.iterator();
    while (ite.hasNext()) {
        Operation op = ite.next();
        System.out.println("operation implementation is: " + op.getClass());
        Number result = op.calc(3,4);
        System.out.println("Result of 3 and 4 is " + result);
    }
    

SPI https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html , ServiceLocator Java 6. SPI, .

, /META-INF/services

0

If I were you, I would give the Reflections library a chance. This is a very nice program that allows you to do exactly what you want:

Reflections reflections = new Reflections(new ConfigurationBuilder()
    .setUrls(ClasspathHelper.forPackage("my.project.prefix"))
    .setScanners(new SubTypesScanner()),
    .filterInputsBy(
        new FilterBuilder().includePackage("my.project.prefix")));

where my.project.prefixpoints to your folder.

Then you can simply use the instance reflectionsto get your classes:

Set<Class<? extends Operator>> operators = 
    reflections.getSubTypesOf(Operator.class);

Here Operatorwill be your base class or interface.

0
source

All Articles