[jboss-cvs] JBossAS SVN: r93810 - projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Sep 21 11:53:32 EDT 2009


Author: alesj
Date: 2009-09-21 11:53:32 -0400 (Mon, 21 Sep 2009)
New Revision: 93810

Added:
   projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/CertificateReaderInputStream.java
   projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/EntryInfoAdapter.java
Modified:
   projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
   projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java
   projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java
Log:
[JBVFS-122]; initial fix - better in theory than before.
It is now reproducible - see ExplodeCleanupUnitTC (so much about theory :-).

Copied: projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/CertificateReaderInputStream.java (from rev 93483, projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java)
===================================================================
--- projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/CertificateReaderInputStream.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/CertificateReaderInputStream.java	2009-09-21 15:53:32 UTC (rev 93810)
@@ -0,0 +1,276 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.context.zip;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+
+import org.jboss.logging.Logger;
+
+/**
+ * ZipEntryInputStream is part of ZipFileWrapper implementation.
+ *
+ * It wraps the stream retrieved from ZipFile.getInputStream(entry)
+ * and releases the underlying ZipFileWrapper when detecting end of use.
+ *
+ * It also reads certificates before closing the stream.
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
+ * @version $Revision: 1.0 $
+ */
+class CertificateReaderInputStream extends InputStream
+{
+   /** ZipEntry */
+   private ZipEntry entry;
+
+   /** Underlying zip source */
+   private ZipFileWrapper zipWrapper;
+
+   /** Underlying input stream */
+   private InputStream delegate;
+
+   /** Is stream closed */
+   private boolean closed;
+
+   /**
+    * ZipEntryInputStream constructor.
+    *
+    * @param entry zip entry
+    * @param zipWrapper underlying zip source
+    * @param is underlying input stream
+    * @throws java.io.IOException for any error
+    * @throws IllegalArgumentException if insput stream is null
+    */
+   CertificateReaderInputStream(ZipEntry entry, ZipFileWrapper zipWrapper, InputStream is) throws IOException
+   {
+      if (is == null)
+         throw new IllegalArgumentException("Input stream is null");
+
+      this.entry = entry;
+      this.zipWrapper = zipWrapper;
+      delegate = is;
+   }
+
+   /**
+    * Close this stream and release zipWrapper
+    *
+    * @param doClose do we close stream
+    */
+   private void streamClosed(boolean doClose)
+   {
+      if (closed == false && doClose)
+      {
+         closed = true;
+
+         try
+         {
+            if (entry instanceof EntryInfoAdapter)
+               EntryInfoAdapter.class.cast(entry).readCertificates();
+         }
+         catch (RuntimeException e)
+         {
+            Logger.getLogger(getClass()).error("ZipWraper:" + zipWrapper);
+            throw e;
+         }
+         finally
+         {
+            zipWrapper.release();
+         }
+      }
+   }
+
+   /**
+    * Read one byte.
+    *
+    * @return whatever the underlying input stream returns
+    * @throws java.io.IOException for any error
+    * @see java.io.InputStream#read
+    */
+   public int read() throws IOException
+   {
+      int rc = -1;
+      try
+      {
+         rc = delegate.read();
+         return rc;
+      }
+      finally
+      {
+         streamClosed(rc < 0);
+      }
+   }
+
+   /**
+    * Read a buffer of bytes.
+    *
+    * @param buf read buffer
+    * @return whatever the underlying input stream returns
+    *
+    * @throws java.io.IOException for any error
+    * @see java.io.InputStream#read(byte[])
+    */
+   public int read(byte buf[]) throws IOException
+   {
+      int rc = -1;
+      try
+      {
+         rc = delegate.read(buf);
+         return rc;
+      }
+      finally
+      {
+         streamClosed(rc < 0);
+      }
+   }
+
+   /**
+    * Read a buffer of bytes.
+    *
+    * @param buf read buffer
+    * @param off position within buffer to start reading at
+    * @param len maximum bytes to read
+    * @return whatever the underlying input stream returns
+    * @throws java.io.IOException for any error
+    * @see java.io.InputStream#read(byte[],int,int)
+    */
+   public int read(byte buf[], int off, int len) throws IOException
+   {
+      int rc = -1;
+      try
+      {
+         rc = delegate.read(buf, off, len);
+         return rc;
+      }
+      finally
+      {
+         streamClosed(rc < 0);
+      }
+   }
+
+   /**
+    * @see java.io.InputStream#reset
+    */
+   public synchronized void reset() throws IOException
+   {
+      boolean ok = false;
+      try
+      {
+         delegate.reset();
+         ok = true;
+      }
+      finally
+      {
+         streamClosed(ok == false);
+      }
+   }
+
+   /**
+    * @see java.io.InputStream#mark
+    */
+   public synchronized void mark(int readlimit)
+   {
+      boolean ok = false;
+      try
+      {
+         delegate.mark(readlimit);
+         ok = true;
+      }
+      finally
+      {
+         streamClosed(ok == false);
+      }
+   }
+
+   /**
+    * @see java.io.InputStream#available
+    */
+   public int available() throws IOException
+   {
+      boolean ok = false;
+      try
+      {
+         int ret = delegate.available();
+         ok = true;
+         return ret;
+      }
+      finally
+      {
+         streamClosed(ok == false);
+      }
+   }
+
+   /**
+    * @see java.io.InputStream#skip
+    */
+   public long skip(long n) throws IOException
+   {
+      boolean ok = false;
+      try
+      {
+         long ret = delegate.skip(n);
+         ok = true;
+         return ret;
+      }
+      finally
+      {
+         streamClosed(ok == false);
+      }
+   }
+
+   /**
+    * Close this stream and release zipWrapper
+    *
+    * @see java.io.InputStream#close
+    */
+   public void close() throws IOException
+   {
+      streamClosed(true);
+      super.close();
+   }
+
+   /**
+    * Properly release held resources
+    */
+   protected void finalize() throws Throwable
+   {
+      try
+      {
+         close();
+      }
+      catch(IOException ignored)
+      {
+      }
+      super.finalize();
+   }
+
+   /**
+    * isClosed.
+    *
+    * @return returns true if closed
+    */
+   boolean isClosed()
+   {
+      return closed;
+   }
+}
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/EntryInfoAdapter.java (from rev 93560, projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java)
===================================================================
--- projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/EntryInfoAdapter.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/EntryInfoAdapter.java	2009-09-21 15:53:32 UTC (rev 93810)
@@ -0,0 +1,66 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.context.zip;
+
+import java.security.cert.Certificate;
+import java.util.jar.JarEntry;
+import java.util.zip.ZipEntry;
+
+/**
+ * EntryInfo wrapper.
+ * It knows how to read certificates.
+ *
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
+ */
+class EntryInfoAdapter extends ZipEntry
+{
+   private ZipEntryContext.EntryInfo ei;
+
+   EntryInfoAdapter(ZipEntryContext.EntryInfo ei)
+   {
+      super(ei.entry);
+      this.ei = ei;
+   }
+
+   /**
+    * Get original entry.
+    *
+    * @return the original entry
+    */
+   ZipEntry getOriginalEntry()
+   {
+      return ei.entry;
+   }
+
+   /**
+    * Read certificates.
+    */
+   void readCertificates()
+   {
+      ZipEntry entry = ei.entry;
+      if (ei.certificates == null && entry instanceof JarEntry)
+      {
+         Certificate[] certs = JarEntry.class.cast(entry).getCertificates();
+         ei.certificates = (certs != null) ? certs : ZipEntryContext.EntryInfo.MARKER;
+      }
+   }
+}
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
===================================================================
--- projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java	2009-09-21 14:18:01 UTC (rev 93809)
+++ projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java	2009-09-21 15:53:32 UTC (rev 93810)
@@ -50,7 +50,6 @@
 import java.util.TreeMap;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.jar.JarEntry;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -1081,7 +1080,8 @@
       if(ei.entry == null)
          return new ByteArrayInputStream(NO_BYTES);
 
-      return getZipSource().openStream(ei.entry);
+      ZipEntry wrapper = new EntryInfoAdapter(ei);
+      return getZipSource().openStream(wrapper);
    }
 
    /**
@@ -1187,21 +1187,7 @@
    Certificate[] getCertificates(ZipEntryHandler handler)
    {
       EntryInfo ei = entries.get(handler.getLocalPathName());
-      if (ei != null && ei.entry != null)
-      {
-         ZipEntry entry = ei.entry;
-         JarEntry je;
-         if (entry instanceof JarEntry)
-         {
-            je = (JarEntry)entry;
-         }
-         else
-         {
-            je = new JarEntry(entry);
-         }
-         return je.getCertificates();
-      }
-      return null;
+      return (ei != null) ? ei.getCertificates() : null;
    }
 
    /**
@@ -1209,12 +1195,18 @@
     */
    static class EntryInfo
    {
+      /** a marker */
+      static final Certificate[] MARKER = new Certificate[]{};
+
       /** a handler */
       private AbstractVirtualFileHandler handler;
 
       /** a <tt>ZipEntry</tt> */
-      private ZipEntry entry;
+      ZipEntry entry;
 
+      /** the certificates */
+      Certificate[] certificates;
+
       /** a list of children */
       private Map<String, AbstractVirtualFileHandler> children;
 
@@ -1231,6 +1223,16 @@
       }
 
       /**
+       * Get certificates.
+       *
+       * @return the certificates
+       */
+      private Certificate[] getCertificates()
+      {
+         return (certificates != MARKER) ? certificates : null;
+      }
+
+      /**
        * Get children.
        *
        * @return returns a list of children for this handler (by copy)

Modified: projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java
===================================================================
--- projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java	2009-09-21 14:18:01 UTC (rev 93809)
+++ projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java	2009-09-21 15:53:32 UTC (rev 93810)
@@ -32,8 +32,9 @@
  *
  * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
  * @version $Revision: 1.0 $
+ * @deprecated this is no longer used
  */
-
+ at Deprecated
 public class ZipEntryInputStream extends InputStream
 {
    /** Underlying input stream */
@@ -64,6 +65,8 @@
 
    /**
     * Close this stream and release zipWrapper
+    *
+    * @param doClose do we close
     */
    private void streamClosed(boolean doClose)
    {

Modified: projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java
===================================================================
--- projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java	2009-09-21 14:18:01 UTC (rev 93809)
+++ projects/vfs/branches/Branch_2_1/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java	2009-09-21 15:53:32 UTC (rev 93810)
@@ -75,9 +75,6 @@
    /** true if noReaper mode is forced on a per-instance basis */
    private boolean noReaperOverride;
 
-   // used for debugging stream leaks
-   //ConcurrentLinkedQueue<ZipEntryInputStream> streams = new ConcurrentLinkedQueue<ZipEntryInputStream>();
-
    /**
     * ZipFileWrapper
     *
@@ -191,6 +188,7 @@
       if (zipFile != null && getReferenceCount() <= 0)
       {
          ZipFile zf = zipFile;
+         //log.error(toString(), new Exception());
          zipFile = null;
          zf.close();
          if (forceNoReaper == false && noReaperOverride == false)
@@ -212,15 +210,20 @@
          return recomposeZipAsInputStream(ent.getName());
 
       ensureZipFile();
-      InputStream is = zipFile.getInputStream(ent);
+
+      // do lookup on original
+      ZipEntry lookup;
+      if (ent instanceof EntryInfoAdapter)
+         lookup = EntryInfoAdapter.class.cast(ent).getOriginalEntry();
+      else
+         lookup = ent;
+
+      InputStream is = zipFile.getInputStream(lookup);
       if (is == null)
          throw new IOException("Entry no longer available: " + ent.getName() + " in file " + file);
       
-      ZipEntryInputStream zis = new ZipEntryInputStream(this, is);
+      InputStream zis = new CertificateReaderInputStream(ent, this, is);
 
-      // debugging code
-      //streams.add(zis);
-
       incrementRef();
       return zis;
    }
@@ -398,7 +401,7 @@
     */
    public String toString()
    {
-      return super.toString() + " - " + file.getAbsolutePath();
+      return super.toString() + " - " + file.getAbsolutePath() + " -- " + zipFile;
    }
 
    /**




More information about the jboss-cvs-commits mailing list