Integrating javassist bytecode using maven compilation

I have a maven project that compiles using the javac / aspectj compiler.
I want to run classes that have been compiled by a javassist program that manipulates compiled classes and adds material to them.
I thought using the phase "process-classes" to run my tool.
My question is the best way to repeat with javassist over class files created in "target / classes" so that I can load, fix and save afterwards.
Another requirement is to run the tool on test classes.
If there is an open source project that does similar stuff, it will be great to see a live example.
Thanks,
Avner

+4
source share
1 answer

I recently came across the same issue and I wrote a small Maven plugin to apply Javassist class transformations during build. I shared the code https://github.com/drochetti/javassist-maven-plugin

You guessed that you should use the process-classes phase, and the complex part is setting up the class. After some testing and errors, I was able to guess the whole ClassPath problem from Project, Dependencies and Javassist (please refer to com.github.drochetti.javassist.maven.JavassistMojo.execute() if you want to check the solution).

Below are some guidelines on the GitHub link, but basically you need to:

1 - configure the plugin on pom.xml

 <plugin> <groupId>com.github.drochetti</groupId> <artifactId>javassist-maven-plugin</artifactId> <version>1.0.0-SNAPSHOT</version> <configuration> <includeTestClasses>false</includeTestClasses> <transformerClasses> <transformerClass>com.domain.ToStringTransformer</transformerClass> </transformerClasses> </configuration> <executions> <execution> <phase>process-classes</phase> <goals> <goal>javassist</goal> </goals> </execution> </executions> </plugin> 

2 - Implement a ClassTransformer , here is an example:

 /** * Silly transformer, used to hack the toString method. */ public class ToStringTransformer extends ClassTransformer { /** * We'll only transform subtypes of MyInterface. */ @Override protected boolean filter(CtClass candidateClass) throws Exception { CtClass myInterface = ClassPool.getDefault().get(MyInterface.class.getName()); return !candidateClass.equals(myInterface) && candidateClass.subtypeOf(myInterface); } /** * Hack the toString() method. */ @Override protected void applyTransformations(CtClass classToTransform) throws Exception { // Actually you must test if it exists, but it just an example... CtMethod toStringMethod = classToTransform.getDeclaredMethod("toString"); classToTransform.removeMethod(toStringMethod); CtMethod hackedToStringMethod = CtNewMethod.make( "public String toString() { return \"toString() hacked by Javassist\"; }", classToTransform); classToTransform.addMethod(hackedToStringMethod); } } 

Note. To implement a transformer, you need to add a plug-in depending on your project, but don’t worry, since it is used only during assembly, it can be provided in scope, this will not be a dependency of your final build.

I hope this helps! Let me know if you need more help.

Daniel

+6
source

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


All Articles