0

I upgraded the plugin id 'org.springframework.boot' version '2.6.5' which led to the following changes

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.6.5'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'jacoco'
    id 'org.barfuin.gradle.jacocolog' version '1.0.1'
}

bootRun {
    args = [
            '--spring.config.location=./src/configs.properties',
    ]
}

springBoot {
    mainClass = 'com.company.service.ServiceClass'
}

jar {
    // This would avoid creating an additional "-plain" jar
    enabled = true
    archiveClassifier = ''
    // Before the plugin upgrade I wasnt getting manifest attribute related error. Because of one of such errors, I added it the attribute explicitly.
    manifest {
        attributes 'Main-Class': 'com.company.service.ServiceClass'
    }
}

bootJar {
    layered {
        enabled = true
    }
}

dependencies {
    testImplementation group: 'junit', name: 'junit', version: '4.12'
    implementation 'org.bouncycastle:bcprov-jdk16:1.46'
    implementation 'org.immutables:value:2.9.0'
    implementation('org.apache.lucene:lucene-core:8.10.0')
    implementation('com.fasterxml.jackson.core:jackson-core:2.13.2')
    implementation('com.fasterxml.jackson.core:jackson-annotations:2.13.2')
    implementation('com.fasterxml.jackson.core:jackson-databind:2.13.2')
    implementation('org.apache.poi:poi-ooxml:5.2.2')
    implementation('io.netty:netty-codec:4.1.75.Final')
    implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.13.2'
    compileOnly 'org.projectlombok:lombok:1.18.22'
    annotationProcessor 'org.projectlombok:lombok:1.18.22'
    annotationProcessor 'org.immutables:value:2.9.0'

    implementation('org.springframework.boot:spring-boot-starter-web:2.6.5') {
        testImplementation('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
            exclude group: 'org.slf4j', module: 'slf4j-simple'
            exclude group: 'org.slf4j', module: 'slf4j-log4j12'
            exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
            exclude group: 'ch.qos.logback', module: 'logback-classic'
        }
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
        exclude group: 'org.slf4j', module: 'slf4j-simple'
        exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
        exclude group: 'ch.qos.logback', module: 'logback-classic'
        implementation('org.apache.tomcat.embed:tomcat-embed-core:9.0.54')
    }
    implementation('org.springframework.boot:spring-boot-starter-security:2.6.5') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
        exclude group: 'org.slf4j', module: 'slf4j-simple'
        exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
        exclude group: 'ch.qos.logback', module: 'logback-classic'
    }

    implementation('org.keycloak:keycloak-spring-boot-starter:17.0.1') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
        exclude group: 'org.slf4j', module: 'slf4j-simple'
        exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        exclude group: 'org.slf4j', module: 'jcl-over-slf4j'
        exclude group: 'ch.qos.logback', module: 'logback-classic'
    }
    implementation('org.keycloak.bom:keycloak-adapter-bom:17.0.1')
    implementation('io.springfox:springfox-boot-starter:3.0.0')
    implementation('io.springfox:springfox-swagger-ui:3.0.0')
}
// some jacoco and checkstyle configs here.

When I run the jar, I get the following error

>> java -jar build/libs/service-1.0-SNAPSHOT.jar
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
    at java.lang.Class.getDeclaredMethods0(Native Method)

From the solutions I found on SO, I added the dependency

implementation group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'

But this doesnt work. Plus I am still using jdk8 and there is no org.bouncycastle for jdk8. Any suggestions how I can work around this exception?

EDIT: Running the application with intelliJ doesnt throw this problem. But happens when running from command line.

EDIT:

>> % java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.292-b10, mixed mode)

Full stack trace

% java -jar build/libs/my-service-class.jar 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    at java.lang.Class.getMethod0(Class.java:3018)
    at java.lang.Class.getMethod(Class.java:1784)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:650)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:632)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    ... 7 more
A_G
  • 2,260
  • 3
  • 23
  • 56
  • Can you provide some more details? The complete stacktrace of the failure, how you are running the app, complete build.gradle, output from `java -version`, etc – Andy Wilkinson Apr 01 '22 at 06:14
  • Hey Andy, I have updated the code piece to include the gradle file and also added an EDIT to output java version and full stack trace – A_G Apr 01 '22 at 16:36
  • Note versions like `jdk13 jdk14 jdk15[on] jdk16[on]` in Bouncy jar names mean 1.3 1.4 1.5 1.6 in the old Sun numbering (from the noughties) not 13 14 15 16 in the new scheme from the last few years. These must vary because before 1.5 and sometimes 1.6 the Java crypto APIs weren't stable and Bouncy had to handle or fill-in some gaps. In general the same Bouncy code runs on all Java from 1.5 or (1.)6 up, including 8, and that's what jar names jdk15on and jdk16on mean ('[and] on[ward]' = beginning at the stated point and continuing forward in time or sequence) ... – dave_thompson_085 Apr 01 '22 at 19:31
  • ... For recent _Oracle_ Java there is an issue running jars before about 2018 because Oracle requires provider jars (which bcprov is, and 1.46 is from 2011) to be code-signed and the Sun/Oracle root cert expired and was replaced so old jars needed to be re-signed; I don't know what repo you are using and if it has these updates, but this shouldn't matter for OpenJDK which does not require provider signing, and if this were the issue you should get a more specific exception something like 'provider not validated'. – dave_thompson_085 Apr 01 '22 at 19:33

1 Answers1

0

Running the application with intelliJ doesnt throw this problem. But happens when running from command line.

java -jar build/libs/my-service-class.jar

For executing a jar directly from command line, it should contain manifest information. Assuming the aforementioned jar contain the same as you're facing the the other issue(class def not found) so looks like your jar my-service-class.jar is thin jar and doesn't contain the other dependencies that you've added in the project. Two way to solve this problem. Either you can create uber jar i.e jar with all the dependencies included by using available plugins for the same and then execute the command or just add all the required dependencies into some folder and give path to it while runing the above command.

b.s
  • 2,409
  • 2
  • 16
  • 26
  • As per the Layering Docker images section (https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#container-images.efficient-images.layering) `layered=true` in `bootjar` should have been sufficient to execute the jar. But i cant see where the "dependencies", "spring-boot-loader", etc are created o.O – A_G Apr 01 '22 at 17:18
  • You can easily verify it by extracting the content of the jar and see whether the `my-service-class.jar` contain the other dependencies or class files of those dependencies. – b.s Apr 01 '22 at 17:22
  • `java -Djarmode=layertools -jar build/libs/precision-enhancer-tool-1.0-SNAPSHOT.jar list` didnt return the layers but when I removed the entire `jar` task, the layers started showing up and the jar starts up. – A_G Apr 01 '22 at 18:39