Intellij overwriting "provided" scope classes in Maven target/classes on code change
I have an API definition (published as classes with method stub-s by upstream) included in Maven as a dependency. There is an implementation that depends on this interface and implements it. Once the implementation is compiled, the stub classes are unpacked to target/classes and the implementation is injected into the API definition with ASM (Maven's “process-classes” lifecycle).
Everything works OK from Maven perspective - compile-transform-test cycle works as expected. After Maven compilation, there will be bytecode processed files in target/classes. It _also_ works after a Maven compile from IntelliJ. But as soon as I change anything in a test class (or anything that would trigger a rebuild), the dependency with only stubs is unpacked into target/classes and tests will obviously fail, as the stub-s are missing the implementation that tests assume would be there.
Default options in Intellij are set for Maven. I know there's a “delegate run/test to maven” option but that is slow, and breaks the idea of fast testing of single methods in IDE.
Is there a way to make IntelliJ not behave this way, or should it be copying provided scope dependencies into target/classes in the first place?
请先登录再写评论。
Hello,
Short answer: IntelliJ is behaving “correctly” for its own compiler, but that behavior is fundamentally incompatible with your current “modify bytecode in target/classes during process-classes” design. You need to either isolate the transformation or force IntelliJ to use Maven for builds/tests
Best Regards
Hi Martin, thanks for your question.
In your case, it is indeed recommended to use delegation to Maven. You can read more about this in the documentation: https://www.jetbrains.com/help/idea/delegate-build-and-run-actions-to-maven.html#delegate_to_maven
If you would still prefer to avoid delegating to Maven, the following approach will most likely suit your needs: before running a JUnit test, execute a Maven goal that places the correct implementations into target/classes. To do this:
1. Go to Run | Edit Configurations… and open the run configuration for your test, or create a new one;
2. Specify your test class;
3. Open the Modify Options menu and add 'Add before launch task' → Add task → Run Maven Goal
4. In the dialog that opens, specify your module and the goal/phase to which your ASM step is bound.
You may also add the
-DskipTestsoption if needed.5. Save the configuration.
With this approach, even if changes affect target/classes, the required implementations will be written to target/classes before the tests are executed.
Please let us know whether this solution works for you.
I am OK with the “workaround” of generic and simple “dlegate to maven” toggle (made me optimize the build a bit as well) but to me it feels that the overwrite of provided scope deps is not “right”. Just to let you know! Thanks & Happy Holidays, Martin
Hi Martin, Thanks for your reply!
I will discuss this with my colleagues and get back to you with an update. It is possible that we can improve this scenario.
Thank you for your feedback! Season’s greetings and best wishes for the New Year!
Hi Martin, Thanks for your patience!
Unfortunately, we cannot provide an additional workaround to this without a more detailed investigation.
To allow for a detailed investigation of this behavior in your specific workflow scenario, please create a new ticket using this link and attach a sample project where this behavior is reproducible on your side. This will allow us to reproduce it accurately and improve the scenario accordingly.
We appreciate your cooperation and efforts!