You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Richard S. Hall (JIRA)" <ji...@apache.org> on 2009/06/25 23:52:08 UTC

[jira] Commented: (FELIX-1032) NPE on URL#openStream()

    [ https://issues.apache.org/jira/browse/FELIX-1032?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12724313#action_12724313 ] 

Richard S. Hall commented on FELIX-1032:
----------------------------------------

I investigated this bug rather thoroughly and have come to the conclusion that it is a JRE bug. This is what is happening:

ZipFile.getInputStream() returns an instance of an anonymous subclass of InflaterInputStream.

InflaterInputStream is constructed with an Inflater instance coming from a pool of inflaters in ZipFile.

The InflaterInputStream subclass inserts the Inflater back into the ZipFile inflater pool on close(); note that the InflaterInputStream subclass instance does not call close() on itself in its finalizer.

So, if this InflaterInputStream is wrapped in another InputStream and/or object that does call close() on it from the wrapper's finalizer(), then we run into a potential issue.

What I am seeing is if there is no reference to the wrapper, then the garbage collector is trying to finalize the wrapper, the InflaterInputStream subclass, and the Inflater inside it. In this case, the wrapper's finalizer() calls close() on the InflaterInputStream subclass which inserts a reference to its Inflater back into the ZipFile's inflater pool. Then the garbage collector continues to call finalize() on the other objects. In particular, Inflater.finalize() calls end() on itself, which invalidates the Inflater for future use.

This is the crux of the issue, since we now have an invalid Inflater in the ZipFile's inflater pool.

Since it is not uncommon for people to close() in finalizers, I think the JRE should not have side effects like this in close(). The JRE should be modified such that ZipFile does not simply remove Inflater instances from its "unused" pool when creating InflaterInputStreams, it should also insert them into another "used" pool to keep a hard reference to them. That way it won't get GC'd in the above scenario and end() won't be called on it to invalidate it.

Until that happens, the work around is to explicitly call close() on all input streams rather than doing it in the finalizer.

In this particular cases, it looks like mortbay was not explicitly closing a resource input stream, since I saw this stack trace snippet:

!!! Thread[Finalizer,8,system] RELEASING INFLATER java.util.zip.Inflater@f96093
!!! Thread[Finalizer,8,system] java.lang.Thread.getStackTrace(Thread.java:1436)
!!! Thread[Finalizer,8,system] java.util.zip.ZipFile.releaseInflater(ZipFile.java:280)
!!! Thread[Finalizer,8,system] java.util.zip.ZipFile.access$000(ZipFile.java:29)
!!! Thread[Finalizer,8,system] java.util.zip.ZipFile$1.close(ZipFile.java:217)
!!! Thread[Finalizer,8,system] org.mortbay.resource.URLResource.release(URLResource.java:82)

This is not a Felix bug. QED ;-)

> NPE on URL#openStream()
> -----------------------
>
>                 Key: FELIX-1032
>                 URL: https://issues.apache.org/jira/browse/FELIX-1032
>             Project: Felix
>          Issue Type: Bug
>          Components: Framework
>    Affects Versions: felix-1.4.1, felix-1.6.0, felix-1.6.1, felix-1.8.0
>         Environment: Linux bono 2.6.28-6-generic #17-Ubuntu SMP Fri Jan 30 15:34:36 UTC 2009 i686 GNU/Linux
> java version "1.6.0_13"
> Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
> Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)
>            Reporter: Martin Zdila
>            Priority: Critical
>         Attachments: hack.patch
>
>
> Note that also affected is felix-1.6.0 (it is not in the list).
> I am often getting NPE with the following code:
> new URL("bundle://66.0:0/somewhere/my.resource" /* or any other bundle:// URL */).openStream();
> java.lang.NullPointerException
> 	at java.util.zip.Inflater.ensureOpen(Inflater.java:336)
> 	at java.util.zip.Inflater.getBytesWritten(Inflater.java:296)
> 	at java.util.zip.ZipFile$1.available(ZipFile.java:243)
> 	at org.apache.felix.framework.URLHandlersBundleURLConnection.connect(URLHandlersBundleURLConnection.java:125)
> 	at org.apache.felix.framework.URLHandlersBundleURLConnection.getInputStream(URLHandlersBundleURLConnection.java:134)
> 	at java.net.URL.openStream(URL.java:1009)
> It is not allways reproducible. The first call causes the NPE and the second call with the same URL string goes without problems.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.