Watching Non-Java Files to Trigger a Java Build

I am currently working on a project where I am using a continuous build. The build use an annotation processor that parses an html file with the same name as the java file. This all works great but when I change the html I have to “touch” the java file to get the annotation parser to pick up on the change.

Is it possible to watch for changes to html files in the java sources sets path and trigger a build with gradle. I have looked at the new input changes api in gradle 5.4 some but can’t figure out how to use it to watch the java source sets and trigger a compile.

An example project can be found here:
https://github.com/ascendtech/gwt-examples with the html/java components here:https://github.com/ascendtech/gwt-examples/tree/master/todoMaterial/src/main/java/us/ascendtech/client/views

I was able to get Gradle to act on changes to your AppComponent.html and regenerate and recompile related files with the following steps:

  1. I downloaded your project
  2. cd todoMaterial
  3. gradle -i -Dconsole=verbose --build-cache clean -t compileJava
  4. I changed line 62 of AppComponent.html from <v-toolbar-title>Demo</v-toolbar-title> to <v-toolbar-title>omeD</v-toolbar-title>

That resulted in Gradle’s Continuous Build Feature automatically building the „omeD“ change into the following two files:

  1. todoMaterial/build/generated/source/apt/main/us/ascendtech/client/views/AppComponentExposedType.java
  2. todoMaterial/build/classes/java/main/us/ascendtech/client/views/AppComponentExposedType.class

I’m running Gradle 5.2.1 in OpenJDK 11 on Windows.

Thanks for the help. This is a good start. I have other tasks that read from the build directory that do not appreciate it being cleaned but hopefully I can work around that.

Please share what you did when you eventually get it working?

Adding this line to the bottom of your build.gradle.kts:

tasks.named("compileJava") { outputs.upToDateWhen { false }  }

And just running:

 gradle -i -Dconsole=verbose --build-cache -t compileJava

…also worked. No clean required in that case.

After running ...-t compileJava just the one initial time, I was of course then able to make as many changes as I liked to your HTML input file. Each time, the change was regenerated and recompiled into those two files I listed earlier.

1 Like

Awesome that worked perfect.

I added the line and ran …/gradlew -i -Dconsole=verbose --build-cache -t compileJava and everything works as it should.

Cool. I’m thrilled that worked for you. I only added the -i -Dconsole=verbose --build-cache stuff just to get some insight into what Gradle was doing incremental build-wise.

Continuous build should still work even without those switches. But you should consider always using the build cache. It reduces build times by massive amounts.

If you read the build output closely, Gradle pointed out some things in your build that if you tweaked, you could reduce your build time even more.

Also, these might be of some value to you:

tasks.named("compileJava") { outputs.upToDateWhen { false }  }

Aren’t you essentially turning off all Java class change compilation avoidance by doing this?

Is that right? I humbly don’t know. But I’d bet @CedricChampeau would.

Meanwhile, I’m sure @mdavis95 wouldn’t object to whatever you suggest @Jazzepi as a better solution to his requirements.

Always love new suggestions but I believe what is happening here is you are forcing a recompile but using the build cache to make this super fast. It does seem as fast too.

I think the solution you want is to expand the definition of the inputs to include the html files. What you’ve done is basically tell it to always recompile no matter what :^)

tasks.named("compileJava") { 
    inputs.files(fileTree(dir: 'relative/directory/where/html/is/at').matching { include '**/*.html' }
}

You should be able to get access to the inputs as shown above.

I’m not 100% sure that the syntax I listed for the matching include is correct. But I think you want something like that. It should take the inputs for the compileJava task and jam in your html files. This will allow the system to use its incremental build avoidance while also recompiling if it sees any html files change.

Continuous build would pickup on the HTML change without anything special. Unfortunately what I need is for a change to AppComponent.html to force a recompile with the annotation parser of AppComponent.java (which reads AppComponent.html when the annotation parser runs).

Have you read the “incremental annotation processor” section of the docs?

I don’t recall reading that page when I originally analyzed the OP’s sitch. That is a very useful find though. Thanks.

I did consult Gradle’s State of support in popular annotation processors list at the time, however.

When I didn’t find his processor on that list, I proceeded on the assumption that it didn’t support incremental annotation processing.