You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Garrett Headley <gc...@yahoo.com> on 2007/12/19 07:15:25 UTC

Class Loader

This sort of relates to a previous post where a user
pointed me in the direction of looking at class
loaders, though I still have some problems.

I am working on a host application where I would like
to be able to include plugins for monitoring sensors. 
The host application uses JMS and ActiveMQ to
communicate between modules from the hardware layer to
the client GUI.  However, I'm hiding the JMS layer
from the plugin developer by having him/her extend
classes that do the actual message sending
(ObjectMessage).  Also, the Serial Port services have
been written as an OSGi module also.

The device module plugin contains classes for parsing
the data from the comm port, framing the data to go
out the comm port, creating a client and server side
device representation, and the gui classes for display
of data.  The SerialPort module is responsible for
listening for the device plugin being started by
Felix, and then loading the parser from that bundle,
by calling bundle.loadClass().  Great.  The
DeviceParser creates a POJO message object, say,
DevicePositionMessage which implements MessageI (from
the host application), and then calls the abstract
class function sendMessage, where the host will send
the message using JMS to the client/GUI side.  

Now, the client & GUI classes are loaded from the host
by listening for bundles started by Felix, and
instances are created when JMS messages are received
in the similar manner... bundle.loadClass().  However,
when the message is unpacked in the Device class (from
the Bundle), it does not register as being an
instanceof DevicePositionMessage, but it does register
as being an instanceof MessageI.

I thought I had a solution to the issue by loading all
of the bundle's classes with the AppClassLoader,
calling bundle.getClass.getClassLoader.loadClass(). 
Which, actually resulted in the messages being
unpacked in such a way that the check of instanceof
DevicePositionMessage was true.  But, unless I
actually declare the plugin JAR file as being a
dependency of the host application, I will get
ClassNotFound exceptions.  And the whole point is to
be able to just drop the plugin JAR files into a
directory and have them be loaded dynamically.

So, kind of a long explanation, but I was trying to be
thorough.  I have a bit of a difficulty accessing this
list from work... if anyone wants to ask for more info
offline, (and I can always repost the solution later),
you can try my work email, headlegc AT nv DOT doe DOT
gov.

Thanks for any help,
Garrett


      ____________________________________________________________________________________
Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 


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


Re: Class Loader

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Headley, Garrett wrote:
> Almost definitely seems to be a class loader issue.  When I print out
> the class loader for the DevicePositionMessage, I get "2.0".  I'm
> assuming this is a felix class loader?
>   

Yes, the "2.0" is the bundle revision associated with the class loader.

> When I print out the class loader used when I try to cast the message
> object to the DevicePositionMessage, I get "AppClassLoader".  
>
> Is there an easy way to force the message creator to use the
> AppClassLoader?  I can't see an easy way to for the Device class to use
> the AppClassLoader.
>
> Or, should I create my own class loader for creating the message and
> then unpacking it again?  Still seems like JMS will have trouble with
> the serializing process if the message is not created with the
> AppClassLoader.
>   

Well, I am not sure how JMS works with class loaders, but you could try 
to set the thread context class loader to the bundle's class loader 
before deserializing the message. If JMS uses the context class loader, 
then it should load it from the bundle's class loader instead of the app 
class loader.

-> richard

> Thanks
> Garrett
>
> -----Original Message-----
> From: Richard S. Hall [mailto:heavy@ungoverned.org] 
> Sent: Friday, December 21, 2007 12:14 PM
> To: Headley, Garrett; users@felix.apache.org
> Subject: Re: Class Loader
>
> Headley, Garrett wrote:
>   
>> Okay, I'll try to be more specific.
>>
>> For the most part, I am pretty much following how your example program
>> works with the shapes loaded as OSGi bundles by the Host application
>> (embedding felix).  Think of the Device as a shape.  On the Host side:
>>
>> class HostMessage implements MessageI.
>>   
>> On the Device side:
>>
>> class DevicePositionMessage extends DeviceMessage implements
>> DevicePositionMessageI
>>
>> interface DevicePositionMessageI extends DeviceMessageI
>>
>> interface DeviceMessageI extends MessageI
>>
>> class DeviceMessage extends HostMessage
>>
>> The Device class, similar to the example where the Shapes import
>> SimpleShape from the host, in my case import HostMessage from the
>>     
> host.
>   
>> And as you can see, there are multiple paths from
>>     
> DevicePositionMessage
>   
>> where you can infer that a DevicePositionMessage is an instance of
>> MessageI.
>>
>> Next, the bundle class DeviceParser extends the abstract class
>> ProtocolParser from the host (which is imported).  The ProtocolParser
>> has a final method call sendMessage, where a MessageI is wrapped as a
>> JMS ObjectMessage, and sent via a Producer.  The DeviceParser on the
>> bundle side calls MessageI msg = new DevicePositionMessage(x, ...);
>> super.sendMessage(msg).  And that way, the imported host classes can
>> hide the JMS message passing from the device class developer.  The
>> developer can simply extend the host ProtocolParser class and call
>> sendMessage(msg).
>>
>> Next, on a client side, the JMS is received.  The device developer
>> creates a class called something like MyDevice (or Device) that
>>     
> extends
>   
>> the host class it imports called PluginDevice.  PluginDevice
>>     
> implements
>   
>> MessageListener and handles the onMessage(Message msg) event.  Then,
>> PluginDevice calls MessageI messageI =
>>     
> ((ObjectMessage)msg).getMessage()
>   
>> to unwrap the message that was wrapped in the host class
>>     
> ProtocolParser
>   
>> where the message was sent from.  This is one place where I get a JMS
>> error trying to unwrap a DevicePositionMessage.  If I add the
>> Device-1.0.0.jar bundle to the project as a module dependency, then at
>> least the message is unwrapped without an exception (but this takes
>>     
> away
>   
>> from the dynamic nature of the plugin architecture I am trying to
>> achieve).  However, when the PluginDevice class on the host side calls
>> the overrided function receiveMessage(messageI) which will get handled
>> in MyDevice, when MyDevice does an instanceof check on the unpacked
>> message, it fails when checked for instanceof DeviceMessageI.  But it
>> passes on instance of MessageI.
>>
>> This may be a ActiveMQ issue.  I've done a debug trace inside of
>> ActiveMQ to the point of finding that the original message is copied
>>     
> to
>   
>> a new message before being sent, and that when the object inside the
>> copy is copied as a byte array, it seems to lose it's identification
>>     
> as
>   
>> being a class implementing the DeviceMessageI interface.  Maybe, like
>> you say, it has something to do with ActiveMQ making a copy of the
>> message, and therefore the DevicePositionMessage object using a
>> different class loader.
>>   
>>     
>
> So, are you actually reflecting on the returned object and printing out 
> all interfaces that it implements? Do you see that it implements 
> DevicePositionMessage? If so, print the class loader for the 
> DevicePositionMessage class that it implements and in your client print 
> DevicePositionMessage.class.getClassLoader()...you should be able to see
>
> which class loaders are loading the classes.
>
> Of course, if the received message doesn't implement the interface at 
> all, well, then I really don't know what is going on.
>
> -> richard
>
>   
>> Anyways,  Thanks for reading so far... is there anything else that
>> stands out in your mind?
>>
>> Thanks
>> Garrett
>>
>> -----Original Message-----
>> From: Richard S. Hall [mailto:heavy@ungoverned.org] 
>> Sent: Thursday, December 20, 2007 8:26 AM
>> To: users@felix.apache.org
>> Cc: Headley, Garrett
>> Subject: Re: Class Loader
>>
>> You exact scenario still isn't clear to me, even after the lengthy 
>> description. Sorry. :-)
>>
>> I don't have much experience in using RMI with OSGi.
>>
>> When you unpack your message in the Device class from the bundle, how 
>> does the bundle have access to the DevicePositionMessage? Does it
>>     
> import
>   
>> it? If so, to which provider is it wired?
>>
>> For JMS to unpack the message, it must have access to the 
>> DevicePositionMessage too. Perhaps it loads it from the wire? It is 
>> likely that JMS is not getting the class from the same place as your 
>> bundle, thus your bundle thinks it is not a DevicePositionMessage,
>>     
> when 
>   
>> it really is, but it was loaded from a different class loader, which 
>> makes them incompatible.
>>
>> The trick would be to get JMS to unpack with your bundle's class
>>     
> loader.
>   
>> I don't know enough about RMI to tell you how to do this.
>>
>> -> richard
>>
>> Garrett Headley wrote:
>>   
>>     
>>> This sort of relates to a previous post where a user
>>> pointed me in the direction of looking at class
>>> loaders, though I still have some problems.
>>>
>>> I am working on a host application where I would like
>>> to be able to include plugins for monitoring sensors. 
>>> The host application uses JMS and ActiveMQ to
>>> communicate between modules from the hardware layer to
>>> the client GUI.  However, I'm hiding the JMS layer
>>> from the plugin developer by having him/her extend
>>> classes that do the actual message sending
>>> (ObjectMessage).  Also, the Serial Port services have
>>> been written as an OSGi module also.
>>>
>>> The device module plugin contains classes for parsing
>>> the data from the comm port, framing the data to go
>>> out the comm port, creating a client and server side
>>> device representation, and the gui classes for display
>>> of data.  The SerialPort module is responsible for
>>> listening for the device plugin being started by
>>> Felix, and then loading the parser from that bundle,
>>> by calling bundle.loadClass().  Great.  The
>>> DeviceParser creates a POJO message object, say,
>>> DevicePositionMessage which implements MessageI (from
>>> the host application), and then calls the abstract
>>> class function sendMessage, where the host will send
>>> the message using JMS to the client/GUI side.  
>>>
>>> Now, the client & GUI classes are loaded from the host
>>> by listening for bundles started by Felix, and
>>> instances are created when JMS messages are received
>>> in the similar manner... bundle.loadClass().  However,
>>> when the message is unpacked in the Device class (from
>>> the Bundle), it does not register as being an
>>> instanceof DevicePositionMessage, but it does register
>>> as being an instanceof MessageI.
>>>
>>> I thought I had a solution to the issue by loading all
>>> of the bundle's classes with the AppClassLoader,
>>> calling bundle.getClass.getClassLoader.loadClass(). 
>>> Which, actually resulted in the messages being
>>> unpacked in such a way that the check of instanceof
>>> DevicePositionMessage was true.  But, unless I
>>> actually declare the plugin JAR file as being a
>>> dependency of the host application, I will get
>>> ClassNotFound exceptions.  And the whole point is to
>>> be able to just drop the plugin JAR files into a
>>> directory and have them be loaded dynamically.
>>>
>>> So, kind of a long explanation, but I was trying to be
>>> thorough.  I have a bit of a difficulty accessing this
>>> list from work... if anyone wants to ask for more info
>>> offline, (and I can always repost the solution later),
>>> you can try my work email, headlegc AT nv DOT doe DOT
>>> gov.
>>>
>>> Thanks for any help,
>>> Garrett
>>>
>>>
>>>
>>>     
>>>       
> ________________________________________________________________________
>   
>> ____________
>>   
>>     
>>> Be a better friend, newshound, and 
>>> know-it-all with Yahoo! Mobile.  Try it now.
>>>     
>>>       
>> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>>   
>>     
>>> ---------------------------------------------------------------------
>>> 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: Class Loader

Posted by "Headley, Garrett" <HE...@nv.doe.gov>.
Almost definitely seems to be a class loader issue.  When I print out
the class loader for the DevicePositionMessage, I get "2.0".  I'm
assuming this is a felix class loader?

When I print out the class loader used when I try to cast the message
object to the DevicePositionMessage, I get "AppClassLoader".  

Is there an easy way to force the message creator to use the
AppClassLoader?  I can't see an easy way to for the Device class to use
the AppClassLoader.

Or, should I create my own class loader for creating the message and
then unpacking it again?  Still seems like JMS will have trouble with
the serializing process if the message is not created with the
AppClassLoader.

Thanks
Garrett

-----Original Message-----
From: Richard S. Hall [mailto:heavy@ungoverned.org] 
Sent: Friday, December 21, 2007 12:14 PM
To: Headley, Garrett; users@felix.apache.org
Subject: Re: Class Loader

Headley, Garrett wrote:
> Okay, I'll try to be more specific.
>
> For the most part, I am pretty much following how your example program
> works with the shapes loaded as OSGi bundles by the Host application
> (embedding felix).  Think of the Device as a shape.  On the Host side:
>
> class HostMessage implements MessageI.
>   
> On the Device side:
>
> class DevicePositionMessage extends DeviceMessage implements
> DevicePositionMessageI
>
> interface DevicePositionMessageI extends DeviceMessageI
>
> interface DeviceMessageI extends MessageI
>
> class DeviceMessage extends HostMessage
>
> The Device class, similar to the example where the Shapes import
> SimpleShape from the host, in my case import HostMessage from the
host.
> And as you can see, there are multiple paths from
DevicePositionMessage
> where you can infer that a DevicePositionMessage is an instance of
> MessageI.
>
> Next, the bundle class DeviceParser extends the abstract class
> ProtocolParser from the host (which is imported).  The ProtocolParser
> has a final method call sendMessage, where a MessageI is wrapped as a
> JMS ObjectMessage, and sent via a Producer.  The DeviceParser on the
> bundle side calls MessageI msg = new DevicePositionMessage(x, ...);
> super.sendMessage(msg).  And that way, the imported host classes can
> hide the JMS message passing from the device class developer.  The
> developer can simply extend the host ProtocolParser class and call
> sendMessage(msg).
>
> Next, on a client side, the JMS is received.  The device developer
> creates a class called something like MyDevice (or Device) that
extends
> the host class it imports called PluginDevice.  PluginDevice
implements
> MessageListener and handles the onMessage(Message msg) event.  Then,
> PluginDevice calls MessageI messageI =
((ObjectMessage)msg).getMessage()
> to unwrap the message that was wrapped in the host class
ProtocolParser
> where the message was sent from.  This is one place where I get a JMS
> error trying to unwrap a DevicePositionMessage.  If I add the
> Device-1.0.0.jar bundle to the project as a module dependency, then at
> least the message is unwrapped without an exception (but this takes
away
> from the dynamic nature of the plugin architecture I am trying to
> achieve).  However, when the PluginDevice class on the host side calls
> the overrided function receiveMessage(messageI) which will get handled
> in MyDevice, when MyDevice does an instanceof check on the unpacked
> message, it fails when checked for instanceof DeviceMessageI.  But it
> passes on instance of MessageI.
>
> This may be a ActiveMQ issue.  I've done a debug trace inside of
> ActiveMQ to the point of finding that the original message is copied
to
> a new message before being sent, and that when the object inside the
> copy is copied as a byte array, it seems to lose it's identification
as
> being a class implementing the DeviceMessageI interface.  Maybe, like
> you say, it has something to do with ActiveMQ making a copy of the
> message, and therefore the DevicePositionMessage object using a
> different class loader.
>   

So, are you actually reflecting on the returned object and printing out 
all interfaces that it implements? Do you see that it implements 
DevicePositionMessage? If so, print the class loader for the 
DevicePositionMessage class that it implements and in your client print 
DevicePositionMessage.class.getClassLoader()...you should be able to see

which class loaders are loading the classes.

Of course, if the received message doesn't implement the interface at 
all, well, then I really don't know what is going on.

-> richard

> Anyways,  Thanks for reading so far... is there anything else that
> stands out in your mind?
>
> Thanks
> Garrett
>
> -----Original Message-----
> From: Richard S. Hall [mailto:heavy@ungoverned.org] 
> Sent: Thursday, December 20, 2007 8:26 AM
> To: users@felix.apache.org
> Cc: Headley, Garrett
> Subject: Re: Class Loader
>
> You exact scenario still isn't clear to me, even after the lengthy 
> description. Sorry. :-)
>
> I don't have much experience in using RMI with OSGi.
>
> When you unpack your message in the Device class from the bundle, how 
> does the bundle have access to the DevicePositionMessage? Does it
import
>
> it? If so, to which provider is it wired?
>
> For JMS to unpack the message, it must have access to the 
> DevicePositionMessage too. Perhaps it loads it from the wire? It is 
> likely that JMS is not getting the class from the same place as your 
> bundle, thus your bundle thinks it is not a DevicePositionMessage,
when 
> it really is, but it was loaded from a different class loader, which 
> makes them incompatible.
>
> The trick would be to get JMS to unpack with your bundle's class
loader.
>
> I don't know enough about RMI to tell you how to do this.
>
> -> richard
>
> Garrett Headley wrote:
>   
>> This sort of relates to a previous post where a user
>> pointed me in the direction of looking at class
>> loaders, though I still have some problems.
>>
>> I am working on a host application where I would like
>> to be able to include plugins for monitoring sensors. 
>> The host application uses JMS and ActiveMQ to
>> communicate between modules from the hardware layer to
>> the client GUI.  However, I'm hiding the JMS layer
>> from the plugin developer by having him/her extend
>> classes that do the actual message sending
>> (ObjectMessage).  Also, the Serial Port services have
>> been written as an OSGi module also.
>>
>> The device module plugin contains classes for parsing
>> the data from the comm port, framing the data to go
>> out the comm port, creating a client and server side
>> device representation, and the gui classes for display
>> of data.  The SerialPort module is responsible for
>> listening for the device plugin being started by
>> Felix, and then loading the parser from that bundle,
>> by calling bundle.loadClass().  Great.  The
>> DeviceParser creates a POJO message object, say,
>> DevicePositionMessage which implements MessageI (from
>> the host application), and then calls the abstract
>> class function sendMessage, where the host will send
>> the message using JMS to the client/GUI side.  
>>
>> Now, the client & GUI classes are loaded from the host
>> by listening for bundles started by Felix, and
>> instances are created when JMS messages are received
>> in the similar manner... bundle.loadClass().  However,
>> when the message is unpacked in the Device class (from
>> the Bundle), it does not register as being an
>> instanceof DevicePositionMessage, but it does register
>> as being an instanceof MessageI.
>>
>> I thought I had a solution to the issue by loading all
>> of the bundle's classes with the AppClassLoader,
>> calling bundle.getClass.getClassLoader.loadClass(). 
>> Which, actually resulted in the messages being
>> unpacked in such a way that the check of instanceof
>> DevicePositionMessage was true.  But, unless I
>> actually declare the plugin JAR file as being a
>> dependency of the host application, I will get
>> ClassNotFound exceptions.  And the whole point is to
>> be able to just drop the plugin JAR files into a
>> directory and have them be loaded dynamically.
>>
>> So, kind of a long explanation, but I was trying to be
>> thorough.  I have a bit of a difficulty accessing this
>> list from work... if anyone wants to ask for more info
>> offline, (and I can always repost the solution later),
>> you can try my work email, headlegc AT nv DOT doe DOT
>> gov.
>>
>> Thanks for any help,
>> Garrett
>>
>>
>>
>>     
>
________________________________________________________________________
> ____________
>   
>> Be a better friend, newshound, and 
>> know-it-all with Yahoo! Mobile.  Try it now.
>>     
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>   
>> ---------------------------------------------------------------------
>> 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: Class Loader

Posted by "Headley, Garrett" <HE...@nv.doe.gov>.
Thanks for the help, Richard.  I'm thinking of chalking it up to a
serialization issue with JMS.  I can trace the message through the JMS
code until it gets to the receiving end, where it tries and fails to
de-serialize the object inside of the ObjectMessage.  Which could be a
result of the class loader issue you mention below.  Not sure exactly
how to get around the problem right now, but you've given me a couple of
ideas.

Thanks
Garrett

-----Original Message-----
From: Richard S. Hall [mailto:heavy@ungoverned.org] 
Sent: Friday, December 21, 2007 12:14 PM
To: Headley, Garrett; users@felix.apache.org
Subject: Re: Class Loader

Headley, Garrett wrote:
> Okay, I'll try to be more specific.
>
> For the most part, I am pretty much following how your example program
> works with the shapes loaded as OSGi bundles by the Host application
> (embedding felix).  Think of the Device as a shape.  On the Host side:
>
> class HostMessage implements MessageI.
>   
> On the Device side:
>
> class DevicePositionMessage extends DeviceMessage implements
> DevicePositionMessageI
>
> interface DevicePositionMessageI extends DeviceMessageI
>
> interface DeviceMessageI extends MessageI
>
> class DeviceMessage extends HostMessage
>
> The Device class, similar to the example where the Shapes import
> SimpleShape from the host, in my case import HostMessage from the
host.
> And as you can see, there are multiple paths from
DevicePositionMessage
> where you can infer that a DevicePositionMessage is an instance of
> MessageI.
>
> Next, the bundle class DeviceParser extends the abstract class
> ProtocolParser from the host (which is imported).  The ProtocolParser
> has a final method call sendMessage, where a MessageI is wrapped as a
> JMS ObjectMessage, and sent via a Producer.  The DeviceParser on the
> bundle side calls MessageI msg = new DevicePositionMessage(x, ...);
> super.sendMessage(msg).  And that way, the imported host classes can
> hide the JMS message passing from the device class developer.  The
> developer can simply extend the host ProtocolParser class and call
> sendMessage(msg).
>
> Next, on a client side, the JMS is received.  The device developer
> creates a class called something like MyDevice (or Device) that
extends
> the host class it imports called PluginDevice.  PluginDevice
implements
> MessageListener and handles the onMessage(Message msg) event.  Then,
> PluginDevice calls MessageI messageI =
((ObjectMessage)msg).getMessage()
> to unwrap the message that was wrapped in the host class
ProtocolParser
> where the message was sent from.  This is one place where I get a JMS
> error trying to unwrap a DevicePositionMessage.  If I add the
> Device-1.0.0.jar bundle to the project as a module dependency, then at
> least the message is unwrapped without an exception (but this takes
away
> from the dynamic nature of the plugin architecture I am trying to
> achieve).  However, when the PluginDevice class on the host side calls
> the overrided function receiveMessage(messageI) which will get handled
> in MyDevice, when MyDevice does an instanceof check on the unpacked
> message, it fails when checked for instanceof DeviceMessageI.  But it
> passes on instance of MessageI.
>
> This may be a ActiveMQ issue.  I've done a debug trace inside of
> ActiveMQ to the point of finding that the original message is copied
to
> a new message before being sent, and that when the object inside the
> copy is copied as a byte array, it seems to lose it's identification
as
> being a class implementing the DeviceMessageI interface.  Maybe, like
> you say, it has something to do with ActiveMQ making a copy of the
> message, and therefore the DevicePositionMessage object using a
> different class loader.
>   

So, are you actually reflecting on the returned object and printing out 
all interfaces that it implements? Do you see that it implements 
DevicePositionMessage? If so, print the class loader for the 
DevicePositionMessage class that it implements and in your client print 
DevicePositionMessage.class.getClassLoader()...you should be able to see

which class loaders are loading the classes.

Of course, if the received message doesn't implement the interface at 
all, well, then I really don't know what is going on.

-> richard

> Anyways,  Thanks for reading so far... is there anything else that
> stands out in your mind?
>
> Thanks
> Garrett
>
> -----Original Message-----
> From: Richard S. Hall [mailto:heavy@ungoverned.org] 
> Sent: Thursday, December 20, 2007 8:26 AM
> To: users@felix.apache.org
> Cc: Headley, Garrett
> Subject: Re: Class Loader
>
> You exact scenario still isn't clear to me, even after the lengthy 
> description. Sorry. :-)
>
> I don't have much experience in using RMI with OSGi.
>
> When you unpack your message in the Device class from the bundle, how 
> does the bundle have access to the DevicePositionMessage? Does it
import
>
> it? If so, to which provider is it wired?
>
> For JMS to unpack the message, it must have access to the 
> DevicePositionMessage too. Perhaps it loads it from the wire? It is 
> likely that JMS is not getting the class from the same place as your 
> bundle, thus your bundle thinks it is not a DevicePositionMessage,
when 
> it really is, but it was loaded from a different class loader, which 
> makes them incompatible.
>
> The trick would be to get JMS to unpack with your bundle's class
loader.
>
> I don't know enough about RMI to tell you how to do this.
>
> -> richard
>
> Garrett Headley wrote:
>   
>> This sort of relates to a previous post where a user
>> pointed me in the direction of looking at class
>> loaders, though I still have some problems.
>>
>> I am working on a host application where I would like
>> to be able to include plugins for monitoring sensors. 
>> The host application uses JMS and ActiveMQ to
>> communicate between modules from the hardware layer to
>> the client GUI.  However, I'm hiding the JMS layer
>> from the plugin developer by having him/her extend
>> classes that do the actual message sending
>> (ObjectMessage).  Also, the Serial Port services have
>> been written as an OSGi module also.
>>
>> The device module plugin contains classes for parsing
>> the data from the comm port, framing the data to go
>> out the comm port, creating a client and server side
>> device representation, and the gui classes for display
>> of data.  The SerialPort module is responsible for
>> listening for the device plugin being started by
>> Felix, and then loading the parser from that bundle,
>> by calling bundle.loadClass().  Great.  The
>> DeviceParser creates a POJO message object, say,
>> DevicePositionMessage which implements MessageI (from
>> the host application), and then calls the abstract
>> class function sendMessage, where the host will send
>> the message using JMS to the client/GUI side.  
>>
>> Now, the client & GUI classes are loaded from the host
>> by listening for bundles started by Felix, and
>> instances are created when JMS messages are received
>> in the similar manner... bundle.loadClass().  However,
>> when the message is unpacked in the Device class (from
>> the Bundle), it does not register as being an
>> instanceof DevicePositionMessage, but it does register
>> as being an instanceof MessageI.
>>
>> I thought I had a solution to the issue by loading all
>> of the bundle's classes with the AppClassLoader,
>> calling bundle.getClass.getClassLoader.loadClass(). 
>> Which, actually resulted in the messages being
>> unpacked in such a way that the check of instanceof
>> DevicePositionMessage was true.  But, unless I
>> actually declare the plugin JAR file as being a
>> dependency of the host application, I will get
>> ClassNotFound exceptions.  And the whole point is to
>> be able to just drop the plugin JAR files into a
>> directory and have them be loaded dynamically.
>>
>> So, kind of a long explanation, but I was trying to be
>> thorough.  I have a bit of a difficulty accessing this
>> list from work... if anyone wants to ask for more info
>> offline, (and I can always repost the solution later),
>> you can try my work email, headlegc AT nv DOT doe DOT
>> gov.
>>
>> Thanks for any help,
>> Garrett
>>
>>
>>
>>     
>
________________________________________________________________________
> ____________
>   
>> Be a better friend, newshound, and 
>> know-it-all with Yahoo! Mobile.  Try it now.
>>     
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>   
>> ---------------------------------------------------------------------
>> 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: Class Loader

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Headley, Garrett wrote:
> Okay, I'll try to be more specific.
>
> For the most part, I am pretty much following how your example program
> works with the shapes loaded as OSGi bundles by the Host application
> (embedding felix).  Think of the Device as a shape.  On the Host side:
>
> class HostMessage implements MessageI.
>   
> On the Device side:
>
> class DevicePositionMessage extends DeviceMessage implements
> DevicePositionMessageI
>
> interface DevicePositionMessageI extends DeviceMessageI
>
> interface DeviceMessageI extends MessageI
>
> class DeviceMessage extends HostMessage
>
> The Device class, similar to the example where the Shapes import
> SimpleShape from the host, in my case import HostMessage from the host.
> And as you can see, there are multiple paths from DevicePositionMessage
> where you can infer that a DevicePositionMessage is an instance of
> MessageI.
>
> Next, the bundle class DeviceParser extends the abstract class
> ProtocolParser from the host (which is imported).  The ProtocolParser
> has a final method call sendMessage, where a MessageI is wrapped as a
> JMS ObjectMessage, and sent via a Producer.  The DeviceParser on the
> bundle side calls MessageI msg = new DevicePositionMessage(x, ...);
> super.sendMessage(msg).  And that way, the imported host classes can
> hide the JMS message passing from the device class developer.  The
> developer can simply extend the host ProtocolParser class and call
> sendMessage(msg).
>
> Next, on a client side, the JMS is received.  The device developer
> creates a class called something like MyDevice (or Device) that extends
> the host class it imports called PluginDevice.  PluginDevice implements
> MessageListener and handles the onMessage(Message msg) event.  Then,
> PluginDevice calls MessageI messageI = ((ObjectMessage)msg).getMessage()
> to unwrap the message that was wrapped in the host class ProtocolParser
> where the message was sent from.  This is one place where I get a JMS
> error trying to unwrap a DevicePositionMessage.  If I add the
> Device-1.0.0.jar bundle to the project as a module dependency, then at
> least the message is unwrapped without an exception (but this takes away
> from the dynamic nature of the plugin architecture I am trying to
> achieve).  However, when the PluginDevice class on the host side calls
> the overrided function receiveMessage(messageI) which will get handled
> in MyDevice, when MyDevice does an instanceof check on the unpacked
> message, it fails when checked for instanceof DeviceMessageI.  But it
> passes on instance of MessageI.
>
> This may be a ActiveMQ issue.  I've done a debug trace inside of
> ActiveMQ to the point of finding that the original message is copied to
> a new message before being sent, and that when the object inside the
> copy is copied as a byte array, it seems to lose it's identification as
> being a class implementing the DeviceMessageI interface.  Maybe, like
> you say, it has something to do with ActiveMQ making a copy of the
> message, and therefore the DevicePositionMessage object using a
> different class loader.
>   

So, are you actually reflecting on the returned object and printing out 
all interfaces that it implements? Do you see that it implements 
DevicePositionMessage? If so, print the class loader for the 
DevicePositionMessage class that it implements and in your client print 
DevicePositionMessage.class.getClassLoader()...you should be able to see 
which class loaders are loading the classes.

Of course, if the received message doesn't implement the interface at 
all, well, then I really don't know what is going on.

-> richard

> Anyways,  Thanks for reading so far... is there anything else that
> stands out in your mind?
>
> Thanks
> Garrett
>
> -----Original Message-----
> From: Richard S. Hall [mailto:heavy@ungoverned.org] 
> Sent: Thursday, December 20, 2007 8:26 AM
> To: users@felix.apache.org
> Cc: Headley, Garrett
> Subject: Re: Class Loader
>
> You exact scenario still isn't clear to me, even after the lengthy 
> description. Sorry. :-)
>
> I don't have much experience in using RMI with OSGi.
>
> When you unpack your message in the Device class from the bundle, how 
> does the bundle have access to the DevicePositionMessage? Does it import
>
> it? If so, to which provider is it wired?
>
> For JMS to unpack the message, it must have access to the 
> DevicePositionMessage too. Perhaps it loads it from the wire? It is 
> likely that JMS is not getting the class from the same place as your 
> bundle, thus your bundle thinks it is not a DevicePositionMessage, when 
> it really is, but it was loaded from a different class loader, which 
> makes them incompatible.
>
> The trick would be to get JMS to unpack with your bundle's class loader.
>
> I don't know enough about RMI to tell you how to do this.
>
> -> richard
>
> Garrett Headley wrote:
>   
>> This sort of relates to a previous post where a user
>> pointed me in the direction of looking at class
>> loaders, though I still have some problems.
>>
>> I am working on a host application where I would like
>> to be able to include plugins for monitoring sensors. 
>> The host application uses JMS and ActiveMQ to
>> communicate between modules from the hardware layer to
>> the client GUI.  However, I'm hiding the JMS layer
>> from the plugin developer by having him/her extend
>> classes that do the actual message sending
>> (ObjectMessage).  Also, the Serial Port services have
>> been written as an OSGi module also.
>>
>> The device module plugin contains classes for parsing
>> the data from the comm port, framing the data to go
>> out the comm port, creating a client and server side
>> device representation, and the gui classes for display
>> of data.  The SerialPort module is responsible for
>> listening for the device plugin being started by
>> Felix, and then loading the parser from that bundle,
>> by calling bundle.loadClass().  Great.  The
>> DeviceParser creates a POJO message object, say,
>> DevicePositionMessage which implements MessageI (from
>> the host application), and then calls the abstract
>> class function sendMessage, where the host will send
>> the message using JMS to the client/GUI side.  
>>
>> Now, the client & GUI classes are loaded from the host
>> by listening for bundles started by Felix, and
>> instances are created when JMS messages are received
>> in the similar manner... bundle.loadClass().  However,
>> when the message is unpacked in the Device class (from
>> the Bundle), it does not register as being an
>> instanceof DevicePositionMessage, but it does register
>> as being an instanceof MessageI.
>>
>> I thought I had a solution to the issue by loading all
>> of the bundle's classes with the AppClassLoader,
>> calling bundle.getClass.getClassLoader.loadClass(). 
>> Which, actually resulted in the messages being
>> unpacked in such a way that the check of instanceof
>> DevicePositionMessage was true.  But, unless I
>> actually declare the plugin JAR file as being a
>> dependency of the host application, I will get
>> ClassNotFound exceptions.  And the whole point is to
>> be able to just drop the plugin JAR files into a
>> directory and have them be loaded dynamically.
>>
>> So, kind of a long explanation, but I was trying to be
>> thorough.  I have a bit of a difficulty accessing this
>> list from work... if anyone wants to ask for more info
>> offline, (and I can always repost the solution later),
>> you can try my work email, headlegc AT nv DOT doe DOT
>> gov.
>>
>> Thanks for any help,
>> Garrett
>>
>>
>>
>>     
> ________________________________________________________________________
> ____________
>   
>> Be a better friend, newshound, and 
>> know-it-all with Yahoo! Mobile.  Try it now.
>>     
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>   
>> ---------------------------------------------------------------------
>> 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: Class Loader

Posted by "Headley, Garrett" <HE...@nv.doe.gov>.
Okay, I'll try to be more specific.

For the most part, I am pretty much following how your example program
works with the shapes loaded as OSGi bundles by the Host application
(embedding felix).  Think of the Device as a shape.  On the Host side:

class HostMessage implements MessageI.
  
On the Device side:

class DevicePositionMessage extends DeviceMessage implements
DevicePositionMessageI

interface DevicePositionMessageI extends DeviceMessageI

interface DeviceMessageI extends MessageI

class DeviceMessage extends HostMessage

The Device class, similar to the example where the Shapes import
SimpleShape from the host, in my case import HostMessage from the host.
And as you can see, there are multiple paths from DevicePositionMessage
where you can infer that a DevicePositionMessage is an instance of
MessageI.

Next, the bundle class DeviceParser extends the abstract class
ProtocolParser from the host (which is imported).  The ProtocolParser
has a final method call sendMessage, where a MessageI is wrapped as a
JMS ObjectMessage, and sent via a Producer.  The DeviceParser on the
bundle side calls MessageI msg = new DevicePositionMessage(x, ...);
super.sendMessage(msg).  And that way, the imported host classes can
hide the JMS message passing from the device class developer.  The
developer can simply extend the host ProtocolParser class and call
sendMessage(msg).

Next, on a client side, the JMS is received.  The device developer
creates a class called something like MyDevice (or Device) that extends
the host class it imports called PluginDevice.  PluginDevice implements
MessageListener and handles the onMessage(Message msg) event.  Then,
PluginDevice calls MessageI messageI = ((ObjectMessage)msg).getMessage()
to unwrap the message that was wrapped in the host class ProtocolParser
where the message was sent from.  This is one place where I get a JMS
error trying to unwrap a DevicePositionMessage.  If I add the
Device-1.0.0.jar bundle to the project as a module dependency, then at
least the message is unwrapped without an exception (but this takes away
from the dynamic nature of the plugin architecture I am trying to
achieve).  However, when the PluginDevice class on the host side calls
the overrided function receiveMessage(messageI) which will get handled
in MyDevice, when MyDevice does an instanceof check on the unpacked
message, it fails when checked for instanceof DeviceMessageI.  But it
passes on instance of MessageI.

This may be a ActiveMQ issue.  I've done a debug trace inside of
ActiveMQ to the point of finding that the original message is copied to
a new message before being sent, and that when the object inside the
copy is copied as a byte array, it seems to lose it's identification as
being a class implementing the DeviceMessageI interface.  Maybe, like
you say, it has something to do with ActiveMQ making a copy of the
message, and therefore the DevicePositionMessage object using a
different class loader.

Anyways,  Thanks for reading so far... is there anything else that
stands out in your mind?

Thanks
Garrett

-----Original Message-----
From: Richard S. Hall [mailto:heavy@ungoverned.org] 
Sent: Thursday, December 20, 2007 8:26 AM
To: users@felix.apache.org
Cc: Headley, Garrett
Subject: Re: Class Loader

You exact scenario still isn't clear to me, even after the lengthy 
description. Sorry. :-)

I don't have much experience in using RMI with OSGi.

When you unpack your message in the Device class from the bundle, how 
does the bundle have access to the DevicePositionMessage? Does it import

it? If so, to which provider is it wired?

For JMS to unpack the message, it must have access to the 
DevicePositionMessage too. Perhaps it loads it from the wire? It is 
likely that JMS is not getting the class from the same place as your 
bundle, thus your bundle thinks it is not a DevicePositionMessage, when 
it really is, but it was loaded from a different class loader, which 
makes them incompatible.

The trick would be to get JMS to unpack with your bundle's class loader.

I don't know enough about RMI to tell you how to do this.

-> richard

Garrett Headley wrote:
> This sort of relates to a previous post where a user
> pointed me in the direction of looking at class
> loaders, though I still have some problems.
>
> I am working on a host application where I would like
> to be able to include plugins for monitoring sensors. 
> The host application uses JMS and ActiveMQ to
> communicate between modules from the hardware layer to
> the client GUI.  However, I'm hiding the JMS layer
> from the plugin developer by having him/her extend
> classes that do the actual message sending
> (ObjectMessage).  Also, the Serial Port services have
> been written as an OSGi module also.
>
> The device module plugin contains classes for parsing
> the data from the comm port, framing the data to go
> out the comm port, creating a client and server side
> device representation, and the gui classes for display
> of data.  The SerialPort module is responsible for
> listening for the device plugin being started by
> Felix, and then loading the parser from that bundle,
> by calling bundle.loadClass().  Great.  The
> DeviceParser creates a POJO message object, say,
> DevicePositionMessage which implements MessageI (from
> the host application), and then calls the abstract
> class function sendMessage, where the host will send
> the message using JMS to the client/GUI side.  
>
> Now, the client & GUI classes are loaded from the host
> by listening for bundles started by Felix, and
> instances are created when JMS messages are received
> in the similar manner... bundle.loadClass().  However,
> when the message is unpacked in the Device class (from
> the Bundle), it does not register as being an
> instanceof DevicePositionMessage, but it does register
> as being an instanceof MessageI.
>
> I thought I had a solution to the issue by loading all
> of the bundle's classes with the AppClassLoader,
> calling bundle.getClass.getClassLoader.loadClass(). 
> Which, actually resulted in the messages being
> unpacked in such a way that the check of instanceof
> DevicePositionMessage was true.  But, unless I
> actually declare the plugin JAR file as being a
> dependency of the host application, I will get
> ClassNotFound exceptions.  And the whole point is to
> be able to just drop the plugin JAR files into a
> directory and have them be loaded dynamically.
>
> So, kind of a long explanation, but I was trying to be
> thorough.  I have a bit of a difficulty accessing this
> list from work... if anyone wants to ask for more info
> offline, (and I can always repost the solution later),
> you can try my work email, headlegc AT nv DOT doe DOT
> gov.
>
> Thanks for any help,
> Garrett
>
>
>
________________________________________________________________________
____________
> Be a better friend, newshound, and 
> know-it-all with Yahoo! Mobile.  Try it now.
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>
>
> ---------------------------------------------------------------------
> 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: Class Loader

Posted by "Richard S. Hall" <he...@ungoverned.org>.
You exact scenario still isn't clear to me, even after the lengthy 
description. Sorry. :-)

I don't have much experience in using RMI with OSGi.

When you unpack your message in the Device class from the bundle, how 
does the bundle have access to the DevicePositionMessage? Does it import 
it? If so, to which provider is it wired?

For JMS to unpack the message, it must have access to the 
DevicePositionMessage too. Perhaps it loads it from the wire? It is 
likely that JMS is not getting the class from the same place as your 
bundle, thus your bundle thinks it is not a DevicePositionMessage, when 
it really is, but it was loaded from a different class loader, which 
makes them incompatible.

The trick would be to get JMS to unpack with your bundle's class loader. 
I don't know enough about RMI to tell you how to do this.

-> richard

Garrett Headley wrote:
> This sort of relates to a previous post where a user
> pointed me in the direction of looking at class
> loaders, though I still have some problems.
>
> I am working on a host application where I would like
> to be able to include plugins for monitoring sensors. 
> The host application uses JMS and ActiveMQ to
> communicate between modules from the hardware layer to
> the client GUI.  However, I'm hiding the JMS layer
> from the plugin developer by having him/her extend
> classes that do the actual message sending
> (ObjectMessage).  Also, the Serial Port services have
> been written as an OSGi module also.
>
> The device module plugin contains classes for parsing
> the data from the comm port, framing the data to go
> out the comm port, creating a client and server side
> device representation, and the gui classes for display
> of data.  The SerialPort module is responsible for
> listening for the device plugin being started by
> Felix, and then loading the parser from that bundle,
> by calling bundle.loadClass().  Great.  The
> DeviceParser creates a POJO message object, say,
> DevicePositionMessage which implements MessageI (from
> the host application), and then calls the abstract
> class function sendMessage, where the host will send
> the message using JMS to the client/GUI side.  
>
> Now, the client & GUI classes are loaded from the host
> by listening for bundles started by Felix, and
> instances are created when JMS messages are received
> in the similar manner... bundle.loadClass().  However,
> when the message is unpacked in the Device class (from
> the Bundle), it does not register as being an
> instanceof DevicePositionMessage, but it does register
> as being an instanceof MessageI.
>
> I thought I had a solution to the issue by loading all
> of the bundle's classes with the AppClassLoader,
> calling bundle.getClass.getClassLoader.loadClass(). 
> Which, actually resulted in the messages being
> unpacked in such a way that the check of instanceof
> DevicePositionMessage was true.  But, unless I
> actually declare the plugin JAR file as being a
> dependency of the host application, I will get
> ClassNotFound exceptions.  And the whole point is to
> be able to just drop the plugin JAR files into a
> directory and have them be loaded dynamically.
>
> So, kind of a long explanation, but I was trying to be
> thorough.  I have a bit of a difficulty accessing this
> list from work... if anyone wants to ask for more info
> offline, (and I can always repost the solution later),
> you can try my work email, headlegc AT nv DOT doe DOT
> gov.
>
> Thanks for any help,
> Garrett
>
>
>       ____________________________________________________________________________________
> Be a better friend, newshound, and 
> know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 
>
>
> ---------------------------------------------------------------------
> 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