I got this error when I try to reload class (hot swap) with changed method bodies in my project. Before everything works fine, but suddenly it stop and I don't remember nothing what could be a cause. What is strange I have another project with the same setting and hot swap for method bodies works fine.
Here is configuration for NOT-working project:
And my VM settings:
-XX:PermSize=512m
-XX:MaxPermSize=1024m
-Xms1024m
-Xmx2048m
-Dcatalina.home="C:\Programy\apache-tomcat-7.0.57"
-Djava.endorsed.dirs="C:\Programy\apache-tomcat-7.0.57\endorsed"
-javaagent:C:\Programy\apache-tomcat-7.0.57/lib/spring-instrument-3.1.2.RELEASE.jar
-Dspring.profiles.active=closeMonthTest
-Dnpk.jobs.enabled=true
and here is configuration for my working project:
VM options:
-XX:PermSize=512m
-XX:MaxPermSize=1024m
-Xms1024m
-Xmx2048m
-Dcatalina.home="C:\Programy\apache-tomcat-7.0.57"
-Djava.endorsed.dirs="C:\Programy\apache-tomcat-7.0.57\endorsed"
-javaagent:C:\Programy\apache-tomcat-7.0.57/lib/spring-instrument-3.1.2.RELEASE.jar
-Dspring.profiles.active=test
It is very difficult to find the root cause without code. However, I can write an artificial test case where the Java compiler will create synthetic methods even if I just change a method body:
public class Test {
static class Inner {
private void getPrivate(int i) {
Thread.dumpStack();
}
private void getPrivate() {
Thread.dumpStack();
}
}
public static void main(String[] args) {
Inner inner = new Inner();
inner.getPrivate(0);
inner.getPrivate();
}
}
This effect is explained by a synthetic method access$000 which javac generates to allow access to a private member of the Inner class.
javac Test.java
javap -c -private Test\$Inner
...
static void access$000(edu.Test$Inner, int);
Code:
0: aload_0
1: iload_1
2: invokespecial #2 // Method getPrivate:(I)V
5: return
static void access$100(edu.Test$Inner);
Code:
0: aload_0
1: invokespecial #1 // Method getPrivate:()V
4: return
Let's change the order of two methods in the main:
public static void main(String[] args) {
Inner inner = new Inner();
inner.getPrivate();
inner.getPrivate(0);
}
As a result the compiler has changed methods signatures.
...
static void access$000(edu.Test$Inner);
Code:
0: aload_0
1: invokespecial #2 // Method getPrivate:()V
4: return
static void access$100(edu.Test$Inner, int);
Code:
0: aload_0
1: iload_1
2: invokespecial #1 // Method getPrivate:(I)V
5: return
From HotSwap point of view this change is prohibited because signature of method access$000
was changed.