有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案