Loading a singleton with a specified classloader in Eclipse
I have a little problem in my project. We develop a client for our server as eclipse plugin.
There, we have our 'ApplicationRegistry' which is barely more than a map that holds all objects we need only once but shouldn't be singletons. This ApplicationRegistry is implemented as enum singleton and among some other stuff in another plugin. Everything works fine so far.
Now the customer wants different 'perspectives' which show slightly different features. This is also no problem. By now we only have two runnables and 开发者_运维百科two different menu entries to start the two different classes but it is no problem (and would probably be better) to divide them in to two or three plugins.
Now I come to the problem: We can run both of those perspectives at a time. But the ApplicationRegistry is created by the classloader of its own plugin and therefor exists once for all of our perspectives. So when we try to open a new tab in the first perspective, it opens in the second.
To cut a long story short: plugins 'parent1' and 'parent2' use a singleton in plugin 'child' and affect each other in an undesirable way. My idea is to load the singleton in each of the parent plugins with their own classloader. But since I have no idea how to load an enum singleton with a specified classloader, I cannot verify if this solution would do it.
Can anybody tell me how to load an enum singleton with a specified classloader (and if the correct ApplicationRegistry would get addressed furthermore in each plugin), if this could work or if there is another solution that doesn't involve a huge re-engineering in the whole project?
Thanks, Sebastian
Don't load the same enum with multiple classloaders. You'll go to hell for that (runtime error hell, that is). While enum singletons / multitons are great for simple tasks, they just don't scale for purposes like that. Two possible solutions
a) Use one enum per perspective (i.e. the Perspective must "know" what enum to look for
b) Let the enum items "know" which perspective they belong to (use a second enum for your perspectives):
public enum Perspective{
A, B, C
}
public enum Thing{
FOO(Perspective.A, Perspective.B),
BAR(Perspective.C),
BAZ(Perspective.A, Perspective.B, Perspective.C),
;
private final Perspective[] perspectives;
private Thing(Perspective ... perspectives){
this.perspectives=perspectives;
}
public static Set<Thing> forPerspective(Perspective p){
Set<Perspective> set = EnumSet.noneOf(Perspective.class);
for(Thing t : values()){
if(EnumSet.of(t.perspectives).contains(p)){set.add(t);}
}
return t;
}
}
精彩评论