Create a java class dynamically and compile and instantiate at run time

风流意气都作罢 提交于 2020-04-10 05:59:24

问题


I have a String that I need to convert to java class, compile and create an instance at run time: Suppose my String is:

String s = " public class Test {
  public Double add(Double x, Double y){
    return (x+y);
  }
}"

How can I convert it to a class Test.class, instantiate it and call the method add(Double x, Double y) at run time?

I read about Byte Buddy , but the examples I see has a class already defined. In a situation like the above, could anyone give an example how can I use ByteBuddy or any other libraries through which I can achieve this?

Any inputs or suggestions on how to convert this String to compilable and instantiable java class would be helpful.


回答1:


Can we use something like this :

package com.demo;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

public class StringToClass
{
    public static void main(String[] args)
    {
        String s = "import com.demo.FormulaAPI; public class FormulaExecutor" +
                " { public Double formula1(FormulaAPI apiReference)" +
                " { System.out.println(apiReference.evaluate(\"10.10\"));  return apiReference.evaluate(\"10.10\"); } }";
        try
        {
            dynamicClass(s, "FormulaExecutor");
        } catch (IOException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e)
        {
            e.printStackTrace();
        }

    }

    static void dynamicClass(String sourceCode, String className) throws IOException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException
    {
        File parent = new File(System.getProperty("user.dir"));
        File sourceFile = new File(parent, className + ".java");
        sourceFile.deleteOnExit();

        FileWriter writer = new FileWriter(sourceFile);
        writer.write(sourceCode);
        writer.close();

        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager standardJavaFileManager = javaCompiler.getStandardFileManager(null, null, null);
        File parentDir = sourceFile.getParentFile();
        standardJavaFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(parentDir));
        Iterable<? extends JavaFileObject> compilationUnits = standardJavaFileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile));
        javaCompiler.getTask(null, standardJavaFileManager, null, null, null, compilationUnits).call();
        standardJavaFileManager.close();

        URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[] {parentDir.toURI().toURL()});
        Class<?> dynamicClass = urlClassLoader.loadClass(className);


        Method formula1 = dynamicClass.getDeclaredMethod("formula1", FormulaAPI.class);
        formula1.invoke(dynamicClass.newInstance(), new Object[] {new FormulaAPI()});
    }


}

package com.demo;

public class FormulaAPI
{
    public Double evaluate(String str)
    {
        return Double.valueOf(str);
    }
}

For Now, Method name is hardcoded

        Method addMethod = dynamicClass.getDeclaredMethod("add", Double.class, Double.class);

We can even generate it at runTime using reflection

We can import the class in the source code.




回答2:


Byte Buddy works on the byte code level and does not process source code. You can use Javassist for this purpose which offers limited processing of source code as it ships its own compiler.

Alternatively, use the Java compiler API as suggested.



来源:https://stackoverflow.com/questions/60664816/create-a-java-class-dynamically-and-compile-and-instantiate-at-run-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!