I use Spring Boot and Spring Security in combination with Keycloak. The build tool is gradle.
When I run ./gradlew bootRun
the application works flawless. If I use the resulting fat jar (i.e. java -jar myapp.jar
) the application will boot but I encounter an exception when the application tries to invoke some keyloak stuff:
java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource referenced from a method is not visible from class loader
at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:851) ~[na:na]
at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:682) ~[na:na]
at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:628) ~[na:na]
at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) ~[na:na]
at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:327) ~[na:na]
at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:203) ~[na:na]
at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) ~[na:na]
at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:999) ~[na:na]
at org.jboss.resteasy.client.jaxrs.ProxyBuilder.proxy(ProxyBuilder.java:79) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
at org.jboss.resteasy.client.jaxrs.ProxyBuilder.build(ProxyBuilder.java:131) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
at org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.proxy(ClientWebTarget.java:93) ~[resteasy-client-3.1.4.Final.jar!/:3.1.4.Final]
at org.keycloak.admin.client.Keycloak.realms(Keycloak.java:114) ~[keycloak-admin-client-3.4.3.Final.jar!/:3.4.3.Final]
at org.keycloak.admin.client.Keycloak.realm(Keycloak.java:118) ~[keycloak-admin-client-3.4.3.Final.jar!/:3.4.3.Final]
So I figured out that there must be something wrong how I start the application in the terminal. I found this official site, which explains how to run an Spring application from terminal. So I tried all of the solutions including:
$ unzip -q myapp.jar
$ java org.springframework.boot.loader.JarLauncher
but I get the same error.
After 2 days of searching and experimenting I'm out of any ideas.
So my question is basically: Does anyone have any idea how to solve this problem?
My knowledge regarding the classloader is also limited - so any pratical hints in this direction are very welcomed as well.
EDIT (added build.gradle): There were some Jackson problems that's why the Spring web dependencies are included directly (without the starter and therefor without Jackson). Here is the build.gradle:
buildscript {
ext {
kotlinVersion = '1.2.20'
springBootVersion = '1.5.7.RELEASE'
keycloakVersion = '3.4.3.Final'
restEasyClientVersion = '3.1.4.Final'
postgresServerVersion = '10.0'
postgresJdbcDriverVersion = '42.1.4'
spekVersion = '1.1.5'
jacksonVersion = '2.8.10'
javaxWsRsVersion = '2.1'
logbackVersion = '1.2.3'
slf4jVersion = '1.7.25'
}
repositories {
mavenCentral()
jcenter()
//spring dev
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
//Kotlin dev
maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.2' }
//gradle plugins
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
classpath('com.bmuschko:gradle-docker-plugin:3.2.0')
//for tests
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
}
}
allprojects {
repositories {
mavenCentral()
jcenter()
//spring dev
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
}
subprojects {
repositories {
maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.2' }
// for tests
maven { url "http://dl.bintray.com/jetbrains/spek" }
}
// for kotlin
apply plugin: 'kotlin'
// for tests
apply plugin: 'org.junit.platform.gradle.plugin'
apply plugin: 'kotlin-spring'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
// for tests
junitPlatform {
filters {
engines {
include 'spek'
}
}
}
sourceCompatibility = 1.9
dependencies {
// kotlin
compile("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
compile("org.jetbrains.kotlin:kotlin-test:${kotlinVersion}")
compile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
// jackson
compile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
compile "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:${jacksonVersion}"
compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base:${jacksonVersion}"
compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.2"
// Java WS RS
compile "javax.ws.rs:javax.ws.rs-api:${javaxWsRsVersion}"
// for tests
testCompile "org.jetbrains.spek:spek-api:${spekVersion}"
testRuntime "org.jetbrains.spek:spek-junit-platform-engine:${spekVersion}"
testCompile ("org.jetbrains.spek:spek-api:${spekVersion}") {
exclude group: 'org.jetbrains.kotlin'
}
testRuntime ("org.jetbrains.spek:spek-junit-platform-engine:${spekVersion}") {
exclude group: 'org.junit.platform'
exclude group: 'org.jetbrains.kotlin'
}
// spring security
compile('org.springframework.boot:spring-boot-starter-security')
testCompile('org.springframework.security:spring-security-test')
// begin: spring web without jackson
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-tomcat')
compile('org.springframework:spring-web')
compile('org.springframework:spring-webmvc')
testCompile('org.springframework.boot:spring-boot-starter-test')
// end: spring web without jackson
// Keycloak
compile("org.keycloak:keycloak-spring-security-adapter:${keycloakVersion}")
compile("org.keycloak:keycloak-spring-boot-adapter:${keycloakVersion}")
compile("org.keycloak:keycloak-tomcat8-adapter:${keycloakVersion}")
compile("org.keycloak:keycloak-admin-client:${keycloakVersion}")
compile("org.jboss.resteasy:resteasy-client:${restEasyClientVersion}")
compile("org.jboss.resteasy:resteasy-jackson2-provider:${restEasyClientVersion}")
}
compileKotlin {
kotlinOptions.jvmTarget = '1.8'
kotlinOptions.allWarningsAsErrors = true
}
compileTestKotlin {
kotlinOptions.jvmTarget = '1.8'
}
}