Reputation: 33
I have a requirement where jars have to be changed based on distribution where distribution is captured from UI.
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.
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.
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.
Can anyone suggest whether this is possible?
Upvotes: 2
Views: 2292
Reputation: 299048
A naive approach would be a ClassLoader that delegates to distribution-specific ClassLoaders. 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. I'm not sure there is a proper solution, but this may get you started.
Upvotes: 1