简体   繁体   English

从类路径中动态删除jar

[英]Dynamically removing jars from classpath

I have a requirement where jars have to be changed based on distribution where distribution is captured from UI. 我有一个要求,必须根据从UI捕获分发的分发来更改jar。

Distribution varies from one group to another. 分布从一组到另一组。 If a distribution is selected then jars related to that distribution have to be added to the class-path dynamically/programmatically. 如果选择了一个发行版,则必须动态/以编程方式将与该发行版相关的jar添加到类路径中。

If another distribution is selected then the previous jars which were added to the class-path have to be removed from class-path dynamically and new jars related to new distribution have to be added dynamically.The same has to be continued for other distributions. 如果选择了另一个发行版,则必须动态地从类路径中删除之前添加到类路径中的jars,并且必须动态添加与新发行版相关的新jars。对于其他发行版,必须继续这样做。

I have seen earlier threads which state that adding jars at run-time is possible through Class Loader but I haven't seen any thread where jars can be removed dynamically from class-path. 我见过较早的线程,其中指出可以在运行时通过Class Loader添加jar,但是我还没有看到可以从类路径中动态删除jar的任何线程。

Can anyone suggest whether this is possible? 谁能建议这是否可能?

A naive approach would be a ClassLoader that delegates to distribution-specific ClassLoaders. 天真的方法是将ClassLoader委派给特定于发行版的ClassLoader。 Here's a rough draft of such a class: 这是此类课程的草稿:

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);
    }
}

Several problems remain, however: when switching distributions, we'd want to unload all classes from the previous distribution. 但是,仍然存在一些问题:在切换发行版时,我们希望卸载先前发行版中的所有类。 I see no way to achieve that. 我认为没有办法实现这一目标。 Also: if you have any references to objects created by the delegate ClassLoaders, these objects will keep references to their ClassLoaders. 另外:如果您对委托ClassLoader创建的对象有任何引用,则这些对象将保留对其ClassLoader的引用。 I'm not sure there is a proper solution, but this may get you started. 我不确定是否有合适的解决方案,但这可能会让您入门。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM