Best way to get file for project classes directory

I’m experimenting with converting a big Maven build to Gradle.

I’ve defined a custom taglet and made that available with a GAV. One quirk of the taglet is that it needs to get access to the class file corresponding to the source file it is contained within. So, the “tagletPath” has the File corresponding to the taglet artifact, but I also need to add to this the path to the “build/classes/java/main” directory. I suppose I could pass that to the “file” method, but that seems like a hack to me. What is the proper way to refer to the classes built within the project?

To be clear, I have the following block within the “subprojects” block in the root build.gradle:

javadoc {
    options {
        encoding = 'UTF-8'
      
        taglets "com.att.det.taglet.ValidationConstraintsTaglet", "com.att.det.taglet.ValidationConstraintsCombinedTaglet"

        tagletPath (configurations.taglet.files as File[])
    }
}

This correctly puts the taglet classes in the classpath for “javadoc”, but I have to add the project class files to “tagletPath” also.

I guess this would involve “configurations.compile.files” in some way, but I can’t get this to work. The result has to include the files from the taglet configuration plus the files from the compile configuration, all casted to “File”.

My first guess was:

tagletPath ((configurations.taglet.files + configurations.compile.files) as File[])

When I run “gradle javadoc”, this gave me a pretty inexplicable error of:

A problem occurred evaluating project ':usl-account-api'.
> Cannot change dependencies of configuration ':usl-account-api:compile' after it has been resolved.

The “usl-account-api” project is one of the subprojects. The referenced line for the error is in the following:

description = 'usl-account-api'
dependencies {
  compile project(':usl-base')    // this line
  compile project(':usl-metrics')
  compile project(':usl-shared')
}

When I changed the line back to the original of:

tagletPath ((configurations.taglet.files) as File)

Then “gradle javadoc” does exactly what it should (except giving a ClassNotFoundException when the taglet executes, as it can’t find the relevant class).

I’m still trying to find a reasonable solution for this. I did manage to find something that “works”, but it’s truly vile.

The following gets it done:

afterEvaluate {
tagletPath ((configurations.taglet.files + file(project.name + “/build/classes/java/main”)) as File)
}

This is vile for multiple reasons. I really don’t want to be left with this.

The problem is that you’re resolving the configuration at configuration time, which causes strange ordering issues. You can get around that with a configureJavadoc task.

You can try this:

task configureJavadoc {
    doLast {
        javadoc.options.tagletPath sourceSets.main.runtimeClasspath as List
    }
}
javadoc.dependsOn configureJavadoc

You can just add to the taglet Configuration

dependencies {
   taglet 'foo:bar:1.0'
   taglet sourceSets.main.runtimeClasspath
} 

Or if the runtime classpath has everything you need then get rid of the taglet Configuration and use sourceSets.main.runtimeClasspath instead to configure the taglet classpath