Information relevant to the above GraalJS proof-of-concept:
Some challenges I faced
There is surprisingly little documentation on the use of GraalVM on the web. Practical examples are few and far between.
GraalVM has only been around for 5 to 6 years. So it is relatively new Java technology. But it has a growing following. As such, it is developing and changing rapidly in the wild. It is being extended in different directions by different interest groups. One consequence is that, during my web searches, I could not find 2 GraalJS code examples that are implemented in the same way.
I faced complexity at every turn. GraalVM is available in two Editions, Community and Enterprise. The functionality and capability of the editions are quite different. However, when you search the web for GraalVM you see that the information about the two editions is all mixed up. Add to this the fact that GraalVM can serve a variety of programming flavours. It can run applications written in programming languages such as Java, Python, Ruby, R, and Javascript. This is Graal's so-called polyglot capability. Not only that, Graal allows for tight integration between the different languages. For example, it enables you to call Java methods from JavaScript and vice versa. Great versatility and power, for sure. But it is quite complex to get to grips with implementation, especially when there is inadequate documentation and guidance.
2. Reference notes For reference purposes, here are some of the important obstacles and errors I encountered along the way (together with the solutions):
Location of GraalJS JAR files GraalJS depends on 14 JARs and 2 POM files. I quickly discovered that it was impractical to copy them into ColdFusion's lib directory. For a start, that was poor design. It didn't promote separation-of-concerns. In any case, it led to classpath errors. The solution was to bundle the JARs and POM files into a separate directory dedicated to GraalJS, namely, C:\ColdFusion2023\cfusion\GraalJS_library. I then appended {application.home}/graalJS_library to the setting -Dcoldfusion.classPath in jvm.config.
javax.script.ScriptEngineManager inadequate Try as I could, I could not get the combination scriptEngineManager=createObject("java", "javax.script.ScriptEngineManager").init() and scriptEngineManager.getEngineByName("js") to work. I solved this by using Graal's polyglot engine instead.
Frequent occurrence of the error messages "The eval method was not found" and "Access to language 'JS' is not permitted" Access problems persisted even after the move from javax.script.ScriptEngineManager to org.graalvm.polyglot.Context. This resulted from the fact that the class org.graalvm.polyglot.Context may be instantiated by means of a variety of methods. These range from the single create() to a chain such as newBuilder().allowHostAccess().allowIO().build().getBindings().putMember() Researching and experimenting with the various combinations led to success eith newBuilder(["js"]).allowAllAccess(true).allowIO(true).build()​
You should yourself look into each of these methods if you're interested. You might come up with a more optimal solution than mine.
Frequent occurrence of error message "java.nio.file.InvalidPathException: Illegal char <:> at index 2: /C:/ColdFusion2023/cfusion/lib/updates/chf20230012.jar" This is caused by the phenomenon of classpath isolation in GraalVM's polyglot engine. To fix this, apply the following JVM flag in ColdFusion's jvm.config: -Dpolyglotimpl.DisableClassPathIsolation=true​
Frequent warning in the logs to configure runtime compilation for polyglot engine Apparently, without runtime compilation polyglot will use a fallback runtime. The fallback runtime does not support runtime compilation to native code, which will negatively impact performance of the guest application. To solve this, the GraalVM documentation recommends that you migrate to GraalVM or to a GraalVM-compatible JDK. That is impractical for our purposes, as ColdFusion 2023 is untested on GraalVM. Hence we resort to an alternative solution, namely, to suppress the warning and accept any temporary performance drop. To suppress the warning in ColdFusion's Java, use the JVM flag -Dpolyglot.engine.WarnInterpreterOnly=false​
... View more