Вариант 1 (для выражений):
var jShell = JShell.create();
jShell.eval("String k1, k2;");
jShell.eval("k1 = \"test\"; k2 = \"tset\";");
var k1 = jShell.variables().filter(v -> v.name().equals("k1")).findAny().get();
System.out.println(jShell.varValue(k1));
Вариант 2 (требует org.patrodyne:patrodyne-scripting-java:1.0.0):
var scriptEngineManager = new ScriptEngineManager();
var scriptEngine = scriptEngineManager.getEngineByName("Java");
var evalString = "k1 = \"test\"; k2 = \"tset\";";
var evalClass = (Class<?>) scriptEngine.eval("" +
"class Example {" +
" String k1, k2;" +
" Example() {" +
" }" +
" void run() {" +
" " + evalString + "" +
" }" +
"}");
var evalCtor = evalClass.getDeclaredConstructor();
evalCtor.setAccessible(true);
var evalObj = evalCtor.newInstance();
Method evalRunMethod = evalClass.getDeclaredMethod("run");
evalRunMethod.setAccessible(true);
evalRunMethod.invoke(evalObj);
Field evalK1Field = evalClass.getDeclaredField("k1");
evalK1Field.setAccessible(true);
var k1 = evalK1Field.get(evalObj);
System.out.println(k1);
Вариант 3 (то, что ты описал, но без работы с диском, требует com.google.jimfs:jimfs:1.1):
var javaCompiler = ToolProvider.getSystemJavaCompiler();
var fileManager = javaCompiler.getStandardFileManager(null, ENGLISH, UTF_8);
var fileSystem = Jimfs.newFileSystem(Configuration.unix());
var evalString = "k1 = \"test\"; k2 = \"tset\";";
Files.writeString(fileSystem.getPath("/Example.java"), "" +
"public class Example implements Runnable {" +
" public String k1, k2;" +
" public void run() {" +
" " + evalString + "" +
" }" +
"}");
var sources = fileManager.getJavaFileObjects(fileSystem.getPath("/Example.java"));
javaCompiler.getTask(null, fileManager, null, null, null, sources).call();
var bytecode = Files.readAllBytes(fileSystem.getPath("/Example.class"));
var classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (name.equals("Example")) {
return defineClass(name, bytecode, 0, bytecode.length);
}
return super.findClass(name);
}
};
var exampleClass = classLoader.findClass("Example");
var exampleObj = (Runnable) exampleClass.getConstructor().newInstance();
exampleObj.run();
System.out.println(exampleClass.getField("k1").get(exampleObj));
Эти примеры из
этой темы.