Use of custom classloaders to load (and unload) modules

In one of my nebulous “projects”, I created a setup of separate Classloaders so I could import and disconnect code from the project during runtime. This has proved helpful for testing physics modules (such as buoyancy and magnetism) as I could now unload and reload the code in nearly real-time. It definitely sped up debugging. I intend to use it on a network project where a user can connect to another user’s server, and then receive and import new .jar files (after it’s been sandboxed first) to step into another user’s gamespace. This was already mostly possible with some calls to the default classloader, but you couldn’t unload modules.

Fluff aside, would being able to load and unload modules at runtime be a good fit for some JmonkeyEngine projects? Or… has almost everybody else already had this idea and found some red flags?

I think most games simply don’t need it.

…but the big red flag is that there really isn’t a fully safe “sandbox”. Even the Java developers’ themselves couldn’t get this 100% right which is why Java is basically dead on the browsers.

“Portable” code (ie: code that can move between games) is never going to be 100% secure so you will probably want big giant warnings to play only with folks you know well.

2 Likes

You may discover a lot of things ahead, like security and performance problems with lowlevel ClassLoader like what pspeed said. Such “blackmagic” like dynamic loading and redefining classes is kind of prohibited in Java language and JVM landscape… but it was afew years ago, I personally use ClassLoader a lot cause i love plugins…

To get started try research about OSGi, thats the standard way. I used it to create plugin and load games with assets and code from my Editor (it reload on the fly like what Unity do). If you want to do scripting, try Groovy. And if you want to do low level connection between codes, use ClassLoader and ByteBuddy

2 Likes

I can see there’s definitely a big “trust” element. I’ve left room in my works for the asset server code to deal with storing a hash for comparison, but that only really helps verify that they’re getting what they’re asking for. The trust part would still come down to the user. SecurityManagers could help me lock some of it down. Though, I could just keep this part as a warning-laden variant of my project (ideally, for collaboration).

I would definitely recommend looking into OSGI. Apache Felix is a lightweight OSGI container that you can embed in your game and it does exactly what your looking for. It can be a little bit tricky as you need to define and provide any dependencies, but you can add new ones on the fly, and load/unload jars programmatically. If you need any assistance with that pm me.

1 Like

Being able to unload/reload code in nearly real time is definitely useful.
When?
During development.
There’s some in-build support for this in NetBeans. While debugging you can change the contents of a method and have it recompiled, almost immediately, by clicking the green button to apply code changes. However, this action is limited to code in methods, you cannot add new methods, change their signature etc.

I also tried to separate my code into ecs,systems on one part, and java files which create the gameplay world, gameplay behaviour on another. I use another class loaded for the gameplay stuff. Thus I can with a button refresh the whole thing. This way, even new classes/new methods can be added deleted as long as I do not touch the part of the code which does not support reloading.

It’s quite useful for some scenarios when, eg I edit the Blend file, click import button, to see the changes in game. Or add a new behavior or event to a part of the map.

However, although it helps, this kind of interactivity is still very much limited. For example, let’s say I’d want to tweak some material parameters to see how they look. This system still does not allow to do this at interactive base. Or i’d would like to quickly swap a texture an object has with a different one… etc.

Currently for such cases, I got a window on a side with bunch of sliders, buttons to tweak the params that I’m interested in. But the problem is that to add a new tweakable param I got to restart either the gameplay classloader or whole game.

Atm, I got a new idea to reach general interactivity. And its simply a node system. Where each node is a Java method/Java object.
For the example of editing material params of some scene object, it could work like following: First of all, there would have to be a way or several ways to search for a geometry or just select a material. Eg. a button to pick 3d geometry with mouse from scene. Then this geometry would pop out as a Geometry Node in the Node Editor. Then user would use Geometry.getMaterial() Node to obtain the material and eg let’s say he would be interested in tweaking the Color of the material. He would add Material.setColor() Node to change the color. Finally, he would need a node that would display GUI for color selection. Then just plug it in and as he changes the color, the color in jme 3D view changes interactively.

The above would not be too much work as 99.99% of the nodes are generated automatically, they are created with Java reflection and are simply Java methods. The work would have to be done to create GUI for eg. color selection, etc.

Let me know what you think.