alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SAJDIClassLoader.java)

This example Java source code file (SAJDIClassLoader.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

class, classnotfoundexception, debug, inputstream, net, network, runtimeexception, sajdiclassloader, string, url, urlclassloader

The SAJDIClassLoader.java Java example source code

/*
 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code 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 code 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 in the LICENSE file that
 * accompanied this code).
 *
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.jdi;

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

/*
 * This class loader is used for two different reasons:
 *
 * 1) To support multiple simultaneous debuggees.
 *
 * SA's architecture does not allow us to use multiple simultaneous
 * debuggees. This is because of lots of static fields caching
 * vmStruct fields and singleton assumption in classes such as
 * 'sun.jvm.hotspot.runtime.VM'. Hence, we use instances of this
 * class loader to create a separate namespace for each debuggee VM.
 *
 * 2) To support cross VM version debugging.
 *
 * SA has very close dependency on VM data structures. Due to this, a
 * version of SA can only support debuggees running a same dot-dot release and
 * update releases only. For eg. this version of SA supports only 1.4.2 and
 * 1.4.2_xx releases only. But, users may want to debug debuggees running
 * a different version of VM. To support this, we use an instance of this
 * class loader to load classes from corresponding sa-jdi.jar.
 *
 * Note that JDI classes would still be loaded from the debugger's tools.jar
 * and not from debuggee's tools.jar. This means that if JDI interface evolved
 * b/w debuggee and debugger VM versions, user may still get problems. This is
 * the case when debugger runs on 1.5.0 and debuggee runs on 1.4.2. Because JDI
 * evolved b/w these versions (generics, enum, varargs etc.), 1.4.2 sa-jdi.jar
 * won't implement 1.5.0 JDI properly and user would get verifier errors. This
 * class loader solution is suited for different dot-dot release where JDI will
 * not evolve but VM data structures might change and SA implementation might
 * have to change. For example, a debuggee running 1.5.1 VM can be debugged
 * with debugger running on 1.5.0 VM. Here, JDI is same but VM data structures
 * could still change.
 */

class SAJDIClassLoader extends URLClassLoader {
    private static final boolean DEBUG;
    static {
        DEBUG = System.getProperty("sun.jvm.hotspot.jdi.SAJDIClassLoader.DEBUG") != null;
    }

    private ClassLoader parent;
    private boolean classPathSet;

    SAJDIClassLoader(ClassLoader parent) {
        super(new URL[0], parent);
        this.parent = parent;
    }

    SAJDIClassLoader(ClassLoader parent, String classPath) {
        this(parent);
        this.classPathSet = true;
        try {
            addURL(new File(classPath).toURI().toURL());
        } catch(MalformedURLException mue) {
            throw new RuntimeException(mue);
        }
    }

    public synchronized Class loadClass(String name)
        throws ClassNotFoundException {
        // First, check if the class has already been loaded
        Class c = findLoadedClass(name);
        if (c == null) {
            /* If we are loading any class in 'sun.jvm.hotspot.'  or any of the
             * sub-packages (except for 'debugger' sub-pkg. please refer below),
             * we load it by 'this' loader. Or else, we forward the request to
             * 'parent' loader, system loader etc. (rest of the code follows
             * the patten in java.lang.ClassLoader.loadClass).
             *
             * 'sun.jvm.hotspot.debugger.' and sub-package classes are
             * also loaded by parent loader. This is done for two reasons:
             *
             * 1. to avoid code bloat by too many classes.
             * 2. to avoid loading same native library multiple times
             *    from multiple class loaders (which results in getting a
             *    UnsatisifiedLinkageError from System.loadLibrary).
             */

            if (name.startsWith("sun.jvm.hotspot.") &&
                !name.startsWith("sun.jvm.hotspot.debugger.")) {
                return findClass(name);
            }
            if (parent != null) {
                c = parent.loadClass(name);
            } else {
                c = findSystemClass(name);
            }
        }
        return c;
    }

    protected Class findClass(String name) throws ClassNotFoundException {
        if (DEBUG) {
            System.out.println("SA/JDI loader: about to load " + name);
        }
        if (classPathSet) {
            return super.findClass(name);
        } else {
            byte[] b = null;
            try {
                InputStream in = getResourceAsStream(name.replace('.', '/') + ".class");
                // Read until end of stream is reached
                b = new byte[1024];
                int total = 0;
                int len = 0;
                while ((len = in.read(b, total, b.length - total)) != -1) {
                    total += len;
                    if (total >= b.length) {
                        byte[] tmp = new byte[total * 2];
                        System.arraycopy(b, 0, tmp, 0, total);
                        b = tmp;
                    }
                }
                // Trim array to correct size, if necessary
                if (total != b.length) {
                    byte[] tmp = new byte[total];
                    System.arraycopy(b, 0, tmp, 0, total);
                    b = tmp;
                }
            } catch (Exception exp) {
                throw (ClassNotFoundException) new ClassNotFoundException().initCause(exp);
            }
            return defineClass(name, b, 0, b.length);
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java SAJDIClassLoader.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.