
Leading the Way: Payara Platform Community 7 Beta Now Fully Jakarta EE 11 Certified
We’re excited to announce that Payara Platform Community 7 Beta application server is now fully certified as Jakarta EE 11 […]
The Java Virtual Machine comes in different flavors. On one hand, you have the OpenJDK based JVMs. Many vendors, including Oracle, RedHat, Amazon, and Azul to name just a few, create builds from the OpenJDK source to bring the JVM to your development machine or server.
Other JVMs do not have OpenJDK as a base. The most known ones are the Eclipse OpenJ9 and GraalVM.
Besides a JVM that runs your Java application, GraalVM has two specific features, the polyglot capabilities and the native compilation possibilities.
In the standard usage of a JVM, the source code is compiled to Java ByteCode which is ‘interpreted’ by the JVM at runtime. This makes it possible to use the same byte code on different operating systems. The JVM can convert some of this byte code into native during runtime when it sees clear benefits from it.
Native compilation goes a step further than that. Here the compiler generates native byte code for the operating system. The application can start up much faster due to the preparation done at compile time. Also, the memory consumption is lower since the binary is optimised for your application and it doesn’t need the general-purpose JVM. But it has also some drawbacks. For example, some well-known features from Java, such as reflection (usually requires manual configuration) and dynamic interceptions, won’t work anymore, and performance is a bit lower in general.
Another feature which is also very useful is the polyglot support within GraalVM. With polyglot support, it is not only possible to run JVM-based languages, like Scala, Groovy, and Kotlin, which is possible on all JVMs, but you can also have interoperability with other languages like Python, R, and JavaScript.
There is no interfacing or translation of some kind of context, all the languages share the same memory space. Each of the languages can access the variables directly and thus values can be used directly by the different languages.
So what does it mean to develop a polyglot application? There are different variations possible. Your application can be mainly a Java program but you call some JavaScript functions because the functionality you require is already available in a JavaScript library. Or you can develop a JavaScript program and make calls to other languages like Java or R.
To create a polyglot application with Java, you need to add the graal-sdk dependency to your applications. It contains all constructs required to combine the different languages. This also means of course that your application can be run only on the GraalVM as other runtimes like OpenJDK doesn’t have the required classes on board.
val chromaResource = Thread.currentThread().contextClassLoader.getResource("chroma.min.js")
val content = String(Files.readAllBytes(Paths.get(chromaResource!!.toURI())))
val context = Context.create()
context.eval("js", content)
chroma = context.eval("js", "chroma")
The above snippet reads the file containing the Chroma ‘library’ written in JavaScript (https://github.com/gka/chroma.js/), evaluates the file within a Graal Context, capable of handling JavaScipt language by default, and then we execute the JavaScript function to return a reference to the Chroma Object which we keep for further reference.
Oh, and if you think that the above snippet is not Java, you are correct. It is written in Kotlin. (Remember the goal of this blog was to show you how you can combine different languages.)
Later on, we can use the reference to the Chroma value to execute some functions on it, like this statement:
chroma.getMember("darken").execute()
The syntax is not as direct as in Java, you cannot just reference the name of the method. Instead, you have to request a reference to the method by specifying the name as a String parameter and then execute it.
But when you hide this interaction with JavaScript behind some interface, you can easily call JavaScript in a Java-like manner in your application.
The source code of the example can be found in our Github examples demo.
The example is mainly in Kotlin and defines a JAX-RS endpoint. This endpoint calls the Chroma JavaScript library to perform his functionality.
Within the pom file, we have to include the Graal SDK as explained earlier in the article and the kotlin dependency to work with Java 8.
<dependency>
<groupId>org.graalvm</groupId>
<artifactId>graal-sdk</artifactId>
<version>0.30</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
The maven project file also contains the kotlin maven plugin with his configuration to be able to have a entire project within Kotlin.
The JAX-RS resources within Kotlin is also quite readable for those who are familiar with the Java Version. As an example, I share here the hello world type version. The actual resource is just using that `chroma` variable referring to the JavaScript we discussed earlier.
@Path("/hello")
open class HelloResource {
@GET
@Path("/{name}")
open fun read(@PathParam("name") name: String): String {
return "Hello $name"
}
}
Besides the different syntax for parameters and return types, we should not forget to define the class and methods as open. Since all Kotlin artefacts are final by default, we explicitly need to indicate that they can be extended so that proxies can be created within the Java EE framework.
The JavaScript specific code is already described in the previous section and can be seen in the demo application on GitHub.
After you build the project (mvn clean package), you start Payara Micro the same as always.
java -jar payara-micro-5.193.jar --noCluster target/graalvm-example.war
And testing can be done using the following URL which gives you a darker version of the colour
http://localhost:8080/graalvm/chroma/darken/D4F880
It’s also interesting when there are exceptions occurring within the JavaScript code, as with the following URL:
http://localhost:8080/graalvm-example/chroma/darken/xyz
You clearly see the stacktrace joining into the JavaScript code:
org.graalvm.polyglot.PolyglotException: unknown color: xyz
unknown color: xyz
at <js> D(Unnamed:32:16430-16453)
at <js> k.hex(Unnamed:32:16873-16876)
at <js> a(Unnamed:32:3339-3353)
at <js> :anonymous(Unnamed:32:2659-2670)
at <js> t(Unnamed:32:2605-2722)
at org.graalvm.polyglot.Value.newInstance(Value.java:416)
One of the major benefits of the GraalVM is this Polyglot feature. Using this, you can combine code written in other languages like JavaScript, Python and R, which normally do not run on the JVM, in combination with your Java code. The integration is seamless so that the program code shares the same memory space and thus variables can be accessed from different languages.
This allows you to write polyglot applications which can run on Payara Micro and Payara Platform in general. It allows you to choose the most optimal library providing you the required functionality you have for your application, and it doesn’t need to be a JVM language.
{{cta(‘b2e4c2b6-f33a-4ae4-9290-f1cf476f445a’)}}
Share:
We’re excited to announce that Payara Platform Community 7 Beta application server is now fully certified as Jakarta EE 11 […]
Welcome aboard the August 2025 issue of The Payara Monthly Catch! With summer in full swing, things may have felt […]
Enterprise Java applications power global commerce, healthcare, government and countless other industries. These systems must be scalable, secure and […]
Thank you for article, are we using here the native capability of graalvm? Or only the polyglot capability? Sorry its not clear for me.
Hi Laurent,
The article describes the polyglot features of GraalVM and combining it with Jakarta EE.
Best regards
Rudy
Hi Rudy,
GraalVM now supports JDK 11
Nonetheless, I was not able to use a polyglot EE application using JDK 11
org.graalvm.polyglot.Context#create always throws “java.lang.IllegalStateException: No language and polyglot implementation was found on the classpath. Make sure the truffle-api.jar is on the classpath.”
The problem comes from org.graalvm.sdk:org.graalvm.polyglot.Engine#initEngineImpl which attempts to ServiceLoader.load(AbstractPolyglotImpl.class), expecting an instance of org.graalvm.truffle:com.oracle.truffle.polyglot.PolyglotImpl. But nothing is found…
Do you have any experience running polyglot EE apps with JDK 11 ? Is it a payara issue (I tried with 5.2020.7 and graalVM 20.3.0) ? Should I file one ?
Did I miss something regarding java modules ? I tried various combination of java –add-module, –add-exports, –add-opens without success.
Running the same code outside any EE context works perfectly.
Kind regards
Hi Maxence,
When I update the example that I have for JDK 11 and GraalVM, I encounter the same issue. However, the truffle-api.jar is available (within the GraalVM distribution or added to the application). Looking at various internet resources, many runtimes have the same issue and it might be an issue with the Classloader or an issue in GraalVM when using the classpath (and not the module path)
You can open an issue on Github but keep in mind that Polyglot applications are not our main focus and GraalVM is not officially supported.
Best Regards
Rudy