JetBrains / JetBrainsRuntime

Runtime environment based on OpenJDK for running IntelliJ Platform-based products on Windows, macOS, and Linux
GNU General Public License v2.0
1.35k stars 198 forks source link

different from the previous jdk8 dcevm #414

Closed xiandafu closed 3 months ago

xiandafu commented 4 months ago

it seem different from the previous jdk8 dcevm. When modifying the hot variable, i can see that the class MyHotSwap has been redefined, but with 14 lines, the output remains the same. Using line 15, modify the hot and i can see that the output has changed.

why?

image

the output

image
skybber commented 4 months ago

It must remain the same; there is no mechanism in DCEVM that calls the instance initializer <init> on each instance of a redefined class. Values of static fields are copied from the old class to the new class, so the value of instance should be the same as before the redefinition. HotswapAgent is able to initialize new static fields by parsing the <clinit> method, but in your case, instance is already initialized, and HotswapAgent does not change it.

I've tested instance.call() with this release of TravaOpenJDK, and it does not update the hot value, which is correct. The same result I see in the jbr21 case.

xiandafu commented 4 months ago

thanks @skybber
i modify the Constants.a,i cannot see any change.

public class TestMain {
    public static void main(String[] args) throws Exception {
        while(true){
            System.out.println(Constants.a);
            Thread.sleep(3000);
        }
    }
    public static class Constants{
        public static int a =5;  //5-->6,not work
    }
}

image

BTW,can hotswap.jar support programmers to define the logic of hot swap instead of relying on hotswap plugins, ?such as

public class TestMain {
    public static void main(String[] args) throws Exception {
      ........
    }
    @HotSwap
    public static changeIt(ObjectRealoadWrapper oldIns){
       oldIns.setField("xxxx",Constants.a)
    }
    public static class Constants{
        public static int a =6;  //not work

    }
}

in this case ,the method wtih @HotSwap would be invoked after hotswap .jar reload TestMain.class. programmers decide how to how swap ?

skybber commented 4 months ago

public static int a = 5; is not a constant, but a static variable. Neither DCEVM nor HotswapAgent updates static variable values after a hotswap; instead, they copy static values from the old class to the new class.

To make the @HotSwap annotation work, you need to collect all instances of ObjectReloadWrapper and call your method for each instance. To collect all instances is not supported in JVM as I know.