HotswapProjects / HotswapAgent

Java unlimited redefinition of classes at runtime.
GNU General Public License v2.0
2.32k stars 491 forks source link

HotswapAgent don't pickup new mapping and new class in spring boot #465

Open hnpanther opened 1 year ago

hnpanther commented 1 year ago

Hi I create simple spring boot application with @RestController and @GetMapping annotation I use Dcevm-11.0.15+1 and tomcat 9 outside ide with this args:

-javaagent:C:\jdk\dcevm-11.0.15\lib\hotswap\hotswap-agent.jar=autoHotswap=true

If I change existing method body everything is ok and woks(but in log file see error: HOTSWAP AGENT: 02:04:57.101 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - flushClassInfoCache() exception Unable to make field private static final com.sun.beans.util.Cache com.sun.beans.introspect.ClassInfo.CACHE accessible: module java.desktop does not "opens com.sun.beans.introspect" to unnamed module @12468a38.

If I create new method with @GetMapping hotswapagent detect and reload : HOTSWAP AGENT: 02:04:57.101 RELOAD (org.hotswap.agent.config.PluginManager) - Reloading classes [com.hnp.myapp.FirstController] (autoHotswap)

but new @GetMapping not working

also If I add new class, hotswapAgent don't detect it my simple app: https://github.com/hnpanther/myapp

skybber commented 1 year ago

Are you using -XX:HotswapAgent=external ? If not, you haven't dcevm. Setup information are available at : https://github.com/TravaOpenJDK/trava-jdk-11-dcevm

hnpanther commented 1 year ago

Are you using -XX:HotswapAgent=external ? If not, you haven't dcevm. Setup information are available at : https://github.com/TravaOpenJDK/trava-jdk-11-dcevm

I add this arg but but nothing changes java option for running tomcat: -XX:HotswapAgent=external -javaagent:C:\jdk\dcevm-11.0.15\lib\hotswap\hotswap-agent.jar=autoHotswap=true

hotswap-agent.properties(under resource directory): autoHotswap=true LOGGER=debug extraClasspath=C:\extraclass

skybber commented 1 year ago

Is it working if you use internal HA using -XX:HotswapAgent=fatjar, omit -javaagent.. and use debugger to redefine classes?

hnpanther commented 1 year ago

Is it working if you use internal HA using -XX:HotswapAgent=fatjar, omit -javaagent.. and use debugger to redefine classes?

I change my jdk and use jbr17 with IDEA. use this config in hotswap-agent.properties: autoHotswap=true LOGGER=debug for run app, in configuration setting use this java option: -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar

everything is ok when use above config with IDEA. when I use tomcat without IDEA and using this option for runs tomcat: -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=external -javaagent:C:\jdk\jbrsdk_jcef-17.0.6\lib\hotswap\hotswap-agent.jar=autoHotswap=true

hotswapAgent doesn't detect changes.(when I change method body its detect it but when I create new method with @GetMapping, doesn't detect)

hnpanther commented 1 year ago

When I change method body, tomcat log: HOTSWAP AGENT: 13:26:27.258 RELOAD (org.hotswap.agent.config.PluginManager) - Reloading classes [com.hnp.myapp.NewController] (autoHotswap) HOTSWAP AGENT: 13:26:27.311 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception No such field java.beans.Introspector.declaredMethodCache on null. HOTSWAP AGENT: 13:26:27.312 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap').

When I add new method with @GetMapping, tomcat log: HOTSWAP AGENT: 13:30:11.119 RELOAD (org.hotswap.agent.config.PluginManager) - Reloading classes [com.hnp.myapp.NewController] (autoHotswap) HOTSWAP AGENT: 13:30:11.140 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception No such field java.beans.Introspector.declaredMethodCache on null. HOTSWAP AGENT: 13:30:11.140 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap').

skybber commented 1 year ago

I have no problem with your project, HA detected @GetMapping correctly and redefine classes, but I'm not using autoHotswap=true, this option is useful only if you are not using debugger simultaneously.

hnpanther commented 1 year ago

I have no problem with your project, HA detected @GetMapping correctly and redefine classes, but I'm not using autoHotswap=true, this option is useful only if you are not using debugger simultaneously.

I don't wnat using debugger(I try to load new class or change class at runtime same as production). also I set extraClassPath and watchResources in properties file : `autoHotswap=true LOGGER=debug

extraClasspath=F:\apache-tomcat-9.0.73\webapps\test watchResources=F:\apache-tomcat-9.0.73\webapps\test1`

but When I copy new .class in test and test1 directory, HA Idoesn't seem to do anything(nothing in tomcat log)

HA only works when method body changes(but When I use IDEA everything works and no problem)

skybber commented 1 year ago

If it works only if you change method body, then you are probably not using dcevm. -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar

hnpanther commented 1 year ago

I do test with -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar but There was no difference When I change in IDEA, log: HOTSWAP AGENT: 08:05:23.041 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on 'G:\Project\myapp\target\classes\com\hnp\myapp\NewController.class' --> com\hnp\myapp\NewController.class HOTSWAP AGENT: 08:05:23.042 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on 'G:\Project\myapp\target\classes\com\hnp\myapp\NewController.class' --> com\hnp\myapp\NewController.class HOTSWAP AGENT: 08:05:23.050 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on 'G:\Project\myapp\target\classes\com\hnp\myapp\MyService.class' --> com\hnp\myapp\MyService.class HOTSWAP AGENT: 08:05:23.050 DEBUG (org.hotswap.agent.watch.nio.TreeWatcherNIO) - Watch event 'ENTRY_MODIFY' on 'G:\Project\myapp\target\classes\com\hnp\myapp\MyService.class' --> com\hnp\myapp\MyService.class HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.annotation.handler.WatchEventCommand) - Executing resource changed method watchReload on class org.hotswap.agent.plugin.hotswapper.HotswapperPlugin for event WatchFileEvent on path G:\Project\myapp\target\classes\com\hnp\myapp\MyService.class for event ENTRY_MODIFY HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.annotation.handler.WatchEventCommand) - Executing resource changed method watchReload on class org.hotswap.agent.plugin.hotswapper.HotswapperPlugin for event WatchFileEvent on path G:\Project\myapp\target\classes\com\hnp\myapp\NewController.class for event ENTRY_MODIFY HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.annotation.handler.WatchEventCommand) - Executing resource changed method watchReload on class org.hotswap.agent.plugin.hotswapper.HotswapperPlugin for event WatchFileEvent on path G:\Project\myapp\target\classes\com\hnp\myapp\NewController.class for event ENTRY_MODIFY HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.plugin.hotswapper.HotswapperPlugin) - Class com.hnp.myapp.MyService will be reloaded from URL file:/G:/Project/myapp/target/classes/com/hnp/myapp/MyService.class HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.plugin.hotswapper.HotswapperPlugin) - Class com.hnp.myapp.NewController will be reloaded from URL file:/G:/Project/myapp/target/classes/com/hnp/myapp/NewController.class HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.annotation.handler.WatchEventCommand) - Executing resource changed method watchReload on class org.hotswap.agent.plugin.hotswapper.HotswapperPlugin for event WatchFileEvent on path G:\Project\myapp\target\classes\com\hnp\myapp\MyService.class for event ENTRY_MODIFY HOTSWAP AGENT: 08:05:23.188 DEBUG (org.hotswap.agent.plugin.hotswapper.HotswapperPlugin) - Class com.hnp.myapp.MyService will be reloaded from URL file:/G:/Project/myapp/target/classes/com/hnp/myapp/MyService.class HOTSWAP AGENT: 08:05:23.189 DEBUG (org.hotswap.agent.plugin.hotswapper.HotswapperPlugin) - Class com.hnp.myapp.NewController will be reloaded from URL file:/G:/Project/myapp/target/classes/com/hnp/myapp/NewController.class HOTSWAP AGENT: 08:05:23.296 DEBUG (org.hotswap.agent.command.impl.SchedulerImpl) - Executing pluginManager.hotswap([class com.hnp.myapp.MyService, class com.hnp.myapp.NewController]) HOTSWAP AGENT: 08:05:23.296 RELOAD (org.hotswap.agent.config.PluginManager) - Reloading classes [com.hnp.myapp.MyService, com.hnp.myapp.NewController] (autoHotswap) HOTSWAP AGENT: 08:05:23.301 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.MyService from com.sun.beans.introspect.ClassInfo cache HOTSWAP AGENT: 08:05:23.301 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.MyService from ObjectStreamClass caches HOTSWAP AGENT: 08:05:23.301 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap'). HOTSWAP AGENT: 08:05:23.302 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.MyService from introspector HOTSWAP AGENT: 08:05:23.302 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception No such field java.beans.Introspector.declaredMethodCache on null. HOTSWAP AGENT: 08:05:23.306 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.NewController from com.sun.beans.introspect.ClassInfo cache HOTSWAP AGENT: 08:05:23.307 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.NewController from ObjectStreamClass caches HOTSWAP AGENT: 08:05:23.307 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap'). HOTSWAP AGENT: 08:05:23.307 DEBUG (org.hotswap.agent.plugin.jdk.JdkPlugin) - Flushing com.hnp.myapp.NewController from introspector HOTSWAP AGENT: 08:05:23.307 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception No such field java.beans.Introspector.declaredMethodCache on null. HOTSWAP AGENT: 08:05:23.375 DEBUG (org.hotswap.agent.config.PluginManager) - ... reloaded classes [com.hnp.myapp.MyService, com.hnp.myapp.NewController] (autoHotswap)

and When I change in tomcat webapp directory, tomcat log: HOTSWAP AGENT: 07:52:48.657 RELOAD (org.hotswap.agent.config.PluginManager) - Reloading classes [com.hnp.myapp.NewController] (autoHotswap) HOTSWAP AGENT: 07:52:48.676 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception No such field java.beans.Introspector.declaredMethodCache on null. HOTSWAP AGENT: 07:52:48.678 ERROR (org.hotswap.agent.plugin.jdk.JdkPlugin) - classReload() exception class java.io.ObjectStreamClass$Caches$1 cannot be cast to class java.util.Map (java.io.ObjectStreamClass$Caches$1 and java.util.Map are in module java.base of loader 'bootstrap').

DustinQiao commented 5 months ago

I face the same situation, it doesn't work when I hotswap new .class file to the remote machine but it works when I hotswap in my IDEA