2

В настоящее время я пытаюсь отслеживать вызовы методов для обучения.Перезагрузка классов с maniupulated bytecode от rt.jar

Явагент, который я внедрил, представляет собой модифицированную версию реализации в this article. Программа добавляет к какому-либо методу протоколирования вызовов метода в байт-код. К сожалению, bootstrap classloader отказывается загружать любой управляемый контент из rt.jar. Я могу понять, что это не очень хорошая идея для производственной среды, но для ученика это будет действительно потрясающе.

У вас есть идеи, как это осуществить?

ответ

0

Единственный шанс, который у вас есть, - это изменить содержимое rt.jar. Загрузочный загрузчик класса загрузок является особым во многих отношениях, многие, но не все, классов загружаются до того, как агент даже запустится.

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

+0

Спасибо вам за ответ! Можно ли определить пользовательский загрузчик классов ниже системы и загрузчик классов bootload, который будет загружать измененную версию и делегировать только тогда, когда он не найдет класс? Было бы снова действительно грязно ... -> Агент.transform(): проверяет, приходит ли вызов от Boostrtrap -> вызовы CustomClassloader. Трансформатор загружает модифицированный ByteCode – hotzenplotz

+0

Нет, JVM гарантирует, что вы никогда не определяете пользовательские классы в пространстве имен 'java. *'. Такие классы должны загружаться загрузчиком класса bootstrap. –

+0

Я не думаю, что это правильно. Вы можете переопределить java. * Classes. См. Http://stackoverflow.com/questions/29059553/javac-classpath-order-contradicts-oracle-documentation/29060452#29060452 и другие. – Marco13

0

Я мог бы успешно управлять классами из rt.jar.

Например, я манипулировал байт-кодом класса BigDecimal. В каком классе вы тренируетесь, чтобы манипулировать? И какие манипуляции вы делаете? Просто добавляете журналы для каждого метода класса, как в упомянутой статье?

В дополнение к следующему руководству по статье я должен был сделать что-то еще, чтобы управлять классами rt.jar.

  1. В LoggerAgent классе я добавил массив классов, которые я явно хотят манипулировать.

    String[] includeArr = new String[] { "java/math/BigDecimal" }; 
    ArrayList<String> include = new ArrayList(Arrays.asList(includeArr)); 
    
  2. В transform способе LoggerAgent класса я изменил цикл, чтобы включить классы я явно хотят манипулировать.

    for (int i = 0; i < ignore.length; i++) { 
        if (className.startsWith(ignore[i]) && !include.contains(className)) {   
         return bytes; 
        } 
    } 
    
  3. Фиксированный методу methodReturnsValue из JavassistHelper правильно различать методы и конструктор.

    private static boolean methodReturnsValue(CtBehavior method)throws NotFoundException { 
    
        if (method instanceof CtMethod){ 
         CtClass returnType = ((CtMethod) method).getReturnType(); 
         String returnTypeName = returnType.getName(); 
         if(returnTypeName.equals("void")){ 
          return false; 
         }else{ 
          return true; 
         }  
        } else{ 
         return false; 
        } 
    } 
    
  4. Последний, в классе HelloWorld я создал BigDecimal просто проверить поведение манипуляции.

Результат выглядит следующим образом:

19/06/2015 16:00:26 java.math.BigDecimal signum 
INFO: << signum() returns: 1 
19/06/2015 16:00:26 java.math.BigDecimal layoutChars 
INFO: << layoutChars(1=true) returns: 11.1099999999999994315658113919198513031005859375 
19/06/2015 16:00:26 java.math.BigDecimal toString 
INFO: << toString() returns: 11.1099999999999994315658113919198513031005859375 
19/06/2015 16:00:26 com.runjva.demo.HelloWorld main 
INFO: << main(args=[]) 
BigDecimal=11.1099999999999994315658113919198513031005859375 
Stop at Fri Jun 19 16:00:26 PDT 2015 

Я надеюсь, что это помогает. Если нет, добавьте более подробную информацию о том, что вы пытаетесь сделать.

+0

Спасибо за ваш ответ! Я исправил конструктор в LoggerAgent.doMethod(). Я попытался включить ведение журнала, это, возможно, неправильный подход;) Я попробую сделать это с вашего пути. :) Меня интересует Framework Collection и все, что связано с Streams & Lambdas. Вы знаете, как классы с собственным кодом получают перевод или execeuted JVM? Например, попытка использовать hashmap инструмента вызвала некоторые странные ошибки со стороны JVM. (упоминались некоторые классы исключений .cpp) – hotzenplotz

Смежные вопросы