leaningtech / cheerpj-meta

Run Java 8 applications, libraries, applets, Java Web Start, and Oracle Forms on the web without legacy plugins.
https://labs.leaningtech.com/cheerpj
459 stars 21 forks source link

Resetting the Classloader / static fields after program execution. #174

Closed BlazingTwist closed 1 year ago

BlazingTwist commented 1 year ago

Currently it seems that class initialization is only run once. As a result Java code such as this causes "unexpected" behaviour:

package blazingtwist;

public class Main {
    public static String myStaticVariable = null;

    public static String getMyStaticVariable(String initializer) {
        if (myStaticVariable == null) {
            myStaticVariable = initializer;
        }
        return myStaticVariable;
    }

    public static void main(String[] args) {
        String myVariable = getMyStaticVariable(args[0]);
        System.out.println("myVariable is '" + myVariable + "'");
        System.exit(0);
    }
}

Executing the Main class like this:

cheerpjInit();
cheerpjRunMain("blazingtwist.Main", "/app/CheerpJTesting.jar", "hello");
cheerpjRunMain("blazingtwist.Main", "/app/CheerpJTesting.jar", "world");

Results in this output:

myVariable is 'hello'
myVariable is 'hello'

Whereas the expected output would be:

myVariable is 'hello'
myVariable is 'world'

The same behaviour occurs for

cheerpjRunJar("/app/CheerpJTesting.jar", "hello");
cheerpjRunJar("/app/CheerpJTesting.jar", "world");

Obviously "fixing" that example is trivial, but for more complicated programs this preservation of static fields causes a lot of unexpected side effects.

Ideally there would be some way to restart the JVM / or re-run all static initializers, such that subsequent cheerpjRunMain calls start from a fresh slate.

For completeness sake, I have attached the full source code / jar / jar.js source.zip


Just to clarify, this does provide the expected output:

java -jar .\CheerpJTesting.jar "hello"
java -jar .\CheerpJTesting.jar "world"
alexp-sssup commented 1 year ago

The behavior you observed is expected with the CheerpJ 2.x architecture, which is currently being deprecated in favor of the new CheerpJ 3. CheerpJ 3 will behave correctly for this test case.

A first release candidate CheerpJ 3.0 will be made available in mid-october, but you can already try out current builds. Please join our Discord for more information: https://discord.gg/X9ruPkchM5