External change to manually compiled files [message #1751316] |
Sun, 08 January 2017 11:32 |
Benno Kallweit Messages: 8 Registered: November 2016 |
Junior Member |
|
|
Hi everybody,
i am developing a plugin which mainly handles uml diagrams. To get a better understanding of the preceding steps (if the error might happen somewhere there) here is what i do:
- Generate a UML Model with MagicDraw
- Load the uml 2.3 model into a emf resource in the plugin
- transform it according to a company metamodel using ATL
- generate java code out of this model using Acceleo
- compile the code at runtime
- execute the code <- here comes the problem, the rest works fine so far
The compilation of the generated file works without any problems. If i trigger the process the generated java file is always correct (according to the models content) and the class file corresponds to the java file, so the compilation worked.
I use for compilation and the start of the class the following code:
File file = new File(pathToFile);
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, file.getPath());
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {file.getParentFile().toURI().toURL()});
Class<?> cls = classLoader.loadClass("nameOfTheClass"); //name replaced
CustomInterface instance = (CustomInterface ) cls.newInstance();
classLoader.close();
instance.startSimulation();
The main problem now is, that the instantiated class is not the one i compiled before, but the one i compiled at first execution of the code. So no external changes in the files are noticed by java. I guess eclipse keeps the class in memory, although i always create a new classLoader instance.
If i open the generated java file in eclipse and eclipse reloads the file (automatically) then in the next execution the class of the point of time when i open the java file in eclipse is used. Further changes are only loaded if i open the java file again.
I already tried to delete the class file before recompilation and to call classLoader.clearAssertionStatus() but both did not solve the problem.
So does anyone have an idea how to call java, that the newly generated class file has to be loaded? I thought classLoader.loadClass(...) would do exactly this but it seems it doesn't...
Thanks in advance for your help!
|
|
|
|
Re: External change to manually compiled files [message #1751810 is a reply to message #1751415] |
Sat, 14 January 2017 14:45 |
Benno Kallweit Messages: 8 Registered: November 2016 |
Junior Member |
|
|
Thanks for your reply! Unfortunately this does not work for me.
Meanwhile i found a workaround myself. I load the generated classfile as byte[] using the 'defineClass' Method, which forces the classloader to explicitly reload the class content from the byte[]. My solution now looks like the following:
public class ByteArrayClassLoader extends ClassLoader {
public ByteArrayClassLoader() {
super();
}
public Class<?> findClass(String name, byte[] ba) {
return defineClass(name,ba,0,ba.length);
}
}
File file = new File(pathToFile);
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, file.getPath());
//changed part:
Path path = classFile.toPath();
byte[] data = Files.readAllBytes(path);
Class<?> cls = new ByteArrayClassLoader().findClass("cpsModeler.logic.interceptor.codeGenerator.genSrc.generatedFSM", data);
CustomInterface instance = (CustomInterface ) cls.newInstance();
classLoader.close();
instance.startSimulation();
|
|
|
Powered by
FUDForum. Page generated in 0.03404 seconds