Redirect logging from a library using commons-logging #669
Replies: 4 comments
-
Don't do exclude meta data...you are losing services. Slf4j 2 uses the services loader and you've excluded it from logback. You also do not need to exclude module info, that will happen automatically if not using java 9+.
So remove this entirely
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
Drop logback to 1.3.6, you are not using JakartaEE, rather JavaEE still. That may not matter for your logging purposes but it's the wrong one. Both are active.
And its not a good idea to even using shading any more these days. Just wrap with spring boot (doesn't mean you have to be spring), must better solution and the meta data in jars is not corrupted. Further, if you do that, you won't need jcl-over-slf4j as spring has spring-jcl that does a much better job along with spring boot to ensure logging routing.
Other hints, bouncy cast, switch to jdk18on and use 1.73. the 15on is obsolete (ie java 5+). The other is java 8+.
Hope that helps.
From: michal ***@***.***>
Sent: Monday, May 29, 2023 3:49 PM
To: qos-ch/logback ***@***.***>
Cc: Subscribed ***@***.***>
Subject: [qos-ch/logback] Redirect logging from a library using commons-logging (Discussion #669)
Hi guys,
I have a problem I've struggling with for some quite time now.
tl;dr: I'd like to filter out some unneeded logs (and leave other) from pdfbox library. This library uses commons-logging facade.
Longer version
I'd like to filter out some unneeded logs (and leave other) from pdfbox library. It has in its own dependencies commons-logging, which is (as I understand it) a facade similar to slf4j. I also have another dependency (picocli), which also has dependency to commons-logging albeit with a newer version. There is a project called jcl-over-slf4j which redirects logs coming from commons-logging to slf4j facade. I decided to use it together with logback-classic. I also wrote a custom filter to filter out logs I don't need. Everything works fine when I run junit test (from IntelliJ and using CLI - by running mvn clean package). But running the final (fat) jar including my own code and all the dependencies results in a message printed out to console saying that I don't have any supported logger on classpath:
SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
Why is that? It seems that everything works fine during test execution and fails to work when using fat jar.
I will describenow the fat jar issue and how I run my application. To create fat jar I use the maven shade plugin together with the configuration seen below. I create fat jar by executing mvn clean package and run the application by java -jar myapp.jar.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.github.menteith.pdfexample.Main</mainClass>
<manifestEntries>
<Built-By />
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Here's my custom Logback filter:
[class LogbackTurboFilter
extends TurboFilter {
@OverRide<https://github.com/OverRide>
public FilterReply decide(final Marker marker, final Logger logger, final Level level,
final String format, final Object[] params, final Throwable t) {
System.out.println("In decide!!!"); // this is printed during tests, but not when final jar is run
if ( !isStarted() ) {
return FilterReply.NEUTRAL;
}
if ( level == Level.WARN
&& logger.getName().startsWith("org.apache.pdfbox") ) {
return FilterReply.DENY;
} else {
return FilterReply.NEUTRAL;
}
}
}](url)
Here's my logback.xml:
%-4relative [%thread] %-5level %logger - %msg%n
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
Relevant parts of pom.xml: pdfbox org.apache.pdfbox 2.0.27 commons-logging commons-logging info.picocli picocli 4.7.1 org.slf4j jcl-over-slf4j 2.0.6 ch.qos.logback logback-classic 1.4.5 And dependency tree from maven:
+- org.apache.pdfbox:pdfbox:jar:2.0.27:compile
| \- org.apache.pdfbox:fontbox:jar:2.0.27:compile
+- info.picocli:picocli:jar:4.7.1:compile
+- org.slf4j:jcl-over-slf4j:jar:2.0.6:compile
| \- org.slf4j:slf4j-api:jar:2.0.6:compile
+- ch.qos.logback:logback-classic:jar:1.4.5:compile
| \- ch.qos.logback:logback-core:jar:1.4.5:compile
+- org.bouncycastle:bcprov-jdk15on:jar:1.70:compile
+- org.bouncycastle:bcmail-jdk15on:jar:1.70:compile
| +- org.bouncycastle:bcutil-jdk15on:jar:1.70:compile
| \- org.bouncycastle:bcpkix-jdk15on:jar:1.70:compile
+- com.github.jai-imageio:jai-imageio-jpeg2000:jar:1.4.0:compile
| \- com.github.jai-imageio:jai-imageio-core:jar:1.4.0:compile
+- org.projectlombok:lombok:jar:1.18.24:provided
+- org.junit.jupiter:junit-jupiter-engine:jar:5.9.2:test
| +- org.junit.platform:junit-platform-engine:jar:1.9.2:test
| | +- org.opentest4j:opentest4j:jar:1.2.0:test
| | \- org.junit.platform:junit-platform-commons:jar:1.9.2:test
| +- org.junit.jupiter:junit-jupiter-api:jar:5.9.2:test
| \- org.apiguardian:apiguardian-api:jar:1.1.2:test
\- org.assertj:assertj-core:jar:3.24.0:test
\- net.bytebuddy:byte-buddy:jar:1.12.20:test
-
Reply to this email directly, view it on GitHub<#669>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAHODIYVCUWM5EWCLIMWUZDXIT4RVANCNFSM6AAAAAAYTDVI3Q>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.******@***.***>>
|
Beta Was this translation helpful? Give feedback.
-
Thanks for this. I don't use Spring. I wrote a small Swing application. When something is logged, it shows a window with a log. If I remove
When I try to run my application, I get
|
Beta Was this translation helpful? Give feedback.
-
The error you are having has to do with bouncy castle. Its bad trying to shade bouncy castle. The JARs are signed. At least JCE is. If you want to filter those out it's the manifest.mf of bouncy castle not all the other stuff and specifically the jce jar.
The other warnings are entirely valid. And it should be clear at least using shading is bad in general.
The point with wrapping with spring boot is that you don't have to make your app spring at all (meaning nothing in it needs to even reference spring). Just wrap it (pom) and use the spring boot plugin to build the jar solution. Then you don't have to touch anything else, won't get warnings and it will simply work. Works fine with swing. This also sounds very similar to a solution we did at my day job few months back and in fact wrapped spring boot for same reason as team was facing considerable issues around messing with bouncy castle this way. Give that a try. If still facing issues, I can look to see what else we did via magic. Now if you wrap with spring boot, drop slf4j to 1.7.36 and logback to 1.2.12 for best compatibility or face other hoops. At the moment cannot think of anything else that should jump out.
IMO - spring boot offers this side benefit that is so great that both shading / assembly to achieve the same is obsolete as a result.
For your proposes if you want to continue as is and not flip to spring boot, only filter the JCE manifest.mf jar. (ie META-inf/MANIFEST.MF of the bcprov jar as well as exclude the .DSA and .SF items there too). That should resolve the issue you are otherwise facing with signature.
From: michal ***@***.***>
Sent: Monday, May 29, 2023 4:10 PM
To: qos-ch/logback ***@***.***>
Cc: Jeremy Landis ***@***.***>; Comment ***@***.***>
Subject: Re: [qos-ch/logback] Redirect logging from a library using commons-logging (Discussion #669)
Thanks for this. I don't use Spring. I wrote a small Swing application. When something is logged, it shows a window with a log.
If I remove <filters> section, then I get:
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.
[WARNING] jai-imageio-core-1.4.0.jar, jai-imageio-jpeg2000-1.4.0.jar define 2 overlapping resources:
[WARNING] - META-INF/services/javax.imageio.spi.ImageReaderSpi
[WARNING] - META-INF/services/javax.imageio.spi.ImageWriterSpi<%5Burl%5D(url)>
When I try to run my application, I get
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
at java.base/sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:340)
-
Reply to this email directly, view it on GitHub<#669 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAHODI7MWSBFOC4XV5ADX23XIT7DFANCNFSM6AAAAAAYTDVI3Q>.
You are receiving this because you commented.Message ID: ***@***.******@***.***>>
|
Beta Was this translation helpful? Give feedback.
-
Thanks for this! It helped. Thanks one more time! |
Beta Was this translation helpful? Give feedback.
-
Hi guys,
I have a problem I've struggling with for some quite time now.
tl;dr: I'd like to filter out some unneeded logs (and leave other) from pdfbox library. This library uses commons-logging facade.
Longer version
I'd like to filter out some unneeded logs (and leave other) from pdfbox library. It has in its own dependencies commons-logging, which is (as I understand it) a facade similar to slf4j. I also have another dependency (picocli), which also has dependency to commons-logging albeit with a newer version. There is a project called jcl-over-slf4j which redirects logs coming from commons-logging to slf4j facade. I decided to use it together with logback-classic. I also wrote a custom filter to filter out logs I don't need. Everything works fine when I run junit test (from IntelliJ and using CLI - by running mvn clean package). But running the final (fat) jar including my own code and all the dependencies results in a message printed out to console saying that I don't have any supported logger on classpath:
I will describenow the fat jar issue and how I run my application. To create fat jar I use the maven shade plugin together with the configuration seen below. I create fat jar by executing mvn clean package and run the application by java -jar myapp.jar.
Here's my custom Logback filter:
Here's my logback.xml:
Relevant parts of pom.xml:
And dependency tree from maven:
Beta Was this translation helpful? Give feedback.
All reactions