1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.util; 19 20 import java.lang.reflect.Method; 21 import java.lang.reflect.Modifier; 22 23 /** 24 * Java interpreter replacement, i.e., wrapper that uses its own ClassLoader 25 * to modify/generate classes as they're requested. You can take this as a template 26 * for your own applications.<br> 27 * Call this wrapper with: 28 * 29 * <pre>java org.apache.bcel.util.JavaWrapper <real.class.name> [arguments]</pre> 30 * 31 * <p>To use your own class loader you can set the "bcel.classloader" system property<p> 32 * <pre>java org.apache.bcel.util.JavaWrapper -Dbcel.classloader=foo.MyLoader <real.class.name> [arguments]</pre> 33 * 34 * @version $Id$ 35 * @see ClassLoader 36 */ 37 public class JavaWrapper { 38 39 private final java.lang.ClassLoader loader; 40 41 getClassLoader()42 private static java.lang.ClassLoader getClassLoader() { 43 final String s = System.getProperty("bcel.classloader"); 44 if ((s == null) || "".equals(s)) { 45 throw new IllegalArgumentException("The property 'bcel.classloader' must be defined"); 46 } 47 try { 48 return (java.lang.ClassLoader) Class.forName(s).newInstance(); 49 } catch (final Exception e) { 50 throw new RuntimeException(e.toString(), e); 51 } 52 } 53 54 JavaWrapper(final java.lang.ClassLoader loader)55 public JavaWrapper(final java.lang.ClassLoader loader) { 56 this.loader = loader; 57 } 58 59 JavaWrapper()60 public JavaWrapper() { 61 this(getClassLoader()); 62 } 63 64 65 /** Runs the main method of the given class with the arguments passed in argv 66 * 67 * @param class_name the fully qualified class name 68 * @param argv the arguments just as you would pass them directly 69 */ runMain( final String class_name, final String[] argv )70 public void runMain( final String class_name, final String[] argv ) throws ClassNotFoundException { 71 final Class<?> cl = loader.loadClass(class_name); 72 Method method = null; 73 try { 74 method = cl.getMethod("main", new Class[] { 75 argv.getClass() 76 }); 77 /* Method main is sane ? 78 */ 79 final int m = method.getModifiers(); 80 final Class<?> r = method.getReturnType(); 81 if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m) 82 || (r != Void.TYPE)) { 83 throw new NoSuchMethodException(); 84 } 85 } catch (final NoSuchMethodException no) { 86 System.out.println("In class " + class_name 87 + ": public static void main(String[] argv) is not defined"); 88 return; 89 } 90 try { 91 method.invoke(null, new Object[] { 92 argv 93 }); 94 } catch (final Exception ex) { 95 ex.printStackTrace(); 96 } 97 } 98 99 100 /** Default main method used as wrapper, expects the fully qualified class name 101 * of the real class as the first argument. 102 */ main( final String[] argv )103 public static void main( final String[] argv ) throws Exception { 104 /* Expects class name as first argument, other arguments are by-passed. 105 */ 106 if (argv.length == 0) { 107 System.out.println("Missing class name."); 108 return; 109 } 110 final String class_name = argv[0]; 111 final String[] new_argv = new String[argv.length - 1]; 112 System.arraycopy(argv, 1, new_argv, 0, new_argv.length); 113 final JavaWrapper wrapper = new JavaWrapper(); 114 wrapper.runMain(class_name, new_argv); 115 } 116 } 117