Vertispan / j2clmavenplugin

Maven plugin to launch new J2CL compilation
https://vertispan.github.io/j2clmavenplugin/
Apache License 2.0
53 stars 26 forks source link

Do not proc apt if possible #232

Closed treblereel closed 8 months ago

treblereel commented 1 year ago

We can determine that an external dependency is an annotation processor if there's "META-INF/services/javax.annotation.processing.Processor" in the jar. So, we don't need to compile/transpile it and so on. It’s enough to pass it to Javac at the BYTECODE stage to have it executed. I tried it and it worked for me. I tested it on swf, which is a big project with many apt (crysknife, gwt3-processors, json,yaml, xml marshallers and so on), so the build sped up, gwt3BuildCache size went down from 681M to 354M, and the files in it reduced from 106793 to 53268.

If apt is a part of the reactor, it ll be processed just like a dep (old scenarion)

treblereel commented 1 year ago

static-resource, @niloc132 may I ask you re-run it once again, on my local fedora I can't reproduce it

treblereel commented 9 months ago

First attempt at a compromise (aside from "give up and use gradle", with its configuration allowing us to separate classpaths as desired):

  • If we have to add something to the task api, add only Project.isAptOnly(). That property is always false unless a config setting is set to opt in AND the project is non-reactor (plus the obvious "it has a processor in it"). I still don't like it, but is it slightly less "poking holes in the abstraction", and a task that doesnt know/care about isAptOnly() can just ignore it.
  • Task factories then can test for this, and depend only on the raw bytecode inputs for apt projects if needed, or ignore them entirely as desired.

But in thinking about this further, if the above satisfies your requirements (also notes in the review), then we don't care about in-reactor apt projects anyway? Then, we can go a step further, and return to the usual approach:

  • tasks that care and can handle this can test the config value to see if the user is opting-in
  • those tasks, when the task itself runs, can test the contents of the inputs to see if there is a processor. If so, add the processor to the list of processors to pass to javac/turbine, if not, specify that there are no processors (and instead pass the jar as part of the normal classpath). Likewise, when calling j2cl or javac/turbine, skip entirely when appropriate (caching will preserve this decision over rebuilds).

If I've made an error here and this is intended to operate on reactor projects that declare processors, let me know - but there are appear to be other changes (discussed in one of my comments I think?) that would be necessary to handle that.

The only way to identify a dependency as an annotation processor is to check for the presence of the marker "META-INF/services/javax.annotation.processing.Processor".

In the j2cl-m-p context we cam split nnotation processors into two types: reactor dependencies and third-party annotation processors. The last ones remains unchanged and does not require compilation before use (and they already have marker). Basically, we only need to pass its name to Javac, and it will be invoked during the build process.

The situation is more complex when a Maven module (reactor case) itself is an annotation processor. At the initial launch of BytecodeTask, it is not yet compiled, which means we cannot determine it as an annotation processor until its marker is created.

So, the workflow can be divided into four scenarios:

1) No processors present, no action required.

2) There are APT processors, but they are third-party, so we pass their names in the -processor option. (and don't need to compile them to use them)

3) All APT processors are reactor dependencies. We use the original approach, and they will be found through the classpath.

4) The project includes both reactor annotation processors and standalone Maven dependency annotation processors. We add the standalone Maven dependency annotation processors to a Set during the initial launch of BytecodeTask. Once the reactor annotation processors are compiled and we have verified the presence of their markers, we add them to the Set and pass it to Javac for the -processor option.