Giter VIP home page Giter VIP logo

Comments (4)

montanajava avatar montanajava commented on May 29, 2024 1

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.

Hakky54 avatar Hakky54 commented on May 29, 2024

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;

I have an example here: https://github.com/Hakky54/java-tutorials/blob/522a10f15965cc7bd6e8292169ad2e67be26cbd6/log-captor-examples/log-captor-with-quarkus-jboss-lombok/src/test/java/nl/altindag/quarkus/resource/GreetingsResourceWithoutQuarkusTestShould.java#L22

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.

Hakky54 avatar Hakky54 commented on May 29, 2024

@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.

Hakky54 avatar Hakky54 commented on May 29, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.