Java/Reflection/ClassPath

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Classpath Utils

 
/**
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright
 *    statements and notices.  Redistributions must also contain a
 *    copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. The name "OpenEJB" must not be used to endorse or promote
 *    products derived from this Software without prior written
 *    permission of The OpenEJB Group.  For written permission,
 *    please contact openejb-group@openejb.sf.net.
 *
 * 4. Products derived from this Software may not be called "OpenEJB"
 *    nor may "OpenEJB" appear in their names without prior written
 *    permission of The OpenEJB Group. OpenEJB is a registered
 *    trademark of The OpenEJB Group.
 *
 * 5. Due credit should be given to the OpenEJB Project
 *    (http://openejb.sf.net/).
 *
 * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
 * ``AS IS"" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
 *
 * $Id: ClasspathUtils.java 1076 2004-03-01 07:17:26Z dblevins $
 */
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
 */
public class ClasspathUtils{
    
    private static Loader tomcatLoader = new ClasspathUtils().new TomcatLoader();
    private static Loader sysLoader = new ClasspathUtils().new SystemLoader();
    private static Loader ctxLoader = new ClasspathUtils().new ContextLoader();
    
   
    public static void addJarToPath(final File jar) throws Exception {
        addJarToPath( jar.toURI().toURL() );
    }       
    public static void addJarToPath(final URL jar) throws Exception {
        getLoader().addJarToPath( jar );
    }       
    
     
    public static void addJarToPath(final File jar, String loaderName) throws Exception {
        addJarToPath( jar.toURI().toURL() , loaderName);
    }       
    public static void addJarToPath(final URL jar, String loaderName) throws Exception {
        getLoader(loaderName).addJarToPath( jar );
    }       
    
     
    public static void addJarsToPath(final File dir) throws Exception {
        if ( dir == null ) return;
        getLoader().addJarsToPath( dir );
    }       
    
    
    public static void addJarsToPath(final File dir, String loaderName) throws Exception {
        getLoader(loaderName).addJarsToPath( dir );
    }       
   
    /**
     * Appends the jar to the classpath of the classloader passed in.
     *
     * @param url the URL to be added to the search path of URLs
     */
    public static void addJarToSystemPath(final File jar) throws Exception {
        addJarToSystemPath( jar.toURI().toURL() );
    }       
    /**
     * Appends the jar to the classpath of the classloader passed in.
     *
     * @param url the URL to be added to the search path of URLs
     */
    public static void addJarToSystemPath(final URL jar) throws Exception {
    }       
    
    protected static Loader getLoader(){
        String name = getContextClassLoader().getClass().getName();
        if (name.startsWith("org.apache.catalina.loader")) {
            return tomcatLoader;
        } else if (name.startsWith("org.apache.jasper.servlet")) {
            return tomcatLoader;
        } else if (name.startsWith( "sun.misc.Launcher" )) {
            return sysLoader;
        } else {
            return ctxLoader;
        }
    }
    
    protected static Loader getLoader(String name){
        if (name.equalsIgnoreCase("tomcat")) {
            return tomcatLoader;
        } else if (name.equalsIgnoreCase("bootstrap")) {
            return sysLoader;
        } else if (name.equalsIgnoreCase("system")) {
            return sysLoader;
        } else if (name.equalsIgnoreCase("thread")) {
            return ctxLoader;
        } else if (name.equalsIgnoreCase("context")) {
            return ctxLoader;
        } else {
            return ctxLoader;
        }
    }
    
    public static ClassLoader getContextClassLoader() {
        return (ClassLoader) java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
                public Object run() {
                    return Thread.currentThread().getContextClassLoader();
                }
            }
        );
    }
    public static void rebuildJavaClassPathVariable() throws Exception{
    }

    interface Loader {
        public void addJarsToPath(File dir) throws Exception;
        public void addJarToPath(URL dir) throws Exception;
    }
    
    class BasicURLLoader implements Loader{
        public void addJarsToPath(File dir) throws Exception {
        }
        
        public void addJarToPath(URL jar) throws Exception {
        }
    
        private java.lang.reflect.Field ucpField;
        
    
        protected void addJarToPath(final URL jar, final URLClassLoader loader) throws Exception {
            this.getURLClassPath(loader).addURL( jar );
        }
    
        protected void addJarsToPath(final File dir, final URLClassLoader loader) throws Exception {
        //System.out.println("DIR "+dir);
        // Get the list of jars and zips
        String[] jarNames = dir.list(new java.io.FilenameFilter(){
            public boolean accept(File dir, String name) {
                //System.out.println("FILE "+name);
                return (name.endsWith(".jar") ||name.endsWith(".zip"));
            }
        });
        // Create URLs from them
        final URL[] jars = new URL[jarNames.length];
        for (int j=0; j < jarNames.length; j++){
            jars[j] = new File( dir, jarNames[j]).toURI().toURL();
            }
        
        sun.misc.URLClassPath path = getURLClassPath(loader);
        for (int i=0; i < jars.length; i++){
            //System.out.println("URL "+jars[i]);
            path.addURL( jars[i] );
        }
    }
        protected sun.misc.URLClassPath getURLClassPath(URLClassLoader loader) throws Exception{
        return (sun.misc.URLClassPath)getUcpField().get(loader);
    }
        private java.lang.reflect.Field getUcpField() throws Exception{
        if (ucpField == null) {
            // Add them to the URLClassLoader"s classpath
            ucpField = (java.lang.reflect.Field)AccessController.doPrivileged(
                new PrivilegedAction(){
                    public Object run() { 
                        java.lang.reflect.Field ucp = null;
                        try{
                        ucp = URLClassLoader.class.getDeclaredField("ucp");
                        ucp.setAccessible(true);
                        } catch (Exception e2){
                            e2.printStackTrace();
                        }
                        return ucp;
                    }
                }
            );
        }
        
        return ucpField;
    }
}
    /*-------------------------------------------------------*/
    /*    System ClassLoader Support                         */
    /*-------------------------------------------------------*/
    class SystemLoader extends BasicURLLoader{
        
        private URLClassLoader sysLoader;
    
        public void addJarsToPath(File dir) throws Exception {
            this.addJarsToPath( dir , getSystemLoader() );
            this.rebuildJavaClassPathVariable();
        }
        
        public void addJarToPath(URL jar) throws Exception {
            //System.out.println("[|] SYSTEM "+jar.toExternalForm());
            this.addJarToPath( jar, getSystemLoader() );
            this.rebuildJavaClassPathVariable();
        }
    
        private URLClassLoader getSystemLoader() throws Exception{
            if (sysLoader == null) {
                sysLoader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
            }
            return sysLoader;
        }
        
        private void rebuildJavaClassPathVariable() throws Exception{
            sun.misc.URLClassPath cp = getURLClassPath(getSystemLoader());
            URL[] urls = cp.getURLs();
            //for (int i=0; i < urls.length; i++){
            //    System.out.println(urls[i].toExternalForm());
            //}
            if (urls.length < 1) return;
    
            StringBuffer path = new StringBuffer(urls.length*32);
            
            File s = new File( urls[0].getFile() );
            path.append( s.getPath() );
            //System.out.println(s.getPath());
    
            for (int i=1; i < urls.length; i++){
                path.append( File.pathSeparator );
                
                s = new File( urls[i].getFile() );
                //System.out.println(s.getPath());
                path.append( s.getPath() );
            }
            try{
                System.setProperty("java.class.path", path.toString() );
            } catch (Exception e){}
        }
    }
    
    /*-------------------------------------------------------*/
    /*    Thread Context ClassLoader Support                 */
    /*-------------------------------------------------------*/
    class ContextLoader extends BasicURLLoader{
        
        public void addJarsToPath(File dir) throws Exception {
            URLClassLoader loader = (URLClassLoader)ClasspathUtils.getContextClassLoader();
            this.addJarsToPath( dir , loader );
        }
        
        public void addJarToPath(URL jar) throws Exception {
            URLClassLoader loader = (URLClassLoader)ClasspathUtils.getContextClassLoader();
            this.addJarToPath( jar, loader );
        }
    }
    
    /*-------------------------------------------------------*/
    /*    Tomcat ClassLoader Support                         */
    /*-------------------------------------------------------*/
    class TomcatLoader extends BasicURLLoader{
    
        /**
         * The Tomcat Common ClassLoader
         */
        private ClassLoader tomcatLoader;
    
    
        /**
         * The addRepository(String jar) method of the Tomcat Common ClassLoader
         */
        private java.lang.reflect.Method addRepositoryMethod;
        
        public void addJarsToPath(File dir) throws Exception {
            String[] jarNames = dir.list(new java.io.FilenameFilter(){
                public boolean accept(File dir, String name) {
                    //System.out.println("FILE "+name);
                    return (name.endsWith(".jar") ||name.endsWith(".zip"));
                }
            });
        
            for (int j=0; j < jarNames.length; j++){
                this.addJarToPath( new File( dir, jarNames[j]).toURL() );
            }
            rebuild();
        }
        
        public void addJarToPath(URL jar) throws Exception {
            //System.out.println("[|] TOMCAT "+jar.toExternalForm());
            this._addJarToPath(jar);
            rebuild();
        }
        public void _addJarToPath(URL jar) throws Exception {
            String path = jar.toExternalForm();
            //System.out.println("[] PATH "+path);
          //if (path.startsWith("file:/C")) {
          //    path = path.substring("file:/C".length());
          //    path = "file:C"+path;
          //}
            this.addRepository( path );
          //ClassLoader cl = ClasspathUtils.getContextClassLoader();
          //cl = getCommonLoader(cl);
          //System.out.println("[] "+cl.getClass().getName());
          //System.out.println("[] "+cl);
          //
          ////Reloader loader = (Reloader)cl.getParent();
          //cl = cl.getParent();
          //java.lang.reflect.Method m = getAddRepositoryMethod( cl.getClass());        
          //m.invoke( cl, new Object[]{jar.toExternalForm()});
          ////loader.addRepository( jar.toExternalForm() );
        }
        
        public void addRepository(String path) throws Exception{
            this.getAddRepositoryMethod().invoke(getCommonLoader(), new Object[]{path});        
        }
    
        private void rebuild(){
            try{
            sun.misc.URLClassPath cp = getURLClassPath((URLClassLoader)getCommonLoader());
            URL[] urls = cp.getURLs();
            //for (int i=0; i < urls.length; i++){
            //    System.out.println(urls[i].toExternalForm());
            //}
            if (urls.length < 1) return;
            
            StringBuffer path = new StringBuffer(urls.length*32);
            
            File s = new File( urls[0].getFile() );
            path.append( s.getPath() );
            //System.out.println(s.getPath());
            
            for (int i=1; i < urls.length; i++){
                path.append( File.pathSeparator );
            
                s = new File( urls[i].getFile() );
                //System.out.println(s.getPath());
                path.append( s.getPath() );
            }
            System.setProperty("java.class.path", path.toString() );
            } catch (Exception e){}
        }
        private ClassLoader getCommonLoader(){
            if (tomcatLoader == null) {
                tomcatLoader = this.getCommonLoader(ClasspathUtils.getContextClassLoader()).getParent();
            }
            return tomcatLoader;
        }
    
        private ClassLoader getCommonLoader(ClassLoader loader){
            if (loader.getClass().getName().equals("org.apache.catalina.loader.StandardClassLoader")) {
                return loader;                
            } else {
                return this.getCommonLoader(loader.getParent());
            }
        }
    
        /**
         * This method gets the Tomcat StandardClassLoader.addRepository method via
         * reflection.  This allows us to call the addRepository method for Tomcat
         * integration, but doesn"t require us to include or ship any Tomcat 
         * libraries.
         * 
         * @param clazz
         * @return 
         * @exception Exception
         */
        private java.lang.reflect.Method getAddRepositoryMethod() 
        throws Exception{
            if (addRepositoryMethod == null) {
                final Class clazz = getCommonLoader().getClass();
                this.addRepositoryMethod = (java.lang.reflect.Method)AccessController.doPrivileged(
                    new PrivilegedAction(){
                        public Object run() { 
                            java.lang.reflect.Method method = null;
                            try{
                                method = clazz.getDeclaredMethod("addRepository", 
                                                                 new Class[]{String.class});
                                method.setAccessible(true);
                            } catch (Exception e2){
                                e2.printStackTrace();
                            }
                            return method;
                        }
                    }
                );
            }
            
            return addRepositoryMethod;
        }
    }
}





Find occurrencens of a classname in system classpath or the specified ClassLoader

 
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don"t indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
/*
Copyright (c) 2003, theshoemakers.org
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright notice, this 
      list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, 
      this list of conditions and the following disclaimer in the documentation 
      and/or other materials provided with the distribution.
    * Neither the name of the theshoemakers.org nor the names of its contributors 
      may be used to endorse or promote products derived from this software without 
      specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.StringTokenizer;
/**
 * Find occurrencens of a particular classname in the system classpath
 * or the specified ClassLoader.
 * 
 * This class can be run in command-line mode to search your system
 * classpath for all occurrences of the specified classname.
 * 
 * This class can also be used programmatically to search a particular
 * ClassLoader for the first occurrence of the specified classname.
 * <p>
 * Revision: $Revision: 1.2 $
 * 
 * @author , Sun Microsystems, Inc.
 * @version 0.1
 */
public class Which4J {
    private static boolean debug = false;
    /**
     * Main method used in command-line mode for searching the system
     * classpath for <em>all</em> occurrences of the specified classname.
     * 
     * @param args command-line arguments (run "<code>java org.theshoemakers.tools.which4j.Which4J 
     *             -help</code>" for a detailed description).
     */
    public static void main(String[] args) {
        if (args.length == 2) {
            if (args[0].equals("-debug")) {
                debug = true;
                findIt(args[1]);
            } else {
                System.err.println(
                    "error: unrecognized \"" + args[0] + "\" option ");
                System.exit(-1);
            }
        } else if (args.length == 1 && args[0].equals("-help")) {
            usage();
        } else if (args.length == 1) {
            findIt(args[0]);
        } else {
            usage();
        }
        System.exit(0);
    }
    private static void usage() {
        System.err.println(
            "usage: java Which4J [-debug] <classname>"
                + "\n\tThe commandline version of Which4J will search the system"
                + "\tclasspath defined in your environment for all occurences"
                + "\tof the class.  Alternatively, you can use this class"
                + "\tprogrammatically to search the current (or any) ClassLoader."
                + "\tSee the javadoc for more detail."
                + "\n\t"
                + "\n\tNote: if the name of the jar file listed after \"found in:\""
                + "\tdoesn"t match the name of the jar listed next to \"url:\", then "
                + "\tthere is likely a \"Class-Path\" entry in the jar manifest "
                + "\tthat is causing the classloader to indirectly find the class.");
        System.exit(-1);
    }
    /**
     * Iterate over the system classpath defined by "java.class.path" searching
     * for all occurrances of the given class name.
     * 
     * @param classname the fully qualified class name to search for
     */
    private static void findIt(String classname) {
        try {
            // get the system classpath
            String classpath = System.getProperty("java.class.path", "");
            if (classpath.equals("")) {
                System.err.println("error: classpath is not set");
            }
            if (debug) {
                System.out.println("classname: " + classname);
                System.out.println("system classpath = " + classpath);
            }
            if (isPrimitiveOrVoid(classname)) {
                System.out.println(""" + classname + "" primitive");
                return;
            }
            StringTokenizer st =
                new StringTokenizer(classpath, File.pathSeparator);
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                File classpathElement = new File(token);
                if (debug)
                    System.out.println(
                        classpathElement.isDirectory()
                            ? "dir: " + token
                            : "jar: " + token);
                URL[] url = { classpathElement.toURL()};
                URLClassLoader cl = URLClassLoader.newInstance(url, null);
                String classnameAsResource =
                    classname.replace(".", "/") + ".class";
                URL it = cl.findResource(classnameAsResource);
                if (it != null) {
                    System.out.println("found in: " + token);
                    System.out.println("     url: " + it.toString());
                    System.out.println("");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * Search the current classloader for the given classname.
     * 
     * Equivalent to calling which( String classname, Which4J.class.getClassLoader ).
     * 
     * @param classname the fully qualified name of the class to search for
     * @return the source location of the resource, or null if it wasn"t found
     */
    public static String which(String classname) {
        return which(classname, Which4J.class.getClassLoader());
    }
    /**
     * Search the specified classloader for the given classname.
     * 
     * @param classname the fully qualified name of the class to search for
     * @param loader the classloader to search
     * @return the source location of the resource, or null if it wasn"t found
     */
    public static String which(String classname, ClassLoader loader) {
        if (isArrayType(classname)) {
            classname = getElementType(classname);
        }
        if (isPrimitiveOrVoid(classname)) {
            return """ + classname + "" primitive";
        }
        String classnameAsResource = classname.replace(".", "/") + ".class";
        if (loader == null) {
            // some VM"s return null from getClassLoader to indicate that
            // the class was loaded by the bootstrap class loader
            loader = ClassLoader.getSystemClassLoader();
        }
        URL it = loader.getResource(classnameAsResource);
        if (it != null) {
            return it.toString();
        } else {
            return null;
        }
    }
    /**
     * Search the current classloader for the given classname.
     * 
     * Equivalent to calling which( Class clazz, Which4J.class.getClassLoader ).
     * 
     * @param clazz the class object to search for
     * @return the source location of the resource, or null if it wasn"t found
     */
    public static String which(Class clazz) {
        return which(clazz, clazz.getClassLoader());
    }
    /**
     * Search the specified classloader for the given class object.
     * 
     * @param clazz the class object to search for
     * @param loader the classloader to search
     * @return the source location of the resource, or null if it wasn"t found
     */
    public static String which(Class clazz, ClassLoader loader) {
        return which(clazz.getName(), loader);
    }
    /**
     * Determine if the class name corresponds to a primitive Java datatype or
     * the void datatype.
     * 
     * @param classname the name of the class
     * @return true iff the classname corresponds to a primitive Java datatype
     * or the void datatype, false otherwise.
     */
    private static boolean isPrimitiveOrVoid(String classname) {
        return (
            classname.equals("boolean")
                || classname.equals("byte")
                || classname.equals("char")
                || classname.equals("double")
                || classname.equals("float")
                || classname.equals("int")
                || classname.equals("long")
                || classname.equals("short")
                || classname.equals("void"));
    }
    /**
     * Determine if the classname corresponds to an array type as defined by
     * the Java Language Specification.
     * 
     * @param classname the name of the class
     * @return true iff the classname corresponds to an array type, false
     * otherwise.
     */
    private static boolean isArrayType(String classname) {
        return classname.startsWith("[");
    }
    /**
     * Determine the element type of the array type.  This can be the name
     * of a primitive type or the fully qualified class name of a non primitive
     * type.
     *  
     * @param classname the array type
     * @return the name of the base element type.
     */
    private static String getElementType(String classname) {
        // remove leading "["
        String elementType = classname.split("^\\[+")[1];
        char encoding = elementType.charAt(0);
        if (encoding == "L") {
            // don"t include the first char "L" or last char ";"
            return elementType.substring(1, elementType.length() - 1);
        } else if (encoding == "Z") {
            return "boolean";
        } else if (encoding == "B") {
            return "byte";
        } else if (encoding == "C") {
            return "char";
        } else if (encoding == "D") {
            return "double";
        } else if (encoding == "F") {
            return "float";
        } else if (encoding == "I") {
            return "int";
        } else if (encoding == "J") {
            return "long";
        } else if (encoding == "S") {
            return "short";
        } else {
            throw new InternalError(
                "unknown array type: ""
                    + encoding
                    + "".\nplease file a bug report at http://which4j.dev.java.net");
        }
    }
}





Parses the CLASSPATH and returns the directories used within it.

 
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
 * as indicated by the @author tags. 
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors. 
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A 
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
 * MA  02110-1301, USA.
 * 
 * (C) 2005-2006,
 * @author JBoss Inc.
 */
/*
* Copyright (C) 2001,
*
* Arjuna Solutions Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: ClassPathParser.java 2342 2006-03-30 13:06:17Z  $
*/

import java.lang.StringIndexOutOfBoundsException;
/**
 * This class parses the CLASSPATH and returns the directories used
 * within it.
 *
 * @author Mark Little (mark@arjuna.ru)
 * @version $Id: ClassPathParser.java 2342 2006-03-30 13:06:17Z  $
 * @since JTS 2.1.
 */
public class ClassPathParser
{
   public ClassPathParser ()
   {
      _classPath = System.getProperty("java.class.path");
      _start = 0;
   }
   /**
    * @return the directory path of the next entry in the CLASSPATH that
    * contains the specified string.
    */
   public final String getPath (String contains)
   {
      String toReturn = null;
      if ((_classPath != null) && (contains != null))
      {
         int indx = _classPath.indexOf(contains, _start);
         if (indx != -1)
         {
            int lastIndex = _classPath.indexOf(pathSeparator, _start);
            int sepIndex = lastIndex+1;
            if (lastIndex > indx)  // at start of path?
               sepIndex = 0;
            else
            {
               while ((lastIndex < indx) && (lastIndex != -1))
               {
                  lastIndex = _classPath.indexOf(pathSeparator, sepIndex);
                  if (lastIndex == -1)
                     lastIndex = _classPath.length();
                  else
                  {
                     if (lastIndex < indx)
                        sepIndex = lastIndex+1;
                  }
               }
            }
            try
            {
               toReturn = _classPath.substring(sepIndex, lastIndex);
               _start = indx+1;
            }
            catch (StringIndexOutOfBoundsException e)
            {
               // nothing left!!
            }
         }
      }
      return toReturn;
   }
   /**
    * Reload the classpath and reset the class ready to re-parse.
    *
    * @return <code>true</code> if a non-null CLASSPATH was loaded,
    * <code>false</code> otherwise.
    */
   public final boolean reset ()
   {
      _classPath = System.getProperty("java.class.path");
      _start = 0;
      return (boolean) (_classPath != null);
   }
   private String _classPath;
   private int    _start;
   private static final char winSeparator = ";";
   private static final char unixSeparator = ":";
   private static char pathSeparator = unixSeparator;
   static
   {
      pathSeparator = System.getProperty("path.separator").charAt(0);
   }
}





Responsible for loading (class) files from the CLASSPATH. Inspired by sun.tools.ClassPath.

 

/*
 * Copyright  2000-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); 
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 *
 */
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
 * Responsible for loading (class) files from the CLASSPATH. Inspired by
 * sun.tools.ClassPath.
 * 
 * @version $Id: ClassPath.java 386056 2006-03-15 11:31:56Z tcurdt $
 * @author 
 */
public class ClassPath implements Serializable {
  public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
  private PathEntry[] paths;
  private String class_path;
  /**
   * Search for classes in given path.
   */
  public ClassPath(String class_path) {
    this.class_path = class_path;
    List vec = new ArrayList();
    for (StringTokenizer tok = new StringTokenizer(class_path, System.getProperty("path.separator")); tok
        .hasMoreTokens();) {
      String path = tok.nextToken();
      if (!path.equals("")) {
        File file = new File(path);
        try {
          if (file.exists()) {
            if (file.isDirectory()) {
              vec.add(new Dir(path));
            } else {
              vec.add(new Zip(new ZipFile(file)));
            }
          }
        } catch (IOException e) {
          System.err.println("CLASSPATH component " + file + ": " + e);
        }
      }
    }
    paths = new PathEntry[vec.size()];
    vec.toArray(paths);
  }
  /**
   * Search for classes in CLASSPATH.
   * 
   * @deprecated Use SYSTEM_CLASS_PATH constant
   */
  public ClassPath() {
    this(getClassPath());
  }
  /**
   * @return used class path string
   */
  public String toString() {
    return class_path;
  }
  public int hashCode() {
    return class_path.hashCode();
  }
  public boolean equals(Object o) {
    if (o instanceof ClassPath) {
      return class_path.equals(((ClassPath) o).class_path);
    }
    return false;
  }
  private static final void getPathComponents(String path, List list) {
    if (path != null) {
      StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
      while (tok.hasMoreTokens()) {
        String name = tok.nextToken();
        File file = new File(name);
        if (file.exists()) {
          list.add(name);
        }
      }
    }
  }
  /**
   * Checks for class path components in the following properties:
   * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
   * 
   * @return class path as used by default by BCEL
   */
  public static final String getClassPath() {
    String class_path = System.getProperty("java.class.path");
    String boot_path = System.getProperty("sun.boot.class.path");
    String ext_path = System.getProperty("java.ext.dirs");
    List list = new ArrayList();
    getPathComponents(class_path, list);
    getPathComponents(boot_path, list);
    List dirs = new ArrayList();
    getPathComponents(ext_path, dirs);
    for (Iterator e = dirs.iterator(); e.hasNext();) {
      File ext_dir = new File((String) e.next());
      String[] extensions = ext_dir.list(new FilenameFilter() {
        public boolean accept(File dir, String name) {
          name = name.toLowerCase(Locale.ENGLISH);
          return name.endsWith(".zip") || name.endsWith(".jar");
        }
      });
      if (extensions != null) {
        for (int i = 0; i < extensions.length; i++) {
          list.add(ext_dir.getPath() + File.separatorChar + extensions[i]);
        }
      }
    }
    StringBuffer buf = new StringBuffer();
    for (Iterator e = list.iterator(); e.hasNext();) {
      buf.append((String) e.next());
      if (e.hasNext()) {
        buf.append(File.pathSeparatorChar);
      }
    }
    return buf.toString().intern();
  }
  /**
   * @param name
   *          fully qualified class name, e.g. java.lang.String
   * @return input stream for class
   */
  public InputStream getInputStream(String name) throws IOException {
    return getInputStream(name.replace(".", "/"), ".class");
  }
  /**
   * Return stream for class or resource on CLASSPATH.
   * 
   * @param name
   *          fully qualified file name, e.g. java/lang/String
   * @param suffix
   *          file name ends with suff, e.g. .java
   * @return input stream for file on class path
   */
  public InputStream getInputStream(String name, String suffix) throws IOException {
    InputStream is = null;
    try {
      is = getClass().getClassLoader().getResourceAsStream(name + suffix);
    } catch (Exception e) {
    }
    if (is != null) {
      return is;
    }
    return getClassFile(name, suffix).getInputStream();
  }
  /**
   * @param name
   *          fully qualified file name, e.g. java/lang/String
   * @param suffix
   *          file name ends with suff, e.g. .java
   * @return class file for the java class
   */
  public ClassFile getClassFile(String name, String suffix) throws IOException {
    for (int i = 0; i < paths.length; i++) {
      ClassFile cf;
      if ((cf = paths[i].getClassFile(name, suffix)) != null) {
        return cf;
      }
    }
    throw new IOException("Couldn"t find: " + name + suffix);
  }
  /**
   * @param name
   *          fully qualified class name, e.g. java.lang.String
   * @return input stream for class
   */
  public ClassFile getClassFile(String name) throws IOException {
    return getClassFile(name, ".class");
  }
  /**
   * @param name
   *          fully qualified file name, e.g. java/lang/String
   * @param suffix
   *          file name ends with suffix, e.g. .java
   * @return byte array for file on class path
   */
  public byte[] getBytes(String name, String suffix) throws IOException {
    DataInputStream dis = null;
    try {
      InputStream is = getInputStream(name, suffix);
      if (is == null) {
        throw new IOException("Couldn"t find: " + name + suffix);
      }
      dis = new DataInputStream(is);
      byte[] bytes = new byte[is.available()];
      dis.readFully(bytes);
      return bytes;
    } finally {
      if (dis != null) {
        dis.close();
      }
    }
  }
  /**
   * @return byte array for class
   */
  public byte[] getBytes(String name) throws IOException {
    return getBytes(name, ".class");
  }
  /**
   * @param name
   *          name of file to search for, e.g. java/lang/String.java
   * @return full (canonical) path for file
   */
  public String getPath(String name) throws IOException {
    int index = name.lastIndexOf(".");
    String suffix = "";
    if (index > 0) {
      suffix = name.substring(index);
      name = name.substring(0, index);
    }
    return getPath(name, suffix);
  }
  /**
   * @param name
   *          name of file to search for, e.g. java/lang/String
   * @param suffix
   *          file name suffix, e.g. .java
   * @return full (canonical) path for file, if it exists
   */
  public String getPath(String name, String suffix) throws IOException {
    return getClassFile(name, suffix).getPath();
  }
  private static abstract class PathEntry implements Serializable {
    abstract ClassFile getClassFile(String name, String suffix) throws IOException;
  }
  /**
   * Contains information about file/ZIP entry of the Java class.
   */
  public interface ClassFile {
    /**
     * @return input stream for class file.
     */
    public abstract InputStream getInputStream() throws IOException;
    /**
     * @return canonical path to class file.
     */
    public abstract String getPath();
    /**
     * @return base path of found class, i.e. class is contained relative to
     *         that path, which may either denote a directory, or zip file
     */
    public abstract String getBase();
    /**
     * @return modification time of class file.
     */
    public abstract long getTime();
    /**
     * @return size of class file.
     */
    public abstract long getSize();
  }
  private static class Dir extends PathEntry {
    private String dir;
    Dir(String d) {
      dir = d;
    }
    ClassFile getClassFile(String name, String suffix) throws IOException {
      final File file = new File(dir + File.separatorChar + name.replace(".", File.separatorChar)
          + suffix);
      return file.exists() ? new ClassFile() {
        public InputStream getInputStream() throws IOException {
          return new FileInputStream(file);
        }
        public String getPath() {
          try {
            return file.getCanonicalPath();
          } catch (IOException e) {
            return null;
          }
        }
        public long getTime() {
          return file.lastModified();
        }
        public long getSize() {
          return file.length();
        }
        public String getBase() {
          return dir;
        }
      } : null;
    }
    public String toString() {
      return dir;
    }
  }
  private static class Zip extends PathEntry {
    private ZipFile zip;
    Zip(ZipFile z) {
      zip = z;
    }
    ClassFile getClassFile(String name, String suffix) throws IOException {
      final ZipEntry entry = zip.getEntry(name.replace(".", "/") + suffix);
      return (entry != null) ? new ClassFile() {
        public InputStream getInputStream() throws IOException {
          return zip.getInputStream(entry);
        }
        public String getPath() {
          return entry.toString();
        }
        public long getTime() {
          return entry.getTime();
        }
        public long getSize() {
          return entry.getSize();
        }
        public String getBase() {
          return zip.getName();
        }
      } : null;
    }
  }
}





Use reflection to access the true classpath info.

 
import java.lang.reflect.Method;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
public class Main {

  /**
   * Format a string buffer containing the Class, Interfaces, CodeSource, and
   * ClassLoader information for the given object clazz.
   * 
   * @param clazz
   *          the Class
   * @param results -
   *          the buffer to write the info to
   */
  public static void displayClassInfo(Class clazz, StringBuffer results) {
    // Print out some codebase info for the clazz
    ClassLoader cl = clazz.getClassLoader();
    results.append("\n");
    results.append(clazz.getName());
    results.append("(");
    results.append(Integer.toHexString(clazz.hashCode()));
    results.append(").ClassLoader=");
    results.append(cl);
    ClassLoader parent = cl;
    while (parent != null) {
      results.append("\n..");
      results.append(parent);
      URL[] urls = getClassLoaderURLs(parent);
      int length = urls != null ? urls.length : 0;
      for (int u = 0; u < length; u++) {
        results.append("\n....");
        results.append(urls[u]);
      }
      if (parent != null)
        parent = parent.getParent();
    }
    CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource();
    if (clazzCS != null) {
      results.append("\n++++CodeSource: ");
      results.append(clazzCS);
    } else
      results.append("\n++++Null CodeSource");
    results.append("\nImplemented Interfaces:");
    Class[] ifaces = clazz.getInterfaces();
    for (int i = 0; i < ifaces.length; i++) {
      Class iface = ifaces[i];
      results.append("\n++");
      results.append(iface);
      results.append("(");
      results.append(Integer.toHexString(iface.hashCode()));
      results.append(")");
      ClassLoader loader = ifaces[i].getClassLoader();
      results.append("\n++++ClassLoader: ");
      results.append(loader);
      ProtectionDomain pd = ifaces[i].getProtectionDomain();
      CodeSource cs = pd.getCodeSource();
      if (cs != null) {
        results.append("\n++++CodeSource: ");
        results.append(cs);
      } else
        results.append("\n++++Null CodeSource");
    }
  }

  /**
   * Use reflection to access a URL[] getURLs or URL[] getClasspath method so
   * that non-URLClassLoader class loaders, or class loaders that override
   * getURLs to return null or empty, can provide the true classpath info.
   * 
   * @param cl
   * @return the urls
   */
  public static URL[] getClassLoaderURLs(ClassLoader cl) {
    URL[] urls = {};
    try {
      Class returnType = urls.getClass();
      Class[] parameterTypes = {};
      Class clClass = cl.getClass();
      Method getURLs = clClass.getMethod("getURLs", parameterTypes);
      if (returnType.isAssignableFrom(getURLs.getReturnType())) {
        Object[] args = {};
        urls = (URL[]) getURLs.invoke(cl, args);
      }
      if (urls == null || urls.length == 0) {
        Method getCp = clClass.getMethod("getClasspath", parameterTypes);
        if (returnType.isAssignableFrom(getCp.getReturnType())) {
          Object[] args = {};
          urls = (URL[]) getCp.invoke(cl, args);
        }
      }
    } catch (Exception ignore) {
    }
    return urls;
  }
}