IntellJ Idea tomcat热插拔失败:未实现架构更改VM不支持操作

bie*_*dka 9 tomcat jvm intellij-idea jvm-hotspot hotswap

当我尝试在项目中使用已更改的方法主体重新加载类(热交换)时出现此错误.在一切正常之前,但突然停止,我不记得什么可能是一个原因.有什么奇怪我有另一个项目具有相同的设置和方法体的热交换工作正常.

以下是NOT-working项目的配置:

在此输入图像描述

在此输入图像描述

我的VM设置:

-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
Run Code Online (Sandbox Code Playgroud)

这是我工作项目的配置:

在此输入图像描述

在此输入图像描述

VM选项:

-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
Run Code Online (Sandbox Code Playgroud)

Iva*_*tov 9

没有代码就很难找到根本原因.但是,我可以编写一个人工测试用例,即使我只是更改方法体,Java编译器也会创建合成方法:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这种效果通过合成方法访问$ 000来解释,javac生成该方法以允许访问Inner类的私有成员.

javac Test.java 
javap -c -private Test\$Inner
Run Code Online (Sandbox Code Playgroud)
  ...
  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        
Run Code Online (Sandbox Code Playgroud)

让我们改变main中两个方法的顺序:

    public static void main(String[] args) {
        Inner inner = new Inner();
        inner.getPrivate();
        inner.getPrivate(0);
    }
Run Code Online (Sandbox Code Playgroud)

结果,编译器更改了方法签名.

  ...
  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     
Run Code Online (Sandbox Code Playgroud)

从HotSwap的角度来看,由于方法的签名access$000被更改,因此禁止此更改.