You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Ziegenlippe <zi...@googlemail.com> on 2009/12/01 19:44:21 UTC

OSGI Deserialization

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


Re: OSGI Deserialization

Posted by Ziegenlippe <zi...@googlemail.com>.
I gave it a trial and it really works. Seems to work in general or at 
least when you have the chance to replace the ObjectIn/OutputStream 
implementation (which is for god sake possible for Hazelcast).
Regarding dynamically going bundles I would say hasta la vista baby. If 
your classes are not available you cannot deserialize Osgi or plain Java 
there is no difference.
But on the other hand if you update bundles you may have newer and 
better classes available which are still compatible. This could be 
handled with Kris solution too. This nice PackageAdmin can give you 
bundles for version ranges. The only thing you need take care about is a 
proper version scheme e.g. like APR does or at least proposes: 
http://apr.apache.org/versioning.html. Than the deserializer would know 
up to which version it could go. I guess something like that is done 
with MS dot net. They have the module system integrated into the 
platform and I think there are version compatibility rules too.
Bye,
Andy



Mike Haney schrieb:
> 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).
>
> On Tue, Dec 1, 2009 at 3:11 PM, Kris Pruden <kp...@gmail.com> 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: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>>>
>>>>         
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>       
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>>     
>
>   

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Kris Pruden <kp...@gmail.com>.
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 <kp...@gmail.com> 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: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Mike Haney <tx...@gmail.com>.
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).

On Tue, Dec 1, 2009 at 3:11 PM, Kris Pruden <kp...@gmail.com> 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: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: OSGI Deserialization

Posted by andrea ziege <zi...@googlemail.com>.
The Hazelcast solution is quite ok and not to much effort. I like it.
Do the guys from Hazelcast know about it? They have an issue exactly for
that problem (http://code.google.com/p/hazelcast/issues/detail?id=161).
Thank you Kris.
Bye,
Andy


2009/12/1 Kris Pruden <kp...@gmail.com>

> 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: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: OSGI Deserialization

Posted by Kris Pruden <kp...@gmail.com>.
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: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Trejkaz <tr...@trypticon.org>.
All this talk of serialisation has led me to think how it should be
done in a true OSGi way, and I wound up concluding basically this.

Firstly, that the serialise/deserialise implementations for a given
class should be registered from the same bundle that uses the class,
or at the very least some separate bundle which only depends on that
bundle, so that it's easier to swap out the bundle and its
serialisation logic at the same time.

Secondly, that what the serialiser should be putting into the stream
is the name of the interface rather than the name of their
implementation class, otherwise you defeat the purpose of OSGi by
depending on a specific implementation when you load it back in.  And
as Mike Haney was suggesting earlier in the thread, the bundle which
implemented the interface might not exist when you read it back in, so
whatever performs the over deserialisation would need to take that
into account and leave in some kind of stub object which can hang
around in the model while the real implementation isn't loaded.

I think you would have to take account of the reverse as well.  The
model might be built while a bundle was loaded, and then the bundle
might be unloaded -- yet you would expect serialising the model to
still work as expected.

All of this seems feasible if you're implementing an alternative to
Object(Input|Output)Stream, but what if you want to use an ODBMS?  I
imagine this would make things very difficult indeed.

TX

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Ziegenlippe <zi...@googlemail.com>.
Hello Kris,
thank you for your profound answer.
I think I'll agree to that when I worked more with Osgi.
Bye,
Andy

Kris Pruden schrieb:
> On Dec 2, 2009, at 1:46 PM, Ziegenlippe wrote:
>
>> I had some thoughts on that Osgi serialization issue.
>> If Osgi would disallow to place one and the same class name in 
>> different bundles (even just by convention) it would be always 
>> possible to find the proper bundle for an input data  stream.
>
> Unfortunately, OSGi does not impose that restriction.  In fact, the 
> ability for more than one bundle to provide or contain the "same" 
> class (by FQN) is one of the key benefits of OSGi.
>
>> Class name + version (or serialId) would uniquely identify the class 
>> to be loaded. To add the bundle name to the stream does work but is 
>> somehow strange to me.
>
> Fully-qualified class name plus the serial ID might be good enough to 
> unambiguously identify a class, but I don't think it's guaranteed.  
> Regardless of the approach, you need to get to a bundle, because 
> that's how you get the classloader.  You could use a heuristic like 
> this to search for the bundle, but for my application at least, it was 
> a lot easier to just include the owning bundle name in the serialized 
> form and use that on the other end.  I figure if you can influence the 
> deserialization logic, you can probably also influence the 
> serialization logic, so you may as well have them cooperate...
>
>> Having the same interface placed in different bundles seem to me 
>> quite mysterious. For the osgi framework interface package you could 
>> use for instance:
>> the felix bundle:      <groupId>org.apache.felix</groupId>
>>     <artifactId>org.osgi.core</artifactId>
>>     <version>1.4.0</version>
>> or
>> the osgi bundle:
>>   <groupId>org.osgi</groupId>
>>   <artifactId>org.osgi.core</artifactId>
>>   <version>4.2.0</version>
>> What for is this good? In my opinion there should be only one 
>> distribution bundle of an interface. This possibly would make also 
>> serialization easier?
>
> One use case I know of for allowing this is to permit multiple 
> versions of the same bundle to be loaded at the same time, to satisfy 
> mutually-exclusive version dependencies of other (presumably) 
> independent bundles.
>
> I agree that this is an odd situation in which to find oneself.  
> However, when it does happen, and it's not an accident or oversight, 
> I'd imagine it's because the developers really had no other 
> alternative.  The fact that OSGi can accommodate these scenarios at 
> all (afaik no other java container has this level of flexibility) is a 
> bit part of its appeal imo.
>
>> Since in Osgi you imports bundles not modules you wouldn't know how 
>> many redistributions of one and the same interface you have in your 
>> environment.
>> Bye,
>> Andy
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Kris Pruden <kp...@gmail.com>.
On Dec 2, 2009, at 1:46 PM, Ziegenlippe wrote:

> I had some thoughts on that Osgi serialization issue.
> If Osgi would disallow to place one and the same class name in  
> different bundles (even just by convention) it would be always  
> possible to find the proper bundle for an input data  stream.

Unfortunately, OSGi does not impose that restriction.  In fact, the  
ability for more than one bundle to provide or contain the "same"  
class (by FQN) is one of the key benefits of OSGi.

> Class name + version (or serialId) would uniquely identify the class  
> to be loaded. To add the bundle name to the stream does work but is  
> somehow strange to me.

Fully-qualified class name plus the serial ID might be good enough to  
unambiguously identify a class, but I don't think it's guaranteed.   
Regardless of the approach, you need to get to a bundle, because  
that's how you get the classloader.  You could use a heuristic like  
this to search for the bundle, but for my application at least, it was  
a lot easier to just include the owning bundle name in the serialized  
form and use that on the other end.  I figure if you can influence the  
deserialization logic, you can probably also influence the  
serialization logic, so you may as well have them cooperate...

> Having the same interface placed in different bundles seem to me  
> quite mysterious. For the osgi framework interface package you could  
> use for instance:
> the felix bundle:      <groupId>org.apache.felix</groupId>
>     <artifactId>org.osgi.core</artifactId>
>     <version>1.4.0</version>
> or
> the osgi bundle:
>   <groupId>org.osgi</groupId>
>   <artifactId>org.osgi.core</artifactId>
>   <version>4.2.0</version>
> What for is this good? In my opinion there should be only one  
> distribution bundle of an interface. This possibly would make also  
> serialization easier?

One use case I know of for allowing this is to permit multiple  
versions of the same bundle to be loaded at the same time, to satisfy  
mutually-exclusive version dependencies of other (presumably)  
independent bundles.

I agree that this is an odd situation in which to find oneself.   
However, when it does happen, and it's not an accident or oversight,  
I'd imagine it's because the developers really had no other  
alternative.  The fact that OSGi can accommodate these scenarios at  
all (afaik no other java container has this level of flexibility) is a  
bit part of its appeal imo.

> Since in Osgi you imports bundles not modules you wouldn't know how  
> many redistributions of one and the same interface you have in your  
> environment.
> Bye,
> Andy
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Ziegenlippe <zi...@googlemail.com>.
I had some thoughts on that Osgi serialization issue.
If Osgi would disallow to place one and the same class name in different 
bundles (even just by convention) it would be always possible to find 
the proper bundle for an input data  stream.
Class name + version (or serialId) would uniquely identify the class to 
be loaded. To add the bundle name to the stream does work but is somehow 
strange to me.
Having the same interface placed in different bundles seem to me quite 
mysterious. For the osgi framework interface package you could use for 
instance:
the felix bundle:  
     <groupId>org.apache.felix</groupId>
      <artifactId>org.osgi.core</artifactId>
      <version>1.4.0</version>
or
the osgi bundle:
    <groupId>org.osgi</groupId>
    <artifactId>org.osgi.core</artifactId>
    <version>4.2.0</version>
What for is this good? In my opinion there should be only one 
distribution bundle of an interface. This possibly would make also 
serialization easier?
Since in Osgi you imports bundles not modules you wouldn't know how many 
redistributions of one and the same interface you have in your environment.
Bye,
Andy


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Ziegenlippe <zi...@googlemail.com>.
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,
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: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Kris Pruden <kp...@gmail.com>.
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: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Mike Haney <tx...@gmail.com>.
Deserialization is indeed an issue with OSGi.  There is no standard
catch-all solution which I am aware of.

If you control the serialization/deserialization process, you can implement
solutions like the previous poster mentioned.  This doesn't help in cases
like Wicket though, where the serialization is done behind the scenes.

If you think about it at the conceptual level, serialization kind of runs
counter to the dynamic nature of OSGi (although it's a necessary evil in
many cases, like Wicket).  When you serialize an object, there is no
guarantee that the bundle containing the implementation of that object will
even be available when you deserialize it.  Or, perhaps the implementation
of that service has been replaced with a different implementation, which
most likely has an incompatible implementation (at least at the object
serialization level).

On Tue, Dec 1, 2009 at 12:44 PM, Ziegenlippe <zi...@googlemail.com>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
>
>

Re: OSGI Deserialization

Posted by Ziegenlippe <zi...@googlemail.com>.
A more concrete example would be if you want to store a JMS message. JMS 
provides an interface for Message and another interface Session in order 
to create it.
I guess the Message interface is always something to be exported whereas 
the real message type e.g. MantaMqMessage which implements this 
interface is private property.
So what I have is just a pointer to Message:
  Message msg=Session.createMessage(){
       return new MantaMqMessage();
  }
Serialization is no problem so far because you know the MantaMqMessage 
through reflection. But deserialization would have to create a 
MantaMqMessage instance but cannot find it since is secretly kept in 
some bundle classloader.
Bye,
Andy

Angelo vd Sijpt schrieb:
> I'm not quite sure what you're trying to accomplish in that way...
> If the references are not necessary when deserializing, make them transient.
> If they are necessary, there's something peculiar about your design; is it
> really necessary that they are implementations of some interface because
> they're used as services, or are they actually just value objects?
>
> Angelo
>
> On Wed, Dec 2, 2009 at 10:49 AM, andrea ziege <zi...@googlemail.com>wrote:
>
>   
>> This is ok I do it the same way:
>>        XStream stream=new XStream();
>>        stream.setClassLoader(Activator.class.getClassLoader());
>>
>> My problem was that the class I serialize contains references to interfaces
>> which are visible from my bundle. But the implementation classes are
>> invisible. This isn't a problem for serialization but for deserialization.
>> So even DynamicImport doesn't work. So I would need to make the impl
>> classes
>> public visible. Which I'm not able in all cases and what is in my opinion a
>> dirty fix.
>> Bye,
>> Andy
>>
>> 2009/12/2 Angelo vd Sijpt <an...@gmail.com>
>>
>>     
>>> Maybe I'm going down the wrong path here, but if your bundle B uses
>>>       
>> XStream
>>     
>>> too, you can make use of that.
>>> XStream will by default use (I believe) the system classloader, and not
>>>       
>> the
>>     
>>> classloader of bundle B. You can make it use the correct one by passing
>>> your
>>> own classloader:
>>>
>>> new XStream(null, new XppDriver(), BundleBClass.class.getClassLoader());
>>>
>>> You should make sure BundleBClass is some class that is loaded by the
>>> classloader of bundle B, since that has access to the imported classes
>>>       
>> from
>>     
>>> bundle A.
>>>
>>> Angelo
>>>
>>> On Tue, Dec 1, 2009 at 7:44 PM, Ziegenlippe <ziegenlippe@googlemail.com
>>>       
>>>> 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: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGI Deserialization

Posted by Angelo vd Sijpt <an...@gmail.com>.
I'm not quite sure what you're trying to accomplish in that way...
If the references are not necessary when deserializing, make them transient.
If they are necessary, there's something peculiar about your design; is it
really necessary that they are implementations of some interface because
they're used as services, or are they actually just value objects?

Angelo

On Wed, Dec 2, 2009 at 10:49 AM, andrea ziege <zi...@googlemail.com>wrote:

> This is ok I do it the same way:
>        XStream stream=new XStream();
>        stream.setClassLoader(Activator.class.getClassLoader());
>
> My problem was that the class I serialize contains references to interfaces
> which are visible from my bundle. But the implementation classes are
> invisible. This isn't a problem for serialization but for deserialization.
> So even DynamicImport doesn't work. So I would need to make the impl
> classes
> public visible. Which I'm not able in all cases and what is in my opinion a
> dirty fix.
> Bye,
> Andy
>
> 2009/12/2 Angelo vd Sijpt <an...@gmail.com>
>
> > Maybe I'm going down the wrong path here, but if your bundle B uses
> XStream
> > too, you can make use of that.
> > XStream will by default use (I believe) the system classloader, and not
> the
> > classloader of bundle B. You can make it use the correct one by passing
> > your
> > own classloader:
> >
> > new XStream(null, new XppDriver(), BundleBClass.class.getClassLoader());
> >
> > You should make sure BundleBClass is some class that is loaded by the
> > classloader of bundle B, since that has access to the imported classes
> from
> > bundle A.
> >
> > Angelo
> >
> > On Tue, Dec 1, 2009 at 7:44 PM, Ziegenlippe <ziegenlippe@googlemail.com
> > >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
> > >
> > >
> >
>

Re: OSGI Deserialization

Posted by andrea ziege <zi...@googlemail.com>.
This is ok I do it the same way:
        XStream stream=new XStream();
        stream.setClassLoader(Activator.class.getClassLoader());

My problem was that the class I serialize contains references to interfaces
which are visible from my bundle. But the implementation classes are
invisible. This isn't a problem for serialization but for deserialization.
So even DynamicImport doesn't work. So I would need to make the impl classes
public visible. Which I'm not able in all cases and what is in my opinion a
dirty fix.
Bye,
Andy

2009/12/2 Angelo vd Sijpt <an...@gmail.com>

> Maybe I'm going down the wrong path here, but if your bundle B uses XStream
> too, you can make use of that.
> XStream will by default use (I believe) the system classloader, and not the
> classloader of bundle B. You can make it use the correct one by passing
> your
> own classloader:
>
> new XStream(null, new XppDriver(), BundleBClass.class.getClassLoader());
>
> You should make sure BundleBClass is some class that is loaded by the
> classloader of bundle B, since that has access to the imported classes from
> bundle A.
>
> Angelo
>
> On Tue, Dec 1, 2009 at 7:44 PM, Ziegenlippe <ziegenlippe@googlemail.com
> >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
> >
> >
>

Re: OSGI Deserialization

Posted by Angelo vd Sijpt <an...@gmail.com>.
Maybe I'm going down the wrong path here, but if your bundle B uses XStream
too, you can make use of that.
XStream will by default use (I believe) the system classloader, and not the
classloader of bundle B. You can make it use the correct one by passing your
own classloader:

new XStream(null, new XppDriver(), BundleBClass.class.getClassLoader());

You should make sure BundleBClass is some class that is loaded by the
classloader of bundle B, since that has access to the imported classes from
bundle A.

Angelo

On Tue, Dec 1, 2009 at 7:44 PM, Ziegenlippe <zi...@googlemail.com>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
>
>