Java11 class path only application gives errors related to java modules

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?

How do you build it and how do you run it?

I have two applications in project:

KlaesArchimedeTranslator
|-KlaesArchimedeTranslatorAdminApp
|-KlaesArchimedeTranslatorApp

My settings.gradle.kts file:

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:

.\gradlew -p KlaesArchimedeTranslatorApp clean
.\gradlew -p KlaesArchimedeTranslatorApp saveDependencies
.\gradlew -p KlaesArchimedeTranslatorApp slimJar
.\gradlew -p KlaesArchimedeTranslatorApp copySlimJar

Problem arises when I try to run the resulting file with

java -jar KlaesArchimedeTranslatorApp.jar -user parameters

I have somewhat resolved the issue with a launcher script:

java --add-opens java.base/java.lang=ALL-UNNAMED -jar KlaesArchimedeTranslatorApp.jar %*

But I have built similarly configured database project with Maven and I have not run into any problems with JPMS

Apologies, I must have misplaced my hand on numpad when typing version number for HikariCP.
Problem was caused by old version of HikariCP.

1 Like