Issue Details (XML | Word | Printable)

Key: GLASSFISH-19443
Type: Bug Bug
Status: Resolved Resolved
Resolution: Works as designed
Priority: Critical Critical
Assignee: Sanjeeb Sahoo
Reporter: jthoennes
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
glassfish

GFv312 getting ClassCastException after redeploy OSGI bundle and the EJB jar

Created: 14/Dec/12 04:15 PM   Updated: 20/Dec/12 08:01 AM   Resolved: 14/Dec/12 05:12 PM
Component/s: OSGi
Affects Version/s: 3.1.2_b05
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments: 1. Zip Archive mainProject-v2.zip (49 kB) 14/Dec/12 04:20 PM - jthoennes
2. Text File server.log (18 kB) 14/Dec/12 04:24 PM - jthoennes
3. Text File steps-to-reproduce.txt (5 kB) 14/Dec/12 04:19 PM - jthoennes


Tags:
Participants: chrjohn, jthoennes and Sanjeeb Sahoo


 Description  « Hide

We use the following set up:

  • An OSGi bundle containing a simple java class named MyOSGI.
    This bundle is deployed on Glassfish as OSGi bundle as well as
    available as simple jar file in the classpath of a java process.
  • A MessageDrivenBean which processes object messages. The object
    messages containing instances of MyOSGI.
  • The object messages are sent from external jms clients.

This works fine if

  • you start Glassfish,
  • deploy the OSGI bundle,
  • deploy the EJB jar containing the MessageDrivenBean
  • call the external JMS client.

This failes if

  • you redeploy the OSGI bundle,
  • redeploy the EJB jar containing the MessageDrivenBean
  • call the external JMS client,
    without restarting the Glassfish instance.

So if you redeploy the OSGI bundle and the EJB jar processing
of message fails because the MessageDrivenBean can not cast the
received object to MyOSGI.

The following exception is seen in that case, after redeployment:
java.lang.ClassCastException: com.macd.osgi.bundle.MyOSGI cannot be cast to
com.macd.osgi.bundle.MyOSGI

server.log
[#|2012-12-11T16:47:00.264+0100|SEVERE|oracle-glassfish3.1.2|javax.enterprise.
system.std.com.sun.enterprise.server.logging|_ThreadID=27;_ThreadName=Thread-2
;|java.lang.ClassCastException: com.macd.osgi.bundle.MyOSGI cannot be cast to 
com.macd.osgi.bundle.MyOSGI
        at com.macd.mdb.MessageDriveBeanOSGI.onMessage(MessageDriveBeanOSGI.java:45)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j
ava:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at 
org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurit
yManager.java:1052)
        at 
org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityMa
nager.java:1124)
        at 
com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java
:4180)
        at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5368)
        at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
        at 
com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContaine
r.java:1099)
        at 
com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListe
nerImpl.java:81)
        at 
com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(
MessageEndpointInvocationHandler.java:171)
        at $Proxy260.onMessage(Unknown Source)
        at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114)
        at 
com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWo
rk(ThreadPoolImpl.java:497)
        at 
com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(Threa
dPoolImpl.java:540)
|#]


jthoennes added a comment - 14/Dec/12 04:19 PM

Attached steps to reproduce.


jthoennes added a comment - 14/Dec/12 04:20 PM

Attached Maven project used to reproduce this issue.


jthoennes added a comment - 14/Dec/12 04:24 PM

Attached server log from complete run:

  • start-domain
  • deploy 1
  • deploy 2
  • stop-domain

Sanjeeb Sahoo added a comment - 14/Dec/12 05:12 PM

This is the expected behavior. Since the message receiver app is a non-OSGi application, it's class loader can't be updated while it is running, so it maintains references to the previous bundle class loader. I suggest you make your message receiver an OSGi aware application. We have some sample like this available in https://svn.java.net/svn/glassfish~svn/trunk/fighterfish/test/testapp/ . test.app16 is related to JMS.


jthoennes added a comment - 14/Dec/12 09:08 PM

Thanks for the quick response.

But both apps are redeployed: First the OSGi bundle, then the MDB.
On redeployment, I would expect that the MDB picks up the new classloader.
But it stays with the previously deployed old version of the OSGi bundle.

What you are telling me is that while the MDB is running (being deployed),
any change of the OSGi bundle (redeploy) would not affect the MDB.

Or am I wrong here?


Sanjeeb Sahoo added a comment - 15/Dec/12 12:52 AM

The classes from OSGi bundles for all Java EE apps are loaded using a common class loader which can't be flushed out when bundles are updated. SO, even though you redeployed the jms app after updating the bundle, it does not see the updated bundle. It is something in our plan to improve. In the mean while, I recommend you turning your jms app to a bundle (ie a hybrid app).


chrjohn added a comment - 20/Dec/12 08:01 AM

I'm not sure if this is only an issue of the class loader which can't be updated. We were also seeing the classes still listed after an undeploy of the bundle and the MDB. At least in output of "jmap -histo:live <pid>". Or is this not the correct means to tell if the undeployed applications have been removed completely?