FileDocCategorySizeDatePackage
JRClassLoader.javaAPI DocExample4169Mon Jan 15 13:33:08 GMT 2001javasec.samples.appd

JRClassLoader.java

package javasec.samples.appd;

import java.io.*;
import java.net.*;
import java.util.*;

public class JRClassLoader extends ClassLoader {

    private URL urlBase;
    private static URL trustedBase;
    private Hashtable trustedClasses;
    private static int groupNum;
    private ThreadGroup threadGroup;

    static {
        String s = System.getProperty("trustedBase");
        if (s != null)
            try {
                trustedBase = new URL(s);
            } catch (Exception e) {
                throw new IllegalArgumentException(
                                 "Bad value for trustedBase " + s);
            }
    }

    public JRClassLoader(String base) {
        try {
            if (!(base.endsWith("/")))
                base = base + "/";
                urlBase = new URL(base);
        } catch (Exception e) {
            throw new IllegalArgumentException(base);
        }
        trustedClasses = new Hashtable(13);
    }

    protected Class loadClass(String name, boolean resolve) {
        Class c;
        SecurityManager sm = System.getSecurityManager();

        // Step 1 -- Check to make sure that we can access this class
        if (sm != null) {
        int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageAccess(name.substring(0, i));
        }

         // Step 2 -- Check for a previously loaded class
         c = findLoadedClass(name);
         if (c != null)
            return c;

        // Step 3 -- Check for system class first
        try {
            c = findSystemClass(name);
            return c;
        } catch (ClassNotFoundException cnfe) {
            // Not a system class, simply continue
        }

        // Step 4 -- Check to make sure that we can define this class
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0)
                sm.checkPackageDefinition(name.substring(0, i));
        }

        // Step 5 -- Read in the class file
        byte data[] = lookupData(name);
        if (data == null)
             return null;

        // Step 6 and 7 -- Define the class from the data; this also
        //         passes the data through the byte code verifier
        c = defineClass(name, data, 0, data.length);
        if (trustedClasses.get(name) != null) {
            trustedClasses.remove(name);
            trustedClasses.put(c, name);
        }

        // Step 8 -- Resolve the internal references of the class
        if (resolve)
            resolveClass(c);

        return c;
    }

    byte[] lookupData(String n) {
        try {
            byte[] b = null;
            String urlName = n.replace('.', '/');

            if (trustedBase != null) {
                URL url = new URL(trustedBase, urlName + ".class");
                b = readData(url);
            }

            if (b == null) {
                URL url = new URL(urlBase, urlName + ".class");
                b = readData(url);
            }
            else trustedClasses.put(n, "dummy");

            return b;
        } catch (Exception e) {
            return null;
        }
    }

    byte[] readData(URL url) {
        try {
            InputStream is = url.openConnection().getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            boolean eof = false;
            while (!eof) {
                int i = bis.read();
                if (i == -1)
                    eof = true;
                else baos.write(i);
            }
            return baos.toByteArray();
        } catch (Exception e) {
            return null;
        }
    }

    boolean getTrusted(Class c) {
        return trustedClasses.get(c) != null;
    }

    private static synchronized int getGroupNum() {
        return groupNum++;
    }

    synchronized ThreadGroup getThreadGroup() {
        if (threadGroup == null)
            threadGroup = new ThreadGroup("JavaRunner ThreadGroup-"
                                          + getGroupNum());
        return threadGroup;
    }

    String getHost() {
        return urlBase.getHost();
    }
}