我有一个要求,即必须根据从UI捕获分布的分布来更改jar。
分布因人而异。如果选择了分布,则必须以动态/编程方式将与该分布相关的jar添加到类路径中。
如果选择了另一个分发,则必须动态地从类路径中删除添加到类路径中的先前jar,并且必须动态添加与新分发相关的新jar。对于其他分配必须继续分布。
我见过早期的线程,声明可以通过Class Loader在运行时添加jar,但是我没有看到任何可以从class-path动态删除jar的线程。
有人可以建议这是否可行?
答案 0 :(得分:1)
一种天真的方法是一个ClassLoader,它委托给特定于发行版的ClassLoader。以下是这类课程的草稿:
public class DistributionClassLoader extends ClassLoader {
public DistributionClassLoader(ClassLoader parent) {
super(parent);
}
private Map<String, ClassLoader> classLoadersByDistribution =
Collections.synchronizedMap(new WeakHashMap<>());
private final AtomicReference<String> distribution = new AtomicReference<>();
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
final ClassLoader delegate = classLoadersByDistribution.get(distribution.get());
if (delegate != null) return Class.forName(name, true, delegate);
throw new ClassNotFoundException(name);
}
public void addDistribution(String key, ClassLoader distributionClassLoader){
classLoadersByDistribution.put(key,distributionClassLoader);
}
public void makeDistributionActive(String key){distribution.set(key);}
public void removeDistribution(String key){
final ClassLoader toRemove = classLoadersByDistribution.remove(key);
}
}
然而,仍然存在一些问题:在切换分发时,我们希望从先前的分发中卸载所有类。我认为无法实现这一目标。另外:如果您对委托ClassLoader创建的对象有任何引用,则这些对象将保留对其ClassLoader的引用。我不确定是否有合适的解决方案,但这可能会让你开始。