Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resilience4j dependency pulls in a transitive slf4j which is too old #499

Open
berndruecker opened this issue Oct 25, 2023 · 8 comments
Open
Assignees
Labels

Comments

@berndruecker
Copy link
Contributor

Running a plain worker (like https://github.com/camunda/camunda-platform-tutorials/tree/main/orchestrate-microservices/worker-java) on spring-zeebe 8.2.x or 8.3.0 will result in the following exception:

[WARNING]
java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.helpers.NOPLoggerFactory loaded from file:/C:/Users/ruecker/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.helpers.NOPLoggerFactory
    at org.springframework.util.Assert.instanceCheckFailed (Assert.java:713)
    at org.springframework.util.Assert.isInstanceOf (Assert.java:632)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext (LogbackLoggingSystem.java:389)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize (LogbackLoggingSystem.java:123)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent (LoggingApplicationListener.java:238)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent (LoggingApplicationListener.java:220)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener (SimpleApplicationEventMulticaster.java:174)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener (SimpleApplicationEventMulticaster.java:167)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent (SimpleApplicationEventMulticaster.java:145)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent (SimpleApplicationEventMulticaster.java:133)
    at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent (EventPublishingRunListener.java:136)
    at org.springframework.boot.context.event.EventPublishingRunListener.starting (EventPublishingRunListener.java:75)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0 (SpringApplicationRunListeners.java:54)
    at java.lang.Iterable.forEach (Iterable.java:75)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners (SpringApplicationRunListeners.java:118)
    at org.springframework.boot.SpringApplicationRunListeners.starting (SpringApplicationRunListeners.java:54)
    at org.springframework.boot.SpringApplication.run (SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run (SpringApplication.java:1309)
    at org.springframework.boot.SpringApplication.run (SpringApplication.java:1298)
    at io.camunda.getstarted.tutorial.Worker.main (Worker.java:16)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:833)

This is because in this plain worker, no Maven BOM is used to set versions, an thus resilience4j brings in a slf4j in an too old version (1.7.3 instead of 2.0.x):

[INFO]    \- io.github.resilience4j:resilience4j-retry:jar:2.1.0:compile
[INFO]       +- io.github.resilience4j:resilience4j-core:jar:2.1.0:compile
[INFO]       \- org.slf4j:slf4j-api:jar:1.7.30:compile

When manually overwriting this version to 2.0.9 or use a Spring BOM in the worker, the problem goes away:

	<dependencies>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>2.0.9</version>
		</dependency>
		<dependency>
			<groupId>io.camunda</groupId>
			<artifactId>spring-zeebe-starter</artifactId>
			<version>8.3.0</version>
		</dependency>
	</dependencies>

But I think we should actually let users don't experience this obstacle themselves and thus solve it within Spring Zeebe itself.

@berndruecker
Copy link
Contributor Author

Which is interesting, because I thought this should solve those kind of problems already:
https://github.com/camunda-community-hub/spring-zeebe/blob/main/pom.xml#L60 🤔

@berndruecker
Copy link
Contributor Author

Labeled it as bug as we either have to fix it or update the get started tutorial - as it does not run out of the box right now

@berndruecker
Copy link
Contributor Author

I think we should add a dependency to that slf4j-api within the spring-boot-starter project, this way the version is pulled from the dependencyManagement and written to the resulting pom. I will create a PR for it.

I also thought about looking into the Maven Flatten Plugin (https://stackoverflow.com/questions/75510285/dependencymanagement-unfortunately-not-transitive, https://blog.frankel.ch/maven-flatten-plugin/) but restrained from touching too much for now :-)

@jonathanlukas
Copy link
Contributor

There is a way to enforce dependency convergence by using the maven enforcer plugin. This will help cleaning up issues like this.

@1nb0und
Copy link
Contributor

1nb0und commented Oct 25, 2023

Nice catch, I wasn't encountering this before due to the fact I always include the Spring BOM. I think your approach of adding an explicit dependency looks fine.

I prefer to have that fixed now so prospects will not encounter that issue.

@jonathanlukas Thats interesting will take look at that approach when I get some capacity.

@jonathanlukas
Copy link
Contributor

I would prefer excluding the dependency instead of managing it in our artefact.

@1nb0und
Copy link
Contributor

1nb0und commented Oct 25, 2023

Added slf4j dependency to enforce correct version on transitive depen…

Could you provide an example on how we can exclude the dependency? From a first thought, we could do that, but then the customer will then be responsible (which I think is an extra work and might be a showstopper for first-time users) for putting the right version in their implementation either by hardcoding a version number, or relying on another dependency that will supersede the old sl4j in our resilience4j

@berndruecker
Copy link
Contributor Author

You can't exclude slf4j-api as it is used by resilience4j - we just have to make sure the version compatible with the current Spring Boot setup is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants