Skip to content

Conversation

@infotexture
Copy link
Member

@infotexture infotexture commented Nov 16, 2025

Description

Test jyjeanne/dita-ot-gradle per dita-ot/discussions/4722 & jyjeanne/dita-ot-gradle#quick-migration-tldr.

Motivation and Context

Confirm whether the new jyjeanne/dita-ot-gradle Gradle plugin works in our environment to take advantage of recent Gradle features that are not supported by the original eerohele/dita-ot-gradle plugin.

How Has This Been Tested?

  1. Update build.gradle in Refactor for Gradle 9 compatibility #644
  2. Update modified build.gradle@e11be3b to use jyjeanne/dita-ot-gradle

Result

❌ Build fails:

FAILURE: Build failed with an exception.

* Where:
Build file '/path/to/docs/build.gradle' line: 45

* What went wrong:
A problem occurred evaluating root project 'docs'.
> Could not get unknown property 'ditaOt' for root project 'docs' of type org.gradle.api.Project.

infotexture and others added 2 commits November 4, 2025 00:05
Use Cursor’s `claude-4-sonnet` model to replace deprecated constructs from Gradle 7 and earlier versions with their Gradle 8 and 9 equivalents to quiet deprecation warnings.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Roger Sheen <[email protected]>
@infotexture infotexture self-assigned this Nov 16, 2025
@infotexture infotexture added the build Ant/Gradle build scripts & CI/CD issues label Nov 16, 2025
@jyjeanne
Copy link

@infotexture i made some improvment on latest version 2.30 and solve problem on cache configuration , can you try with this new version of the plugin : https://github.com/jyjeanne/dita-ot-gradle/releases/tag/v2.3.0 ?

@infotexture
Copy link
Member Author

@jyjeanne Thanks, tried again with the new v2.3.0 as you suggested.

Build proceeds and announces success in the (new) transformation report summaries, so the explicit directory config in 567d0a3 works, and v2.3.0 seems to solve the AntClassLoader error from 2.2.0:

> Task :html
Starting DITA-OT transformation

═══════════════════════════════════════════════════════
DITA-OT Transformation Report
═══════════════════════════════════════════════════════
Status:           SUCCESS
DITA-OT version:  unknown
Files processed:  1
Formats:          html5
Output size:      2.12 MB
Duration:         9.82s
═══════════════════════════════════════════════════════

> Task :pdf
Starting DITA-OT transformation

═══════════════════════════════════════════════════════
DITA-OT Transformation Report
═══════════════════════════════════════════════════════
Status:           SUCCESS
DITA-OT version:  unknown
Files processed:  1
Formats:          pdf
Output size:      4.60 MB
Duration:         15.21s
═══════════════════════════════════════════════════════

However, the properties in the html and pdf tasks are apparently ignored.

For example:

@infotexture infotexture changed the title Test jyjeanne/dita-ot-gradle 2.2.0 Test jyjeanne/dita-ot-gradle Dec 7, 2025
@jyjeanne
Copy link

@infotexture Hi, I finally find a solution :

Root Cause

The properties { } closure syntax that worked in v2.2.x no longer functions correctly in v2.3.0:

// ❌ BROKEN in v2.3.0 - Properties are silently ignored
properties {
    property name: 'args.copycss', value: 'yes'
    property name: 'args.css', value: 'dita-ot-doc.css'
}

Solution: Use ditaProperties.put() Directly

The v2.3.0 plugin exposes a ditaProperties MapProperty that must be used directly:

// ✅ WORKS in v2.3.0 - Properties are correctly applied
ditaProperties.put('args.copycss', 'yes')
ditaProperties.put('args.css', 'dita-ot-doc.css')
ditaProperties.put('args.csspath', 'css')
ditaProperties.put('args.cssroot', "${projectDirPath}/resources/")

Updated Task Examples for v2.3.0

html task:

task html(type: DitaOtTask, dependsOn: autoGenerate) {
    ditaOt file(findProperty('ditaHome') ?: ditaHome)
    input "${projectDirPath}/userguide.ditamap"
    output outputDir
    transtype 'html5'
    filter "${projectDirPath}/resources/html.ditaval"

    // Use ditaProperties MapProperty directly for v2.3.0 compatibility
    ditaProperties.put('args.copycss', 'yes')
    ditaProperties.put('args.css', 'dita-ot-doc.css')
    ditaProperties.put('args.csspath', 'css')
    ditaProperties.put('args.cssroot', "${projectDirPath}/resources/")
    ditaProperties.put('args.gen.task.lbl', 'YES')
    ditaProperties.put('args.hdr', "${projectDirPath}/resources/header.xml")
    ditaProperties.put('args.rellinks', 'noparent')
    ditaProperties.put('html5.toc.generate', 'no')
    ditaProperties.put('nav-toc', 'partial')
}

pdf task:

task pdf(type: DitaOtTask, dependsOn: autoGenerate) {
    ditaOt file(findProperty('ditaHome') ?: ditaHome)
    input "${projectDirPath}/userguide-book.ditamap"
    output outputDir
    transtype 'pdf'
    filter "${projectDirPath}/resources/pdf.ditaval"

    // Use ditaProperties MapProperty directly for v2.3.0 compatibility
    ditaProperties.put('args.chapter.layout', 'BASIC')
    ditaProperties.put('args.gen.task.lbl', 'YES')
    ditaProperties.put('include.rellinks', '#default external')
    ditaProperties.put('outputFile.base', 'userguide')
    ditaProperties.put('theme', "${projectDirPath}/samples/themes/dita-ot-docs-theme.yaml")
}

site task (with conditional property):

task site(type: DitaOtTask) {
    ditaOt file(findProperty('ditaHome') ?: ditaHome)
    // ...

    def includeCommitMeta = !providers.gradleProperty('noCommitMeta')
        .map { Boolean.parseBoolean(it) }.getOrElse(false)

    // Use ditaProperties MapProperty directly for v2.3.0 compatibility
    ditaProperties.put('args.gen.task.lbl', 'YES')
    ditaProperties.put('args.rellinks', 'noparent')
    if (includeCommitMeta) {
        ditaProperties.put('commit', gitCommitHash)
    }
}

Verification

After applying the fix, the build correctly applies all properties:

$ ./gradlew -PditaHome='C:\dita-ot\dita-ot-4.3.5' html

> Task :html
Starting DITA-OT transformation
Status:           SUCCESS
Output size:      5.02 MB
Duration:         69.65s

BUILD SUCCESSFUL in 1m 12s

CSS verification:

$ ls out/css/
commonltr.css
commonrtl.css
dita-ot-doc.css    ← Custom CSS correctly copied!

@jyjeanne
Copy link

I will update plugin documentation about this bug and add workaround . I also add new test case to prevent this bug.

I wanted to thank you for your assistance in identifying and resolving the recent issue. Your insights were valuable in addressing the bug efficiently

Best regards

@infotexture
Copy link
Member Author

@jyjeanne Thanks for your persistence here, it works with the ditaProperties.put() syntax.

I'll switch the status of this PR to Ready for review, run a few more tests, and discuss with the team before merging, but looks like this could work well for our purposes. 🙏

Use ditaProperties MapProperty directly for compatibility with jyjeanne/dita-ot-gradle v2.3.0

Per #645 (comment)
 

Signed-off-by: Roger Sheen <[email protected]>
@infotexture infotexture marked this pull request as ready for review December 11, 2025 14:07
@infotexture infotexture requested a review from jelovirt December 11, 2025 14:08
@jyjeanne
Copy link

hi, i also make a bug fix into version 2.3.1 to allow user to use two groovy syntax :

  • ditaProperties.put()

OR

  • properties {
    property name: 'args.copycss', value: 'yes'
    property name: 'args.css', value: 'dita-ot-doc.css'
    }

Best regards

@infotexture
Copy link
Member Author

infotexture commented Jan 4, 2026

@jyjeanne This now works fine when run from the docs repository, but we hadn't merged it yet because we hadn't tested it with the DITA-OT distribution build file.

When we do that, we get errors about implicit dependencies between the docs html and pdf tasks.

Both of those run fine independently, but the error suggests they depend on one another — but they don't.

Upon further inspection, this is likely caused by the fact that dita-ot-gradle uses the entire DITA-OT installation directory as task input directory.

This seems like a bug in the plug-in rather than something we should work around.

While the toolkit directory does contain resource files used by the transformation, the start map and filter files are actually the only known inputs.

@jyjeanne
Copy link

jyjeanne commented Jan 5, 2026

@infotexture i analyze the root cause and the Problem is on : @InputDirectory on ditaOtDir.

In DitaOtTask.kt, the DITA-OT installation directory is declared as:

@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val ditaOtDir: DirectoryProperty

This annotation causes Gradle to:

  1. Track the entire directory as task input for up-to-date checks
  2. Monitor all files within the directory for changes
  3. Infer implicit dependencies between tasks sharing the same input directory

Why It Manifests in Distribution Builds

In a typical DITA-OT distribution structure:

dita-ot-4.x/
├── bin/
├── config/
├── doc/              ← OUTPUT directory (inside ditaOtDir!)
├── docsrc/           ← Input source files
├── lib/
├── plugins/
└── build.xml

When multiple tasks are configured:

task html(type: DitaOtTask) {
    ditaOt file(ditaHome)      // Points to dita-ot-4.x/
    output "${ditaHome}/doc"   // Writes INSIDE ditaOtDir
}

task pdf(type: DitaOtTask) {
ditaOt file(ditaHome) // Same ditaOtDir as html
output "${ditaHome}/doc" // Same output location
}

Gradle's perspective:

  • Both tasks declare ditaOtDir as input (due to @InputDirectory)
  • Task html writes to doc/ which is inside ditaOtDir
  • Task pdf also uses ditaOtDir as input
  • Gradle infers: "pdf depends on html because html modifies pdf's input"

Why This is Incorrect

The DITA-OT installation directory is a tool, not a data input:

Concept Example Should be Task Input?
Tool/Runtime DITA-OT, JDK, Node.js No (@internal)
Data Input .ditamap, .dita, .ditaval Yes (@InputFiles)

You don't declare JAVA_HOME as a task input when compiling Java code - the same principle applies here.

Solution

Change ditaOtDir to @Internal into the plugin and add additional tests on this case

// BEFORE (problematic):
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val ditaOtDir: DirectoryProperty

// AFTER (fixed):
@get:Internal
abstract val ditaOtDir: DirectoryProperty

Pros:

  • Simple one-line change
  • Fixes the implicit dependency issue immediately
  • DITA-OT directory is correctly treated as a tool, not input data

Cons:

  • Loses up-to-date checking when DITA-OT itself changes
  • Tasks won't re-run automatically if plugins are modified

Mitigation: Users who need up-to-date checks on DITA-OT changes can use devMode(true) or manually invalidate the build.


Workaround (Until Fix is Released)

you can add this to the build.gradle as a temporary workaround:

tasks.withType(DitaOtTask).configureEach {
    // Disable up-to-date checks to avoid implicit dependency errors
    outputs.upToDateWhen { false }
}

Or for specific tasks:

task html(type: DitaOtTask) {
    // ... configuration ...

    // Workaround: disable caching
    outputs.upToDateWhen { false }
}

I will send you a message when plugin with fix is released

@jyjeanne
Copy link

jyjeanne commented Jan 5, 2026

@infotexture i made a new release of the plugin with the bug fix : https://github.com/jyjeanne/dita-ot-gradle/releases/tag/v2.3.2 i hope it will help you .

@jyjeanne
Copy link

jyjeanne commented Jan 5, 2026

@infotexture Finaly i check docs with new plugin release v2.3.2 containing bug fix and it solved this issue. Can you also check and confirm this result ? Best regards

@infotexture infotexture force-pushed the feature/jyjeanne.dita-ot-gradle branch from de990cd to 3e0fce2 Compare January 5, 2026 23:24
@infotexture
Copy link
Member Author

@jyjeanne 🙏 Thanks, the changes in v2.3.2 allow the distribution build in the core repo to complete successfully.

@infotexture infotexture changed the base branch from feature/gradle-9-compatibility to develop January 7, 2026 21:52
@infotexture infotexture merged commit eaaa935 into develop Jan 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Ant/Gradle build scripts & CI/CD issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants