You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle重复包排除问题:解决jOpenDocument与java.xml的org.w3c.dom冲突

问题描述

使用Gradle构建项目,依赖JavaFX、Maven仓库的log4j,以及本地flatDir目录中的jOpenDocument-1.5包。在JDK19环境下构建时出现以下错误:

error: the unnamed module reads package org.w3c.dom from both jOpenDocument and java.xml
error: module javafx.graphicsEmpty reads package org.w3c.dom from both jOpenDocument and java.xml
error: module javafx.baseEmpty reads package org.w3c.dom from both jOpenDocument and java.xml
error: module org.apache.logging.log4j.core reads package org.w3c.dom from both jOpenDocument and java.xml
error: module javafx.controlsEmpty reads package org.w3c.dom from both jOpenDocument and java.xml
error: module jOpenDocument reads package org.w3c.dom from both java.xml and jOpenDocument

希望保留java.xml中的org.w3c.dom包,排除jOpenDocument中的该包(仅包含org.w3c.dom.UserDataHandler.class,移除后副作用小)。尝试了如下build.gradle配置但无效,因为org.w3c.dom是Java包而非Gradle/Maven模块:

dependencies {
    testImplementation 'org.testng:testng:7.4.0'

    implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
    implementation 'org.apache.logging.log4j:log4j-core:2.14.1'

    implementation ('libs:jOpenDocument-1.5') {
        exclude module: 'org.w3c.dom'
    }

}

咨询两个问题:

  1. 应如何修改build.gradle文件以解决该重复依赖冲突?
  2. 若Gradle构建依赖模块不是Java包,那它指的是什么?
解决方案

1. 解决重复包冲突的配置方式

Gradle的exclude机制只能排除整个依赖模块,无法直接移除jar包内的单个类或包。要解决这个问题,需要先处理jOpenDocument的jar包,移除冲突的org.w3c.dom.UserDataHandler.class,再依赖处理后的jar包。可以通过自定义Gradle任务实现:

// 自定义任务:处理jOpenDocument原jar,移除冲突类
task processJOpenDocumentJar(type: Jar) {
    // 读取原jar文件
    from zipTree(file('libs/jOpenDocument-1.5.jar'))
    // 排除冲突的类文件
    exclude 'org/w3c/dom/UserDataHandler.class'
    // 设置处理后的jar文件名
    archiveFileName = 'jOpenDocument-processed-1.5.jar'
    // 指定处理后的jar输出目录
    destinationDirectory = file("$buildDir/libs")
}

dependencies {
    testImplementation 'org.testng:testng:7.4.0'

    implementation 'org.apache.logging.log4j:log4j-api:2.14.1'
    implementation 'org.apache.logging.log4j:log4j-core:2.14.1'

    // 依赖处理后的jar包,指定该jar由processJOpenDocumentJar任务生成
    implementation files("$buildDir/libs/jOpenDocument-processed-1.5.jar") {
        builtBy processJOpenDocumentJar
    }
}

执行构建时,Gradle会先运行processJOpenDocumentJar任务生成处理后的jar,再用这个jar参与构建,避免包重复读取的问题。

2. Gradle依赖模块的定义

Gradle中的依赖模块不是Java包(package),而是Maven/Gradle生态中的独立依赖单元:

  • 通常对应一个可执行的jar/war/aar等文件,每个模块有唯一的group:name:version标识(例如org.apache.logging.log4j:log4j-core:2.14.1)。
  • 一个模块可以包含多个Java包,同时一个Java包也可能被多个模块包含(比如本次问题中的org.w3c.dom被JDK的java.xml模块和jOpenDocument模块同时包含)。
  • Gradle的exclude机制作用于整个模块或模块的子依赖,无法直接操作单个Java包或类。

内容的提问来源于stack exchange,提问作者Emma Atkinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:24:59