Comments (20)
Sorry about that. I guess repackaging Cglib would be an option. This should sit in the core project, next to javassist? Would you like me to add it there?
from hotswapagent.
I think it will not solve the issue - although the net.sf.cglib.proxy.Callback class will be available at startup, it will be different to the class loaded by webapp classloader.
If your code runs from "agent" classloader (directly from the plugin), it must be launched via java reflection, because "agent" classloader does not know anything about classes from weabpp.
The other way is to call the method from modified class in webapp classloader. It is possible, because all "agent" classes are replicated into all webapp classloaders (see org.hotswap.agent.util.classloader.ClassLoaderPatcher).
Javaassist is something else - it is included only to support bytecode manipulation.
from hotswapagent.
I have removed the dependencies with the commit erkieh@e703606
from hotswapagent.
There are still issues in multi classloader projects. The problem is with ProxyTransformationUtils.getClassPool() method. You need to have classPool with classpath of current classLoader - classPool.appendClassPath(new LoaderClassPath(classLoader));
- for each application classloader. You can add ClassPool method parameter to @OnClassLoadEvent annotated method and the framework will create correct ClassPool for you.
HOTSWAP AGENT: 7:35:58.319 ERROR (org.hotswap.agent.plugin.proxy.cglib.GeneratorParametersRecorder) - error modifying class for cglib proxy creation parameter recording
org.hotswap.agent.javassist.NotFoundException: org.springframework.cglib.core.ClassGenerator
at org.hotswap.agent.javassist.ClassPool.get(ClassPool.java:445)
at org.hotswap.agent.javassist.CtClassType.getInterfaces(CtClassType.java:685)
at org.hotswap.agent.plugin.proxy.cglib.GeneratorParametersRecorder.transform(GeneratorParametersRecorder.java:33)
at org.hotswap.agent.plugin.proxy.ProxyPlugin.transformDefinitions(ProxyPlugin.java:48)
at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.hotswap.agent.annotation.handler.OnClassLoadedHandler.transform(OnClassLoadedHandler.java:157)
from hotswapagent.
Thank you for the feedback. Up until now I have only used this plugin for development with an embedded Jetty server so the multi classloader environment issues had not come up.
I have done some refactoring and added more comments at https://github.com/HotswapProjects/HotswapAgent.git
Can you please take a look?
I have chosen to share the ClassPool instance between calls, because I Know that I need to access the classes from previous calls anyway.
from hotswapagent.
Hi, I have run tests from HotswapAgentExamples project and it looks good.
There are still errors inside SpringPlugin (org.hotswap.agent.javassist.NotFoundException: net.sf.cglib.proxy.MethodInterceptor
) because of EnhancerProxyCreater,getCp() method, which uses EnhancerProxyCreater.class.getClassLoader()
classloader - this is still the HotswapAgent/root classloader, not the application classloader.
In some cases it would be convenient to use HotswapAgent concepts. For example ProxyPlugin:
- ClassPool is available as method param
- CtClass is available as method param, if modified, it is automatically converted to target bytecode
- Concept of plugin "instance" - use @init to initialize classloader (see HotswapperPlugin). You can than use
PluginManagerInvoker.callPluginMethod()
to invoke plugin method, while application classloader (and ClassPool) will be instance fields.
It is not necessary to rewrite current code. However, using of common CtClass/ClassPool will enable the agent to share single instance across multiple plugins.
@init method will also clean the plugin instance after the associated webapp is undeployed. There is String initalizer = "{" + PluginManagerInvoker.buildInitializePlugin(ProxyPlugin.class) + "}";
code inside GeneratorParametersTransformer
, but I am not sure what is the purpose, because the plugin instance is never used.
The code is quite complex and I have not yet time to go through it thoroughly, hence I may miss some important points.
from hotswapagent.
I though the ClassLoaderPatcher defined all my plugin classes in the WebApp Classloader?
from hotswapagent.
Indeed it did. But the EnhancerProxyCreater
is now defined in both classloaders - main AND WebApp classloader.
How to use the class from WebApp classloader?
- manually via reflection - WebAppClassloader.loadClass(EnhancerProxyCreater.getClass().getName())
- use
org.hotswap.agent.command.ReflectionCommand
(see Hibernate plugin) - modify bytecode of a framework class running in WebApp classloader and call your class directly
from hotswapagent.
Method number 3 should be in effect here.
I think the issue might have been with the ClassPool toClass method, which uses the ClassLoader of the ancestor thread by default. I have explicitly set it now and tried to make the Proxy plugin code simpler, while using more framework features.
I tried executing the run-tests.sh script in the examples project, but i receive the following error:
[WARNING] Error injecting: org.codehaus.cargo.maven2.ContainerStartMojo
com.google.inject.ProvisionException: Guice provision errors:
- Error injecting constructor, java.lang.NoClassDefFoundError: org/apache/tools
/ant/BuildException
from hotswapagent.
I think SpringPlugin.cglibAopProxyDisableCache should not be necessary when proxy replacement works.
But we should keep it around in case a user disables the Proxy plugin?
What do you think would be the best method to detect if Proxy plugin is enabled in the Spring plugin?
from hotswapagent.
First, let me thank you for the plugin, it looks very promising. I have merged current version into master, but there are still several issues in my real-life projects. I will try to simulate it in https://github.com/HotswapProjects/HotswapAgentExamples/tree/master/spring-hibernate.
Proxy should be pretty core plugin and if the user disables it, I think it is Ok if Spring fails to reload proxied clasess. But you can use @Init PluginConfiguration config; config.isDisabledPlugin("pluginName");
.
I now that run_test.sh is not optimal (plaform specific), but it just launches maven for several configurations. Can you run mvn clean install
from command line and check, what the error is?
from hotswapagent.
I found an issue in CtClassJavaProxyGenerator that i fixed in erkieh@34c4e0c
from hotswapagent.
All my issues were related to obsolete JavaBean cache. I have merged your latest version into master and added loader.loadClass("java.beans.Introspector").getMethod("flushCaches").invoke(null);
to ProxyPlugin before any class modification. Now everything looks Ok, even complete recompilation of a project at runtime.
from hotswapagent.
That is great to hear.
BTW Have you experienced any JVM locking/hanging while using this plugin? I have and I suspect it might have something to do with the SpringChangesAnalyzer I have added. Its hard to debug, because when it locks up, the only way I can get a stacktrace is with jstack using the -F option and even that does not show the java agent thread.
I have removed it's usage in my master branch erkieh@ac4395d.
from hotswapagent.
I don't use the Spring plugin but the last version hangs sometimes during boot up of my project (Tomcat / Seam + Hibernate + JSF).
from hotswapagent.
This issue is still seen with the latest code.
HOTSWAP AGENT: 1:32:48.345 ERROR (org.hotswap.agent.plugin.spring.getbean.EnhancerProxyCreater) - Creating a proxy failed
org.hotswap.agent.javassist.NotFoundException: net.sf.cglib.proxy.MethodInterceptor
at org.hotswap.agent.javassist.ClassPool.get(ClassPool.java:445)
at org.hotswap.agent.plugin.spring.getbean.EnhancerProxyCreater.buildProxyCallbackClass(EnhancerProxyCreater.java:221)
at org.hotswap.agent.plugin.spring.getbean.EnhancerProxyCreater.getProxyCreationMethod(EnhancerProxyCreater.java:115)
at org.hotswap.agent.plugin.spring.getbean.EnhancerProxyCreater.create(EnhancerProxyCreater.java:83)
at org.hotswap.agent.plugin.spring.getbean.EnhancerProxyCreater.createProxy(EnhancerProxyCreater.java:78)
at org.hotswap.agent.plugin.spring.getbean.ProxyReplacer.register(ProxyReplacer.java:46)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
from hotswapagent.
Please provide a quickstart demonstrating the problem. I have used it with some spring 3 and 4 versions and can't say i have seen this issue again.
from hotswapagent.
The problem is with Spring 4.1.5 release. It doesn't show up with spring 4.0.X versions.
But with Spring 4.0.X I see a different issue.
HOTSWAP AGENT: 10:59:23.399 ERROR (org.hotswap.agent.annotation.handler.OnClassLoadedHandler) - InvocationTargetException in transform method on plugin 'class org.hotswap.agent.plugin.proxy.ProxyPlugin' class 'com/Acme/service/AcmeServiceImpl$$EnhancerBySpringCGLIB$$b7103509'.
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.hotswap.agent.annotation.handler.OnClassLoadedHandler.transform(OnClassLoadedHandler.java:157)
at org.hotswap.agent.annotation.handler.OnClassLoadedHandler$1.transform(OnClassLoadedHandler.java:76)
at org.hotswap.agent.util.HotswapTransformer.transform(HotswapTransformer.java:129)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at org.hotswap.agent.config.PluginManager.hotswap(PluginManager.java:254)
at org.hotswap.agent.plugin.hotswapper.HotswapperPlugin$1.executeCommand(HotswapperPlugin.java:94)
at org.hotswap.agent.command.impl.CommandExecutor.run(CommandExecutor.java:25)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: No such field class org.hotswap.agent.plugin.proxy.hscglib.GeneratorParams.getParam on org.hotswap.agent.plugin.proxy.hscglib.GeneratorParams@21079b1d
at org.hotswap.agent.plugin.proxy.hscglib.GeneratorParametersTransformer.getGeneratorParams(GeneratorParametersTransformer.java:116)
at org.hotswap.agent.plugin.proxy.ProxyPlugin.transformCglibProxy(ProxyPlugin.java:71)
... 14 more
Caused by: java.lang.IllegalArgumentException: No such field class org.hotswap.agent.plugin.proxy.hscglib.GeneratorParams.getParam on org.hotswap.agent.plugin.proxy.hscglib.GeneratorParams@21079b1d
at org.hotswap.agent.util.ReflectionHelper.get(ReflectionHelper.java:84)
at org.hotswap.agent.plugin.proxy.hscglib.GeneratorParams.valueOf(GeneratorParams.java:79)
at org.hotswap.agent.plugin.proxy.hscglib.GeneratorParametersTransformer.getGeneratorParams(GeneratorParametersTransformer.java:114)
... 15 more
'''
from hotswapagent.
About the 4.0.x issue:
Are you sure you don't have any local changes?
For some reason ReflectionHelper is looking for a field named "getParam" but the String literal for the fieldname in
https://github.com/HotswapProjects/HotswapAgent/blob/4e1643652a9cb8719cd6a8cc6117a80b12eda092/plugin/hotswap-agent-proxy-plugin/src/main/java/org/hotswap/agent/plugin/proxy/hscglib/GeneratorParams.java
is "param"
from hotswapagent.
I didn't have any changes. But, I tried again after rebuilding, i don't see the issue any more. Thanks for checking on it, i will let you know if I see it again.
On a side note, I had to use a older revision ** Merge pull request #61 from frankdavid/master ** - commit sha1 - eff4f76 because the HEAD revision from git is failing during 'mvn clean install' with error
HOTSWAP AGENT: 9:56:53.480 ERROR (org.hotswap.agent.plugin.weld.command.BeanDeploymentArchiveAgent) - basePackage '/C:/workspace/git/HotswapAgent/plugin/hotswap-agent-weld-plugin/target/test-classes' not associated with any archiveAgent
Tests run: 7, Failures: 2, Errors: 1, Skipped: 0, Time elapsed: 3.384 sec <<< FAILURE! - in org.hotswap.agent.plugin.weld.WeldPluginTest
hotswapPrototypeTest(org.hotswap.agent.plugin.weld.WeldPluginTest) Time elapsed: 1.232 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at org.hotswap.agent.plugin.weld.WeldPluginTest.swapClasses(WeldPluginTest.java:166)
at org.hotswap.agent.plugin.weld.WeldPluginTest.hotswapPrototypeTest(WeldPluginTest.java:125)
hotswapSeviceAddMethodTest(org.hotswap.agent.plugin.weld.WeldPluginTest) Time elapsed: 1.102 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at org.hotswap.agent.plugin.weld.WeldPluginTest.swapClasses(WeldPluginTest.java:166)
at org.hotswap.agent.plugin.weld.WeldPluginTest.hotswapSeviceAddMethodTest(WeldPluginTest.java:77)
hotswapRepositoryNewMethodTest(org.hotswap.agent.plugin.weld.WeldPluginTest) Time elapsed: 0.034 sec <<< ERROR!
java.lang.NullPointerException: null
at java.lang.String.length(String.java:623)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:414)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at org.hotswap.agent.plugin.weld.testBeans.HelloServiceImpl.hello(HelloServiceImpl2.java:22)
at org.hotswap.agent.plugin.weld.WeldPluginTest.hotswapRepositoryNewMethodTest(WeldPluginTest.java:108)
Results :
Failed tests:
WeldPluginTest.hotswapPrototypeTest:125->swapClasses:166 null
WeldPluginTest.hotswapSeviceAddMethodTest:77->swapClasses:166 null
Tests in error:
WeldPluginTest.hotswapRepositoryNewMethodTest:108 ยป NullPointer
Tests run: 7, Failures: 2, Errors: 1, Skipped: 0
from hotswapagent.
Related Issues (20)
- MyBatis Plus Dynamic Sql Hotswap do not work
- cannot create release HOT 1
- Caused by: compile error: no such class: ManagedBean
- No match for watchkey event
- Does the solution of JetBrainsRuntime 11 + HotswapAgent can work? HOT 1
- Getting error every build HOT 1
- Errors thrown when starting jbr_jcef-17.0.7 Minecraft Paper server. HOT 4
- IntelliJ plugin or other easy way to launch from IntelliJ HOT 1
- Can HotswapAgent support add @Resource/@Autowired fields in springboot based project? HOT 6
- JacksonPlugin ConcurrentModificationException
- What is the ProxyReplacerTransformer in the Spring plugin used for? HOT 1
- HotswapAgent IDEA plugin Could not identify JBR17's dcevm HOT 1
- bug: my Spring Boot project will OOM after running for a day
- Can not get a JavaCompiler instance with jbr_17.0.7 HOT 1
- Executing ReloadJavaProxyCommand caused an infinite loop HOT 5
- What is the ProxyReplacerTransformer in the Spring plugin used for? HOT 1
- How do I run this from gradle / openjdk? (Exception on changes) HOT 2
- NullPointerException: Cannot invoke "java.net.URL.getFile()" because the return value of "org.hotswap.agent.javassist.ClassPool.find(String)" is null HOT 3
- Application run failed HOT 2
- java.lang.NullPointerException: Cannot invoke "java.net.URL.getFile()" because the return value of "org.hotswap.agent.javassist.ClassPool.find(String)" is null
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hotswapagent.