I have a WebApplication in Java that has 3 threads which just sends some data to a program that calls the application and saves data (log files from log4j) to a h2 database.
Now I don't want to have 3 threads which are more or less the same. So I'm trying to inject the code with javassist and an Agent after some tries I think I will get the result I want! so if my code is right( I'll post it later would be nice if you could take a look) some bytecode will be inserted to my 3 thread Methods before they get called but....
I used this tutorial http://appcrawler.com/wordpress/2013/01/02/simple-byte-code-injection-example-with-javassist/
and if I want to call my Application I need to write java -javaagent:myAgent.jar foo so says the tutorial but my webApplication gets called by an other java program can I just call it now and my Agent which inserts the Bytecode will work? Probably not, I think. so it would be nice if you could tell me how to do that or maybe how to advance my code so that I don't need it.
Code: My Transform class (bytecode gets inserted)
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.test.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(" Thread thread0 = new Thread(new Runnable() {\n" +
"\n" +
" @Override\n" +
" public void run() {\n" +
"\n" +
"\n" +
" try {\n" +
" threadLogger.logCall(Webservice.class.getMethod(\"startThread0\"),\"Thread0\");\n" +
" } catch (Exception e) {\n" +
" e.printStackTrace();\n" +
" }\n" +
" }\n" +
" });\n" +
" thread0.start();");
}
}
}