The
Java Shell tool (JShell), which was introduced with JDK 9, is an interactive tool for learning and prototyping Java. But JShell scripts can also be called up directly. This enables Java code to be executed without a separate compilation process, so it runs like a script. VCF Automation contains a JDK and therewith JShell. This blog post shows how this can be used in VCF Automation, to execute Java code.
Execute Java Code via JShell
Below we will use some extensions that make the use much easier, of JShell in particular and code from other programming languages in general. With this scheme we can integrate any programming language. Here are the necessary actions required for this:
JShell Code
We start with the JShell source code which outputs hello world and the JShell version.
System.out.println("Hello World from JShell " + Runtime.version());
/exit
|
Advanced Operating System Command Execution
The VCF Automation standard Command object has some disadvantages. For this reason the operating system command is executed here uses an extended implementation of operating system command call, with more options.
Read Action as Text and Store it as File
We use a JavaScript action, called getActionAsText, to read the content of an action as text, as the name suggests. This is a prerequisite for using an action, called writeActionAsFileInTempDirectory, to save the content of an action as a file in the temporary directory. Later we can then call JShell with it.
Execute Java Code
Executing the JShell code is very easy. The content of the action, containing the JShell code, is written to the temporary directory. After that, JShell will be run with this file and the output will be displayed.
/**
* @author Stefan Schnell <mail@stefan-schnell.de>
* @license MIT
* @version 0.1.0
*
* Checked with Aria Automation 8.12.0
*/
System.getModule("de.stschnell").writeActionAsFileInTempDirectory(
"de.stschnell",
"helloWorld_jsh",
"helloWorld.jsh"
);
var jshFileName = System.getTempDirectory() + "/helloWorld.jsh";
var output = System.getModule("de.stschnell").executeCommand(
["jshell", jshFileName], 5000
).output;
System.log(output);
|
That shows us how easy it is to integrate JShell.
Bypassing Automatic Type Casting
Java code can be used directly in the JavaScript Runtime Environment, so this approach initially does not promise any added value. However, there is an elementary disadvantage when using Java code in the JavaScript Runtime Environment. If a Java class is used, that has the same name as a VMware object, an
automatic type casting is done. Let us take a look at this behavior. In the following JavaScript code we define a variable of type java.net.URL. The name URL is also used by an VCF Automation object.
/**
* @author Stefan Schnell <mail@stefan-schnell.de>
* @license MIT
* @version 0.1.0
*/
function main() {
if (
java.lang.System.getenv("VCO_CONTROLCENTER_SERVICE_PORT") !== null
) {
System.log("JavaScript runs in VMware Aria Automation context");
}
var url = java.net.URL(
"https",
"blog.stschnell.de",
"/coreConcepts/"
);
try {
System.log("Java class name: " + url.getClass().getName());
} catch (exception) {
System.log("Aria Automation object: " + url.constructor.name);
}
// Program crashes here, because java.net.URL is type casted to URL
System.log("Protocol: " + url.getProtocol());
System.log("Hostname: " + url.getHost());
System.log("Path: " + url.getPath());
}
main();
|
Although we would expect that we get a java.net.URL object, but we get the VMware object with the same name. We can see from the log output that it is not a Java class name that is returned but the name of a JavaScript object. Calling the getProtocol method leads to an exception, because this method does not exist in the VMware object.
To get a workaround for this behavior we can use JShell. The following JShell code is equivalent to the JavaScript code above. We save this as an action.
/**
* @author Stefan Schnell <mail@stefan-schnell.de>
* @license MIT
* @version 0.1.0
*/
import java.net.MalformedURLException;
import java.net.URL;
void main() throws MalformedURLException {
if (System.getenv("VCO_CONTROLCENTER_SERVICE_PORT") != null) {
System.out.println("JShell runs in VMware Aria Automation context");
}
var url = new URL(
"https",
"blog.stschnell.de",
"/coreConcepts/"
);
System.out.println("Java class name: " + url.getClass().getName());
System.out.println("Protocol: " + url.getProtocol());
System.out.println("Hostname: " + url.getHost());
System.out.println("Path: " + url.getPath());
}
main();
/exit
|
Now this code can be executed with a command call.
/**
* @author Stefan Schnell <mail@stefan-schnell.de>
* @license MIT
* @version 0.1.0
*
* Checked with Aria Automation 8.12.0
*/
System.getModule("de.stschnell").writeActionAsFileInTempDirectory(
"de.stschnell",
"javaNetUrl_jsh",
"javaNetUrl.jsh"
);
var jshFileName = System.getTempDirectory() + "/javaNetUrl.jsh";
var output = System.getModule("de.stschnell").executeCommand(
["jshell", jshFileName], 5000
).output;
System.log(output);
|
And as we see, everything is executed as expected.
The use of JShell has a valid application area at least in this use case.
Conclusion
This is an additional integration scenario that shows us how easy it is to integrate JShell. This is more or less a second channel, an alternative, for executing Java code with the JavaScript runtime environment of VCF Automation. JShell is available as standard and can be used without any problems seamlessly with the it. In addition JShell offers us a workaround to eliminate disadvantages that arise in the context of specific Java classes, that have the same name as VCF Automation objects.