How to check ClassFileTransformer / javaagent?

I have implemented ClassFileTransformer for javaagent using ASM. Since it has some errors, I want to write a JUnit test case for it. How to do it?

Using pseudo code, I thought line by line:

 // Have a test class as subject public static class Subject { public void doSomething(){...} } // Manually load and transform the subject ...? // Normally execute some now transformed methods of the subject new Subject().doSomething(); // Check the result of the call (ie whether the correct attached methods were called) Assert.assertTrue(MyClassFileTransformer.wasCalled()); 

Now the question arises: how to manually download and transform a theme and force the JVM / Classloader to use my managed version? Or am I missing something?

+6
source share
1 answer

I understood. You need to implement your own ClassLoader , which performs the same transformations with the test as ClassFileTransformer (for example, calls it). And, of course, the object class may not have already been loaded, so it cannot be used directly. Therefore, I used the Java reflection API to execute object class methods.

In a separate file:

 public static class Subject { public void doSomething(){...} } 

In the test:

 private static class TransformingClassLoader extends ClassLoader { private final String className; public TransformingClassLoader(String className) { super(); this.className = className; } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { if (name.equals(className)) { byte[] byteBuffer = instrumentByteCode(fullyQualifiedSubjectClass); return defineClass(className, byteBuffer, 0, byteBuffer.length); } return super.loadClass(name); } } @Test public void testSubject(){ ClassLoader classLoader = new TransformingClassLoader(fullyQualifiedSubjectClass); Class<?> subjectClass = classLoader.loadClass(fullyQualifiedSubjectClass); Constructor<?> constructor = subjectClass.getConstructor(); Object subject = constructor.newInstance(); Method doSomething = subjectClass.getMethod("doSomething"); doSomething.invoke(subject); Assert.assertTrue(MyClassFileTransformer.wasCalled()); } 
+6
source

Source: https://habr.com/ru/post/892062/


All Articles