midletclassloader.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 307 行

JAVA
307
字号
/* * @(#)MIDletClassLoader.java   1.11 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* * @(#)MIDletClassLoader.java   1.5     03/07/09 * * Class loader for midlets running on CDC/PP * * It loads from a single JAR file and deligates to other class loaders.  * It has a few of interesting properties: * 1) it is careful, perhaps overly so, about not loading classes that *    are in system packages from the JAR file persumed to contain the MIDlet *    code. * 2) it uses a MemberFilter to process classes for illegal field references. *    This is easiest to do after the constant pool is set up. * 3) it remembers which classes have failed the above test and refuses to *    load them, even though the system thinks they're already loaded. * * It lets the underlying URLClassLoader do all the hard work. *     */package sun.misc;import java.net.URL;import java.net.URLConnection;import java.net.URLClassLoader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.HashSet;import java.security.CodeSource;import java.security.PermissionCollection;import java.security.AccessController;import java.security.AccessControlContext;import java.security.PrivilegedAction;public class MIDletClassLoader extends URLClassLoader {    URL     myBase[];    String[]systemPkgs;    private MemberFilter memberChecker; /* to check for amputated members */    private PermissionCollection perms;    private HashSet badMidletClassnames = new HashSet();    private MIDPImplementationClassLoader implementationClassLoader;    private AccessControlContext ac = AccessController.getContext();    /*     * If the filter is disabled, all classes on the bootclasspath     * can be accessed from midlet.     */    private boolean enableFilter;    private ClassLoader auxClassLoader;    public MIDletClassLoader(        URL base[],        String systemPkgs[],        PermissionCollection pc,        MemberFilter mf,        MIDPImplementationClassLoader  parent,        boolean enableFilter,        ClassLoader auxClassLoader)    {        super(base, parent);        myBase = base;        this.systemPkgs = systemPkgs;        memberChecker = mf;        perms = pc;        implementationClassLoader = parent;        this.enableFilter = enableFilter;        this.auxClassLoader = auxClassLoader;    }    protected PermissionCollection getPermissions(CodeSource cs){        URL srcLocation = cs.getLocation();        for (int i=0; i<myBase.length; i++){            if (srcLocation.equals(myBase[i])){                return perms;            }        }        return super.getPermissions(cs);    }    /* Check if class belongs to restricted system packages. */    private boolean    packageCheck(String pkg) {        String forbidden[] = systemPkgs;        int fLength = forbidden.length;        /* First check the default list specified by MIDPConfig */        for (int i=0; i< fLength; i++){            if (pkg.startsWith(forbidden[i])){                return true;            }        }        /* Then Check with MIDPPkgChecker. The MIDPPkgChecker knows         * the restricted MIDP and JSR packages specified in their         * rom.conf files. */        return MIDPPkgChecker.checkPackage(pkg);    }    private Class    loadFromUrl(String classname) throws ClassNotFoundException    {        Class newClass;        try {            newClass = super.findClass(classname); // call URLClassLoader        }catch(Exception e){            /*DEBUG e.printStackTrace(); */            // didn't find it.            return null;        }        if (newClass == null )            return null;        /*         * Found the requested class. Make sure it's not from         * restricted system packages.         */        int idx = classname.lastIndexOf('.');        if (idx != -1) {            String pkg = classname.substring(0, idx);            if (packageCheck(pkg)) {                throw new ClassNotFoundException(classname +                              ". Prohibited package name: " + pkg);            }        }        /*         * Check member access to make sure the class doesn't         * access any hidden CDC APIs.         */        try {            // memberChecker will throw an Error if it doesn't like            // the class.            if (enableFilter) {                memberChecker.checkMemberAccessValidity(newClass);            }            return newClass;        } catch (Error e){            // If this happens, act as if we cannot find the class.            // remember this class, too. If the MIDlet catches the            // Exception and tries again, we don't want findLoadedClass()            // to return it!!            badMidletClassnames.add(classname);            throw new ClassNotFoundException(e.getMessage());        }    }    public synchronized Class    loadClass(String classname, boolean resolve) throws ClassNotFoundException    {        Class resultClass;        Throwable err = null;        int i = classname.lastIndexOf('.');        if (i != -1) {            SecurityManager sm = System.getSecurityManager();            if (sm != null) {                sm.checkPackageAccess(classname.substring(0, i));            }        }        classname = classname.intern();        if (badMidletClassnames.contains(classname)){            // the system thinks it successfully loaded this class.            // But the member checker does not think we should be able            // to use it. We threw an Exception before. Do it again.            throw new ClassNotFoundException(classname.concat(                        " contains illegal member reference"));        }        /* First, check to see if the class has already been loaded. */        resultClass = findLoadedClass(classname);        /* Class has not been loaded. Delegate to the parent classloader. */        if (resultClass == null){            try {                /* Ask the parent to load the class for us. But first                 * make sure the class is allowed to be accessed by                 * midlet.                 */                if (!enableFilter ||                    MIDPConfig.isClassAllowed(classname)) {                    resultClass = implementationClassLoader.loadClass(                                      classname, false);                }            } catch (ClassNotFoundException e) {            } catch (NoClassDefFoundError e) {            }        }        /* Try loading the class ourselves. */        if (resultClass == null) {            try {                resultClass = loadFromUrl(classname);            } catch (ClassNotFoundException e) {                err = e;            } catch (NoClassDefFoundError e) {                err = e;            }        }        /*         * If MIDletClassLoader and the parents failed to         * load the class, try the auxClassLoader.         */        if (resultClass == null && auxClassLoader != null) {            resultClass = auxClassLoader.loadClass(classname);        }        if (resultClass == null) {            if (err == null) {                throw new ClassNotFoundException(classname);            } else {                if (err instanceof ClassNotFoundException) {                    throw (ClassNotFoundException)err;                } else {                    throw (NoClassDefFoundError)err;                }            }        }        if (resolve) {            resolveClass(resultClass);        }        return resultClass;    }   public InputStream   getResourceAsStream(String name){        // prohibit reading .class as a resource        if (name.endsWith(".class")){            return null; // not allowed!        }                int i;        // Replace /./ with /        while ((i = name.indexOf("/./")) >= 0) {            name = name.substring(0, i) + name.substring(i + 2);        }        // Replace /segment/../ with /        i = 0;        int limit;        while ((i = name.indexOf("/../", i)) > 0) {            if ((limit = name.lastIndexOf('/', i - 1)) >= 0) {                name = name.substring(0, limit) + name.substring(i + 3);                i = 0;            } else {                i = i + 3;            }        }        // The JAR reader cannot find the resource if the name starts with         // a slash.  So we remove the leading slash if one exists.        if (name.startsWith("/") || name.startsWith(File.separator)) {                  name = name.substring(1);        }                final String n = name;        // do not delegate. We only use our own URLClassLoader.findResource to        // look in our own JAR file. That is always allowed.        // Nothing else is.        InputStream retval;        retval = (InputStream) AccessController.doPrivileged(                new PrivilegedAction(){                    public Object run(){                        URL url = findResource(n);                        try {                            return url != null ? url.openStream() : null;                        } catch (IOException e) {                            return null;                        }                    }                }, ac);        return retval;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?