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 */ 018package org.apache.bcel.util; 019 020import java.lang.reflect.Method; 021import 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 * 029 * <pre>java org.apache.bcel.util.JavaWrapper <real.class.name> [arguments]</pre> 030 * 031 * <p>To use your own class loader you can set the "bcel.classloader" system property<p> 032 * <pre>java org.apache.bcel.util.JavaWrapper -Dbcel.classloader=foo.MyLoader <real.class.name> [arguments]</pre> 033 * 034 * @version $Id: JavaWrapper.java 1806200 2017-08-25 16:33:06Z ggregory $ 035 * @see ClassLoader 036 */ 037public class JavaWrapper { 038 039 private final java.lang.ClassLoader loader; 040 041 042 private static java.lang.ClassLoader getClassLoader() { 043 final String s = System.getProperty("bcel.classloader"); 044 if ((s == null) || "".equals(s)) { 045 throw new IllegalArgumentException("The property 'bcel.classloader' must be defined"); 046 } 047 try { 048 return (java.lang.ClassLoader) Class.forName(s).newInstance(); 049 } catch (final Exception e) { 050 throw new RuntimeException(e.toString(), e); 051 } 052 } 053 054 055 public JavaWrapper(final java.lang.ClassLoader loader) { 056 this.loader = loader; 057 } 058 059 060 public JavaWrapper() { 061 this(getClassLoader()); 062 } 063 064 065 /** Runs the main method of the given class with the arguments passed in argv 066 * 067 * @param class_name the fully qualified class name 068 * @param argv the arguments just as you would pass them directly 069 */ 070 public void runMain( final String class_name, final String[] argv ) throws ClassNotFoundException { 071 final Class<?> cl = loader.loadClass(class_name); 072 Method method = null; 073 try { 074 method = cl.getMethod("main", new Class[] { 075 argv.getClass() 076 }); 077 /* Method main is sane ? 078 */ 079 final int m = method.getModifiers(); 080 final Class<?> r = method.getReturnType(); 081 if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m) 082 || (r != Void.TYPE)) { 083 throw new NoSuchMethodException(); 084 } 085 } catch (final NoSuchMethodException no) { 086 System.out.println("In class " + class_name 087 + ": public static void main(String[] argv) is not defined"); 088 return; 089 } 090 try { 091 method.invoke(null, new Object[] { 092 argv 093 }); 094 } catch (final Exception ex) { 095 ex.printStackTrace(); 096 } 097 } 098 099 100 /** Default main method used as wrapper, expects the fully qualified class name 101 * of the real class as the first argument. 102 */ 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}