I created a web application. I am using Gradle. I am new to Gradle and I am trying to migrate one of my projects to Java 9 module system. I moved all the jars to module path instead of the classpath. Here is the snippet of my 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()
}
}
Now if I execute the gradle build
or buildDependents
or testClasses
task then I get the following errors
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
....
So Why I am getting module not found exception for jUnit
, log4j.api
and org.apache.logging.log4j.web
. I checked in the module path and jars are there.
Second I read about split packages. My question is as I know from the error that the two jars are java.sql and javax.transaction.api
and jaxb.runtime and jaxb.core
and similary for other jars.
Can I make a Gradle task that merges these two jars into one and includes that one jar on the module path so these errors can be removed? Or there is another way to resolve such kind of errors?
Is it possible to move some jars to module path and some jars to the classpath? And how you can find which jars to move module path and which jars to move classpath?
Thank you