SLF4J / SLF4J-573 [Open] SLF4J 2.0 searches for providers in the wrong classloader
============================== Here's what changed in this issue in the last few minutes. This issue has been created This issue is now assigned to you. View or comment on issue using this link https://jira.qos.ch/browse/SLF4J-573 ============================== Issue created ------------------------------ Chris Rankin created this issue on 18/Nov/22 1:18 AM Summary: SLF4J 2.0 searches for providers in the wrong classloader Issue Type: Bug Affects Versions: 2.0.3 Assignee: SLF4J developers list Components: Core API Created: 18/Nov/22 1:18 AM Environment: Java 11, Java 17 Labels: SLF4J Priority: Major Reporter: Chris Rankin Description: I have tried to upgrade my tests from SLF4J 1.7.36 to SLF4J 2.0.3, but they are failing with this error: {{java.util.ServiceConfigurationError: org.slf4j.spi.SLF4JServiceProvider: org.slf4j.simple.SimpleServiceProvider not a subtype at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:589) at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1237) at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1265) at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1300) at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1385) at org.slf4j.LoggerFactory.findServiceProviders(LoggerFactory.java:104) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:147) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:139) at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:422) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:408) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383) }} My test has added slf4j-api, slf4j-simple and a jar containing a Callable into a single classloader that has a null parent classloader, and is then executing the task isolated from the application classloader. But unfortunately for me, LoggerFactory.findServiceProviders() is implemented like this: {color:#0033b3}private static {color}{color:#000000}List{color}<{color:#000000}SLF4JServiceProvider{color}> {color:#00627a}findServiceProviders{color}() { {color:#000000}ServiceLoader{color}<{color:#000000}SLF4JServiceProvider{color}> {color:#000000}serviceLoader {color}= {color:#000000}ServiceLoader{color}.load({color:#000000}SLF4JServiceProvider{color}.{color:#0033b3}class{color}); {color:#000000}List{color}<{color:#000000}SLF4JServiceProvider{color}> {color:#000000}providerList {color}= {color:#0033b3}new {color}ArrayList<>(); {color:#0033b3}for {color}({color:#000000}SLF4JServiceProvider provider {color}: {color:#000000}serviceLoader{color}) { {color:#000000}providerList{color}.add({color:#000000}provider{color}); } {color:#0033b3}return {color}{color:#000000}providerList{color}; } Specifically, ServiceLoader.load() does not specify which classloader to use, and so defaults to the ThreadContextClassLoader. I believe a more compatible (with earlier versions of SLF4J) choice would be: {color:#000000}ServiceLoader{color}.load({color:#000000}SLF4JServiceProvider{color}.{color:#0033b3}class, LoggerFactory.class.getClassLoader(){color}) ============================== This message was sent by Atlassian Jira (v8.8.0#808000-sha1:e2c7e59) _______________________________________________ slf4j-dev mailing list slf4j-dev@qos.ch https://mailman.qos.ch/cgi-bin/mailman/listinfo/slf4j-dev