有没有办法在运行时决定使用哪个类(在jboss上部署)?
以下是一个例子:
VERSION1.JAR
package com.something;
public class MyObject {
public void saySomething() {
System.out.println("Output from version 1");
}
}
VERSION2.JAR
package com.something;
public class MyObject {
public void saySomething() {
System.out.println("Output from version 2");
}
}
因此,两个罐子在同一个包装中是同一个类,但是它们做不同的事情。现在我想加载MyObject,但告诉他我想用哪个jar:
package com.main
public class Main{
public static void main(String[] args) {
MyObject v1 = new MyObject();
v1.saySomething();
MyObject v2 = new MyObject();
v2.saySomething();
}
}
这可能吗?我使用Jboss作为应用程序服务器,我在ejb项目中这样做。所以这个例子只是为了解释我的意思。我想也许是在上下文的帮助下?
答案 0 :(得分:2)
不,你无法控制这一点。加载哪一个是由JBoss类加载器的内部决定的,它不会暴露给你的程序。
你应该避免这样的情况。如果您需要控制加载哪个类,则需要将它们放在不同的包中。
答案 1 :(得分:0)
在java中,您可以从jar文件动态加载类,但部署意味着将所有决策留给您的app-server。如果是jboss,您可以定义一个策略,说明哪些类加载器具有优先权。
如果您正在尝试实现某种插件系统 - 那么请不要部署jar。这并不意味着您无法将您的罐子包装在您的应用程序中。对于WAR,只是不要将它们放在/ WEB-INF / lib中。你可以把它们放在例如。 / WEB-INF / plugins并使用类似的东西加载它们:
ClassLoader parent = Thread.currentThread().getContextClassLoader();
URL url = parent.getResource("/WEB-INF/plugins/plugin-x.jar");
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { url },
parent
);
Class<?> clazz = Class.forName("com.something.MyObject", true, loader);
Object myObject = clazz.getConstructor().newInstance();
Method saySomething = class.getMethod("saySomething");
saySomething.invoke(myObject);