On 4 February 2013 11:34, Dawid Loubser <[email protected]> wrote:
> Thanks for the quick response, Dan!
>
> I want to understand the classloading a bit better. Let me explain to
> you how I *think* it works. Also, for reference, I'm using the rio
> project, that has a special classloader that understands URLs in the
> form "artifact:foo:bar:1.0" and which loads classes from Maven
> artifacts, but I think it's conceptually the same as any other URL
> scheme etc.
>
> * When an  Entry it written to space, it's turned into a
> MarshalledInstance. This is annotated with the codebase (a collection of
> URLs). Immediate question: Is there only one codebase at the top-level
> of the entry, or does every object in the graph have (or can have) its
> own codebase?
>

Theoretically you could manufacture an Entry dependent upon multiple
codebases but I honestly can't think of many practical situations.

See here for the basics of how it works:
http://river.apache.org/doc/specs/html/entry-spec.html


> * When a worker takes/reads an entry (which might contain things that
> both are on the worker's classpath, and perhaps lower-level content that
> is not (i.e. specialisations that it does not have to understand), how
> does the space proxy know what to do? I imagine it uses the thread
> context class loader, but then how does it deserialise the objects that
> is not on that classpath (using the codebase annotation of the
> MarshalledInstance, I imagine) whilst not colliding with the classes
> already available to the worker? Using some sort of parent/child
> delegation?

Collision with other classes and the avoidance thereof has to be
managed explicitly typically via preferred classes and the
PreferredClassLoader. I'm not sure how Rio plays with that stuff
(don't use it much, one for Dennis...)

When that's not done you can easily get classes resolved inside of
local classloaders rather than via a remote codebase causing
ClassCastExceptions etc.

>
> I've got a very tricky ClassCastException problem I'm trying to debug,
> where it's clearly the same class loaded by two classloaders, and thus
> the field cannot be assigned. I don't know how to get "in there" and
> solve the problem, it seems I can only respond to the
> UnusableEntryException, get the partial entry, and lose the rest?

If you're getting ClassCastException the most likely cause is there's
something on the classpath that shouldn't be. i.e. The class in
question should be resolved via a codebase annotation. It's possible
that you are losing a codebase annotation somewhere along the line
causing something to be resolved locally rather than remotely - the
infamous "lost codebase problem".

Can't say too much more without seeing it for myself....

>
> thanks so much,
> Dawid
>
>
> On Mon, 2013-02-04 at 11:17 +0000, Dan Creswell wrote:
>> On 4 February 2013 11:10, Dawid Loubser <[email protected]> wrote:
>> > Hi all,
>> >
>> > I have a bunch of entries in a JavaSpace (representing long-running
>> > process state, i.e. they exist for days or weeks), and these contain
>> > some objects that were generated from XML (using JAXB). That vocabulary
>> > has evolved (additions only) but now, of course, the computed
>> > SerialVersionUIDs will be different. When I redeploy my workers that
>> > have been built against the new API, they will surely fail when reading
>> > the old entries.
>> >
>> > Any strategies as to how I can migrate the data in the space? I'm
>> > running a persistent outrigger (snaplogstore). I was thinking of, in a
>> > worker with an 'old' classpath, draining the space, and storing those
>> > entries in some non-java representation on disk, and then in a worker
>> > with the 'new' classpath, reading those entries and re-populating the
>> > space.
>>
>> Slightly more complicated but it's possible to have one worker do all
>> this with some classloader magic. You basically load old and new
>> definitions into separate classloaders with the old version being
>> directly on the classpath, the other dynamically loaded from something
>> not on the classpath.
>>
>> Then you can take the old easily and use reflection magic to populate
>> a new and write it.
>>
>> One other challenge is that most JavaSpace implementations don't like
>> mixed schemas do probably you're better to create a second space,
>> write the migrated ones into that and then turn off the old one (or
>> copy back to the old once you've cleared it down/re-built it).
>>
>> >
>> > Migrating data in a space is surely something that must have caused
>> > problems for somebody before, and I'd love to tackle this problem
>> > drawing on some experience of others.
>> >
>> > regards,
>> > Dawid
>> >
>

Reply via email to