Open chenkd opened 6 months ago
incremental annotation processing
Ultimately the ebean-gradle-plugin IS doing incremental annotation processing. This issue is specifically that the ebean-gradle-plugin is invoking the "build time enhancement" for partial/incremental compiles (as well as full compiles).
In that sense the question becomes, is it possible for the ebean-gradle-plugin to detect if gradle is performing a full compile or partial/incremental compile and hence only invoke the "build time enhancement" for full compiles.
Are you able to research that @chenkd and find out how the ebean-gradle-plugin can detect the type of compile being performed?
In that sense the question becomes, is it possible for the ebean-gradle-plugin to detect if gradle is performing a full compile or partial/incremental compile and hence only invoke the "build time enhancement" for full compiles.
The querybean annotation processor does support Gradle's incremental annotation processing feature using the aggregation
category. I assume it is that category because it also emites the single registry class containing all available entities to avoid classpath scanning later on. Otherwise if could probably also be isolating
. So if we change a file unrelated to ebean then Gradle should be able to skip the ebean annotation processor.
The Gradle ebean plugin on the other hand registeres doLast
actions on several compilation tasks and enhances classes on the fly so that gradle will register the enhanced classes as task output and up-to-date checks work correctly. So the Gradle ebean plugin will execute after all annotation processors have been executed and you cannot skip the enhancement just by detecting if Gradle does an incremental compile or not. You need to know the concrete files.
So the real question is if the Gradle ebean plugin can see the 5 out of 1000 files that Gradle wants to recompile incrementally and only apply the enhancement logic to these 5 files or if the Gradle ebean plugin blindly walks through all 50 entities in the project because they are in the output folder / ebean registry class?
So the real question is if the Gradle ebean plugin can see the 5 out of 1000 files that Gradle wants to recompile incrementally and only apply the enhancement logic to these 5 files
Not really in that it literally can just not enhance them based on the assumption that - This is an IDE build and hence there is an ebean-agent registered to enhance at class at load time (e.g. the IntelliJ IDEA plugin which registers ebean-agent as a Java agent when running tests etc).
To be clear, this is how it all works with maven and IntelliJ. We literally do NOT do any build time enhancement on partial compiles when we use maven and IntelliJ.
That is, we only really need to perform build time enhancement for full-compilation such that the final artifact can be shipped with classes that are already enhanced.
We can and do support the cases where (A) No enhancement has occurred and (B) Some classes are enhanced and not others ... when we are developing and using the IntelliJ ebean plugin (as this will detect if classes are enhanced or not at class load time and perform the enhancement on those classes that need enhancement at that time). When we are not using the IntelliJ ebean plugin we should register the ebean-agent explicitly instead.
So my expectation is that yes if we know gradle is doing a partial compile we can simply NOT perform any enhancement (with the view that you are using something like IntelliJ IDEA with the ebean plugin and that will perform any enhancement necessary at class load time).
IMHO a plugin for a build tool should not assume anything. It should always produce a working build. It is quite dangerous to assume that the ebean-agent is active in one way or the other while editing files and recompile the project. The "IDE" could very well be textedit, neovim, nano, whatever. It could also be a CI environment that caches the state of the last build and incrementally compiles changes introduced by newer commits without any IDE but just Gradle + Gradle ebean plugin.
So the best a build tool plugin should do is to check the files the build tool wants to recompile. Nothing more and nothing less.
By the way I am using IntelliJ + Gradle incremental compile and never installed the IntelliJ Ebean plugin as I never had the need for it. IntelliJ delegates to Gradle when running tests and query beans are provided by annotation processor that can be run independently so you can use the generated code in the IDE. To build the project Gradle is required as it contains all the build logic, so building with IntelliJ isn't really possible anyways.
As I see it, if we can detect gradle partial compile then we can at least try this approach and confirm that it works as expected. I'd be confident of that based on the fact that this is how it works for the maven case.
If it proved to work out in reality in terms of pros vs cons then we could keep it and allow people to turn it on.
IMHO a plugin for a build tool should ...
I'm happy for someone to have a crack at that sort of improvement to ebean-gradle-plugin. One day we might get there but we need to be aware of the complexity involved so I'm personally aiming for the simple approach first and see what that give us. If someone puts there hand up to work on this that would be great.
[Gradle] ... building with IntelliJ isn't really possible
Yes.
never installed the IntelliJ Ebean plugin as I never had the need for it
Yes, and if we have this option for ebean-gradle-plugin and we enable it then we'd need to use the IntelliJ Ebean plugin.
Sorry, I'm new to using ebean, I really like the ebean style. My development environment is IntelliJ + Gradle. Every time I recompile, the enhancement of all classes with @Entity annotations is triggered. However, this is not the case in IntelliJ + Maven(Only the modified parts are compiled each time).
After experiments, I found that this can avoid the full compilation of the ebean class in gradle. Extract the @Entity class into module A, and module B depends on module A. At this time, modifying the classes in module B will not trigger compilation in module A.
Extract the @entity class into module A, and module B depends on module A. At this time, modifying the classes in module B will not trigger compilation in module A.
Yes, that is a workaround because in that case Gradle itself will already figure out that it does not need to recompile module A at all. Thus Ebean Plugin is not triggered at all by Gradle. I use this setup too, but for a different reason. In general I don't like extracting entities into their own module because you quickly need a third module to avoid dependency loops if the entity does more than just getter/setters.
Expected behavior
incremental annotation processing and just compile Main class
Actual behavior
The ebean class is also compiled
Steps to reproduce
Examples used https://github.com/ebean-orm/examples/tree/master/basic-gradle-java Every time I modify a class that is not related to ebean and compile, it will trigger the enhancement of querybean, causing the ebean class to be recompiled.
This problem greatly affects development efficiency, causing hot deployment to not take effect or be very slow.