classloader.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,855 行 · 第 1/5 页
JAVA
1,855 行
final int i = name.lastIndexOf('.'); if (i != -1) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { sm.checkPackageAccess(name.substring(0, i)); return null; } }, new AccessControlContext(new ProtectionDomain[] {pd})); } } domains.add(pd); } /** * Finds the specified class. This method should be overridden by class * loader implementations that follow the delegation model for loading * classes, and will be invoked by the {@link #loadClass * <tt>loadClass</tt>} method after checking the parent class loader for * the requested class. The default implementation throws a * <tt>ClassNotFoundException</tt>. </p> * * @param name * The name of the class * * @return The resulting <tt>Class</tt> object * * @throws ClassNotFoundException * If the class could not be found * * @since 1.2 */ protected Class findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); } /** * Converts an array of bytes into an instance of class <tt>Class</tt>. * Before the <tt>Class</tt> can be used it must be resolved. This method * is deprecated in favor of the version that takes the class name as its * first argument, and is more secure. * * @param b * The bytes that make up the class data. The bytes in positions * <tt>off</tt> through <tt>off+len-1</tt> should have the format * of a valid class file as defined by the <a * href="http://java.sun.com/docs/books/vmspec/">Java Virtual * Machine Specification</a>. * * @param off * The start offset in <tt>b</tt> of the class data * * @param len * The length of the class data * * @return The <tt>Class</tt> object that was created from the specified * class data * * @throws ClassFormatError * If the data did not contain a valid class * * @throws IndexOutOfBoundsException * If either <tt>off</tt> or <tt>len</tt> is negative, or if * <tt>off+len</tt> is greater than <tt>b.length</tt>. * * @see #loadClass(String, boolean) * @see #resolveClass(Class) * * deprecated Replaced by {@link #defineClass(String, byte[], int, int) * defineClass(String, byte[], int, int)} * protected final Class defineClass(byte[] b, int off, int len) throws ClassFormatError { return defineClass(null, b, off, len, null); } */ /** * Converts an array of bytes into an instance of class <tt>Class</tt>. * Before the <tt>Class</tt> can be used it must be resolved. * * <p> This method assigns a default {@link java.security.ProtectionDomain * <tt>ProtectionDomain</tt>} to the newly defined class. The * <tt>ProtectionDomain</tt> is effectively granted the same set of * permissions returned when {@link * java.security.Policy#getPermissions(java.security.CodeSource) * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>} * is invoked. The default domain is created on the first invocation of * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>}, * and re-used on subsequent invocations. * * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use * the {@link #defineClass(String, byte[], int, int, * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a * <tt>ProtectionDomain</tt> as one of its arguments. </p> * * @param name * The expected name of the class, or <tt>null</tt> * if not known, using '<tt>.</tt>' and not '<tt>/</tt>' as the * separator and without a trailing <tt>.class</tt> suffix. * * @param b * The bytes that make up the class data. The bytes in positions * <tt>off</tt> through <tt>off+len-1</tt> should have the format * of a valid class file as defined by the <a * href="http://java.sun.com/docs/books/vmspec/">Java Virtual * Machine Specification</a>. * * @param off * The start offset in <tt>b</tt> of the class data * * @param len * The length of the class data * * @return The <tt>Class</tt> object that was created from the specified * class data. * * @throws ClassFormatError * If the data did not contain a valid class * * @throws IndexOutOfBoundsException * If either <tt>off</tt> or <tt>len</tt> is negative, or if * <tt>off+len</tt> is greater than <tt>b.length</tt>. * * @throws SecurityException * If an attempt is made to add this class to a package that * contains classes that were signed by a different set of * certificates than this class (which is unsigned), or if the * class name begins with "<tt>java.</tt>". * * @see #loadClass(String, boolean) * @see #resolveClass(Class) * @see java.security.CodeSource * @see java.security.SecureClassLoader * * @since 1.1 */ protected final Class defineClass(String name, byte[] b, int off, int len) throws ClassFormatError { return defineClass(name, b, off, len, null); } /** * Converts an array of bytes into an instance of class <tt>Class</tt>, * with an optional <tt>ProtectionDomain</tt>. If the domain is * <tt>null</tt>, then a default domain will be assigned to the class as * specified in the documentation for {@link #defineClass(String, byte[], * int, int)}. Before the class can be used it must be resolved. * * <p> The first class defined in a package determines the exact set of * certificates that all subsequent classes defined in that package must * contain. The set of certificates for a class is obtained from the * {@link java.security.CodeSource <tt>CodeSource</tt>} within the * <tt>ProtectionDomain</tt> of the class. Any classes added to that * package must contain the same set of certificates or a * <tt>SecurityException</tt> will be thrown. Note that if the * <tt>name</tt> argument is <tt>null</tt>, this check is not performed. * You should always pass in the name of the class you are defining as * well as the bytes. This ensures that the class you are defining is * indeed the class you think it is. * * <p> The specified class name cannot begin with "<tt>java.</tt>", since * all classes in the "<tt>java.*</tt> packages can only be defined by the * bootstrap class loader. If the name parameter is not <tt>null</tt>, it * must be equal to the name of the class specified by the byte array * "<tt>b</tt>", otherwise a {@link <tt>NoClassDefFoundError</tt>} will be * thrown. </p> * * @param name * The expected name of the class, or <tt>null</tt> if not known, * using '<tt>.</tt>' and not '<tt>/</tt>' as the separator and * without a trailing "<tt>.class</tt>" suffix. * * @param b * The bytes that make up the class data. The bytes in positions * <tt>off</tt> through <tt>off+len-1</tt> should have the format * of a valid class file as defined by the <a * href="http://java.sun.com/docs/books/vmspec/">Java Virtual * Machine Specification</a>. * * @param off * The start offset in <tt>b</tt> of the class data * * @param len * The length of the class data * * @param protectionDomain * The ProtectionDomain of the class * * @return The <tt>Class</tt> object created from the data, * and optional <tt>ProtectionDomain</tt>. * * @throws ClassFormatError * If the data did not contain a valid class * * @throws NoClassDefFoundError * If <tt>name</tt> is not equal to the name of the class * specified by <tt>b</tt> * * @throws IndexOutOfBoundsException * If either <tt>off</tt> or <tt>len</tt> is negative, or if * <tt>off+len</tt> is greater than <tt>b.length</tt>. * * @throws SecurityException * If an attempt is made to add this class to a package that * contains classes that were signed by a different set of * certificates than this class, or if the class name begins with * "<tt>java.</tt>". */ protected final Class defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError { check(); if ((name != null) && name.startsWith("java.")) { throw new SecurityException("Prohibited package name: " + name.substring(0, name.lastIndexOf('.'))); } if (protectionDomain == null) { protectionDomain = getDefaultDomain(); } if (name != null) checkCerts(name, protectionDomain.getCodeSource()); if (!checkName(name)) throw new NoClassDefFoundError("Illegal name: " + name); Class c = null; try { c = defineClass0(name, b, off, len, protectionDomain); } catch (ClassFormatError cfe) { // Class format error - try to transform the bytecode and // define the class again // Object[] transformers = ClassFileTransformer.getTransformers(); for (int i = 0; transformers != null && i < transformers.length; i++) { try { // Transform byte code using transformer byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len); c = defineClass0(name, tb, 0, tb.length, protectionDomain); break; } catch (ClassFormatError cfe2) { // If ClassFormatError occurs, try next transformer } } // Rethrow original ClassFormatError if unable to transform // bytecode to well-formed // if (c == null) throw cfe; } /* load superclases in a way that avoids C recursion */ c.loadSuperClasses(); if (protectionDomain.getCodeSource() != null) { java.security.cert.Certificate certs[] = protectionDomain.getCodeSource().getCertificates(); if (certs != null) setSigners(c, certs); } return c; } private static boolean checkName(String name) { if (name == null || name.length() == 0) return true; if (name.indexOf('/') != -1) return false; if (name.charAt(0) == '[') return false; return true; } private native Class defineClass0(String name, byte[] b, int off, int len, ProtectionDomain pd); private synchronized void checkCerts(String name, CodeSource cs) { int i = name.lastIndexOf('.'); String pname = (i == -1) ? "" : name.substring(0, i); java.security.cert.Certificate[] pcerts = (java.security.cert.Certificate[]) package2certs.get(pname); if (pcerts == null) { // first class in this package gets to define which // certificates must be the same for all other classes // in this package if (cs != null) { pcerts = cs.getCertificates(); } if (pcerts == null) { if (nocerts == null) nocerts = new java.security.cert.Certificate[0]; pcerts = nocerts; } package2certs.put(pname, pcerts); } else { java.security.cert.Certificate[] certs = null; if (cs != null) { certs = cs.getCertificates(); } if (!compareCerts(pcerts, certs)) { throw new SecurityException("class \""+ name + "\"'s signer information does not match signer information of other classes in the same package"); } } } /** * check to make sure the certs for the new class (certs) are the same as * the certs for the first class inserted in the package (pcerts) */ private boolean compareCerts(java.security.cert.Certificate[] pcerts, java.security.cert.Certificate[] certs) { // certs can be null, indicating no certs. if ((certs == null) || (certs.length == 0)) { return pcerts.length == 0; } // the length must be the same at this point if (certs.length != pcerts.length) return false; // go through and make sure all the certs in one array // are in the other and vice-versa. boolean match; for (int i = 0; i < certs.length; i++) { match = false; for (int j = 0; j < pcerts.length; j++) { if (certs[i].equals(pcerts[j])) { match = true; break; } } if (!match) return false; } // now do the same for pcerts for (int i = 0; i < pcerts.length; i++) { match = false; for (int j = 0; j < certs.length; j++) { if (pcerts[i].equals(certs[j])) { match = true; break; } } if (!match) return false; } return true; } /** * Links the specified class. This (misleadingly named) method may be * used by a class loader to link a class. If the class <tt>c</tt> has * already been linked, then this method simply returns. Otherwise, the * class is linked as described in the "Execution" chapter of the <a * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>. * </p> * * @param c * The class to link * * @throws NullPointerException * If <tt>c</tt> is <tt>null</tt>.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?