Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java130
1 files changed, 82 insertions, 48 deletions
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
index 95cfaabbf9..5b46a140d8 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
@@ -19,6 +19,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -108,7 +109,7 @@ class JarFileResource extends JarResource
/* ------------------------------------------------------------ */
/**
- * Returns true if the respresenetd resource exists.
+ * Returns true if the represented resource exists.
*/
@Override
public boolean exists()
@@ -240,67 +241,100 @@ class JarFileResource extends JarResource
@Override
public synchronized String[] list()
{
+ if (isDirectory() && _list==null)
+ {
+ List<String> list = null;
+ try
+ {
+ list = listEntries();
+ }
+ catch (Exception e)
+ {
+ //Sun's JarURLConnection impl for jar: protocol will close a JarFile in its connect() method if
+ //useCaches == false (eg someone called URLConnection with defaultUseCaches==true).
+ //As their sun.net.www.protocol.jar package caches JarFiles and/or connections, we can wind up in
+ //the situation where the JarFile we have remembered in our _jarFile member has actually been closed
+ //by other code.
+ //So, do one retry to drop a connection and get a fresh JarFile
+ LOG.warn("Retrying list:"+e);
+ LOG.debug(e);
+ release();
+ list = listEntries();
+ }
+
+ if (list != null)
+ {
+ _list=new String[list.size()];
+ list.toArray(_list);
+ }
+ }
+ return _list;
+ }
+
+
+ /* ------------------------------------------------------------ */
+ private List<String> listEntries ()
+ {
+ checkConnection();
- if(isDirectory() && _list==null)
+ ArrayList<String> list = new ArrayList<String>(32);
+ JarFile jarFile=_jarFile;
+ if(jarFile==null)
{
- ArrayList list = new ArrayList(32);
+ try
+ {
+ JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
+ jc.setUseCaches(getUseCaches());
+ jarFile=jc.getJarFile();
+ }
+ catch(Exception e)
+ {
- checkConnection();
+ e.printStackTrace();
+ LOG.ignore(e);
+ }
+ }
+
+ Enumeration e=jarFile.entries();
+ String dir=_urlString.substring(_urlString.indexOf("!/")+2);
+ while(e.hasMoreElements())
+ {
- JarFile jarFile=_jarFile;
- if(jarFile==null)
+ JarEntry entry = (JarEntry) e.nextElement();
+ String name=entry.getName().replace('\\','/');
+ if(!name.startsWith(dir) || name.length()==dir.length())
{
- try
- {
- JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
- jc.setUseCaches(getUseCaches());
- jarFile=jc.getJarFile();
- }
- catch(Exception e)
- {
- LOG.ignore(e);
- }
+ continue;
}
-
- Enumeration e=jarFile.entries();
- String dir=_urlString.substring(_urlString.indexOf("!/")+2);
- while(e.hasMoreElements())
+ String listName=name.substring(dir.length());
+ int dash=listName.indexOf('/');
+ if (dash>=0)
{
-
- JarEntry entry = (JarEntry) e.nextElement();
- String name=entry.getName().replace('\\','/');
- if(!name.startsWith(dir) || name.length()==dir.length())
- {
+ //when listing jar:file urls, you get back one
+ //entry for the dir itself, which we ignore
+ if (dash==0 && listName.length()==1)
continue;
- }
- String listName=name.substring(dir.length());
- int dash=listName.indexOf('/');
- if (dash>=0)
- {
- //when listing jar:file urls, you get back one
- //entry for the dir itself, which we ignore
- if (dash==0 && listName.length()==1)
- continue;
- //when listing jar:file urls, all files and
- //subdirs have a leading /, which we remove
- if (dash==0)
- listName=listName.substring(dash+1, listName.length());
- else
- listName=listName.substring(0,dash+1);
-
- if (list.contains(listName))
- continue;
- }
+ //when listing jar:file urls, all files and
+ //subdirs have a leading /, which we remove
+ if (dash==0)
+ listName=listName.substring(dash+1, listName.length());
+ else
+ listName=listName.substring(0,dash+1);
- list.add(listName);
+ if (list.contains(listName))
+ continue;
}
- _list=new String[list.size()];
- list.toArray(_list);
+ list.add(listName);
}
- return _list;
+
+ return list;
}
+
+
+
+
/* ------------------------------------------------------------ */
/**
* Return the length of the resource

Back to the top