< prev index next >

src/java.base/share/classes/sun/misc/URLClassPath.java

Print this page




  80 public class URLClassPath {
  81     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
  82     private static final String JAVA_HOME;
  83     private static final String JAVA_VERSION;
  84     private static final boolean DEBUG;
  85     private static final boolean DISABLE_JAR_CHECKING;
  86 
  87     static {
  88         JAVA_HOME = java.security.AccessController.doPrivileged(
  89             new sun.security.action.GetPropertyAction("java.home"));
  90         JAVA_VERSION = java.security.AccessController.doPrivileged(
  91             new sun.security.action.GetPropertyAction("java.version"));
  92         DEBUG        = (java.security.AccessController.doPrivileged(
  93             new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
  94         String p = java.security.AccessController.doPrivileged(
  95             new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
  96         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
  97     }
  98 
  99     /* The original search path of URLs. */
 100     private ArrayList<URL> path = new ArrayList<URL>();
 101 
 102     /* The stack of unopened URLs */
 103     Stack<URL> urls = new Stack<URL>();
 104 
 105     /* The resulting search path of Loaders */
 106     ArrayList<Loader> loaders = new ArrayList<Loader>();
 107 
 108     /* Map of each URL opened to its corresponding Loader */
 109     HashMap<String, Loader> lmap = new HashMap<String, Loader>();
 110 
 111     /* The jar protocol handler to use when creating new URLs */
 112     private URLStreamHandler jarHandler;
 113 
 114     /* Whether this URLClassLoader has been closed yet */
 115     private boolean closed = false;
 116 
 117     /**
 118      * Creates a new URLClassPath for the given URLs. The URLs will be
 119      * searched in the order specified for classes and resources. A URL
 120      * ending with a '/' is assumed to refer to a directory. Otherwise,
 121      * the URL is assumed to refer to a JAR file.
 122      *
 123      * @param urls the directory and JAR file URLs to search for classes
 124      *        and resources
 125      * @param factory the URLStreamHandlerFactory to use when creating new URLs
 126      */
 127     public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) {
 128         for (int i = 0; i < urls.length; i++) {
 129             path.add(urls[i]);
 130         }
 131         push(urls);
 132         if (factory != null) {
 133             jarHandler = factory.createURLStreamHandler("jar");
 134         }
 135     }
 136 
 137     public URLClassPath(URL[] urls) {
 138         this(urls, null);
 139     }
 140 
 141     public synchronized List<IOException> closeLoaders() {
 142         if (closed) {
 143             return Collections.emptyList();
 144         }
 145         List<IOException> result = new LinkedList<IOException>();
 146         for (Loader loader : loaders) {
 147             try {
 148                 loader.close();
 149             } catch (IOException e) {
 150                 result.add (e);
 151             }
 152         }
 153         closed = true;
 154         return result;
 155     }
 156 
 157     /**
 158      * Appends the specified URL to the search path of directory and JAR
 159      * file URLs from which to load classes and resources.
 160      * <p>
 161      * If the URL specified is null or is already in the list of
 162      * URLs, then invoking this method has no effect.
 163      */
 164     public synchronized void addURL(URL url) {
 165         if (closed)


 217 
 218         Loader loader;
 219         for (int i = 0; (loader = getLoader(i)) != null; i++) {
 220             Resource res = loader.getResource(name, check);
 221             if (res != null) {
 222                 return res;
 223             }
 224         }
 225         return null;
 226     }
 227 
 228     /**
 229      * Finds all resources on the URL search path with the given name.
 230      * Returns an enumeration of the URL objects.
 231      *
 232      * @param name the resource name
 233      * @return an Enumeration of all the urls having the specified name
 234      */
 235     public Enumeration<URL> findResources(final String name,
 236                                      final boolean check) {
 237         return new Enumeration<URL>() {
 238             private int index = 0;
 239             private URL url = null;
 240 
 241             private boolean next() {
 242                 if (url != null) {
 243                     return true;
 244                 } else {
 245                     Loader loader;
 246                     while ((loader = getLoader(index++)) != null) {
 247                         url = loader.findResource(name, check);
 248                         if (url != null) {
 249                             return true;
 250                         }
 251                     }
 252                     return false;
 253                 }
 254             }
 255 
 256             public boolean hasMoreElements() {
 257                 return next();


 264                 URL u = url;
 265                 url = null;
 266                 return u;
 267             }
 268         };
 269     }
 270 
 271     public Resource getResource(String name) {
 272         return getResource(name, true);
 273     }
 274 
 275     /**
 276      * Finds all resources on the URL search path with the given name.
 277      * Returns an enumeration of the Resource objects.
 278      *
 279      * @param name the resource name
 280      * @return an Enumeration of all the resources having the specified name
 281      */
 282     public Enumeration<Resource> getResources(final String name,
 283                                     final boolean check) {
 284         return new Enumeration<Resource>() {
 285             private int index = 0;
 286             private Resource res = null;
 287 
 288             private boolean next() {
 289                 if (res != null) {
 290                     return true;
 291                 } else {
 292                     Loader loader;
 293                     while ((loader = getLoader(index++)) != null) {
 294                         res = loader.getResource(name, check);
 295                         if (res != null) {
 296                             return true;
 297                         }
 298                     }
 299                     return false;
 300                 }
 301             }
 302 
 303             public boolean hasMoreElements() {
 304                 return next();


 357                 if (urls != null) {
 358                     push(urls);
 359                 }
 360             } catch (IOException e) {
 361                 // Silently ignore for now...
 362                 continue;
 363             }
 364             // Finally, add the Loader to the search path.
 365             loaders.add(loader);
 366             lmap.put(urlNoFragString, loader);
 367         }
 368         return loaders.get(index);
 369     }
 370 
 371     /*
 372      * Returns the Loader for the specified base URL.
 373      */
 374     private Loader getLoader(final URL url) throws IOException {
 375         try {
 376             return java.security.AccessController.doPrivileged(
 377                 new java.security.PrivilegedExceptionAction<Loader>() {
 378                 public Loader run() throws IOException {
 379                     String file = url.getFile();
 380                     if (file != null && file.endsWith("/")) {
 381                         if ("file".equals(url.getProtocol())) {
 382                             return new FileLoader(url);
 383                         } else {
 384                             return new Loader(url);
 385                         }
 386                     } else {
 387                         if (file != null && "file".equals(url.getProtocol())) {
 388                             if (file.endsWith(".jimage"))
 389                                 return new JImageLoader(url);
 390                         }
 391                         return new JarLoader(url, jarHandler, lmap);
 392                     }
 393                 }
 394             });
 395         } catch (java.security.PrivilegedActionException pae) {
 396             throw (IOException)pae.getException();
 397         }


 672             if (!closed) {
 673                 closed = true;
 674                 // in case not already open.
 675                 ensureOpen();
 676                 jar.close();
 677             }
 678         }
 679 
 680         JarFile getJarFile () {
 681             return jar;
 682         }
 683 
 684         private boolean isOptimizable(URL url) {
 685             return "file".equals(url.getProtocol());
 686         }
 687 
 688         private void ensureOpen() throws IOException {
 689             if (jar == null) {
 690                 try {
 691                     java.security.AccessController.doPrivileged(
 692                         new java.security.PrivilegedExceptionAction<Void>() {
 693                             public Void run() throws IOException {
 694                                 if (DEBUG) {
 695                                     System.err.println("Opening " + csu);
 696                                     Thread.dumpStack();
 697                                 }
 698 
 699                                 jar = getJarFile(csu);
 700                                 index = JarIndex.getJarIndex(jar, metaIndex);
 701                                 if (index != null) {
 702                                     String[] jarfiles = index.getJarFiles();
 703                                 // Add all the dependent URLs to the lmap so that loaders
 704                                 // will not be created for them by URLClassPath.getLoader(int)
 705                                 // if the same URL occurs later on the main class path.  We set
 706                                 // Loader to null here to avoid creating a Loader for each
 707                                 // URL until we actually need to try to load something from them.
 708                                     for(int i = 0; i < jarfiles.length; i++) {
 709                                         try {
 710                                             URL jarURL = new URL(csu, jarfiles[i]);
 711                                             // If a non-null loader already exists, leave it alone.
 712                                             String urlNoFragString = URLUtil.urlNoFragString(jarURL);


 853          */
 854         Resource getResource(final String name, boolean check) {
 855             if (metaIndex != null) {
 856                 if (!metaIndex.mayContain(name)) {
 857                     return null;
 858                 }
 859             }
 860 
 861             try {
 862                 ensureOpen();
 863             } catch (IOException e) {
 864                 throw new InternalError(e);
 865             }
 866             final JarEntry entry = jar.getJarEntry(name);
 867             if (entry != null)
 868                 return checkResource(name, check, entry);
 869 
 870             if (index == null)
 871                 return null;
 872 
 873             HashSet<String> visited = new HashSet<String>();
 874             return getResource(name, check, visited);
 875         }
 876 
 877         /*
 878          * Version of getResource() that tracks the jar files that have been
 879          * visited by linking through the index files. This helper method uses
 880          * a HashSet to store the URLs of jar files that have been searched and
 881          * uses it to avoid going into an infinite loop, looking for a
 882          * non-existent resource
 883          */
 884         Resource getResource(final String name, boolean check,
 885                              Set<String> visited) {
 886 
 887             Resource res;
 888             String[] jarFiles;
 889             int count = 0;
 890             LinkedList<String> jarFilesList = null;
 891 
 892             /* If there no jar files in the index that can potential contain
 893              * this resource then return immediately.


 895             if((jarFilesList = index.get(name)) == null)
 896                 return null;
 897 
 898             do {
 899                 int size = jarFilesList.size();
 900                 jarFiles = jarFilesList.toArray(new String[size]);
 901                 /* loop through the mapped jar file list */
 902                 while(count < size) {
 903                     String jarName = jarFiles[count++];
 904                     JarLoader newLoader;
 905                     final URL url;
 906 
 907                     try{
 908                         url = new URL(csu, jarName);
 909                         String urlNoFragString = URLUtil.urlNoFragString(url);
 910                         if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) {
 911                             /* no loader has been set up for this jar file
 912                              * before
 913                              */
 914                             newLoader = AccessController.doPrivileged(
 915                                 new PrivilegedExceptionAction<JarLoader>() {
 916                                     public JarLoader run() throws IOException {
 917                                         return new JarLoader(url, handler,
 918                                             lmap);
 919                                     }
 920                                 });
 921 
 922                             /* this newly opened jar file has its own index,
 923                              * merge it into the parent's index, taking into
 924                              * account the relative path.
 925                              */
 926                             JarIndex newIndex = newLoader.getIndex();
 927                             if(newIndex != null) {
 928                                 int pos = jarName.lastIndexOf('/');
 929                                 newIndex.merge(this.index, (pos == -1 ?
 930                                     null : jarName.substring(0, pos + 1)));
 931                             }
 932 
 933                             /* put it in the global hashtable */
 934                             lmap.put(urlNoFragString, newLoader);
 935                         }




  80 public class URLClassPath {
  81     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
  82     private static final String JAVA_HOME;
  83     private static final String JAVA_VERSION;
  84     private static final boolean DEBUG;
  85     private static final boolean DISABLE_JAR_CHECKING;
  86 
  87     static {
  88         JAVA_HOME = java.security.AccessController.doPrivileged(
  89             new sun.security.action.GetPropertyAction("java.home"));
  90         JAVA_VERSION = java.security.AccessController.doPrivileged(
  91             new sun.security.action.GetPropertyAction("java.version"));
  92         DEBUG        = (java.security.AccessController.doPrivileged(
  93             new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
  94         String p = java.security.AccessController.doPrivileged(
  95             new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
  96         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
  97     }
  98 
  99     /* The original search path of URLs. */
 100     private ArrayList<URL> path = new ArrayList<>();
 101 
 102     /* The stack of unopened URLs */
 103     Stack<URL> urls = new Stack<>();
 104 
 105     /* The resulting search path of Loaders */
 106     ArrayList<Loader> loaders = new ArrayList<>();
 107 
 108     /* Map of each URL opened to its corresponding Loader */
 109     HashMap<String, Loader> lmap = new HashMap<>();
 110 
 111     /* The jar protocol handler to use when creating new URLs */
 112     private URLStreamHandler jarHandler;
 113 
 114     /* Whether this URLClassLoader has been closed yet */
 115     private boolean closed = false;
 116 
 117     /**
 118      * Creates a new URLClassPath for the given URLs. The URLs will be
 119      * searched in the order specified for classes and resources. A URL
 120      * ending with a '/' is assumed to refer to a directory. Otherwise,
 121      * the URL is assumed to refer to a JAR file.
 122      *
 123      * @param urls the directory and JAR file URLs to search for classes
 124      *        and resources
 125      * @param factory the URLStreamHandlerFactory to use when creating new URLs
 126      */
 127     public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) {
 128         for (int i = 0; i < urls.length; i++) {
 129             path.add(urls[i]);
 130         }
 131         push(urls);
 132         if (factory != null) {
 133             jarHandler = factory.createURLStreamHandler("jar");
 134         }
 135     }
 136 
 137     public URLClassPath(URL[] urls) {
 138         this(urls, null);
 139     }
 140 
 141     public synchronized List<IOException> closeLoaders() {
 142         if (closed) {
 143             return Collections.emptyList();
 144         }
 145         List<IOException> result = new LinkedList<>();
 146         for (Loader loader : loaders) {
 147             try {
 148                 loader.close();
 149             } catch (IOException e) {
 150                 result.add (e);
 151             }
 152         }
 153         closed = true;
 154         return result;
 155     }
 156 
 157     /**
 158      * Appends the specified URL to the search path of directory and JAR
 159      * file URLs from which to load classes and resources.
 160      * <p>
 161      * If the URL specified is null or is already in the list of
 162      * URLs, then invoking this method has no effect.
 163      */
 164     public synchronized void addURL(URL url) {
 165         if (closed)


 217 
 218         Loader loader;
 219         for (int i = 0; (loader = getLoader(i)) != null; i++) {
 220             Resource res = loader.getResource(name, check);
 221             if (res != null) {
 222                 return res;
 223             }
 224         }
 225         return null;
 226     }
 227 
 228     /**
 229      * Finds all resources on the URL search path with the given name.
 230      * Returns an enumeration of the URL objects.
 231      *
 232      * @param name the resource name
 233      * @return an Enumeration of all the urls having the specified name
 234      */
 235     public Enumeration<URL> findResources(final String name,
 236                                      final boolean check) {
 237         return new Enumeration<>() {
 238             private int index = 0;
 239             private URL url = null;
 240 
 241             private boolean next() {
 242                 if (url != null) {
 243                     return true;
 244                 } else {
 245                     Loader loader;
 246                     while ((loader = getLoader(index++)) != null) {
 247                         url = loader.findResource(name, check);
 248                         if (url != null) {
 249                             return true;
 250                         }
 251                     }
 252                     return false;
 253                 }
 254             }
 255 
 256             public boolean hasMoreElements() {
 257                 return next();


 264                 URL u = url;
 265                 url = null;
 266                 return u;
 267             }
 268         };
 269     }
 270 
 271     public Resource getResource(String name) {
 272         return getResource(name, true);
 273     }
 274 
 275     /**
 276      * Finds all resources on the URL search path with the given name.
 277      * Returns an enumeration of the Resource objects.
 278      *
 279      * @param name the resource name
 280      * @return an Enumeration of all the resources having the specified name
 281      */
 282     public Enumeration<Resource> getResources(final String name,
 283                                     final boolean check) {
 284         return new Enumeration<>() {
 285             private int index = 0;
 286             private Resource res = null;
 287 
 288             private boolean next() {
 289                 if (res != null) {
 290                     return true;
 291                 } else {
 292                     Loader loader;
 293                     while ((loader = getLoader(index++)) != null) {
 294                         res = loader.getResource(name, check);
 295                         if (res != null) {
 296                             return true;
 297                         }
 298                     }
 299                     return false;
 300                 }
 301             }
 302 
 303             public boolean hasMoreElements() {
 304                 return next();


 357                 if (urls != null) {
 358                     push(urls);
 359                 }
 360             } catch (IOException e) {
 361                 // Silently ignore for now...
 362                 continue;
 363             }
 364             // Finally, add the Loader to the search path.
 365             loaders.add(loader);
 366             lmap.put(urlNoFragString, loader);
 367         }
 368         return loaders.get(index);
 369     }
 370 
 371     /*
 372      * Returns the Loader for the specified base URL.
 373      */
 374     private Loader getLoader(final URL url) throws IOException {
 375         try {
 376             return java.security.AccessController.doPrivileged(
 377                 new java.security.PrivilegedExceptionAction<>() {
 378                 public Loader run() throws IOException {
 379                     String file = url.getFile();
 380                     if (file != null && file.endsWith("/")) {
 381                         if ("file".equals(url.getProtocol())) {
 382                             return new FileLoader(url);
 383                         } else {
 384                             return new Loader(url);
 385                         }
 386                     } else {
 387                         if (file != null && "file".equals(url.getProtocol())) {
 388                             if (file.endsWith(".jimage"))
 389                                 return new JImageLoader(url);
 390                         }
 391                         return new JarLoader(url, jarHandler, lmap);
 392                     }
 393                 }
 394             });
 395         } catch (java.security.PrivilegedActionException pae) {
 396             throw (IOException)pae.getException();
 397         }


 672             if (!closed) {
 673                 closed = true;
 674                 // in case not already open.
 675                 ensureOpen();
 676                 jar.close();
 677             }
 678         }
 679 
 680         JarFile getJarFile () {
 681             return jar;
 682         }
 683 
 684         private boolean isOptimizable(URL url) {
 685             return "file".equals(url.getProtocol());
 686         }
 687 
 688         private void ensureOpen() throws IOException {
 689             if (jar == null) {
 690                 try {
 691                     java.security.AccessController.doPrivileged(
 692                         new java.security.PrivilegedExceptionAction<>() {
 693                             public Void run() throws IOException {
 694                                 if (DEBUG) {
 695                                     System.err.println("Opening " + csu);
 696                                     Thread.dumpStack();
 697                                 }
 698 
 699                                 jar = getJarFile(csu);
 700                                 index = JarIndex.getJarIndex(jar, metaIndex);
 701                                 if (index != null) {
 702                                     String[] jarfiles = index.getJarFiles();
 703                                 // Add all the dependent URLs to the lmap so that loaders
 704                                 // will not be created for them by URLClassPath.getLoader(int)
 705                                 // if the same URL occurs later on the main class path.  We set
 706                                 // Loader to null here to avoid creating a Loader for each
 707                                 // URL until we actually need to try to load something from them.
 708                                     for(int i = 0; i < jarfiles.length; i++) {
 709                                         try {
 710                                             URL jarURL = new URL(csu, jarfiles[i]);
 711                                             // If a non-null loader already exists, leave it alone.
 712                                             String urlNoFragString = URLUtil.urlNoFragString(jarURL);


 853          */
 854         Resource getResource(final String name, boolean check) {
 855             if (metaIndex != null) {
 856                 if (!metaIndex.mayContain(name)) {
 857                     return null;
 858                 }
 859             }
 860 
 861             try {
 862                 ensureOpen();
 863             } catch (IOException e) {
 864                 throw new InternalError(e);
 865             }
 866             final JarEntry entry = jar.getJarEntry(name);
 867             if (entry != null)
 868                 return checkResource(name, check, entry);
 869 
 870             if (index == null)
 871                 return null;
 872 
 873             HashSet<String> visited = new HashSet<>();
 874             return getResource(name, check, visited);
 875         }
 876 
 877         /*
 878          * Version of getResource() that tracks the jar files that have been
 879          * visited by linking through the index files. This helper method uses
 880          * a HashSet to store the URLs of jar files that have been searched and
 881          * uses it to avoid going into an infinite loop, looking for a
 882          * non-existent resource
 883          */
 884         Resource getResource(final String name, boolean check,
 885                              Set<String> visited) {
 886 
 887             Resource res;
 888             String[] jarFiles;
 889             int count = 0;
 890             LinkedList<String> jarFilesList = null;
 891 
 892             /* If there no jar files in the index that can potential contain
 893              * this resource then return immediately.


 895             if((jarFilesList = index.get(name)) == null)
 896                 return null;
 897 
 898             do {
 899                 int size = jarFilesList.size();
 900                 jarFiles = jarFilesList.toArray(new String[size]);
 901                 /* loop through the mapped jar file list */
 902                 while(count < size) {
 903                     String jarName = jarFiles[count++];
 904                     JarLoader newLoader;
 905                     final URL url;
 906 
 907                     try{
 908                         url = new URL(csu, jarName);
 909                         String urlNoFragString = URLUtil.urlNoFragString(url);
 910                         if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) {
 911                             /* no loader has been set up for this jar file
 912                              * before
 913                              */
 914                             newLoader = AccessController.doPrivileged(
 915                                 new PrivilegedExceptionAction<>() {
 916                                     public JarLoader run() throws IOException {
 917                                         return new JarLoader(url, handler,
 918                                             lmap);
 919                                     }
 920                                 });
 921 
 922                             /* this newly opened jar file has its own index,
 923                              * merge it into the parent's index, taking into
 924                              * account the relative path.
 925                              */
 926                             JarIndex newIndex = newLoader.getIndex();
 927                             if(newIndex != null) {
 928                                 int pos = jarName.lastIndexOf('/');
 929                                 newIndex.merge(this.index, (pos == -1 ?
 930                                     null : jarName.substring(0, pos + 1)));
 931                             }
 932 
 933                             /* put it in the global hashtable */
 934                             lmap.put(urlNoFragString, newLoader);
 935                         }


< prev index next >