SnuK87 / keycloak-kafka

Keycloak module to produce events to kafka
Apache License 2.0
100 stars 37 forks source link

Jar includes classes already provided by Keycloak #41

Closed hpedrorodrigues closed 2 months ago

hpedrorodrigues commented 3 months ago

Hey 👋🏻

First of all, thanks for working on this project! 🚀

Problem Description

The jar for the latest version (1.1.5 as of the writing of this issue) includes some classes that are already provided by Keycloak (e.g., slf4j classes). This is not a problem if users don't use other providers that don't need these same classes.

The main problem is when users want to use this provider along with other custom providers (e.g., SCIM) that need to use these same classes. For instance, the SCIM provider doesn't include any slf4j dependencies (because they are already provided by Keycloak) but it uses their classes. During the build phase, when a provider needs to use any of these classes, it may find the classes that are included in this provider (instead of the ones provided by Keycloak), which will make Keycloak to complain due to different class loaders having different versions of the same classes.

e.g.,

Caused by: java.lang.LinkageError: loader constraint violation: when resolving method 'org.slf4j.ILoggerFactory org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()' the class loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @2e16b08d of the current class, org/slf4j/LoggerFactory, and the class loader java.net.URLClassLoader @42463763 for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature (org.slf4j.LoggerFactory is in unnamed module of loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @2e16b08d, parent loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @67427b69; org.slf4j.impl.StaticLoggerBinder is in unnamed module of loader java.net.URLClassLoader @42463763, parent loader 'app')

References

This is also mentioned in the documentation: Server Developer Guide.

Provider JARs are not loaded in isolated classloaders, so do not include resources or classes in your provider JARs that conflict with built-in resources or classes. In particular the inclusion of an application.properties file or overriding the commons-lang3 dependency will cause auto-build to fail if the provider JAR is removed. If you have included conflicting classes, you may see a split package warning in the start log for the server. Unfortunately not all built-in lib jars are checked by the split package warning logic, so you’ll need to check the lib directory JARs before bundling or including a transitive dependency. Should there be a conflict, that can be resolved by removing or repackaging the offending classes.

SLF4J

This project doesn't use SLF4J directly, but since kafka-clients include this dependency, it ends up in the final jar.

dependency tree ``` ♪ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] -------------< com.github.snuk87.keycloak:keycloak-kafka >-------------- [INFO] Building keycloak-kafka 1.1.5 [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- dependency:3.7.0:tree (default-cli) @ keycloak-kafka --- [INFO] com.github.snuk87.keycloak:keycloak-kafka:jar:1.1.5 [INFO] +- org.keycloak:keycloak-core:jar:21.1.1:provided [INFO] | +- org.keycloak:keycloak-common:jar:21.1.1:provided [INFO] | | \- com.sun.activation:jakarta.activation:jar:1.2.2:provided [INFO] | +- com.fasterxml.jackson.core:jackson-core:jar:2.13.4:provided [INFO] | \- com.fasterxml.jackson.core:jackson-databind:jar:2.13.4.2:provided [INFO] | \- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.4:provided [INFO] +- org.keycloak:keycloak-server-spi:jar:21.1.1:provided [INFO] +- org.keycloak:keycloak-server-spi-private:jar:21.1.1:provided [INFO] | \- org.apache.httpcomponents:httpclient:jar:4.5.13:provided [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.13:provided [INFO] | +- commons-logging:commons-logging:jar:1.2:provided [INFO] | \- commons-codec:commons-codec:jar:1.11:provided [INFO] +- org.jboss.logging:jboss-logging:jar:3.5.0.Final:compile [INFO] +- org.apache.kafka:kafka-clients:jar:3.4.0:compile [INFO] | +- com.github.luben:zstd-jni:jar:1.5.2-1:runtime [INFO] | +- org.lz4:lz4-java:jar:1.8.0:runtime [INFO] | +- org.xerial.snappy:snappy-java:jar:1.1.8.4:runtime [INFO] | \- org.slf4j:slf4j-api:jar:1.7.36:runtime <-------------- [INFO] \- org.junit.jupiter:junit-jupiter-api:jar:5.9.2:test [INFO] +- org.opentest4j:opentest4j:jar:1.2.0:test [INFO] +- org.junit.platform:junit-platform-commons:jar:1.9.2:test [INFO] \- org.apiguardian:apiguardian-api:jar:1.1.2:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.360 s [INFO] Finished at: 2024-08-05T16:47:27-03:00 [INFO] ------------------------------------------------------------------------ ```

Possible Solution

If we remove this dependency from the final artifact using an exclusion rule it should solve this issue.


Not sure if I'm missing something here. So, please let me know.