There was a meeting recently to discuss the future of classloaders it relates to DSO. Here's my summary
Current ------- When a graph of objects is shared in DSO, part of the state we capture is the defining classloader of the objects. This classloader information is required when another node accesses the shared objects – DSO needs to be able to locate the logically equivalent classloaders so that the graph can be materialized. To support this concept, DSO maintains a map of classloader names to classloader instances, and mandates that classloaders which define classes to be shared to implement the terracotta interface NamedClassLoader. Some pros/cons of the current implementation: Pros: - 100% explicit and thus easy to explain (ie. The loader is either named or not, or a mapping exists for a given loader name or not) - Implementation is simple (just a map) - Authors of custom loaders just need to define the interface methods in their implementations (no compile time dependency) Cons: - Not documented really - Sharing graphs between hetoregenous apps (webapp plain java app) is difficult and requires ugly workarounds - New containers and frameworks require instrumentation and/or code changes to integrate with DSO The current scheme has issues, but it is transparent for supported containers/frameworks. We need to be careful with adding more machinery with regards to classloader resolution. Ideally, there should be some sort of 80% case where loader resolution isn't even something a DSO user needs to think about. Approaches that increase the conceptual weight of DSO are non-starters. Loader resolution based on thread context ----------------------------------------- There are some alternative means for discovering classloaders without relying on the naming loaders and keeping a registry. There are at least two means that can derive a classloader from context of a given thread: (1) Thread.getContextClassLoader() (2) Serialization loader resolution semantics via ObjectInputStream.latestUserDefinedClassLoader() The thread context loader is a bit of de-facto standard, but by no means is it used consistently throughout the java universe. It most cases though, it will have a reasonable value to use whenever an application thread is faulting shared objects. Leveraging the loader semantics from Serialization would take a small bit of reaching under the covers of the standard java.io classes. The semantic is part of the serialization specification, so all VM vendors should have some means of providing this (although it might be different from vendor to vendor). The main issue with deriving a loader from the calling thread has to do with class resolution that might need to happen from a Terracotta thread. Specifically the case of applying a put() to a shared HashMap as part of processing a txn broadcast. At the moment this change is applied by a Terracotta thread and requires that the key instance for the put() call to be materialized. Neither of the two resolution methods above will work for this thread. One solution to this problem would be to delay the apply and process it in the context of an application thread, but it isn’t clear to how much work that would be. Inherited ClassLoader from referring objects -------------------------------------------- Another scheme for avoiding a loader registry is to record a classloader in the TCObject associated with each root that is faulted. DSO roots are always faulting in the context of a user thread (so either of the thread based resolution methods could be used to determine a loader instance). One could also use the loader that defines the class containing the root field to pick the loader. Either way, once a loader is picked by one of these methods, it is recorded in the TCObject for the root. From that point forward, all new TCObjects that are created inherit the loader from their first referrer. Objects are always faulted either as the consequence of resolving a reference from some other resolved object, or because of a logical action on a resolved object. This provides us the TCObject context, and thus a loader can be selected. Conclusions ----------- We tentatively agreed that a combination of the “inherited loader” and existing “named classloaders” seems like the promising approach for moving forward. The decision to keep named loaders is to provide an explicit solution for when/if the inherited loader scheme breaks down, and for legacy reasons. Next Step --------- Develop and document classloader use cases and test them against the proposed solution(s) Addendum -------- Some other DSO class loading topics that were not discussed at this meeting: - Problems associated with loading the Terracotta client in it’s own class loader - Exporting Terracotta classes (or classes from a DSO plugin) into application classloaders > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:tc-dev- > [EMAIL PROTECTED] On Behalf Of Steven Harris > Sent: Tuesday, May 22, 2007 2:22 PM > To: [email protected] > Subject: [tc-dev] Named Classloaders > > This is something that has come up a few times over the last few > years. Alex mentioned a solution and gkeim mentioned a similar solution. > I want to schedule a brain storming session on it in the coming weeks > but... > > Since I don't believe we ever push objects to a client anymore, at > least not all the way to instantiation, I believe we can just use the > classloader of requesting client. This may not > have always been true but I think it is true now. What reasons can we > think of that would require us to need named classloaders anymore? > > _______________________________________________ > tc-dev mailing list > [email protected] > http://lists.terracotta.org/mailman/listinfo/tc-dev _______________________________________________ tc-dev mailing list [email protected] http://lists.terracotta.org/mailman/listinfo/tc-dev
