robaho / httpserver

a lightweight zero dependency JDK http server implementation designed for embedding and optimized for virtual threads
Other
16 stars 3 forks source link

NullPointerException when Log4J is loaded #2

Closed taranion closed 3 months ago

taranion commented 3 months ago

When I start my server and the System.Logger LOG4J bridge (org.apache.logging.log4j:log4j-jpl:2.22.1) is loaded, I get the following NPE:

java.lang.NullPointerException: Cannot invoke "java.util.logging.Logger.setFilter(java.util.logging.Filter)" because the return value of "java.util.logging.LogManager.getLogger(String)" is null
    at robaho.net.httpserver.ServerImpl.<init>(ServerImpl.java:134)
    at robaho.net.httpserver.HttpServerImpl.<init>(HttpServerImpl.java:43)
    at robaho.net.httpserver.DefaultHttpServerProvider.createHttpServer(DefaultHttpServerProvider.java:35)
    at jdk.httpserver/com.sun.net.httpserver.HttpServer.create(HttpServer.java:152)
    at org.prelle.mud.websocket.WebsocketConnector.start(WebsocketConnector.java:125)

When I remove all traces of the logging provider, it works.

The problem seems to be that LogManager.getLogger returns a null pointer because the Logger isn't known yet. It might be better to use Logger.getLogger instead, because that method creates a named Logger if it does not exist yet.

robaho commented 3 months ago

It seems that the log4j provider is not mapping the system Logger instances to the utility logger instances - which is normally the case.

See this https://www.reddit.com/r/java/comments/14sco4r/slf4j_or_systemlogger/ - are you certain you are loading this correctly so the System logger is mapped properly?

taranion commented 3 months ago

I am not sure what you mean by "loading correctly"? I do have a Log4J configuration to filter what log level I see - that configuration is used and I can see that this is picked up for the System.Logger facade. I have no specific JUL configuration in use.

My Log4J2 config is

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%5p [%15c] (%F:%L) - %m%n" />
    </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console" />
        </Root>
        <Logger name="sun" level="ERROR"/>
        <Logger name="com.sun" level="INFO"/>
        <Logger name="xml" level="WARN"/>
        <Logger name="jdk" level="warn"/>
        <Logger name="java" level="INFO"/>
        <Logger name="javafx" level="INFO"/>
        <Logger name="telnet" level="WARN"/>
        <Logger name="org.prelle.ansi" level="INFO"/>
        <Logger name="de.rpgframework" level="INFO"/>
        <Logger name="org.prelle.splittermond" level="WARN"/>
    </Loggers>
</Configuration>

But my point is: The LogManager method you are using - by API definition - may return NULL and your code is not prepared for the case. Even if it may be possible to make a configuration that would prevent a null pointer being returned, a missing logging configuration should not lead to libraries not working.

robaho commented 3 months ago

Your provided code changes were correct. Thank you for the PR. This is fixed in 1.0.8.