2015-01-16 2 views
7

У меня возникла эта ошибка, когда я пытаюсь перезагрузить класс (горячая замена) с измененными телами метода в моем проекте. Прежде чем все работает нормально, но внезапно это прекратится, и я не помню ничего, что могло быть причиной. Странно, что у меня есть другой проект с одинаковой настройкой и «горячая» замена для тел методов работает отлично.IntellJ Idea tomcat Сбой горячей замены: изменение схемы не реализовано Операция, не поддерживаемая VM

Вот конфигурация для -НЕ работает проект:

enter image description here

enter image description here

И мои настройки 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 

и вот конфигурация для моего рабочего проект:

enter image description here

enter image description here

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 

ответ

7

Это очень трудно найти причину без кода. Тем не менее, я могу написать искусственный тестовый случай, когда компилятор 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(); 
    } 
} 

Этот эффект объясняется синтетический метод доступа $ 000, который Javac генерирует для обеспечения доступа к частный член класса Inner.

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   

Давайте изменим порядок двух методов в основном:

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

В результате компилятор изменил методы подписи.

... 
    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  

С HotSwap точки зрения это изменение запрещено, так как подпись метода access$000 была изменена.

+1

хороший ответ, спасибо – Regenschein