6 Replies Latest reply on Oct 2, 2007 4:29 PM by Brian Stansberry

    Removing classloader issues for PojoCache

    Brian Stansberry Master


      Would like to explore with you the possibility of eliminating the need for region-based marshalling with PojoCache.

      We use region-based marshalling to handle replication of custom types. But, since PojoCache breaks down pojos into primitives, most of the need for replicating custom types is eliminated. AIUI, the remaining areas where custom types are replicated are:

      1) The Class of the pojo, so the remote node knows what type to construct.
      2) Any @Serializable field.

      Could those cases be handled by storing some MarshalledValue variant in the cache (or perhaps just a String for the pojo Class)? Assume here a much more suitable MarshalledValue; i.e. it holds onto the wrapped object for local use; doesn't serialize until needed rather than at construction, etc. I plan to write one of those anyway.

      I'm asking because besides FIELD repl all the other AS web session and SFSB usages of JBC handle things such that they don't need region-based marshalling. I'd like to have the ability to handle all these usages in one cache. If I could eliminate region-based marshalling as a config factor, that would simplify things.


        • 1. Re: Removing classloader issues for PojoCache
          Jason Greene Master

          Switching to a string wouldn't be a problem. However, I don't think we can get away from region based classloading since we must handle serializable types. The following require this:

          • Enums
          • Arrays
          • Custom serializable types


          • 2. Re: Removing classloader issues for PojoCache
            Brian Stansberry Master

            Can these be stored internally in a MarshalledValue variant (i.e. lazy-demarshalling by the interceptor on the field read)?

            Assume the MarshalledValue variant is efficient; i.e. doesn't create a byte[] version of the object until it itself is serialized; discards the byte[] as soon as get() is called.

            • 3. Re: Removing classloader issues for PojoCache
              Jason Greene Master

              Yes, that would work. Although I think this functionality belongs in JBoss Cache directly. There could be some kind of deserializeOnLoad option.


              • 5. Re: Removing classloader issues for PojoCache
                Jason Greene Master

                Ah, so I am not alone here :)

                Ok so, off the top of my head, I can see 3 possible core cache solutions to this problem.

                1) Have an option that enables lazy wrapper style serialization (like you are suggesting) using the TCL. The reason this should be optional is that any wrapper serialization usage has greater cost than a region CL (double buffering + additional synchronization).

                2) Add a serialization manager which allows app registered callbacks when deserializing/serializing an Object. This is essentially the reverse of a region CL. The callback would be passed various node information that could be used to locate the correct deployment CL.

                3) Both 1 + 2. A registered serialization callback could decide to use a wrapper type, which would be deserialized and automatically unwrapped by the cache layer.

                • 6. Re: Removing classloader issues for PojoCache
                  Brian Stansberry Master

                  Chat history related to above:

                  [14:43:27] Jason T. Greene: did you ever review my reply to the marshalvalue thread?
                  [14:48:01] Brian Stansberry: i was a little unclear on #2; i.e. when the deserialization occurs and what gets passed to the callback
                  [14:50:15] ? i.e. how it would be different from the current region-based marshalling
                  [14:51:07] Jason T. Greene: it would just keep you from having to configure the region up front
                  [14:51:27] ? and allow for you to make decisions at the node level
                  [14:52:03] Brian Stansberry: ok, ic.
                  [14:52:17] ? here's a sucky thing about region-based....
                  [14:52:45] ? for a tx prepare, we need to figure out the region
                  [14:53:10] ? we do that by checking the first method call in the set of method calls that make up the prepare
                  [14:53:25] ? if a tx spans classloader regions, that breaks
                  [14:54:24] ? i suppose a serialization manager could be more intelligent
                  [14:54:44] Jason T. Greene: hmm shouldnt prepare deseralize each call separately according to the fqn
                  [14:54:45] ? ?
                  [14:55:41] Brian Stansberry: yeah, that would be better. DOH!
                  [14:56:22] ? just serialize the elements individually and then wrap them up in the prepare method call
                  [14:57:11] Jason T. Greene: yeah you could even do this intelligently with markers that prevent double buffering
                  [14:59:40] Jason T. Greene: so the serialization manager suggestion was really because i was interpreting the problem being allocating the structure to fit the region model
                  [15:01:01] Brian Stansberry: well, its more than that
                  [15:01:18] ? assume the goal is to fit all session repl in a shared cache
                  [15:02:03] ? for most usages, the session is represented by a single key/value pair in one node.
                  [15:02:53] ? and most txs involve changing a single session
                  [15:03:13] ? for that case, a wrapper obj is more efficient than passing a region-fqn as external metadata for every call
                  [15:04:36] Jason T. Greene: ok so the issue is multiple classloaders in the same session right?
                  [15:05:03] Brian Stansberry: no, multiple classloaders in the same cache; only one per session
                  [15:05:27] ? I can either use something like region-based marshalling or wrap the cached objects
                  [15:05:38] Jason T. Greene: oh i see
                  [15:05:50] ? now i get what you are talking about
                  [15:06:27] ? technically the region-fqn is duplicate information
                  [15:06:38] ? you already know the region from the fqn
                  [15:06:38] Brian Stansberry: yes
                  [15:07:27] ? yes, although the Fqn is encapsulated as an arg in the MethodCall, and which arg depends on the method
                  [15:08:12] ? also, an element of the fqn can itself be a custom type, as long as its below the region root
                  [15:08:40] ? BTW that's an issue with Hibernate caching (which is a quite different use case)
                  [15:10:43] Jason T. Greene: the first problem is an issue with the serialization format
                  [15:10:54] ? the second is bigger problem
                  [15:11:21] Brian Stansberry: +1
                  [15:16:17] Jason T. Greene: I want to get rid of that usage in pojo cache
                  [15:16:41] Brian Stansberry: which?
                  [15:16:49] Jason T. Greene: custom types in an fqn
                  [15:16:59] ? its used for maps right now
                  [15:17:39] Brian Stansberry: the key for a map entry is the last Fqn element?
                  [15:18:09] Jason T. Greene: yeah, it was done that way to make locking more efficient
                  [15:18:29] ? and index retrieval is effecient as well
                  [15:19:34] ? what i probably want to do is keep it like that for simple types
                  [15:19:55] ? but when a custom type is used generate a hash based UUID
                  [15:21:39] ? anyway its a problem i have to think about
                  [15:21:48] ? because their are other issues with custom fqns
                  [15:21:53] ? like cache loaders