我创建了一个 Web 应用程序。我正在使用 Gradle。我是 Gradle 的新手,我正在尝试将我的一个项目迁移到 Java 9 模块系统。我将所有 jar 移动到模块路径而不是类路径。这是我的 build.gradle 的片段
plugins {
id 'java-library'
id 'eclipse-wtp'
id 'war'
}
ext {
//logging
log4jGroupId = "org.apache.logging.log4j"
log4jVersion = "2.11.0"
.....
moduleName = "pk.training.basit.kanban"
}
dependencies {
// Unit Testing
testImplementation group: 'junit', name: 'junit', version: junitVersion
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitJupiterEngineVersion
implementation group: log4jGroupId, name: 'log4j-api', version: log4jVersion
.....
['log4j-core', 'log4j-jcl', 'log4j-slf4j-impl', 'log4j-web'].each {
runtime "${log4jGroupId}:$it:${log4jVersion}"
}
implementation group: 'javax.transaction', name: 'javax.transaction-api', version: javaxTransactionApiVersion
implementation (group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: jaxbVersion) {
exclude group: 'org.jvnet.staxex', module: 'stax-ex'
}
...
}
eclipse.classpath.file {
whenMerged {
entries.findAll { isModule(it) }.each { it.entryAttributes['module'] = 'true' }
}
}
boolean isModule(entry) {
// filter java 9 modules
entry.kind == 'lib' // Only libraries can be modules
}
eclipse.wtp.facet.file.withXml { facetXml ->
def root = facetXml.asNode()
root.installed.find { it.@facet == 'jst.java' }.@version = '9'
root.installed.find { it.@facet == 'jst.web' }.@version = '3.1'
}
compileJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
]
classpath = files() // Clears the classpath property by creating an empty file collection
}
}
compileTestJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath, // This is the default value for the classpath property used as the --module-path.
'--add-modules', 'org.junit.jupiter.api', // junit5 automatic module specific
'--add-modules', 'java.xml.bind', // jaxb specific
'--add-reads', "$moduleName=org.junit.jupiter.api", // allow junit to read your module
'--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath, // Adds the test source files to the org.gradle.actors module.
]
classpath = files()
}
}
test {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-MODULE-PATH',
'--add-reads', "$moduleName=org.junit.jupiter.api",
'--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir).asPath,
]
classpath = files()
}
}
现在,如果我执行 gradle build
or buildDependents
ortestClasses
任务,那么我会收到以下错误
module not found: junit --> requires junit;
module not found: log4j.api --> requires log4j.api;
module not found: org.apache.logging.log4j.web --> requires org.apache.logging.log4j.web;
error: the unnamed module reads package javax.transaction.xa from both java.sql and javax.transaction.api
error: the unnamed module reads package javax.activation from both java.activation and activation
error: the unnamed module reads package com.sun.xml.bind from both jaxb.runtime and jaxb.core
error: module spring.web reads package javax.transaction.xa from both javax.transaction.api and java.sql
error: module spring.security.core reads package javax.transaction.xa from both javax.transaction.api and java.sql
....
那么为什么我得到模块未找到异常jUnit
,log4j.api
和org.apache.logging.log4j.web
。我检查了模块路径并且罐子在那里。
其次,我阅读了有关拆分包的信息。我的问题是,我从错误中知道这两个罐子是java.sql and javax.transaction.api
并且jaxb.runtime and jaxb.core
与其他罐子相似。
我可以制作一个 Gradle 任务,将这两个 jar 合并为一个,并在模块路径中包含那个 jar,以便可以删除这些错误?还是有另一种方法来解决此类错误?
是否可以将一些 jar 移动到模块路径并将一些 jar 移动到类路径?以及如何找到要移动模块路径的 jar 以及要移动类路径的 jar?
谢谢