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 <real.class.name> [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 <real.class.name> [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 }