Today we will take a look at how you can execute Java code that you have previously generated directly from within MPS and show its result in an editor.
Our model is a simple concept that will generate code to add two numbers. The editor of the concept has a button that executes the generated code and displays the result:
Here is what the generated code for the adder Five
looks like:
package com.spclngs.calc.sandbox;
/*Generated by MPS */
public class Five {
public int getResult() {
return 2 + 3;
}
public static void main(String[] args) {
System.out.println(new Five().getResult());
}
}
The task of the “Load Result” button in the editor is to create an instance of Fiver
via reflection, call its
getResult()
method, and show the result.
To create an instance of the class we need to obtain it from the module’s class loader. Any “normal” MPS module
(solution or language) implements the interface ReloadableModule
which has methods to obtain the class loader
(getClassLoader0()
) or to load the class directly (getClass()
):
Class<?> theClass = ((ReloadableModule) module).getClass(fqName);
Parameter fqName
above is the fully qualified name of the class which in our case is the same as the fully qualified
name of the adder node.
From here on, we can use classic Java reflection:
Object instance = theClass.getConstructor().newInstance();
Method getResultMethod = theClass.getMethod("getResult");
Object resultObject = getResultMethod.invoke(instance);
And we can then store the result in a property, within a command:
command with editorContext.getRepository() {
node.result = String.valueOf(resultObject);
}
And at this point the result will be shown in the editor.
Limitations
This simple approach will not work if the generated code has special requirements as to library versions. In this case we might need to create a custom class loader to escape class loader hell. I have touched upon this in the article about using Apache POI with MPS a few weeks ago.
Also, since we are running the code in process, we need to trust the code. Any JVM-global effects will affect MPS itself. For example, if the code calls System.exit()
then MPS itself will exit.
Sample source code
The full self-contained sample source code is available on GitHub.