Search code examples
javagradlejdbc

How to use JDBC external jars dynamically from a folder without recompilation in Gradle


First thing I am new to Gradle.

I have a Java project, built with Gradle. I get a fat jar using the Application plugin, which uses java plugin under the bonnet.

I want to be able to supply some JDBC jars to talk to different DBMSs (Oracle, Postgres, DB2 etc.) in different deployment environments - so without re-compilation.

Previously, using ANT, we could manually drop a JDBC jar in lib folder, and the application would pick it up and use it without compilation.

Currently, I am trying to achieve the same with Gradle. I tried the following:

  1. Adding the dependency runtimeOnly fileTree('lib') { include '*.jar' }: but that requires a compilation every time I drop a new jar in the lib folder.

  2. Setting runtimeClasspath in sourceSets:

sourceSets {
    main {
        java {
            runtimeClasspath = fileTree('lib') { include '*.jar' }
        }
    }
}

But it doesn't change anything.

How can this be done? here is how my build.gradle looks like:

plugins {
    id 'application' // implicitly applies java and distribution, see https://docs.gradle.org/7.4/userguide/application_plugin.html    
    id 'com.github.johnrengelman.shadow' version '7.1.2' // For fat jars
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.apache.poi:poi:5.2.3'
    implementation 'org.apache.poi:poi-ooxml:5.2.3'

    // :
    // more implementation dependencies...
    // :

    // runtimeOnly fileTree('lib') { include '*.jar' } <- requires compilation

}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
    
}

application {
    mainClass = 'my_pkg.ProcessAll'
}

shadowJar {
    archiveBaseName.set('MyApp')
    classifier = null
}


sourceSets {
    main {
        java {
            runtimeClasspath = fileTree('lib') { include '*.jar' } // <- doesn't work
        }
    }
}

Solution

  • I resorted to a "simpler" solution:

    • I offloaded all the JDBC jars from Gradle build.gradle to a folder after deployment - let's call it jdbcs.
    • I told java to include that folder as part of the class path using -cp when running the software.

    On Windows systems: java -cp "my_package.jar;jdbcs\*" my_src_pkg.func

    On Linux: java -cp "my_package.jar:jdbcs/*" my_src_pkg.func