// Updates: 2004.08.16
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
/**
* <b>Invoker</b> lets you invoke protected and private methods in any object.
* Examples:<br>
* <pre>
public class TestInvoker {
public TestInvoker() {
Invoker.addPath("C:/AADev/examples/");
VeryPrivate vp = new VeryPrivate();
try {
Invoker.invoke(VeryPrivate.class, vp, "test1", new Object[]{});
Invoker.invoke(VeryPrivate.class, vp, "test2", new Object[]{"Hello!"});
Invoker.invoke(VeryPrivate.class, vp, "test3", new Class[]{Integer.TYPE}, new Object[]{new Integer(555)});
Invoker.invoke(VeryPrivate.class, vp, "test4", new Class[]{String.class, Integer.TYPE}, new Object[]{"Hello again!", new Integer(555)});
}
catch (Exception e) {
System.out.println("Problem: " + e);
}
}
public static void main(String[] args) {
new TestInvoker();
}
}
class VeryPrivate {
private void test1() {
System.out.println("Test1: no parameters");
}
private void test2(String s) {
System.out.println("Test2: a String: " + s);
}
private void test3(int i) {
System.out.println("Test3: an integer: " + i);
}
private void test4(String s, int i) {
System.out.println("Test4: a String: " + s + ", and an Integer: " + i);
}
}
*</pre>
* @author Michel Deriaz
*/
public class Invoker {
private Invoker() {}
/**
* Invokes a method containing no primitive types. If the method has primitive
* types, see the {@link #invoke(Class, Object, String, Class[], Object[])
* invoke(Class, Object, String, Class[], Object[])} method.
* @param className the class of the object, for example
* <code>URLClassLoader.class</code>
* @param obj the object containing the method to invoke
* @param method the name of the method to invoke, for example
* <code>"addURL"</code>
* @param param the parameters, for example <code>new Object[]{url}</code>
* @throws Exception the following exceptions can be thrown from this method:
* <code>NoSuchMethodException</code>,
* <code>NullPointerException</code>,
* <code>SecurityException</code>,
* <code>IllegalAccessException</code>,
* <code>IllegalArgumentException</code>,
* <code>InvocationTargetException</code>,
* <code>ExceptionInInitializerError</code>.
* @see #invoke(Class, Object, String, Class[], Object[])
*/
public static void invoke(Class className, Object obj, String method, Object[] param) throws Exception {
Class[] paramClass = new Class[param.length];
for (int i = 0; i < param.length; i++) {
paramClass[i] = param[i].getClass();
}
invoke(className, obj, method, paramClass, param);
}
/**
* Invokes a method containing primitive types. If the method has no primitive
* types, see the {@link #invoke(Class, Object, String, Object[])
* invoke(Class, Object, String, Object[])} method.
* @param className the class of the object, for example
* <code>MyProgram.class</code>
* @param obj the object containing the method to invoke
* @param method the name of the method to invoke, for example
* <code>"testMethod"</code>
* @param paramClass the classes of the parameters, for exemple
* <code>new Class[]{Integer.TYPE}</code>
* @param param the parameters, for example <code>new Object[]{new
* Integer(555)}</code>
* @throws Exception the following exceptions can be thrown from this method:
* <code>NoSuchMethodException</code>,
* <code>NullPointerException</code>,
* <code>SecurityException</code>,
* <code>IllegalAccessException</code>,
* <code>IllegalArgumentException</code>,
* <code>InvocationTargetException</code>,
* <code>ExceptionInInitializerError</code>.
* @see #invoke(Class, Object, String, Object[])
*/
public static void invoke(Class className, Object obj, String method, Class[] paramClass, Object[] param) throws Exception {
Method m = className.getDeclaredMethod(method, paramClass);
m.setAccessible(true);
m.invoke(obj, param);
}
/**
* Invokes the protected <code>addURL</code> method from the
* <code>URLClassLoader</code> class, in order to bypass the fact that it is
* not possible to modify the classpath during runtime.
* @param path the path to add
*/
public static void addPath(String path) {
if (path == null) return;
try {
URL url = new File(path).toURL();
URLClassLoader loader = (URLClassLoader)ClassLoader.getSystemClassLoader();
invoke(URLClassLoader.class, loader, "addURL", new Object[]{url});
}
catch (Exception e) {}
}
}