java是否可以缓存运行时编译的类?
每当我试图缓存一个在运行时编译Java类的方法的结果时,第一次一切正常,但第二次(当从缓存中获得结果时)它会给我一个ClassNotFoundException
。我不知道这是不可能实现,还是我做错了什么
以下是我如何使用缓存调用该方法:
public void execute() throws Exception {
MyClass myclass = new MyClass();
String code = "This is a really long JavaClass that implements CompiledClass"; // Retrieve JavaCode from somewhere
for (int i = 0; i < 10; i++) {
CompiledClass obj = myclass.getInstance("NameClassToCompile", code);
}
}
这是方法可缓存的类:
@Component
@CacheConfig(cacheNames = "myCache")
public class MyClass implements SomeClass {
@Override
@Cacheable(key = "#name")
public CompiledClass getInstance(String name, String code) throws CustomException {
try {
// Save source in .java file.
File root = Files.createTempDirectory(null).toFile();
File sourceFile = new File(root, (this.getClass().getPackage().getName() + File.separator + name).replace('.', '/') + ".java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), code.getBytes(StandardCharsets.UTF_8));
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
// Load and instantiate compiled class.
Class<?> cls;
try (URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{root.toURI().toURL()})) {
cls = Class.forName((this.getClass().getPackage().getName() + "." + name), true, classLoader);
}
return (CompiledClass) cls.getDeclaredConstructor().newInstance();
} catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException | IOException | ClassNotFoundException e) {
throw new CustomException("didn't work", e);
}
}
我有一个例外:
com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: com.mycompany.myartifact.mypackage.NameClassToCompile
这就是我的Hazelcast配置:
@Bean
public Config hazelCastConfig() {
return new Config()
.setInstanceName("hazelcast")
.addMapConfig(
new MapConfig()
.setName("myCache")
.setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
.setEvictionPolicy(EvictionPolicy.LRU)
.setTimeToLiveSeconds(20));
}
这是实现所有编译类的接口
public interface CompiledClass extends Serializable {
Long calculateSomething(String some);
}
以下是在运行时编译的代码示例:
public class NameClassToCompile implements CompiledClass {
@Override
Long calculateSomething(String some) {
return Long.valueOf(name.length());
}
}
共 (0) 个答案