dokka
dokka copied to clipboard
Javadoc exposes absolute paths in dokka-configuration.json
Describe the bug
Just migrated to Dokka 2.0.0, and I was diffing the artifacts of publishToMavenLocal. I found that the new javadoc jar contains the absolute paths of the source files and classpaths.
This means the resulting artifacts are not reproducible.
There might be also a security risk as some companies use Dokka to generate javadoc for public APIs and publish them online. These could leak internal implementation details of their systems, and the paths could be used to learn about their build machines. This could in theory aid attackers to exploit vulnerabilities more easily.
Expected behaviour
Relative paths or paths with env vars or no paths at all?
(Note re relative paths: my Gradle and Project paths are on separate Windows drive letters, so there's no way to navigate between them with ../. Even if that was possible the depth of the folders would still make it not reproducible.)
Screenshots
I replaced my local absolute paths with GRADLE_USER_HOME and PROJECT_CHECKOUT_DIR.
{
"moduleName": "my-module",
"moduleVersion": "<version>-SNAPSHOT",
"outputDir": "%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\dokka\\javadoc",
"cacheRoot": null,
"offlineMode": false,
"sourceSets": [
{
"displayName": "jvm",
"sourceSetID": {
"scopeId": ":my:module",
"sourceSetName": "main"
},
"classpath": [
"%GRADLE_USER_HOME%\\caches\\8.8\\generated-gradle-jars\\gradle-api-8.8.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-ant-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-astbuilder-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-console-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-datetime-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-dateutil-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-groovydoc-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-json-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-nio-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-sql-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-templates-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-test-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\groovy-xml-3.0.21.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\javaparser-core-3.17.0.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\kotlin-reflect-1.9.22.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\kotlin-stdlib-1.9.22.jar",
"%GRADLE_USER_HOME%\\wrapper\\dists\\gradle-8.8-all\\6gdy1pgp427xkqcjbxw3ylt6h\\gradle-8.8\\lib\\gradle-installation-beacon-8.8.jar",
"%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\classes\\java\\main",
"%PROJECT_CHECKOUT_DIR%\\my\\module\\build\\classes\\kotlin\\main",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-jdk8\\1.4.32\\3302f9ec8a5c1ed220781dbd37770072549bd333\\kotlin-stdlib-jdk8-1.4.32.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-reflect\\1.4.32\\ce852b166d97f0f1991b5130c2bb02e2ef6c554e\\kotlin-reflect-1.4.32.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-jdk7\\1.4.32\\3546900a3ebff0c43f31190baf87a9220e37b7ea\\kotlin-stdlib-jdk7-1.4.32.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib\\1.4.32\\461367948840adbb0839c51d91ed74ef4a9ccb52\\kotlin-stdlib-1.4.32.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.gradle\\gradle-kotlin-dsl\\6.1.1\\4f811c43a0688fb76681c357033c734fa740d898\\gradle-kotlin-dsl-6.1.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\gradle\\8.6.1\\39f7fafdf840259a73a7107af8c64109086ed429\\gradle-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.kotlin\\kotlin-stdlib-common\\1.4.32\\ef50bfa2c0491a11dcc35d9822edbfd6170e1ea2\\kotlin-stdlib-common-1.4.32.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains\\annotations\\13.0\\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\\annotations-13.0.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\builder\\8.6.1\\3ede92b2242a7a5b214479bd81c75c6c894308e8\\builder-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\builder-model\\8.6.1\\f4e5827bbddac07172f97f5d629911a4d49620a2\\builder-model-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\gradle-api\\8.6.1\\1dde4ab125287658b1793e4a023e6249e017d358\\gradle-api-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\manifest-merger\\31.6.1\\74d2b65c9e2b55d6f7de18cced38aa6c777f63d5\\manifest-merger-31.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android\\zipflinger\\8.6.1\\de8e3267995699af356740cf562cbedb485f5763\\zipflinger-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\apksig\\8.6.1\\f005788487574c7d6ba23dea63bf8cb3a4f164a6\\apksig-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.android.tools.build\\apkzlib\\8.6.1\\d656b52facbb301b8bdc1e40a5ae008bcf335fe9\\apkzlib-8.6.1.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\com.squareup\\javawriter\\2.5.0\\81241ff7078ef14f42ea2a8995fa09c096256e6b\\javawriter-2.5.0.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.ow2.asm\\asm\\9.6\\aa205cf0a06dbd8e04ece91c0b37c3f5d567546a\\asm-9.6.jar"
],
"sourceRoots": [
"%PROJECT_CHECKOUT_DIR%\\my\\module\\src\\main\\kotlin"
],
"dependentSourceSets": [
],
"samples": [
],
"includes": [
],
"includeNonPublic": false,
"reportUndocumented": false,
"skipEmptyPackages": true,
"skipDeprecated": false,
"jdkVersion": 11,
"sourceLinks": [
],
"perPackageOptions": [
],
"externalDocumentationLinks": [
{
"url": "https://docs.oracle.com/en/java/javase/11/docs/api/",
"packageListUrl": "https://docs.oracle.com/en/java/javase/11/docs/api/element-list"
},
{
"url": "https://kotlinlang.org/api/core/",
"packageListUrl": "https://kotlinlang.org/api/core/package-list"
}
],
"languageVersion": null,
"apiVersion": null,
"noStdlibLink": false,
"noJdkLink": false,
"suppressedFiles": [
],
"analysisPlatform": "jvm",
"documentedVisibilities": [
"PUBLIC"
]
}
],
"pluginsClasspath": [
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\javadoc-plugin\\2.0.0\\602a87960edaa602969fa4922ad9efc02ed3a39d\\javadoc-plugin-2.0.0.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\templating-plugin\\2.0.0\\2c817817579cd8c92ded6f33fd9e6b746ecf01c7\\templating-plugin-2.0.0.jar",
"%GRADLE_USER_HOME%\\caches\\modules-2\\files-2.1\\org.jetbrains.dokka\\dokka-base\\2.0.0\\dcce26b10e9af3b3f2eba0403d6a9561e6da9098\\dokka-base-2.0.0.jar"
],
"pluginsConfiguration": [
{
"fqPluginName": "org.jetbrains.dokka.base.DokkaBase",
"serializationFormat": "JSON",
"values": "{\"customAssets\":[],\"customStyleSheets\":[],\"separateInheritedMembers\":false,\"mergeImplicitExpectActualDeclarations\":false}"
},
{
"fqPluginName": "org.jetbrains.dokka.versioning.VersioningPlugin",
"serializationFormat": "JSON",
"values": "{\"olderVersions\":[],\"renderVersionsNavigationOnAllPages\":true}"
}
],
"modules": [
],
"failOnWarning": false,
"delayTemplateSubstitution": false,
"suppressObviousFunctions": true,
"includes": [
],
"suppressInheritedMembers": false,
"finalizeCoroutines": false
}
To Reproduce
gradlew dokkaGeneratePublicationJavadoc and inspect the javadoc jar.
Dokka configuration
plugins {
id("org.jetbrains.dokka")
id("org.jetbrains.dokka-javadoc")
}
Workaround (For this users have to notice that this is happening so that they can action it.)
See https://github.com/Kotlin/dokka/blob/v2.0.0/dokka-runners/dokka-gradle-plugin/src/main/kotlin/tasks/DokkaGenerateTask.kt#L99-L106
Attempt 1
Follow docs...
tasks.withType<DokkaGenerateTask>().configureEach {
@OptIn(InternalDokkaGradlePluginApi::class)
dokkaConfigurationJsonFile.set(null as File?)
// or
dokkaConfigurationJsonFile.unset()
}
Tried also wrapping in afterEvaluate, neither worked.
Attempt 2
Delete file at the "right" time.
tasks.withType<DokkaGenerateTask>().configureEach {
doLast {
@OptIn(InternalDokkaGradlePluginApi::class)
dokkaConfigurationJsonFile.orNull?.asFile?.delete()
}
}
but this is way too hacky.
Attempt 3
Hail Mary... based on some random intuition.
tasks.withType<DokkaGenerateTask>().configureEach {
@OptIn(InternalDokkaGradlePluginApi::class)
dokkaConfigurationJsonFile.unsetConvention()
// or
dokkaConfigurationJsonFile.convention(null as RegularFile?)
}
Bingo!
Installation
- Operating system: Windows 10
- Build tool: Gradle v8.12 RC
- Dokka version: 2.0.0
Hi, thanks for the report. I agree that the dokka-configuration.json file should not be included in the final output. It's only intended for debugging purposes on a local or CI machine, and shouldn't be shared.
For some context: I recently changed the dokkaConfigurationJsonFile property to be an explicit task output to help with debugging tricky issues with KMP on CI. This is an unintended consequence I didn't anticipate.
To Reproduce
gradlew dokkaGeneratePublicationJavadocand inspect the javadoc jar.
The dokkaGeneratePublicationJavadoc task doesn't produce a JAR file (there's currently no official Dokka task that will produce a JAR). I assume your project has some custom Javadoc JAR task defined?
When I run the library-publishing-example, it doesn't include the dokka-configuration.json file in the resulting JAR, but that's because it specifically selects the task output directory using from(tasks.dokkaGeneratePublicationJavadoc.flatMap { it.outputDirectory }).
https://github.com/Kotlin/dokka/blob/fc574c855fb75a4fe30185aa9f12b74295b095d4/examples/gradle-v2/library-publishing-example/build.gradle.kts#L12-L16
However, I think it's too easy to make a mistake. I'll see if I can find a better way to prevent the config file from being accidentally shared as an output.
Ah, I see, auto-output usage mine indeed!
It is coming from here: https://github.com/TWiStErRob/net.twisterrob.gradle/blob/dd867db6c0aee19cc75816823890d9be32f8f533/gradle/plugins/src/main/kotlin/net/twisterrob/gradle/build/publishing/withDokkaJar.kt
Used like this: https://github.com/TWiStErRob/net.twisterrob.gradle/blob/dd867db6c0aee19cc75816823890d9be32f8f533/gradle/plugins/src/main/kotlin/net/twisterrob/gradle/build/publishing/net.twisterrob.gradle.build.publish.gradle.kts#L52-L62
Since the param is defined as Object at https://github.com/gradle/gradle/blob/v8.11.1/platforms/jvm/plugins-java-base/src/main/java/org/gradle/api/plugins/internal/JvmPluginsHelper.java#L138
I guess I could do the selection myself as well, but you're right that it's easy to make this mistake if we use implicit outputs.
The same happens for dokkaGeneratePublicationHtml, which I suspect is not a surprise, but thought was worth mentioning.
I am upgrading from Dokka 1.9.20 to 2.0.0 and was using the following configuration to add the javadoc artifact to Maven publications (artifact( javadocJar )).
val javadocJar by tasks.creating( Jar::class )
{
archiveClassifier.set( "javadoc" )
from( tasks.dokkaJavadoc )
}
When upgrading to Dokka 2.0.0 with DGP V2 enabled, I first tried using from( tasks.dokkaGenerate ), which results in an empty javadoc jar output. Then, from( tasks.dokkaGeneratePublicationHtml ), which results in output including the dokka-configuration.json file.
@TWiStErRob 's fix works 🙏 :
tasks.withType<DokkaGenerateTask>().configureEach {
@OptIn( InternalDokkaGradlePluginApi::class )
dokkaConfigurationJsonFile.convention( null as RegularFile? )
}