users@glassfish.java.net

[gf-users] Re: Logger throws NPE

From: Steven Siebert <smsiebe_at_gmail.com>
Date: Thu, 23 Oct 2014 21:16:58 -0400

Andy,

I have replicated what you're seeing in GF 4.1...and I agree with you that
you should not be getting a NPE thrown in this manner and, IMO, it should
be considered a bug...and fixing it in
com.sun.common.util.logging.LoggingOutputStream$LoggingPrintStream.println
would be a solid move.

Although I agree with you, I came to this conclusion a little differently
-- I do think that it's prudent to check for nulls before you attempt to
use them. For example, I can't be sure from your snippit, but I believe
your variable bodyPart is an insance of
org.glassfish.jersey.media.multipart.BodyPart, give the signature of your
method call. If true, you call bodyPart.getContentDisposition() itself can
return null [1], causing your call to getModificationDate() (even in your
condition check) to throw a NPE.

The reason I agree with you that this is a bug, however, is the way you
attempting to log. While you don't have a contract with
LoggingPrintStream, the GF developers has decided to route System.out to an
instance of this class. The developer (you) has, though, made a contract
with PrintStream (System.out) which states " This method calls at first
String.valueOf(x) to get the printed object's string value". If you
further read in String.valueOf(Object), you see "if the argument is null,
then a string equal to "null"". Thus you should NOT be getting a NPE.

I think this smells like a legitimate bug. I can file a bug report for you
if you would like, as I've already created a minimal reproducible package
in testing....just let me know. If you do file, let me know the issue #
please, and I can submit a patch for it.

[1]
https://jersey.java.net/apidocs/2.8/jersey/org/glassfish/jersey/media/multipart/BodyPart.html#getContentDisposition%28%29

Regards,

S



On Thu, Oct 23, 2014 at 7:16 PM, Andreas Junius <andreas.junius_at_gmail.com>
wrote:

> Hi GF fans,
>
> I'm developing a REST endpoint that accepts file uploads and I used a
> bunch of System.out statements to see what I can get from certain objects.
> If any method returns null, GF throws a NPE. That NPE gets thrown by the
> logging mechanism and I think that is a bug; there should be a null check
> within the logging framework, shouldn't it? Otherwise it'd be a bit
> confusing and it adds overhead, because the coder has to add NP checks
> around their test output:
>
> if (bodyPart.getContentDisposition().getModificationDate() != null) {
> System.out.println(bodyPart.getContentDisposition().
> getModificationDate());
> }
>
> That's the exception:
> 2014-10-24T09:31:04.445+1030|Severe: java.lang.NullPointerException
> at com.sun.common.util.logging.LoggingOutputStream$
> LoggingPrintStream.println(LoggingOutputStream.java:230)
> at org.apache.felix.gogo.runtime.threadio.ThreadPrintStream.
> println(ThreadPrintStream.java:205)
> at info.junius.apps.yakka.server.FileUpload.post(FileUpload.
> java:64)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(
> NativeMethodAccessorImpl.java:62)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:483)
> at org.glassfish.jersey.server.model.internal.
> ResourceMethodInvocationHandlerFactory$1.invoke(
> ResourceMethodInvocationHandlerFactory.java:81)
> at org.glassfish.jersey.server.model.internal.
> AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDisp
> atcher.java:125)
> at org.glassfish.jersey.server.model.internal.
> JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(
> JavaResourceMethodDispatcherProvider.java:195)
> at org.glassfish.jersey.server.model.internal.
> AbstractJavaResourceMethodDispatcher.dispatch(
> AbstractJavaResourceMethodDispatcher.java:91)
> at org.glassfish.jersey.server.model.ResourceMethodInvoker.
> invoke(ResourceMethodInvoker.java:346)
> at org.glassfish.jersey.server.model.ResourceMethodInvoker.
> apply(ResourceMethodInvoker.java:341)
> at org.glassfish.jersey.server.model.ResourceMethodInvoker.
> apply(ResourceMethodInvoker.java:101)
> at org.glassfish.jersey.server.ServerRuntime$1.run(
> ServerRuntime.java:224)
> at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
> at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
> at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
> at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
> at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
> at org.glassfish.jersey.process.internal.RequestScope.
> runInScope(RequestScope.java:317)
> at org.glassfish.jersey.server.ServerRuntime.process(
> ServerRuntime.java:198)
> at org.glassfish.jersey.server.ApplicationHandler.handle(
> ApplicationHandler.java:946)
> at org.glassfish.jersey.servlet.WebComponent.service(
> WebComponent.java:323)
> at org.glassfish.jersey.servlet.ServletContainer.service(
> ServletContainer.java:372)
> at org.glassfish.jersey.servlet.ServletContainer.service(
> ServletContainer.java:335)
> at org.glassfish.jersey.servlet.ServletContainer.service(
> ServletContainer.java:218)
> at org.apache.catalina.core.StandardWrapper.service(
> StandardWrapper.java:1682)
> at org.apache.catalina.core.ApplicationFilterChain.
> internalDoFilter(ApplicationFilterChain.java:344)
> at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:214)
> at info.junius.apps.yakka.server.CryptographyFilter.doFilter(
> CryptographyFilter.java:135)
> at org.apache.catalina.core.ApplicationFilterChain.
> internalDoFilter(ApplicationFilterChain.java:256)
> at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:214)
> at info.junius.apps.yakka.server.HeaderFilter.doFilter(
> HeaderFilter.java:50)
> at org.apache.catalina.core.ApplicationFilterChain.
> internalDoFilter(ApplicationFilterChain.java:256)
> at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:214)
> at org.apache.catalina.core.StandardWrapperValve.invoke(
> StandardWrapperValve.java:316)
> at org.apache.catalina.core.StandardContextValve.invoke(
> StandardContextValve.java:160)
> at org.apache.catalina.core.StandardPipeline.doInvoke(
> StandardPipeline.java:734)
> at org.apache.catalina.core.StandardPipeline.invoke(
> StandardPipeline.java:673)
> at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
> at org.apache.catalina.core.StandardHostValve.invoke(
> StandardHostValve.java:174)
> at org.apache.catalina.connector.CoyoteAdapter.doService(
> CoyoteAdapter.java:357)
> at org.apache.catalina.connector.CoyoteAdapter.service(
> CoyoteAdapter.java:260)
> at com.sun.enterprise.v3.services.impl.ContainerMapper.
> service(ContainerMapper.java:188)
> at org.glassfish.grizzly.http.server.HttpHandler.runService(
> HttpHandler.java:191)
> at org.glassfish.grizzly.http.server.HttpHandler.doHandle(
> HttpHandler.java:168)
> at org.glassfish.grizzly.http.server.HttpServerFilter.
> handleRead(HttpServerFilter.java:189)
> at org.glassfish.grizzly.filterchain.ExecutorResolver$
> 9.execute(ExecutorResolver.java:119)
> at org.glassfish.grizzly.filterchain.DefaultFilterChain.
> executeFilter(DefaultFilterChain.java:288)
> at org.glassfish.grizzly.filterchain.DefaultFilterChain.
> executeChainPart(DefaultFilterChain.java:206)
> at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(
> DefaultFilterChain.java:136)
> at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(
> DefaultFilterChain.java:114)
> at org.glassfish.grizzly.ProcessorExecutor.execute(
> ProcessorExecutor.java:77)
> at org.glassfish.grizzly.nio.transport.TCPNIOTransport.
> fireIOEvent(TCPNIOTransport.java:838)
> at org.glassfish.grizzly.strategies.AbstractIOStrategy.
> fireIOEvent(AbstractIOStrategy.java:113)
> at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(
> WorkerThreadIOStrategy.java:115)
> at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$
> 100(WorkerThreadIOStrategy.java:55)
> at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$
> WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
> at org.glassfish.grizzly.threadpool.AbstractThreadPool$
> Worker.doWork(AbstractThreadPool.java:564)
> at org.glassfish.grizzly.threadpool.AbstractThreadPool$
> Worker.run(AbstractThreadPool.java:544)
> at java.lang.Thread.run(Thread.java:745)
>
>
>
> Cheers,
> Andy
>