As a limitation of substrate vm, dynamic class loading is not possible. So what is the idiomatic way of introducing plugin architecture in a native application?
@anidotnet all the plugin implementations need to be available during image building and, assuming they are loaded/allocated via reflection, the classes need to be registered for reflection.
That is very restrictive and totally defies the merit of plugin system. Is there any plan/consideration to add dynamic class loading later in future?
There is no plan to support "true" dynamic class loading in SubstrateVM itself, i.e., dynamic loading of bytecodes that are not available at image build time. This restriction is necessary to preserve the fast startup/low footprint benefits. However, conceptually this can be implemented at the application level, e.g., via a Truffle based Java implementation. We are not currently working on this but are open to contributions.
However, conceptually this can be implemented at the application level, e.g., via a Truffle based Java implementation.
Can you please elaborate more on this?
You can use the Truffle framework to implement language interpreters (like the JavaScript/Ruby/R/Python/llvm/… interpreters right now). These language interpreters can be included in a native image. Therefore, you could develop a Java interpreter on top of Truffle, include that in your native image, and use that for your dynamically loaded plugins. Or just use one of the existing language interpreters and develop your plugins in that language.
Another possibility would be to create a C api and write your plugins in C/C++. You would then compile the plugins with normal gcc/clang to shared library (.so/.dll) and load it with System.loadLibrary.
What about the option to compile Java code or something else into such a shared library with Graal. Would this be possible?
That way, there would be 2 (or more!) Java runtimes loaded into the same process (one for the main application, one for each plugin). I'm not sure if multiple SubstrateVM runtimes can coexist in the same process. Even if it appeared to work, there could be some internal state that is accidentally shared which could later cause some failure. Even if it worked well, a copy of the core Java classes would be included in every plugin. That would cause not only bigger size but also multiple copies of static state. There are probably other issues...
Most helpful comment
You can use the Truffle framework to implement language interpreters (like the JavaScript/Ruby/R/Python/llvm/… interpreters right now). These language interpreters can be included in a native image. Therefore, you could develop a Java interpreter on top of Truffle, include that in your native image, and use that for your dynamically loaded plugins. Or just use one of the existing language interpreters and develop your plugins in that language.