I have a project built with Java 11 that runs fine from IDE (Eclipse), but when I try to run binaries built with Gradle I keep getting an error related to JPMS modules when trying to connect to database with HikariCP:
java.lang.ExceptionInInitializerError
at com.zaxxer.hikari.HikariConfig.<clinit>(HikariConfig.java:31)
at pl.ms.oknadrewniane.db.HikariConnection.<clinit>(HikariConnection.java:11)
at pl.ms.oknadrewniane.klaes.archimede.ArchimedeTranslator.main(ArchimedeTranslator.java:125)
Caused by: java.lang.RuntimeException: Fatal exception during proxy generation
at com.zaxxer.hikari.proxy.JavassistProxyFactory.<clinit>(JavassistProxyFactory.java:61)
... 3 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @457e2f02
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at javassist.ClassPool.toClass2(ClassPool.java:1131)
at javassist.ClassPool.toClass(ClassPool.java:1114)
at javassist.CtClass.toClass(CtClass.java:1300)
at com.zaxxer.hikari.proxy.JavassistProxyFactory.generateProxyClass(JavassistProxyFactory.java:200)
at com.zaxxer.hikari.proxy.JavassistProxyFactory.<init>(JavassistProxyFactory.java:85)
at com.zaxxer.hikari.proxy.JavassistProxyFactory.<clinit>(JavassistProxyFactory.java:57)
... 3 more
Is there some sort of configuration entry necessary for projects without module-info.java to be JPMS free (class path only) build under Java 11?
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
rootProject.name = "KlaesArchimedeTranslator"
include("KlaesArchimedeTranslatorApp")
include("KlaesArchimedeTranslatorAdminApp")
And my KlaesArchimedeTranslatorApp build.gradle.kts file (messy learning in progress, sorry):
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.jvm.tasks.Jar;
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
application
id("com.gradleup.shadow") version "8.3.5"
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
mavenLocal()
}
dependencies {
// Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation("SWIOID:BaseContainers:0.0.3-SNAPSHOT")
implementation ("com.zaxxer:HikariCP:2.3.2")
implementation ("com.mysql:mysql-connector-j:8.0.33")
implementation("org.slf4j:slf4j-nop:1.7.36")
implementation("com.miglayout:miglayout-swing:11.3")
}
// Apply a specific Java toolchain to ease working on different environments.
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
application {
// Define the main class for the application.
mainClass = "pl.ms.oknadrewniane.klaes.archimede.ArchimedeTranslator"
}
tasks.withType<ShadowJar>(){
archiveFileName.set("KlaesArchimedeTranslator-fat.jar")
manifest{
attributes["Implementation-Title"] = "Gradle Jar File Example"
attributes["Implementation-Version"] = version
attributes["Main-Class"] = application.mainClass
}
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
val fatJar = task("fatJar", type = Jar::class){
base.archivesName = "${project.name}-fat"
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest{
attributes["Implementation-Title"] = "Gradle Jar File Example"
attributes["Implementation-Version"] = version
attributes["Main-Class"] = application.mainClass
}
from(configurations.runtimeClasspath.get().map( { if (it.isDirectory) it else zipTree(it) }))
with(tasks["jar"] as CopySpec)
}
val slimJar = task("slimJar", type = Jar::class){
base.archivesName = project.name
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest{
attributes["Implementation-Title"] = "Gradle Jar File Example"
attributes["Implementation-Version"] = version
attributes["Main-Class"] = application.mainClass
attributes["Class-Path"] = configurations.runtimeClasspath.get().joinToString(separator = " "){file -> "libraries/${file.name}"}
}
with(tasks["jar"] as CopySpec)
}
val saveDependencies by tasks.registering(Copy::class) {
val libDir = layout.buildDirectory.dir("lib").get()
from(configurations.runtimeClasspath) {
// Optionally, filter files if needed
include("*.jar")
}
into(libDir)
into("c:\\temp\\gradle\\libraries")
}
val copySlimJar = task<Copy>("copySlimJar"){
from(slimJar)
into("c:\\temp\\gradle")
}
// to also include as part of build
tasks.build {
dependsOn(saveDependencies)
}
tasks.named<Test>("test") {
// Use JUnit Platform for unit tests.
useJUnitPlatform()
}
And I build it on command line with following commands: