18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.util.*; 29 import java.util.jar.JarFile; 30 import sun.misc.JarIndex; 31 import sun.misc.InvalidJarIndexException; 32 import sun.net.www.ParseUtil; 33 import java.util.zip.ZipEntry; 34 import java.util.jar.JarEntry; 35 import java.util.jar.Manifest; 36 import java.util.jar.Attributes; 37 import java.util.jar.Attributes.Name; 38 import java.net.JarURLConnection; 39 import java.net.MalformedURLException; 40 import java.net.URL; 41 import java.net.URLConnection; 42 import java.net.HttpURLConnection; 43 import java.net.URLStreamHandler; 44 import java.net.URLStreamHandlerFactory; 45 import java.io.*; 46 import java.security.AccessController; 47 import java.security.AccessControlException; 48 import java.security.CodeSigner; 49 import java.security.Permission; 50 import java.security.PrivilegedAction; 51 import java.security.PrivilegedExceptionAction; 52 import java.security.cert.Certificate; 53 import sun.misc.FileURLMapper; 54 import sun.net.util.URLUtil; 55 56 /** 57 * This class is used to maintain a search path of URLs for loading classes 58 * and resources from both JAR files and directories. 59 * 60 * @author David Connelly 61 */ 62 public class URLClassPath { 63 final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version"; 64 final static String JAVA_VERSION; 65 private static final boolean DEBUG; 66 67 static { 68 JAVA_VERSION = java.security.AccessController.doPrivileged( 69 new sun.security.action.GetPropertyAction("java.version")); 70 DEBUG = (java.security.AccessController.doPrivileged( 71 new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null); 72 } 73 74 /* The original search path of URLs. */ 75 private ArrayList<URL> path = new ArrayList<URL>(); 76 77 /* The stack of unopened URLs */ 78 Stack<URL> urls = new Stack<URL>(); 79 80 /* The resulting search path of Loaders */ 81 ArrayList<Loader> loaders = new ArrayList<Loader>(); 82 83 /* Map of each URL opened to its corresponding Loader */ 84 HashMap<String, Loader> lmap = new HashMap<String, Loader>(); 85 86 /* The jar protocol handler to use when creating new URLs */ 564 } 565 566 /* 567 * close this loader and release all resources 568 * method overridden in sub-classes 569 */ 570 public void close () throws IOException { 571 if (jarfile != null) { 572 jarfile.close(); 573 } 574 } 575 576 /* 577 * Returns the local class path for this loader, or null if none. 578 */ 579 URL[] getClassPath() throws IOException { 580 return null; 581 } 582 } 583 584 /* 585 * Inner class used to represent a Loader of resources from a JAR URL. 586 */ 587 static class JarLoader extends Loader { 588 private JarFile jar; 589 private URL csu; 590 private JarIndex index; 591 private MetaIndex metaIndex; 592 private URLStreamHandler handler; 593 private HashMap<String, Loader> lmap; 594 private boolean closed = false; 595 596 /* 597 * Creates a new JarLoader for the specified URL referring to 598 * a JAR file. 599 */ 600 JarLoader(URL url, URLStreamHandler jarHandler, 601 HashMap<String, Loader> loaderMap) 602 throws IOException 603 { 771 int pos; 772 if((pos = name.lastIndexOf("/")) != -1) { 773 packageName = name.substring(0, pos); 774 } 775 776 String entryName; 777 ZipEntry entry; 778 Enumeration<JarEntry> enum_ = jar.entries(); 779 while (enum_.hasMoreElements()) { 780 entry = enum_.nextElement(); 781 entryName = entry.getName(); 782 if((pos = entryName.lastIndexOf("/")) != -1) 783 entryName = entryName.substring(0, pos); 784 if (entryName.equals(packageName)) { 785 return true; 786 } 787 } 788 return false; 789 } 790 791 /* 792 * Returns the URL for a resource with the specified name 793 */ 794 URL findResource(final String name, boolean check) { 795 Resource rsc = getResource(name, check); 796 if (rsc != null) { 797 return rsc.getURL(); 798 } 799 return null; 800 } 801 802 /* 803 * Returns the JAR Resource for the specified name. 804 */ 805 Resource getResource(final String name, boolean check) { 806 if (metaIndex != null) { 807 if (!metaIndex.mayContain(name)) { 808 return null; 809 } 810 } 940 // If the count is unchanged, we are done. 941 } while(count < jarFilesList.size()); 942 return null; 943 } 944 945 946 /* 947 * Returns the JAR file local class path, or null if none. 948 */ 949 URL[] getClassPath() throws IOException { 950 if (index != null) { 951 return null; 952 } 953 954 if (metaIndex != null) { 955 return null; 956 } 957 958 ensureOpen(); 959 parseExtensionsDependencies(); 960 if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary 961 Manifest man = jar.getManifest(); 962 if (man != null) { 963 Attributes attr = man.getMainAttributes(); 964 if (attr != null) { 965 String value = attr.getValue(Name.CLASS_PATH); 966 if (value != null) { 967 return parseClassPath(csu, value); 968 } 969 } 970 } 971 } 972 return null; 973 } 974 975 /* 976 * parse the standard extension dependencies 977 */ 978 private void parseExtensionsDependencies() throws IOException { 979 ExtensionDependency.checkExtensionsDependencies(jar); | 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.util.*; 29 import java.util.jar.JarFile; 30 import sun.misc.JarIndex; 31 import sun.misc.InvalidJarIndexException; 32 import sun.net.www.ParseUtil; 33 import java.util.zip.ZipEntry; 34 import java.util.jar.JarEntry; 35 import java.util.jar.Manifest; 36 import java.util.jar.Attributes; 37 import java.util.jar.Attributes.Name; 38 import java.util.jar.UnsupportedProfileException; 39 import java.net.JarURLConnection; 40 import java.net.MalformedURLException; 41 import java.net.URL; 42 import java.net.URLConnection; 43 import java.net.HttpURLConnection; 44 import java.net.URLStreamHandler; 45 import java.net.URLStreamHandlerFactory; 46 import java.io.*; 47 import java.security.AccessController; 48 import java.security.AccessControlException; 49 import java.security.CodeSigner; 50 import java.security.Permission; 51 import java.security.PrivilegedAction; 52 import java.security.PrivilegedExceptionAction; 53 import java.security.cert.Certificate; 54 import sun.misc.FileURLMapper; 55 import sun.net.util.URLUtil; 56 57 /** 58 * This class is used to maintain a search path of URLs for loading classes 59 * and resources from both JAR files and directories. 60 * 61 * @author David Connelly 62 */ 63 public class URLClassPath { 64 final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version"; 65 final static String JAVA_VERSION; 66 private static final boolean DEBUG; 67 68 /** 69 * Used by launcher to indicate that checking of the JAR file "Profile" 70 * attribute has been suppressed. 71 */ 72 private static boolean profileCheckSuppressedByLauncher; 73 74 static { 75 JAVA_VERSION = java.security.AccessController.doPrivileged( 76 new sun.security.action.GetPropertyAction("java.version")); 77 DEBUG = (java.security.AccessController.doPrivileged( 78 new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null); 79 } 80 81 /* The original search path of URLs. */ 82 private ArrayList<URL> path = new ArrayList<URL>(); 83 84 /* The stack of unopened URLs */ 85 Stack<URL> urls = new Stack<URL>(); 86 87 /* The resulting search path of Loaders */ 88 ArrayList<Loader> loaders = new ArrayList<Loader>(); 89 90 /* Map of each URL opened to its corresponding Loader */ 91 HashMap<String, Loader> lmap = new HashMap<String, Loader>(); 92 93 /* The jar protocol handler to use when creating new URLs */ 571 } 572 573 /* 574 * close this loader and release all resources 575 * method overridden in sub-classes 576 */ 577 public void close () throws IOException { 578 if (jarfile != null) { 579 jarfile.close(); 580 } 581 } 582 583 /* 584 * Returns the local class path for this loader, or null if none. 585 */ 586 URL[] getClassPath() throws IOException { 587 return null; 588 } 589 } 590 591 /** 592 * Used by the launcher to suppress further checking of the JAR file Profile 593 * attribute (necessary when the launcher is aborting as the abort involves 594 * a resource lookup that may involve opening additional JAR files) 595 */ 596 public static void suppressProfileCheckForLauncher() { 597 profileCheckSuppressedByLauncher = true; 598 } 599 600 /* 601 * Inner class used to represent a Loader of resources from a JAR URL. 602 */ 603 static class JarLoader extends Loader { 604 private JarFile jar; 605 private URL csu; 606 private JarIndex index; 607 private MetaIndex metaIndex; 608 private URLStreamHandler handler; 609 private HashMap<String, Loader> lmap; 610 private boolean closed = false; 611 612 /* 613 * Creates a new JarLoader for the specified URL referring to 614 * a JAR file. 615 */ 616 JarLoader(URL url, URLStreamHandler jarHandler, 617 HashMap<String, Loader> loaderMap) 618 throws IOException 619 { 787 int pos; 788 if((pos = name.lastIndexOf("/")) != -1) { 789 packageName = name.substring(0, pos); 790 } 791 792 String entryName; 793 ZipEntry entry; 794 Enumeration<JarEntry> enum_ = jar.entries(); 795 while (enum_.hasMoreElements()) { 796 entry = enum_.nextElement(); 797 entryName = entry.getName(); 798 if((pos = entryName.lastIndexOf("/")) != -1) 799 entryName = entryName.substring(0, pos); 800 if (entryName.equals(packageName)) { 801 return true; 802 } 803 } 804 return false; 805 } 806 807 /** 808 * If the Profile attribtue is present then this method checks that the runtime 809 * supports that profile. 810 * 811 * ## Add a fast path like Class-Path to avoid reading the manifest when the attribute 812 * is not present. 813 */ 814 void checkProfileAttribute() throws IOException { 815 Manifest man = jar.getManifest(); 816 if (man != null) { 817 Attributes attr = man.getMainAttributes(); 818 if (attr != null) { 819 String value = attr.getValue(Name.PROFILE); 820 if (value != null && !Version.supportsProfile(value)) { 821 String prefix = Version.profileName().length() > 0 ? 822 "This runtime implements " + Version.profileName() + ", " : ""; 823 throw new UnsupportedProfileException(prefix + csu + " requires " + value); 824 } 825 } 826 } 827 } 828 829 /* 830 * Returns the URL for a resource with the specified name 831 */ 832 URL findResource(final String name, boolean check) { 833 Resource rsc = getResource(name, check); 834 if (rsc != null) { 835 return rsc.getURL(); 836 } 837 return null; 838 } 839 840 /* 841 * Returns the JAR Resource for the specified name. 842 */ 843 Resource getResource(final String name, boolean check) { 844 if (metaIndex != null) { 845 if (!metaIndex.mayContain(name)) { 846 return null; 847 } 848 } 978 // If the count is unchanged, we are done. 979 } while(count < jarFilesList.size()); 980 return null; 981 } 982 983 984 /* 985 * Returns the JAR file local class path, or null if none. 986 */ 987 URL[] getClassPath() throws IOException { 988 if (index != null) { 989 return null; 990 } 991 992 if (metaIndex != null) { 993 return null; 994 } 995 996 ensureOpen(); 997 parseExtensionsDependencies(); 998 999 // check Profile attribute if present 1000 if (!profileCheckSuppressedByLauncher) 1001 checkProfileAttribute(); 1002 1003 if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary 1004 Manifest man = jar.getManifest(); 1005 if (man != null) { 1006 Attributes attr = man.getMainAttributes(); 1007 if (attr != null) { 1008 String value = attr.getValue(Name.CLASS_PATH); 1009 if (value != null) { 1010 return parseClassPath(csu, value); 1011 } 1012 } 1013 } 1014 } 1015 return null; 1016 } 1017 1018 /* 1019 * parse the standard extension dependencies 1020 */ 1021 private void parseExtensionsDependencies() throws IOException { 1022 ExtensionDependency.checkExtensionsDependencies(jar); |