Comments (4)
Thanks much @Hakky54 for your detailed response. In my case, I really do need to use @QuarkusTest so the approach outlined (and interestingly, I had tried every step you outlined before I wrote) will not work in my case. I resolved it by using an appender that Quarkus internal testing library provided which allowed me to query the logs. All that said, your explanation made clear to me how the bootloading issues affected my use case. I will stay aware of your projects and will be sure to use them once I have a use case. Thanks again much for your assistance. Your explanation was golden. From my perspective you can regard this issue as addressed and close the issue.
from log-captor.
Thank you mate, I appreciate your kind words ❤️
Quarkus is a tricky project to use with LogCaptor, so I don't recommend to use it actually. An alternative for capturing logs while using Quarkus would be ConsoleCaptor which I also made.
Let me try to explain what the issue is. So you are getting initially the following error:
SLF4J: Found provider [org.slf4j.impl.JBossSlf4jServiceProvider@10959ece]
SLF4J: Found provider [ch.qos.logback.classic.spi.LogbackServiceProvider@3a6bb9bf]
Which is quite common as most projects provide also the SLF4J provider alongside their library or tool, which is not a big deal actually however LogCaptor is also bundling a SLF4J provider which is Logback. SLF4J warns the end-user when there are multiple providers on the classpath. LogCaptor will fail to capture when there are multiple SLF4J provider. So the trick is to have only one SLF4J provider during the test phase. This can be accomplished in different ways, in your use case with a maven project it would be by adding a small configuration to the surefire and failsafe plugin. So basically we need to tell to maven to exclude JBossSlf4jServiceProvider
only during the tests and in that way during the test there will be only one provider which LogCaptor can use which should be Logback
. The JBossSlf4jServiceProvider is located in org.jboss.slf4j:slf4j-jboss-logmanager
jar file, so we need to exclude it in the test plugins like the snippet below:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.jboss.slf4j:slf4j-jboss-logmanager</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExclude>org.jboss.slf4j:slf4j-jboss-logmanager</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
</plugins>
</build>
If you have configured the plugins like above you will end up with a new error:
java.lang.IllegalArgumentException: Multiple classloaders are being used. The Logging API is created by the following classloader: [jdk.internal.loader.ClassLoaders$AppClassLoader], while it should have been created by the following classloader: [io.quarkus.bootstrap.classloading.QuarkusClassLoader].
at nl.altindag.log.util.ValidationUtils.requireLoggerOfType(ValidationUtils.java:40)
at nl.altindag.log.LogCaptor.<init>(LogCaptor.java:59)
at nl.altindag.log.LogCaptor.forClass(LogCaptor.java:86)
at nl.altindag.hakky54.GreetingResourceTest.testHelloEndpoint(GreetingResourceTest.java:15)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:1013)
at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:827)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
This error is being caused by @QuarkusTest
and @QuarkusIntegrationTest
. The test suite of quarkus is executed in a custom classloader which will result in mixing up classloaders. So lets assume we have greetingsservice which logs. The logger within the greetingsservice will be created using the jdk classloader. LogCaptor is initialized during the tests which is created by the custom classloader of Quarkus. I attempted to create a solution in the past but could not find a way to read correctly objects from different classloaders so LogCaptor will throw an error. I also mentioned something similar on the main page at the known issues section where I also provided an alternative: https://github.com/Hakky54/log-captor?tab=readme-ov-file#mixing-up-different-classloaders
So, does the story end here? Well actually not, it is up to you. If you still prefer to use LogCaptor I can share you the good news that it is possible and I will appreciate your eagerness if you are planning to try it out. What you need to do is still have the surefire and failsafe plugin configuration and when you want to test the logs you should not use @QuarkusTest
and @QuarkusIntegrationTest
. Just use junit/jupiter to run your other tests. So all of your tests can be @QuarkusTest
and @QuarkusIntegrationTest
however where you want to test your logs, just use @Test
from Jupiter. If you add the following import statement it should compile:
import org.junit.jupiter.api.Test;
It was tricky to provide all examples in the test package of this repository, so I created a new repository which contains different code examples for testing logs and other stuff which I found usefull to share, please see here for all of the examples: GitHub hakky54/java-tutorials. It also contaisn examples of LogCaptor with Quarkus and ConsoleCaptor with Quarkus.
I hope this make sense.
from log-captor.
@montanajava was it a bit useful, are you now able to assert your log statements? Just curious which solution you have applied. Or do you need some help?
from log-captor.
@montanajava it seems like you are not the only one having this challenge. It is now raised by someone on the quarkus GitHub page, see here for more: quarkusio/quarkus#38202
from log-captor.
Related Issues (20)
- ConcurrentModificationException in getLogs() HOT 7
- Logcaptor error logs do not contain expected content when reusing instance HOT 7
- log4j HOT 1
- Running the unit test directly from IDEA gives error HOT 7
- Not working with org.jacoco:jacoco-maven-plugin HOT 6
- There appears to be a classloading problem when using LogCaptor with `@QuarkusTest` test classes HOT 2
- LogEvent should implement toString() HOT 4
- Not compatible with log4j2 2.17.2 HOT 5
- Allow to retrieve logs for custom log levels HOT 2
- consoleCaptor.getStandardOutput() doesn't work HOT 6
- Does this project target Log4J API 1.7? HOT 9
- spring-boot-starter + log-captor: log4j-slf4j-impl cannot be present with log4j-to-slf4j HOT 5
- Upgrade to 2.8.0 HOT 18
- Suppressing Console Output HOT 3
- Are we supposed to close LogCaptor at the end of a test? HOT 3
- Issue with custom levels HOT 3
- Seeing DEBUG level logs after adding logcaptor dependency HOT 2
- disableConsoleOutput() is throwing NPE HOT 3
- ava.lang.NoClassDefFoundError: org/slf4j/spi/LoggingEventAware HOT 13
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from log-captor.