jeudi 25 mai 2017

Load jar file with URLCLassLoader

I am trying to load a jar file as if it was run with "java -jar BungeeCord.jar", but I am trying to do this from within another jar. I can not use a process builder because I need get an instance of classes uses in the external jar file.

I have created this:

System.out.println("Loading jar: " + jar.toURI().toURL());

    child = new URLClassLoader(new URL[]{jar.toURI().toURL()}, BungeeServer.class.getClassLoader());

    Class<?> classToLoad = Class.forName("net.md_5.bungee.Bootstrap", true, child);
    final Method method = classToLoad.getDeclaredMethod("main", String[].class);

    new Thread(new Runnable(){

        public void run() {
            try {
                method.invoke(null, (Object) new String[]{});
            } catch (Exception e) {
                e.printStackTrace();
                BungeeControl.shutdown();
            }
        }

    }).start();

This starts up the jar file, but it gets the following error about a dozen times on start which don't occur if I start the same file normally:

java.lang.NoClassDefFoundError: net/md_5/bungee/api/plugin/Plugin
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at net.md_5.bungee.api.plugin.PluginClassloader.loadClass0(PluginClassloader.java:34)
    at net.md_5.bungee.api.plugin.PluginClassloader.loadClass(PluginClassloader.java:27)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at net.md_5.bungee.api.plugin.PluginManager.enablePlugin(PluginManager.java:304)
    at net.md_5.bungee.api.plugin.PluginManager.loadPlugins(PluginManager.java:212)
    at net.md_5.bungee.BungeeCord.start(BungeeCord.java:264)
    at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:55)
    at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.moltrespvp.bungeecontrol.BungeeServer$1.run(BungeeServer.java:31)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: net.md_5.bungee.api.plugin.Plugin
    at net.md_5.bungee.api.plugin.PluginClassloader.loadClass0(PluginClassloader.java:53)
    at net.md_5.bungee.api.plugin.PluginClassloader.loadClass(PluginClassloader.java:27)
    at java.lang.ClassLoader.loadClass(Unknown Source)

If needed, here is the manifest for Bungeecord:

Manifest-Version: 1.0
Implementation-Version: git:BungeeCord-Bootstrap:1.12-SNAPSHOT:16d2615
 :1233
Archiver-Version: Plexus Archiver
Built-By: jenkins
Created-By: Apache Maven 3.2.5
Build-Jdk: 1.8.0_121
Specification-Version: 20170514
Main-Class: net.md_5.bungee.Bootstrap

How can I start this jar file as if I started it with a ProcessBuilder, but be able to access methods from the running instance.

For example, I need to be able to run this for the running instance of BungeeCord ProxyServer.getInstance()?





Aucun commentaire:

Enregistrer un commentaire