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

Log4j writes certain errors to System.out instead of System.err #1484

Closed
hblohm opened this issue May 23, 2023 · 7 comments
Closed

Log4j writes certain errors to System.out instead of System.err #1484

hblohm opened this issue May 23, 2023 · 7 comments
Assignees
Labels
bug Incorrect, unexpected, or unintended behavior of existing code
Milestone

Comments

@hblohm
Copy link

hblohm commented May 23, 2023

When using log4j (tried 2.17.0 and 2.20.0) it initializes StackLocator that writes a warning to System.out when not finding sun.reflect.Reflection.getCallerClass - which is true for Java versions >= 9 I believe.

This pretty much invalidates the use of log4j in a java command line that produces binary output that gets stream for further processing. While text output could possibly be suitably filtered, for binary output that is really unusable.

It would be great, if that output could be dropped or at least sent to System.err (like regular log output).

Any workaround would be greatly appreciated!

Thanks,
Henning

@ppkarwasz
Copy link
Contributor

@hblohm,

The particular warning you are having is most probably due to an incorrect repackaging of Log4j libraries. The Log4j API is a multi-release library, which contains both a version for Java 8 and Java 9+. If you are using Maven Shade plugin use a configuration like in this answer.

Regarding you general remark I agree: we shouldn't ever log errors to System.out, but use LowLevelLogUtil or StatusLogger, whichever is available.

@ppkarwasz ppkarwasz changed the title Please remove or change sun.reflect.Reflection.getCallerClass warning to make sure it does not write to System.out Log4j writes certain error to System.out May 23, 2023
@ppkarwasz ppkarwasz added the bug Incorrect, unexpected, or unintended behavior of existing code label May 23, 2023
@ppkarwasz ppkarwasz changed the title Log4j writes certain error to System.out Log4j writes certain errors to System.out instead of System.err May 23, 2023
@hblohm
Copy link
Author

hblohm commented May 24, 2023

@ppkarwasz

Thank you for that swift reply! With respect to Log4J, my setup includes dependencies

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!-- Log4j 1.x bridge API -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>

and the only log4j libraries I see in use are log4j-1.2-api-2.20.0.jar, log4j-api-2.20.0.jar, and log4j-core-2.20.0.jar. StackLocator can be found in log4j-api-2.20.0.jar. So I guess I cannot really do without it.

I will look for some workaround via writing to intermediate local files - so that this is not a blocker for me.

@ppkarwasz
Copy link
Contributor

@hblohm,

The "workaround" is to prevent the "WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance." from appearing at all.

As I mentioned earlier this is a problem due to the multi-release nature of log4j-api. This usually appears if:

  • either you deploy your application as a so-call fat-jar (or uber-jar): you copy the contents of all dependency jars into a single jar. If this is the case, look at the Maven configuration I proposed here, which solves two other problems related to fat-jars,
  • or you use a classloader that does not support multi-release jars. The classloaders in JRE 9+ all support multi-release, but e.g. Tomcat's classloader didn't support it until version 8.5.24 (late 2017). Other projects implemented multi-release support around that same time.

@hblohm
Copy link
Author

hblohm commented May 24, 2023

Thank you. Now I get it. Yes, could be the classloader.

@FeldrinH
Copy link

FeldrinH commented Jun 16, 2023

I wanted to point out that this is particularly problematic if stdout is used for structured communication with an external system. I spent several hours trying to figure out why a change to some logging statements silently breaks a VS Code extension that communicates over stdout using JSON-RPC and this warning turned out to be the cause.

EDIT: In my case this was especially hard to discover since the the communication with VS Code over stdout is not logged anywhere, so running the extension in VS Code the communication would just stop working with no relevant errors logged anywhere at all.

@FeldrinH
Copy link

It would be nice if these warnings could be printed to System.err instead so future developers that happen to encounter this issue don't waste time like I did.

@ppkarwasz ppkarwasz added this to the 2.20.1 milestone Aug 28, 2023
@vy vy self-assigned this Oct 5, 2023
@vy
Copy link
Member

vy commented Oct 5, 2023

@hblohm, thanks so much for the report, much appreciated! 🙇 Landed a fix replacing System.out with System.err.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect, unexpected, or unintended behavior of existing code
Projects
None yet
Development

No branches or pull requests

4 participants