001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License. 
016     *
017     */
018    package org.apache.bcel.util;
019    
020    import java.lang.reflect.Method;
021    import java.lang.reflect.Modifier;
022    
023    /**
024     * Java interpreter replacement, i.e., wrapper that uses its own ClassLoader
025     * to modify/generate classes as they're requested. You can take this as a template
026     * for your own applications.<br>
027     * Call this wrapper with
028     * <pre>java org.apache.bcel.util.JavaWrapper &lt;real.class.name&gt; [arguments]</pre>
029     * <p>
030     * To use your own class loader you can set the "bcel.classloader" system property
031     * which defaults to "org.apache.bcel.util.ClassLoader", e.g., with
032     * <pre>java org.apache.bcel.util.JavaWrapper -Dbcel.classloader=foo.MyLoader &lt;real.class.name&gt; [arguments]</pre>
033     * </p>
034     *
035     * @version $Id: JavaWrapper.java 1149459 2011-07-22 04:34:27Z dbrosius $
036     * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
037     * @see ClassLoader
038     */
039    public class JavaWrapper {
040    
041        private java.lang.ClassLoader loader;
042    
043    
044        private static java.lang.ClassLoader getClassLoader() {
045            String s = System.getProperty("bcel.classloader");
046            if ((s == null) || "".equals(s)) {
047                s = "org.apache.bcel.util.ClassLoader";
048            }
049            try {
050                return (java.lang.ClassLoader) Class.forName(s).newInstance();
051            } catch (Exception e) {
052                throw new RuntimeException(e.toString(), e);
053            }
054        }
055    
056    
057        public JavaWrapper(java.lang.ClassLoader loader) {
058            this.loader = loader;
059        }
060    
061    
062        public JavaWrapper() {
063            this(getClassLoader());
064        }
065    
066    
067        /** Runs the main method of the given class with the arguments passed in argv
068         *
069         * @param class_name the fully qualified class name
070         * @param argv the arguments just as you would pass them directly
071         */
072        public void runMain( String class_name, String[] argv ) throws ClassNotFoundException {
073            Class<?> cl = loader.loadClass(class_name);
074            Method method = null;
075            try {
076                method = cl.getMethod("main", new Class[] {
077                    argv.getClass()
078                });
079                /* Method main is sane ?
080                 */
081                int m = method.getModifiers();
082                Class<?> r = method.getReturnType();
083                if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m)
084                        || (r != Void.TYPE)) {
085                    throw new NoSuchMethodException();
086                }
087            } catch (NoSuchMethodException no) {
088                System.out.println("In class " + class_name
089                        + ": public static void main(String[] argv) is not defined");
090                return;
091            }
092            try {
093                method.invoke(null, new Object[] {
094                    argv
095                });
096            } catch (Exception ex) {
097                ex.printStackTrace();
098            }
099        }
100    
101    
102        /** Default main method used as wrapper, expects the fully qualified class name
103         * of the real class as the first argument.
104         */
105        public static void main( String[] argv ) throws Exception {
106            /* Expects class name as first argument, other arguments are by-passed.
107             */
108            if (argv.length == 0) {
109                System.out.println("Missing class name.");
110                return;
111            }
112            String class_name = argv[0];
113            String[] new_argv = new String[argv.length - 1];
114            System.arraycopy(argv, 1, new_argv, 0, new_argv.length);
115            JavaWrapper wrapper = new JavaWrapper();
116            wrapper.runMain(class_name, new_argv);
117        }
118    }