On Dec 1, 2009, at 1:16 PM, Mike Haney wrote:
Kris - that's an interesting solution. I'm not familiar enough with
the
inner workings of serialization, but I wonder if it would be
possible to do
this on a global level and package it into a bundle to provide this
support
across the entire OSGi runtime? That would be a decent partial
solution to
the problem. It still doesn't help the problem with bundles
dynamically
coming and going, but should be sufficient for many use cases, for
example
storing data to the HTTP session between request (a la Wicket).
I thought about that, but in the Object{Input,Ouput}Stream cases at
least, for this solution to work you must use a different class. In
other words, You must explicitly use OsgiObjectOutputStream and its
counterpart for this to work. I haven't figured out a way to make the
included-with-java versions to work. I suppose one could resort to a
boot agent that simply replaces the implementations of these classes
with OSGi-aware versions might work.
I think the more general case is harder. Any logic that explicitly
loads classes (as all serialization mechanisms must ultimately do)
pretty much has to be OSGi-aware, or support the injection of OSGi-
aware hooks. Luckily, most well-designed libraries seem to support
this (interestingly, the java.io object streams are *not* well-
designed in this regard). So, while it may never be possible to
provide a library-independent solution to this problem, it should be
possible with some work to make a given library work with OSGi in such
a way that at least the clients of that library don't need to do any
extra work.
Hopefully as OSGi catches on more of these libraries will natively
support it...
Kris
On Tue, Dec 1, 2009 at 3:11 PM, Kris Pruden <[email protected]> wrote:
On Dec 1, 2009, at 11:16 AM, Ziegenlippe wrote:
Nice. Does this mean I have to take care about serialization by my
own? I
use great libs XStream and Hazelcast. Both of them are doing a good
serialization job. But I see without bundle-id+version there is no
way.
Thanks for the answer,
Not necessarily. Some libraries support the injection of custom
hooks at
various stages of the serialization/deserialization process.
As an example, I was able to create OSGi-aware versions of
Object{Output,Input}Stream by overriding the annotateClass() and
resolveClass() methods, respectively.
I'm not familiar with XStream, but it wouldn't surprise me if it
offered
some way to influence the class loading process..
As for Hazelcast, I actually went down that path and got it to work
by
registering custom serializers which used the OSGi-aware object
streams I
talked about above.
Here's the activator I used:
package com.hazelcast.osgi;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.nio.Serializer;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
ServiceReference ref =
context.getServiceReference(PackageAdmin.class.getName());
PackageAdmin pkgAdmin = (PackageAdmin) context.getService(ref);
Serializer.registerTypeSerializer(new OsgiObjectSerializer());
Serializer.registerTypeSerializer(new
OsgiDataSerializer(pkgAdmin));
}
public void stop(BundleContext context) throws Exception {
Serializer.registerTypeSerializer(new
Serializer.ObjectSerializer());
Serializer.registerTypeSerializer(new
Serializer.DataSerializer());
Hazelcast.shutdown();
}
}
The implementations of OsgiObjectSerializer and OsgiDataSerializer
are
pretty similar to the versions that come with Hazelcast; they
simply inject
a bundle name into the stream during serialization, and during
deserialization use that name to lookup the bundle to use to load the
class..
Kris
Andy
Kris Pruden schrieb:
I had a similar problem. The solution boils down to delegating
to the
"owning" bundle to load the class. To do this you need of course
to know
the name of the bundle. In my case I was able to solve this
problem with a
couple helper methods that wrap the PackageAdmin service provided
by OSGi:
public String getBundleName(Class<?> cls) {
Bundle bundle = pkgAdmin.getBundle(cls);
if (bundle != null) {
return bundle.getSymbolicName();
} else {
return null;
}
}
public Class<?> loadClass(String className, String bundleName)
throws
ClassNotFoundException {
Bundle[] bundles = pkgAdmin.getBundles(bundleName, null);
if (bundles == null || bundles.length == 0) {
return null;
}
return bundles[0].loadClass(className);
}
When serializing the object, you can use getBundleName to get the
name of
the bundle which "owns" the class being serialized. This name
needs to be
included in the xml data you store. Then on deserialization,
loadClass
looks up the bundle by the name specified, then uses that bundle
to load the
class.
This code assumes that there will be only one version of the
bundle with
a given name present, but it would be fairly straightforward to
extend this
to look at bundle versions if needed...
HTH...
Kris
On Dec 1, 2009, at 10:44 AM, Ziegenlippe wrote:
Hello,
I cannot find a satisfying solution to a simple looking problem
for
quite a while.
The condensation of the problem:
Bundle A
the producer stores objects as xml files (e.g. with XStream)
it exports the /bundle.a/ package which contains the interface /
Item/
it contains a private implementation package /bundle.a.impl/
which contains
the item implementation class /ItemImpl/
Bundle B
the consumer needs to load and process /Item/ instances
therefor it imports package /bundle.a/ which contains the /Item/
interface
Problem: loading Item instances in bundle B leads always to
ClassNotFoundExceptions
Even working with the last resort /DynamicImport-Package: * /
does not
solve the problem since it imports only exported packages.
From some hints in the internet I got the feeling that this
issue is not
really solved for OSGI. Is there any solution known? How deal
others with
that issue e.g. ActiveMq which claims to be OSGI compliant.
Or am I just on the wrong way?
Thank you in advance,
Andy
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]