2015-06-24 4 views
3

У меня есть тестовый класс под названием «InnerClassTransactionServlet», внутри этого класса я определил внутренний класс с именем RandomResultHandler (InnerClassTransactionServlet $ RandomResultHandler).Переопределить вложенный класс во время выполнения, возможно ли это? (java.lang.NoClassDefFoundError: имена классов не совпадают)

Я пытаюсь переопределить внутренний класс динамически, но инструментовка возвращается «имена классов не совпадают» ошибка:

java.lang.NoClassDefFoundError: class names don't match 
    at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method) 
    at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170) 
    at com.example.Test.redefineClass(Test.java:33) 
    . 
    . 
    . 

Я попытался переопределить также класс ограждающую, но я получаю то же самое ошибка.

метод, отвечающий за переопределение очень просто:

public static void redefineClass(ClassDefinition definition) throws ClassNotFoundException, UnmodifiableClassException{ 
     log.debug("Trying to redefine class "+definition.getDefinitionClass().getName()); 
     Agent.getInstrumentation().redefineClasses(definition); 
} 

Параметр «определение» только объект ClassDefinition определяется с именем класса и результат байт компиляции:

log.debug("Class "+clazz.getName()+" compiled properly. Trying to replace the bytecode in memory."); 
ClassDefinition cd = new ClassDefinition(clazz, compilationResult); 
redefineClass(cd); 

Используя точно такой же код для переопределения не вложенных классов (или классов без вложенных классов), он отлично работает.

Знаете ли вы, можно ли переопределить вложенные классы или классы, которые содержат вложенные классы?

Спасибо!

ответ

2

Наконец я смог найти этот вопрос :)

Необходимо пересмотреть вложенные классы в то же время, чем вмещающие один. Невозможно переопределить только вложенный класс.

Итак, я изменил мой метод переопределения для получения нескольких объектов ClassDefinition:

public static void redefineClasses(ClassDefinition... definition) throws ClassNotFoundException, UnmodifiableClassException{ 
     StringBuffer sb = new StringBuffer(); 
     for (int i = 0; i < definition.length; i++) { 
      if (sb.length() > 0) 
       sb.append(", "); 
      sb.append(definition[i].getDefinitionClass().getName()); 
     } 

     log.debug("Trying to redefine class"+(definition.length>1?"es ":" ")+sb); 
     Agent.getInstrumentation().redefineClasses(definition); 
    } 

Итак, теперь пересмотреть свой внутренний класс я называю этот метод с определением класса из «InnerClassTransactionServlet» и «InnerClassTransactionServlet $ RandomResultHandler ", и код правильно заменен.