Question

I'm part of a team that develops a pretty big Swing Java Applet. Most of our code are legacy and there are tons of singleton references. We've bunched all of them to a single "Application Context" singleton. What we now need is to create some way to separate the shared context (shared across all applets currently showing) and non-shared context (specific to each applet currently showing).

However, we don't have an ID at each of the locations that call to the singleton, nor do we want to propagate the ID to all locations. What's the easiest way to identify in which applet context we're running? (I've tried messing with classloaders, thread groups, thread ids... so far I could find nothing that will enable me to ID the origin of the call).

Was it helpful?

Solution

Singletons are evil, what do you expect? ;)

Perhaps the most comprehensive approach would be to load the bulk of the applet in a different class loader (use java.net.URLClassLoader.newInstance). Then use a WeakHashMap to associate class loader with an applet. If you could split most of the code into a common class loader (as a parent of each per-applet class loader) and into the normal applet codebase, that would be faster but more work.

Other hacks:

If you have access to any component, you can use Component.getParent repeatedly or SwingUtilities.getRoot.

If you are in a per-applet instance thread, then you can set up a ThreadLocal.

From the EDT, you can read the current event from the queue (java.awt.EventQueue.getCurrentEvent()), and possibly find a component from that. Alternatively push an EventQueue with a overridden dispatchEvent method.

OTHER TIPS

If I understand you correctly, the idea is to get a different "singleton" object for each caller object or "context". One thing you can do is to create a thread-local global variable where you write the ID of the current context. (This can be done with AOP.) Then in the singleton getter, the context ID is fetched from the thread-local to use as a key to the correct "singleton" instance for the calling context.

Regarding AOP there should be no problem using it in applets since, depending on your point-cuts, the advices are woven at compile time and a JAR is added to the runtime dependencies. Hence, no special evidence of AOP should remain at run time.

@Hugo regarding threadlocal:

I thought about that solution. However, from experiments I found two problems with that approach:

  1. Shared thread (server connections, etc) are problematic. This can be solved though by paying special attention to these thread (they're all under my control and are pretty much isolated from the legacy code).
  2. The EDT thread is shared across all applets. I failed to find a way to force the creation of a new EDT thread for each applet. This means that the threadlocal for the EDT would be shared across the applets. This one I have no idea how to solve. Suggestions?
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top