1

Я не так хорош на Java, но у меня есть моя веб-приложение, работающая на Wildfly. У меня есть 3 потока, которые просто вызывают функцию, в которую вставляются журналы и функция сохраняет журналы в базе данных, и после этого каждый поток отправляет время, необходимое для этого. Они отправляют данные в другую программу. Я написал, что имеет 3 потока для вызова одного из трех потоков сервера.Попытайтесь использовать Agent в Webapplication для байт-кода Manupulation

Итак, теперь я пытаюсь выполнить манипулирование байтами. Каждый поток на сервере сохраняет вызов datetime. Функция журнала ждет 1 секунду и возвращает время, необходимое им.

1 Thread напишите что-нибудь в файле журнала до или после ожидания 1 секунда. Но эта часть, где они ждут секунду и вызывает функцию журнала, я хочу, чтобы она вводила каждые три потока с манипуляциями Bytecode.

public class MyTransformer implements ClassFileTransformer { 


@Override 
public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { 

    return transformClass(redefiningClass, bytes); 
} 

private byte[] transformClass(Class classToTransform, byte[] b) { 
    ClassPool pool = ClassPool.getDefault(); 
    CtClass cl = null; 
    try { 
     cl = pool.get("de.soptim.ws.MyApplication"); 
    } catch (javassist.NotFoundException e) { 
     e.printStackTrace(); 
    } 
    try { 

     assert cl != null; 
     CtMethod[] methods = cl.getMethods(); 
     for (int i = 0; i < methods.length; i++) { 
      if (methods[i].isEmpty() == false) { 
       changeMethod(methods[i]); 
      } 
     } 
     b = cl.toBytecode(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (cl != null) { 
      cl.detach(); 
     } 
    } 
    return b; 
} 

private void changeMethod(CtMethod method) throws NotFoundException, CannotCompileException { 

    if (method.hasAnnotation(Loggable.class)) { 
     method.insertBefore("threadLogger.info(\"ADDED THIS FROM BYTECODE !!!\");"); 
     method.insertAfter("threadLogger.info(\"ADDED THIS FROM BYTECODE !!!\");"); 
    } 
}} 

Вот мой класс трансформатора должен увеличить код моих методов нужно проверяет, что метод имеет @Loggable аннотации затем добавляет код в него ("на данный момент это только некоторые statments журнала для проверки, если он работает ")

Моя самая большая проблема в том, что я не знаю, как позвонить моему агенту ... Я googled hwo, чтобы вызвать агента во время выполнения с agentmain(), но я думаю, что я действительно не понял, как это работает ,

Агент класса

public class LogAgent { 

public static void agentmain(String agentArgs, Instrumentation inst) { 
    System.out.println("Starting the agent"); 
    inst.addTransformer(new MyTransformer()); 
}} 

Надеюсь, вы понимаете мою проблему :) я и если вы answere мольбы попытаться остаться нуб дружественных: D.

ответ

1

вы не называйте ваш агент явно, вы должны указать дополнительный аргумент для вашей виртуальной машины Java:

java -javaagent:jarpath[=options]

где jarpath это путь к банку, содержащую ваш агент. JVM будет вызывать метод premain до main метод java-программы.

И метод transform будет вызываться перед загрузкой классов с помощью JVM (вы не вызываете его явно).

Последнее замечание: вы должны реализовать метод premain, а не agentmain. agentmain используется при подключении к работе vm, а premain используется при запуске JVM с -javaagent способ.

И убедитесь, что ваша баночка иметь действительный манифест, как описано: https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html

Я не использую javaassit поэтому я не могу сказать, что ваш код действителен, но инструментирование WebApp сервер как Wildfly гораздо сложнее, чем обычный Java app (в основном из-за видимости и иерархии классов загрузчиков).

Смотрите также:

http://www.tomsquest.com/blog/2014/01/intro-java-agent-and-bytecode-manipulation/ Tutorials about javaagents

+0

Оке первых спасибо за ваше answere: D, но "Java -javaagent: jarpath [= опции]" Я просто знаю, что это, как команды для CMD, и я не могу используйте это o: или я могу добавить его где-нибудь еще? – alovaros

+0

И я использовал premain, потому что я пытался изменить код во время его работы, но это тоже не сработало ... – alovaros

+0

Измените скрипт запуска сервера, а это - на аргументы JVM. Я так и сделал, и все отлично. – Grzesuav

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