Javadoc task does not refer package-info how is expected. How set package flag?

I am working with Gradle 4.5.1, about javadoc I have the following:

task masterMainJavadoc(type: Javadoc, group: "Documentation") {
	description = 'Generates a master javadoc from all the modules (main)'
    source exportedProjects.collect { project(it).sourceSets.main.allJava }
    classpath = files(exportedProjects.collect { project(it).sourceSets.main.compileClasspath })
    options.memberLevel = JavadocMemberLevel.PRIVATE
    options.addStringOption("charset", "UTF-8")
    options.links 'https://docs.oracle.com/javase/8/docs/api/'
    options.links 'https://docs.oracle.com/javaee/7/api'
    ...
    destinationDir = file("${buildDir}/docs/javadoc/main")
}

It works how is expected.

Now, I have in some method the following:

	/**
	 *
	 * @see com.manuel.jordan.rest.persona._400.client
	 */

The purpose with above is that @see should refer to the package-info.java file within the same package. I can confirm it works through STS the Javadoc view, it after to have read the following post: Javadoc: link to package-info. Thus if through Javadoc view I do click to the link it goes to the package-info.java file

With the current Gradle's task it does not work, the javadoc generated is:

See Also:
   com.manuel.jordan.rest.persona._400.client

Thus no link.

According with the SO’s approved answer, that I did do, there is a comment that contains the following:

I played around with the javadoc compilation settings. 
I had to set the package flag as well. That made it work.

Not sure if it would be the problem and thus missing setting in the Gradle task.
Thus how I can fix it?

The comment on SO doesn’t make sense as that flag corresponds with the JavadocMemberLevel. You already have set JavadocMemberLevel.PRIVATE, which documents more than JavadocMemberLevel.PACKAGE. Changing it to JavadocMemberLevel.PACKAGE includes the -package flag instead of the -private flag, but this shouldn’t and doesn’t seem to help anything.

Do you have an example that shows this working with the javadoc command directly, or with another build tool? Providing the correct argument with Gradle won’t be an issue if that argument is known, but I can’t recall ever having seen this work.

Hello

I have tested with JavadocMemberLevel.PACKAGE and it does not works too.

No, I have confirmed just through the Javadoc view

I am confused, with this situation too.

Could you test by your side creating a new package and some class where its method refers the package-info.java file? I am assuming you have the correct configuration.

Thank you.

Rather than the -package flag, I think SO poster meant specifying the specific package (i.e. com.manuel.jordan.rest.persona._400.client in your case).

There is not a great way to configure this with what’s provided in the Javadoc task as Gradle is already providing a list of individual files. By adding the argument for the package, classes are duplicated in the documentation.

So, to make these links work, without duplication, you’re going to need custom task. It can either extend Javadoc and add/override a couple methods to coerce the Gradle implementation into doing what is needed or just be a basic task that delegates to the Ant implementation. Have a preference?

I thought it should be automatic done through Gradle

Perhaps, the SO answer is really not correct? It only has two up votes …
I am confused because there are no other post related about this javadoc requirement through other SO posts

The Stack Overflow answer was about Javadoc in general. That answer is correct in that you should @see the package directly, not treat package-info as part of the path.

There is more than one way to provide arguments to Javadoc. Gradle uses the method of providing every individual source file as this aligns with SourceTask semantics, including includes/excludes. Javadoc also supports a source path with package names, which is what the asker on SO was trying to mention in their comment, it’s just an argument, not a flag.

On the Gradle side, the abstraction isn’t overly concerned with allowing you to completely overwrite how it delegates to the underlying tool. When providing the source files, it doesn’t seem that Javadoc is capable of creating links to the packages though. This may be considered a bug in Javadoc, or there may be a good reason this isn’t supported.

Although I saw this work in the Javadoc View in my IDE, like you, using the menu option to generate Javadoc had the same issue. I could force this to work by adding the package names, but classes were duplicated. However, this at least gave an idea of what arguments that would work looked like.

There are a few other mentions here about this issue on the forums, but it seems that using @see with packages instead of specific classes is not that common, so not that many people have encountered or at least noticed it.

Gradle, as well as any tool that specifies source files, not packages, will not create these links automatically. You will have to implement something custom if you want this to work in your project. I did get this working in my simple example, but I wasn’t sure which version (overwriting Javadoc, delgating to Ant) I should extract, clean up, and provide as something that can be used. Which do you prefer?

Sorry by the delay … I would leave this “problem” here, I mean in some way is enough see the reference just in text and not with the link feature. At least I know where to go to know more.

If you already have some way to work around this and if you want to share it, do it please. I have seen the ant term in your post. Seems is something complicated. I thought or expect to see a special task implemented manually.

Using the Gradle / Groovy ant support isn’t that complicated. You just have to structure your call to match the Ant task API rather than the Gradle one. For the settings you’ve shown, you’d end up putting something like the below as your task action:

ant.javadoc(access: access, charset: charset, classpath: classpath.asPath, destdir: destDir) {
    srcDirs.each { srcDir -> packageset(dir: "${srcDir}") }
    links.each { href -> link(href: href) }
}

You would need to declare the variables I’ve used here with proper annotations in a custom task class or hard code them and use the runtime API for ad-hoc task inputs/outputs for proper UP-TO-DATE checking.

The other alternative is extending the current implementation to provide extra arguments. You need the source paths and the root package name. This implementation adds some arguments based on a rootPackage that you would now need to specify and replaces source with sourceDirectorySet because we need to capture the source directory sets before they are only available as individual source files.

class CustomJavadoc extends Javadoc {

    String rootPackage
    SourceDirectorySet sourceDirectorySet
    
    @Override
    @TaskAction
    protected void generate() {
        getOptions().addStringOption('subpackages', rootPackage)
        getOptions().addPathOption('sourcepath', ';').setValue(getSourceDirectorySet().getSrcDirs().asList())
        super.generate()
    }

    @Input
    String getRootPackage() {
        return rootPackage
    }

    void setSourceDirectorySet(SourceDirectorySet sourceDirectorySet) {
        this.sourceDirectorySet = sourceDirectorySet
        setSource(sourceDirectorySet)
    }

}

Usage example:

task customJavadoc (type: CustomJavadoc) {
    classpath = sourceSets.main.compileClasspath
    rootPackage = 'com.manuel.jordan'
    sourceDirectorySet = sourceSets.main.allJava
    options.charSet('UTF-8')
    options.memberLevel = JavadocMemberLevel.PRIVATE
}

Thanks by your support. Consider the following:

package links in JavaDoc do not work with Gradle. #4832

Lets see if a support or solution form the source would be available.