How to access a method from an external jar at runtime?

This is a continuation of the question posted in: How to load a jar file at runtime

I am not sure how to continue the method call level. In my opinion, from a clazz object, I would use getMethod or getDeclaredMethod to get a Method object from which I would invoke invoke. Of course, an instance is required to call. Will this be what doRun is called in the sample code?

Do I need to make a call to the doRun.run () method, although I want to execute a different method than the main one (assuming that it is the main doRun object that is called with the run call)?

Just for a more detailed explanation of the original post, I ask: Does doRun.run () execute a new thread executing an instance of an object of a class type clazz?

Thanks for helping me figure it out.

I really looked at "how-should-i-load-jars-dynamic-at-runtime" (sorry, only one hyperlink allowed), however this seemed to violate the Class.newInstance class evil warning in the first post I referred to.

+6
java jar classloader runtime
source share
3 answers

Here is the reflection code that is not passed to the interface:

public class ReflectionDemo { public void print(String str, int value) { System.out.println(str); System.out.println(value); } public static int getNumber() { return 42; } public static void main(String[] args) throws Exception { Class<?> clazz = ReflectionDemo.class; // static call Method getNumber = clazz.getMethod("getNumber"); int i = (Integer) getNumber.invoke(null /* static */); // instance call Constructor<?> ctor = clazz.getConstructor(); Object instance = ctor.newInstance(); Method print = clazz.getMethod("print", String.class, Integer.TYPE); print.invoke(instance, "Hello, World!", i); } } 

Writing reflected classes on an interface known by a consumer code ( as in the example ) is usually better, because it avoids reflection and takes advantage of a system like Java. Reflection should only be used when you have no choice.

+2
source share

Code example

 ClassLoader loader = URLClassLoader.newInstance( new URL[] { yourURL }, getClass().getClassLoader() ); Class<?> clazz = Class.forName("mypackage.MyClass", true, loader); Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class); // Avoid Class.newInstance, for it is evil. Constructor<? extends Runnable> ctor = runClass.getConstructor(); Runnable doRun = ctor.newInstance(); doRun.run(); 

assumes that the class you are loading implements the specific Runnable interface, and therefore it must cast to this type with asSubclass () and call run ().

What do you know about the classes you load? Can you assume that they implement the particualr interface? If so, adjust the asSubClass () line to indicate your preferred interfipe.

Then yes, if you are working with instance methods, create an instance using the ctor constructor in this example.

In the example, there is no beginning of the stream. Creating a new thread would just require a few lines more code

 Thread myThread = new Thread(doRun); myThread.start(); 
+2
source share

Program Example:

Project Printer:

 public class Printer { public void display(String printtext) { System.out.println(printtext); } } 

This project is exported as Printer.jar.

The printer class has a display() method that takes a string as input.

Caller Code:

  URL url = new URL("file:Printer.jar"); URLClassLoader loader = new URLClassLoader (new URL[] {url}); Class<?> cl = Class.forName ("Printer", true, loader); String printString = "Print this"; Method printit = cl.getMethod("display", String.class); Constructor<?> ctor = cl.getConstructor(); //One has to pass arguments if constructor takes input arguments. Object instance = ctor.newInstance(); printit.invoke(instance, printString); loader.close (); 

Conclusion: Print this

+1
source share

All Articles