< prev index next >

src/java.base/share/classes/jdk/internal/loader/URLClassPath.java

Print this page
rev 51675 : 8207690: Parsing API for classpath and similar path strings


  31 import java.io.FileNotFoundException;
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.net.HttpURLConnection;
  35 import java.net.JarURLConnection;
  36 import java.net.MalformedURLException;
  37 import java.net.URL;
  38 import java.net.URLConnection;
  39 import java.net.URLStreamHandler;
  40 import java.net.URLStreamHandlerFactory;
  41 import java.security.AccessControlContext;
  42 import java.security.AccessControlException;
  43 import java.security.AccessController;
  44 import java.security.CodeSigner;
  45 import java.security.Permission;
  46 import java.security.PrivilegedActionException;
  47 import java.security.PrivilegedExceptionAction;
  48 import java.security.cert.Certificate;
  49 import java.util.ArrayDeque;
  50 import java.util.ArrayList;
  51 import java.util.Arrays;
  52 import java.util.Collections;
  53 import java.util.Enumeration;
  54 import java.util.HashMap;
  55 import java.util.HashSet;
  56 import java.util.LinkedList;
  57 import java.util.List;
  58 import java.util.NoSuchElementException;

  59 import java.util.Properties;
  60 import java.util.Set;
  61 import java.util.StringTokenizer;
  62 import java.util.jar.JarFile;
  63 import java.util.zip.ZipEntry;
  64 import java.util.jar.JarEntry;
  65 import java.util.jar.Manifest;
  66 import java.util.jar.Attributes;
  67 import java.util.jar.Attributes.Name;
  68 import java.util.zip.ZipFile;
  69 
  70 import jdk.internal.misc.JavaNetURLAccess;
  71 import jdk.internal.misc.JavaUtilZipFileAccess;
  72 import jdk.internal.misc.SharedSecrets;

  73 import jdk.internal.util.jar.InvalidJarIndexError;
  74 import jdk.internal.util.jar.JarIndex;
  75 import sun.net.util.URLUtil;
  76 import sun.net.www.ParseUtil;
  77 import sun.security.action.GetPropertyAction;
  78 
  79 /**
  80  * This class is used to maintain a search path of URLs for loading classes
  81  * and resources from both JAR files and directories.
  82  *
  83  * @author  David Connelly
  84  */
  85 public class URLClassPath {
  86     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
  87     private static final String JAVA_VERSION;
  88     private static final boolean DEBUG;
  89     private static final boolean DISABLE_JAR_CHECKING;
  90     private static final boolean DISABLE_ACC_CHECKING;
  91 
  92     static {
  93         Properties props = GetPropertyAction.privilegedGetProperties();
  94         JAVA_VERSION = props.getProperty("java.version");
  95         DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
  96         String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
  97         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
  98 
  99         p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
 100         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
 101     }
 102 
 103     /* The original search path of URLs. */
 104     private final ArrayList<URL> path;
 105 
 106     /* The deque of unopened URLs */
 107     private final ArrayDeque<URL> unopenedUrls;
 108 
 109     /* The resulting search path of Loaders */
 110     private final ArrayList<Loader> loaders = new ArrayList<>();
 111 
 112     /* Map of each URL opened to its corresponding Loader */
 113     private final HashMap<String, Loader> lmap = new HashMap<>();
 114 
 115     /* The jar protocol handler to use when creating new URLs */
 116     private final URLStreamHandler jarHandler;
 117 
 118     /* Whether this URLClassLoader has been closed yet */
 119     private boolean closed = false;
 120 
 121     /* The context to be used when loading classes and resources.  If non-null
 122      * this is the context that was captured during the creation of the
 123      * URLClassLoader. null implies no additional security restrictions. */
 124     private final AccessControlContext acc;


 147         this.path = path;
 148         this.unopenedUrls = unopenedUrls;
 149 
 150         if (factory != null) {
 151             jarHandler = factory.createURLStreamHandler("jar");
 152         } else {
 153             jarHandler = null;
 154         }
 155         if (DISABLE_ACC_CHECKING)
 156             this.acc = null;
 157         else
 158             this.acc = acc;
 159     }
 160 
 161     public URLClassPath(URL[] urls, AccessControlContext acc) {
 162         this(urls, null, acc);
 163     }
 164 
 165     /**
 166      * Constructs a URLClassPath from a class path string.


 167      *
 168      * @param cp the class path string
 169      * @param skipEmptyElements indicates if empty elements are ignored or
 170      *        treated as the current working directory
 171      *
 172      * @apiNote Used to create the application class path.
 173      */
 174     URLClassPath(String cp, boolean skipEmptyElements) {
 175         ArrayList<URL> path = new ArrayList<>();
 176         if (cp != null) {
 177             // map each element of class path to a file URL
 178             int off = 0, next;
 179             do {
 180                 next = cp.indexOf(File.pathSeparator, off);
 181                 String element = (next == -1)
 182                     ? cp.substring(off)
 183                     : cp.substring(off, next);
 184                 if (element.length() > 0 || !skipEmptyElements) {
 185                     URL url = toFileURL(element);
 186                     if (url != null) path.add(url);
 187                 }
 188                 off = next + 1;
 189             } while (next != -1);
 190         }
 191 
 192         // can't use ArrayDeque#addAll or new ArrayDeque(Collection);
 193         // it's too early in the bootstrap to trigger use of lambdas
 194         int size = path.size();
 195         ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);
 196         for (int i = 0; i < size; i++)
 197             unopenedUrls.add(path.get(i));


 198 
 199         this.unopenedUrls = unopenedUrls;
 200         this.path = path;
 201         this.jarHandler = null;
 202         this.acc = null;
 203     }
 204 
 205     public synchronized List<IOException> closeLoaders() {
 206         if (closed) {
 207             return Collections.emptyList();
 208         }
 209         List<IOException> result = new LinkedList<>();
 210         for (Loader loader : loaders) {
 211             try {
 212                 loader.close();
 213             } catch (IOException e) {
 214                 result.add(e);
 215             }
 216         }
 217         closed = true;




  31 import java.io.FileNotFoundException;
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.net.HttpURLConnection;
  35 import java.net.JarURLConnection;
  36 import java.net.MalformedURLException;
  37 import java.net.URL;
  38 import java.net.URLConnection;
  39 import java.net.URLStreamHandler;
  40 import java.net.URLStreamHandlerFactory;
  41 import java.security.AccessControlContext;
  42 import java.security.AccessControlException;
  43 import java.security.AccessController;
  44 import java.security.CodeSigner;
  45 import java.security.Permission;
  46 import java.security.PrivilegedActionException;
  47 import java.security.PrivilegedExceptionAction;
  48 import java.security.cert.Certificate;
  49 import java.util.ArrayDeque;
  50 import java.util.ArrayList;

  51 import java.util.Collections;
  52 import java.util.Enumeration;
  53 import java.util.HashMap;
  54 import java.util.HashSet;
  55 import java.util.LinkedList;
  56 import java.util.List;
  57 import java.util.NoSuchElementException;
  58 import java.util.Objects;
  59 import java.util.Properties;
  60 import java.util.Set;
  61 import java.util.StringTokenizer;
  62 import java.util.jar.JarFile;
  63 import java.util.zip.ZipEntry;
  64 import java.util.jar.JarEntry;
  65 import java.util.jar.Manifest;
  66 import java.util.jar.Attributes;
  67 import java.util.jar.Attributes.Name;
  68 import java.util.zip.ZipFile;
  69 
  70 import jdk.internal.misc.JavaNetURLAccess;
  71 import jdk.internal.misc.JavaUtilZipFileAccess;
  72 import jdk.internal.misc.SharedSecrets;
  73 import jdk.internal.util.PathParser;
  74 import jdk.internal.util.jar.InvalidJarIndexError;
  75 import jdk.internal.util.jar.JarIndex;
  76 import sun.net.util.URLUtil;
  77 import sun.net.www.ParseUtil;
  78 import sun.security.action.GetPropertyAction;
  79 
  80 /**
  81  * This class is used to maintain a search path of URLs for loading classes
  82  * and resources from both JAR files and directories.
  83  *
  84  * @author  David Connelly
  85  */
  86 public class URLClassPath {
  87     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
  88     private static final String JAVA_VERSION;
  89     private static final boolean DEBUG;
  90     private static final boolean DISABLE_JAR_CHECKING;
  91     private static final boolean DISABLE_ACC_CHECKING;
  92 
  93     static {
  94         Properties props = GetPropertyAction.privilegedGetProperties();
  95         JAVA_VERSION = props.getProperty("java.version");
  96         DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
  97         String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
  98         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
  99 
 100         p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
 101         DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
 102     }
 103 
 104     /* The original search path of URLs. */
 105     private final List<URL> path;
 106 
 107     /* The deque of unopened URLs */
 108     private final ArrayDeque<URL> unopenedUrls;
 109 
 110     /* The resulting search path of Loaders */
 111     private final ArrayList<Loader> loaders = new ArrayList<>();
 112 
 113     /* Map of each URL opened to its corresponding Loader */
 114     private final HashMap<String, Loader> lmap = new HashMap<>();
 115 
 116     /* The jar protocol handler to use when creating new URLs */
 117     private final URLStreamHandler jarHandler;
 118 
 119     /* Whether this URLClassLoader has been closed yet */
 120     private boolean closed = false;
 121 
 122     /* The context to be used when loading classes and resources.  If non-null
 123      * this is the context that was captured during the creation of the
 124      * URLClassLoader. null implies no additional security restrictions. */
 125     private final AccessControlContext acc;


 148         this.path = path;
 149         this.unopenedUrls = unopenedUrls;
 150 
 151         if (factory != null) {
 152             jarHandler = factory.createURLStreamHandler("jar");
 153         } else {
 154             jarHandler = null;
 155         }
 156         if (DISABLE_ACC_CHECKING)
 157             this.acc = null;
 158         else
 159             this.acc = acc;
 160     }
 161 
 162     public URLClassPath(URL[] urls, AccessControlContext acc) {
 163         this(urls, null, acc);
 164     }
 165 
 166     /**
 167      * Constructs a URLClassPath from a class path string.
 168      * Empty path strings are later used to open a directory that defaults
 169      * to the current directory.
 170      *
 171      * @param cp the class path string
 172      * @param skipEmptyElements indicates if empty elements are ignored or
 173      *        treated as the current working directory
 174      *
 175      * @apiNote Used to create the application class path.
 176      */
 177     URLClassPath(String cp, boolean skipEmptyElements) {
 178         String[] strings = PathParser
 179                 .parsePath(Objects.requireNonNullElse(cp, ""),
 180                         skipEmptyElements ? null : "");
 181         int size = strings.length;
 182         ArrayList<URL> path = new ArrayList<>(size);
 183         ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);










 184 
 185         // can't use ArrayDeque#addAll or new ArrayDeque(Collection);
 186         // it's too early in the bootstrap to trigger use of lambdas
 187         // Add a URL for each path element to the paths and the unopenedUrls.
 188         for (String s : strings) {
 189             URL url = toFileURL(s);
 190             path.add(url);
 191             unopenedUrls.add(url);
 192         }
 193 
 194         this.unopenedUrls = unopenedUrls;
 195         this.path = path;
 196         this.jarHandler = null;
 197         this.acc = null;
 198     }
 199 
 200     public synchronized List<IOException> closeLoaders() {
 201         if (closed) {
 202             return Collections.emptyList();
 203         }
 204         List<IOException> result = new LinkedList<>();
 205         for (Loader loader : loaders) {
 206             try {
 207                 loader.close();
 208             } catch (IOException e) {
 209                 result.add(e);
 210             }
 211         }
 212         closed = true;


< prev index next >