You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2011/12/16 10:48:48 UTC

svn commit: r1215075 - in /wicket/branches/wicket-1.5.x: wicket-core/src/main/java/org/apache/wicket/util/resource/ wicket-core/src/test/java/org/apache/wicket/util/resource/ wicket-util/src/main/java/org/apache/wicket/util/io/

Author: mgrigorov
Date: Fri Dec 16 09:48:48 2011
New Revision: 1215075

URL: http://svn.apache.org/viewvc?rev=1215075&view=rev
Log:
WICKET-4293
UrlResourceStream closes incorrect InputStream causing stacktraces on undeploy on GlassFish

Keep a list of all acquired InputStreams and close them when UrlResourceStream#close() is invoked.


Modified:
    wicket/branches/wicket-1.5.x/wicket-core/src/main/java/org/apache/wicket/util/resource/UrlResourceStream.java
    wicket/branches/wicket-1.5.x/wicket-core/src/test/java/org/apache/wicket/util/resource/UrlResourceStreamTest.java
    wicket/branches/wicket-1.5.x/wicket-util/src/main/java/org/apache/wicket/util/io/Connections.java

Modified: wicket/branches/wicket-1.5.x/wicket-core/src/main/java/org/apache/wicket/util/resource/UrlResourceStream.java
URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.5.x/wicket-core/src/main/java/org/apache/wicket/util/resource/UrlResourceStream.java?rev=1215075&r1=1215074&r2=1215075&view=diff
==============================================================================
--- wicket/branches/wicket-1.5.x/wicket-core/src/main/java/org/apache/wicket/util/resource/UrlResourceStream.java (original)
+++ wicket/branches/wicket-1.5.x/wicket-core/src/main/java/org/apache/wicket/util/resource/UrlResourceStream.java Fri Dec 16 09:48:48 2011
@@ -20,6 +20,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.util.io.Connections;
@@ -67,8 +69,8 @@ public class UrlResourceStream extends A
 	{
 		private URLConnection connection;
 
-		/** The stream read from this connection */
-		private InputStream inputStream;
+		/** The streams read from this connection */
+		private List<InputStream> inputStreams;
 
 		/** Length of stream. */
 		private long contentLength;
@@ -126,7 +128,7 @@ public class UrlResourceStream extends A
 			{
 				throw new IllegalArgumentException("Invalid URL parameter " + url, ex);
 			}
-		}
+ 		}
 
 		return streamData;
 	}
@@ -143,9 +145,11 @@ public class UrlResourceStream extends A
 		if (data != null)
 		{
 			Connections.closeQuietly(data.connection);
-			if (data.inputStream != null)
+			if (data.inputStreams != null)
 			{
-				IOUtils.closeQuietly(data.inputStream);
+				for (InputStream is : data.inputStreams) {
+					IOUtils.closeQuietly(is);
+				}
 			}
 			streamData = null;
 		}
@@ -160,8 +164,12 @@ public class UrlResourceStream extends A
 		try
 		{
 			StreamData data = getData(true);
-			data.inputStream = data.connection.getInputStream();
-			return data.inputStream;
+			InputStream is = data.connection.getInputStream();
+			if (data.inputStreams == null) {
+				data.inputStreams = new ArrayList<InputStream>();
+			}
+			data.inputStreams.add(is);
+			return is;
 		}
 		catch (IOException e)
 		{

Modified: wicket/branches/wicket-1.5.x/wicket-core/src/test/java/org/apache/wicket/util/resource/UrlResourceStreamTest.java
URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.5.x/wicket-core/src/test/java/org/apache/wicket/util/resource/UrlResourceStreamTest.java?rev=1215075&r1=1215074&r2=1215075&view=diff
==============================================================================
--- wicket/branches/wicket-1.5.x/wicket-core/src/test/java/org/apache/wicket/util/resource/UrlResourceStreamTest.java (original)
+++ wicket/branches/wicket-1.5.x/wicket-core/src/test/java/org/apache/wicket/util/resource/UrlResourceStreamTest.java Fri Dec 16 09:48:48 2011
@@ -17,6 +17,7 @@
 package org.apache.wicket.util.resource;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
@@ -27,19 +28,16 @@ import org.junit.Assert;
 import org.junit.Test;
 
 /**
- * 
  * @author Kent Tong
  */
-public class UrlResourceStreamTest extends Assert
-{
+public class UrlResourceStreamTest extends Assert {
 	/**
 	 * lastModified() shouldn't change the content length if the file isn't really changed.
-	 * 
+	 *
 	 * @throws IOException
 	 */
 	@Test
-	public void lastModifiedForResourceInJar() throws IOException
-	{
+	public void lastModifiedForResourceInJar() throws IOException {
 		String anyClassInJarFile = "/java/lang/String.class";
 		URL url = getClass().getResource(anyClassInJarFile);
 		UrlResourceStream stream = new UrlResourceStream(url);
@@ -50,64 +48,98 @@ public class UrlResourceStreamTest exten
 	}
 
 	/**
+	 * Verifies that a connection is opened just once but each #getInputStream() opens a new one
+	 * and all input streams are closed with UrlResourceStream#close()
+	 *
 	 * https://issues.apache.org/jira/browse/WICKET-3176
-	 * 
+	 * https://issues.apache.org/jira/browse/WICKET-4293
+	 *
 	 * @throws IOException
 	 * @throws ResourceStreamNotFoundException
 	 */
 	@Test
-	public void loadJustOnce() throws IOException, ResourceStreamNotFoundException
-	{
+	public void loadJustOnce() throws IOException, ResourceStreamNotFoundException {
 		String anyClassInJarFile = "/java/lang/String.class";
 		URL realURL = getClass().getResource(anyClassInJarFile);
 
-		final AtomicInteger counter = new AtomicInteger(0);
-		URL url = new URL(null, "test://anything", new CountingURLStreamHandler(realURL, counter));
+		final AtomicInteger connectCounter = new AtomicInteger(0);
+		final AtomicInteger streamCounter = new AtomicInteger(0);
+		URL url = new URL(null, "test://anything", new CountingURLStreamHandler(realURL,
+				connectCounter, streamCounter));
 
 		UrlResourceStream countingStream = new UrlResourceStream(url);
+
 		// assert the call is not made yet
-		assertEquals(0, counter.get());
-		countingStream.length();
+		assertEquals(0, connectCounter.get());
+		assertEquals(0, streamCounter.get());
+
 		// assert the connection is loaded lazily
-		assertEquals(1, counter.get());
+		countingStream.length();
+		assertEquals(1, connectCounter.get());
+		assertEquals(0, streamCounter.get());
 
 		// assert the following calls do not make new connections
 		countingStream.getInputStream();
-		assertEquals(1, counter.get());
+		assertEquals(1, connectCounter.get());
+		assertEquals(1, streamCounter.get());
 		countingStream.getContentType();
-		assertEquals(1, counter.get());
+		assertEquals(1, connectCounter.get());
+		assertEquals(1, streamCounter.get());
 		countingStream.getInputStream();
-		assertEquals(1, counter.get());
+		assertEquals(1, connectCounter.get());
+		assertEquals(2, streamCounter.get());
 		countingStream.close();
-		assertEquals(1, counter.get());
 
-		// assert the connection is re-opened (again lazily) second time
+		assertEquals(1, connectCounter.get());
+		assertEquals(2, streamCounter.get());
+
+		// assert the connection is re-opened (again lazily) second time,
+		// but stream is not re-opened yet
 		countingStream.length();
-		assertEquals(2, counter.get());
+
+		assertEquals(2, connectCounter.get());
+		assertEquals(2, streamCounter.get());
+
+		// assert stream is re-opened on next getInputStream call
+		countingStream.getInputStream();
+		assertEquals(2, connectCounter.get());
+		assertEquals(3, streamCounter.get());
 	}
 
 
 	/**
 	 * {@link URLStreamHandler} that counts the calls to {@link URL#openConnection()}
 	 */
-	private static final class CountingURLStreamHandler extends URLStreamHandler
-	{
-		private final AtomicInteger counter;
+	private static final class CountingURLStreamHandler extends URLStreamHandler {
+		private final AtomicInteger connectCounter, streamCounter;
 
 		private final URL realURL;
 
-		public CountingURLStreamHandler(URL realURL, AtomicInteger counter)
-		{
-			this.counter = counter;
+		public CountingURLStreamHandler(URL realURL, AtomicInteger connectCounter,
+										AtomicInteger streamCounter) {
+			this.connectCounter = connectCounter;
+			this.streamCounter = streamCounter;
 			this.realURL = realURL;
 		}
 
 		@Override
-		protected URLConnection openConnection(URL u) throws IOException
-		{
-			counter.getAndIncrement();
-			return realURL.openConnection();
-		}
+		protected URLConnection openConnection(URL u) throws IOException {
+			connectCounter.getAndIncrement();
 
+			final URLConnection realConn = realURL.openConnection();
+			return new URLConnection(u) {
+
+				@Override
+				public void connect() throws IOException {
+					realConn.connect();
+				}
+
+				@Override
+				public InputStream getInputStream() throws IOException {
+					streamCounter.incrementAndGet();
+					return realConn.getInputStream();
+				}
+			};
+		}
 	}
 }

Modified: wicket/branches/wicket-1.5.x/wicket-util/src/main/java/org/apache/wicket/util/io/Connections.java
URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.5.x/wicket-util/src/main/java/org/apache/wicket/util/io/Connections.java?rev=1215075&r1=1215074&r2=1215075&view=diff
==============================================================================
--- wicket/branches/wicket-1.5.x/wicket-util/src/main/java/org/apache/wicket/util/io/Connections.java (original)
+++ wicket/branches/wicket-1.5.x/wicket-util/src/main/java/org/apache/wicket/util/io/Connections.java Fri Dec 16 09:48:48 2011
@@ -128,9 +128,5 @@ public class Connections
 		{
 			((HttpURLConnection)connection).disconnect();
 		}
-		else
-		{
-			connection.getInputStream().close();
-		}
 	}
 }