Я использую java, чтобы сделать что-то такое же, как использование динамической библиотеки C++.Использовать объект, созданный Classloader без вызова интерфейса или вызвать вызов?
Я не нашел способ напрямую использовать один и тот же объект класса без отражения кода стиля вызова.
это мой динамический библиотечный код, я делаю его банкой.
package com.demo;
public class Logic {
public String doWork() {
System.out.println("Hello from Dll");
return "Dll";
}
}
В моем главном приложении, я могу создать экземпляр по URLClassLoader, призовите на отражения в порядке:
public class Main {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
File file = new File("C:\\plugin.jar");
URL url = file.toURI().toURL();
URL[] urls = {url};
ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
ClassLoader loader = new URLClassLoader(urls, parentLoader);
Thread.currentThread().setContextClassLoader(loader);
Class<?> clazz = loader.loadClass("com.demo.Logic");
System.out.println("New Instance!!");
Object logic = clazz.newInstance();
Method method = logic.getClass().getMethod("doWork");
method.invoke(logic);
}
Выход:
New Instance!!
Hello from Dll
Но когда я изменить код без использования Отразить вызов:
public class Main {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
File file = new File("C:\\plugin.jar");
URL url = file.toURI().toURL();
URL[] urls = {url};
ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
ClassLoader loader = new URLClassLoader(urls, parentLoader);
Thread.currentThread().setContextClassLoader(loader);
Class<?> clazz = loader.loadClass("com.demo.Logic");
Logic logic = (Logic)clazz.newInstance();
logic.doWork();
}
}
Компиляция успеха (компилировать с внешними модулями), но когда я запускаю программу, она не на линии Logic logic = (Logic)clazz.newInstance();
Исключение:
Exception in thread "main" java.lang.NoClassDefFoundError: com/demo/Logic
at Main.main(Main.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassNotFoundException: com.demo.Logic
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 6 more
Есть ли способ, чтобы заставить его работать? Без отражения/интерфейс. (В C++ можно легко достичь этого, доля же структура/класс DECLARE, убедитесь, используя тот же компилятор компилировать из двух частей. ИМХО Java бы сделать это также)
дополнительное объяснение 1
Я хочу, чтобы изменить текущее поведение загрузчика классов сделать это признать динамичный загруженный класс, это попытка является простым и наивным, не может найти другое направление:
ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
ClassLoader loader = new URLClassLoader(urls, parentLoader);
Thread.currentThread().setContextClassLoader(loader);
добро пожаловать в мир классных загрузчиков ... вы можете проверить, что «Logic.class! = Clazz» - они загружаются разными загрузчиками классов, поэтому они представляют собой разные классы (даже если они имеют то же имя класса) – ZhongYu
Соответствующий - http://stackoverflow.com/questions/30227510/sandbox-for-memory/30227614#30227614 – ZhongYu
@ bayou.io Да, они разные загрузчики классов, я хочу, чтобы начальный класс загрузчика распознал класс динамически – Gohan