make/compile and bytecode instrumentation tools

Hi all,

I'm working on tool that does some minor modification to the bytecode. Currently it is maven plugin that's bound to the process-classes phase by default. So it get invoked after compilation.

I am aware that one can configure a "Run configuration" to invoke additional tools to complement or even replace the "make" action. So that could be the place for me to invoke the bytecode mod. tool. Unfortunately things get complicated when using a project with multiple modules as well as when artifacts (like exploded ejb/war etc) are used. Some of the modules are just libraries from the point of view of the modules that used them. As such there is no "Run" config for these modules. The problem is that one quikcly ends up compiling the different modules using IntelliJ's "make" and this end up not having the bytecode undergoing the extra step.

So if you are careful and compile all the module using maven first then it works. Even the classes for exploded artifacts will even get copied verbatim which will preserve the bytecode changes. But if you happen to change something then "make" kicks in, recompiles the stuff and the classes are not transformed that time around. Of course in the end it hard to work this way :(

My question: is there are way to combine say the "make" way of working (being super easy for multi module projects of course) yet also get the additional bytecode transformation step invoked afterwards? Or can (and should) this be done with a plugin? This sound like way more work of course. Any pointer would be much appreciated.

I hope the description of my problem is clear enough and my question as well. If not let me know.

Best regards,

Johan

3 comments

Hi Johan,

The best solution here will be creating a plugin to our build subsustem. We have dedicated base classes for bytecode instrumenters, that you can subclass, so this should be not that hard for you to implement the required logic.
For your instrumenter you will have to register an implementation of

org.jetbrains.jps.incremental.instrumentation.ClassProcessingBuilder

If you use ASM bytecode instrumenting library, there is a convenience abstract class  

org.jetbrains.jps.incremental.instrumentation.BaseInstrumentingBuilder

that will call the abstract instrument() method for all newly compiled classes in current compile session.
You can check existing implementations of these classes (e.g. org.jetbrains.jps.incremental.instrumentation.NotNullInstrumentingBuilder or org.jetbrains.jps.intellilang.instrumentation.PatternValidatorBuilder) for examples of how instrumenters may be implemented.
The PatternValidatorBuilder is a part of "intelliLang" plugin and this class can also give you and idea of what should be done to register your extension within the build system.
If you have any other questions regarding please do not hesitate to mail me directly.

Best regards,
  Eugene Zhuravlev.

0

Hi Eugene,

Many thanks for your informative reply. I will look into the plugin solution you explained. Looks like an interesting challenge ;)

Just this question already. I indeed use ASM to implement the transformation logic. I use asm4, any idea if the BaseInstrumentingBuilder class will work well with it? If I run into some question I'll mail you directly (as you suggested).

Thanks again for your help!

Best regards,

Johan

0

You are welcome Johan,

> asm4, any idea if the BaseInstrumentingBuilder class will work well with it?

Yes, we use this version too. The only specific thing here is that we use repackaged ASM (package org.jetbrains.) in order not to conflict with any versions of ASM that 3rd party plugins may use.

Regards,
  Eugene.

0

Please sign in to leave a comment.