//UPDATE//
Now I can load a Jar, but how can I run methods from it?
//UPDATE//
Now I can load a Jar, but how can I run methods from it?
From the main JAR file where you need to plug games.jar
:
games.jar
file (use File.toURI().toURL()
) and put it in an array (let's call the array urlArray
).Next get a URLClassLoader
instance to load games.jar
:
URLClassLoader urlClassLoader = URLClassLoader.newInstance(urlArray);
Now you can instantiate any class from the games.jar
with the Class.forName
if you pass the new class loader you just created as third parameter:
Class<? extends Main> mainClass = (Class<? extends Main>)
Class.forName("Main", true, urlClassLoader);
On mainClass
you can now call your method: mainClass.loaded();
There are two parts to this. First, you need to import the jar. This can be done at runtime using a slight hack with reflection:
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public void importJar(File file) {
Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURL.setAccessible(True);
addURL.invoke(URLClassLoader.getSystemClassLoader(), new Object[] {file.toURI().toURL()});
}
Now you can import a jar at runtime. If you simply have the path to the jar, you can easily convert it to a File
:
importJar(new File("path/to/jar"));
Second, you need to find the classes defined in your jar. There does not appear to be a built-in way to do this, so you'll have to manually examine the jar itself for classes.
import java.lang.Class;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
public List<Class<?>> findJarClasses(File file) {
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
JarFile jar = new JarFile(file);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.endsWith(".class")) {
name = name.substring(0, name.lastIndexOf('.'));
Class<?> cls = Class.forName(name);
classes.add(cls);
}
}
return classes;
}
Finally, you can iterate over the classes to determine if any of them implement your desired interface.
File jarFile = new File("path/to/Games.jar");
importJar(jarFile);
List<Class<?>> classes = findJarClasses(jarFile);
for (Class<?> cls : classes) {
if (cls.isInstance(YourInterface.class)) {
// Instantiate class.
YearInterface obj = (YourInterface)cls.newInstance();
// Call `loaded()` method.
obj.loaded();
}
}