Discussion:
[openjms-developer] [ openjms-Bugs-831469 ] ClassCastException when using MDBs in Sun ONE AS7
SourceForge.net
2004-05-05 06:38:34 UTC
Permalink
Bugs item #831469, was opened at 2003-10-28 00:26
Message generated for change (Comment added) made by joany123
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=474136&aid=831469&group_id=54559

Category: client
Group: v0.7.6-rc3
Status: Closed
Resolution: Fixed
Priority: 5
Submitted By: Bo Min Jiang (jiangb)
Assigned to: Tim Anderson (tanderson)
Summary: ClassCastException when using MDBs in Sun ONE AS7

Initial Comment:
I am running Sun ONE Application Server 7 with OpenJMS
as the JMS provider, and have run into a problem with
Message Driven Beans.

In the onMessage method of class
org.exolab.jms.client.JmsConnectionConsumer, a
ServerSession object is being retrieved from a server
session pool, and is then cast into a JmsServerSession
object. However, the server session pool is an
application server specific object (for Sun ONE AS7, it's
implemented by class
com.iplanet.ias.ejb.containers.IASServerSessionImpl),
and cannot necessarily be cast into an a
JmsServerSession object - a ClassCastException occurs
as a result. Unfortunately, Sun ONE does not allow me
to specify a different implementation of the
ServerSession interface.

Is there a workaround for the problem described? I need
to use Sun ONE AS7, and am curious if a similar problem
exists when using other application servers.

----------------------------------------------------------------------

Comment By: joany123 (joany123)
Date: 2004-05-05 06:38

Message:
Logged In: YES
user_id=1035507

Hi,
I ve implemented the changes as suggested for the
ConnectionConsumer, Session and other related Class. I am
facing a problem. The onMessage(Message message) of
ConnectionConsumer is never getting invoked.

Am I missing on something.
Please find the code segment from ConnectionConsumer class:

abstract class JmsConnectionConsumer
implements ConnectionConsumer, MessageListener {
...

public void onMessage(Message message) {
try {
// not very sophisticated at this point. Simply get a
session
// from the pool, put the message in it, and start it.

ServerSession serverSession =
_pool.getServerSession();
JmsSession session = (JmsSession)
serverSession.getSession();
message.acknowledge();
session.addMessage(message);
serverSession.start();
} catch (Exception exception) {
LoggerFactory.getLogger().logDebug
("JmsConnectionConsumer.onMessage()") ;
}

Thanx in advance
-J

----------------------------------------------------------------------

Comment By: Bo Min Jiang (bmjiang)
Date: 2004-01-13 03:09

Message:
Logged In: YES
user_id=645251

I've tested the changes - the ClassCastException no longer
appears, and the MDBs that I used for testing work as
expected. I did, however, have to make a couple of classes
serializable in order for Sun ONE AS7 to perform JNDI lookups
of OpenJMS resources - please see item #875841.

----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2004-01-11 02:40

Message:
Logged In: YES
user_id=557161

Fixes checked in to CVS. Please test it as this is the only
thing holding up the final 0.7.6 release.
Note that the fix isn't 100% compliant with the JMS
specification, as messages are being acked by the
ConnectionConsumer - they should be acked by the session
responsible for processing the message, in its run() method.



----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2003-12-22 13:33

Message:
Logged In: YES
user_id=557161

I don't believe the changes are in the spirit of the JMS spec.
Section 8.2.6 states that the application server is responsible
for creating the thread associated with the Session, so the
thread creation in JmsSession.run() should be redundant.
This also means that the session could be accessed by
multiple threads of control, which is not supported by the
spec.
There is no need to cast to a JmsServerSession - in fact this
class should be removed.
Also, the message shouldn't be acknowledged in
JmsConnectionConsumer.onMessage() - the
ServerSessionPool could create CLIENT_ACKNOWLEDGE or
transacted sessions.

----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2003-12-17 12:38

Message:
Logged In: YES
user_id=557161

Will have a look at the changes this weekend (20/12).
Note that patches can be applied faster if you attach diffs,
as per
http://openjms.sourceforge.net/volunteers.html#Submitting
changes

----------------------------------------------------------------------

Comment By: Neil Kolban (kolban)
Date: 2003-12-09 23:39

Message:
Logged In: YES
user_id=625504

I realize that this is completely against the spirit of
OpenSource ... but I would love to test your changes ...
however ... I am not skilled on building Java apps/classes.
Would it be possible to email me a copy of your changes as
replacement JAR files and I will test on WAS V5.1 on your
behalf?

Neil
(***@us.ibm.com)

----------------------------------------------------------------------

Comment By: Bo Min Jiang (bmjiang)
Date: 2003-12-09 19:56

Message:
Logged In: YES
user_id=645251

I downloaded the source for version v0.7.6-rc1 and made
some changes that will allow OpenJMS to work with Sun ONE
when it comes to MDBs. I've done some testing, and would
like to get feedback on whether my logic is correct and
applies with other app servers.

The changes I made are as follows:

JmsSession:
--------------------------------

/**
* The message cache holds all messages for the session.
The messages are
* sent to the listener during start.
*/
private Vector _messageCache = new Vector();


/**
* Add a message to the message cache. This message
will be processed
* when the start method is called.
*
* @param message message to add.
*/
void addMessage(Message message) {
_messageCache.addElement(message);
}

// implementation of Session.run
public void run() {
// application server functionality
(new Thread(new Runnable() {

/**
* This method will iterate through the list of
messages
* in the cache and send them to the registered
listener
*/
public void run() {
try {
Enumeration messages =
_messageCache.elements();
while (messages.hasMoreElements()) {
_listener.onMessage((Message)
messages.nextElement());
}
} catch (Exception exception) {
_log.error(
"Error in the Session.run method",
exception);
} finally {
// Clear message cache
_messageCache.clear();
}
}
})).start();
}

JmsConnectionConsumer:
--------------------------------

public void onMessage(Message message) {
try {
// not very sophisticated at this point. Simply get a
server
// session put the message in it and start it.
getSession().acknowledgeMessage(message);

ServerSession serverSession = (ServerSession)
_pool.getServerSession();

//--------------------------
// BMJ - changes to work with JMSServerSession
// and other app servers
//--------------------------

// If ServerSession is instance of JmsServerSession,
then add message
// to server session, else add message to session in
app server specific server session
if (serverSession instanceof JmsServerSession)
{
JmsServerSession localSession =
(JmsServerSession) _pool.getServerSession();

localSession.addMessage(message);
localSession.start();
}
else
{
// ServerSession is application server specific.
Therefore add
// message to session and process
JmsSession session = (JmsSession)
serverSession.getSession();
session.addMessage(message);

// Cause the Session's run method to be called to
process messages that were just assigned to it.
serverSession.start();
}
} catch (Exception exception) {
_log.error(exception, exception);
}
}

----------------------------------------------------------------------

Comment By: Neil Kolban (kolban)
Date: 2003-12-09 02:31

Message:
Logged In: YES
user_id=625504

Folks,
For what its worth ... I stumbled into EXACTLY this
problem trying to integrate OpenJMS with IBM's WebSphere
Application Server V5. Exactly the same problem, exactly
the same symptoms.

Unfortunately, I have no skills or time to go further into
the guts of OpenJMS and *contribute* any solutions but I
would be DELIGHTED to hear from anyone who attempts to get
this working and am willing to run tests ...

Neil
(***@us.ibm.com)

----------------------------------------------------------------------

Comment By: Mike Spille (scubabear68)
Date: 2003-11-18 20:06

Message:
Logged In: YES
user_id=583085

I don't have time for a fully integrated diff, but the essence
of the fix for this is:

JmsSession.run():

public void run() {
if (connConsumer == null) {
return;
}
Message msg;
while ((msg = connConsumer.nextMessage()) != null) {
execute (msg);
}
connConsumer = null;
}


JmsConnectionConsumer:
abstract class JmsConnectionConsumer
implements ConnectionConsumer, MessageListener
{
private Message activeMessage;
private static int objCount = 0;

/**
* This constructor simply manaages the server session
pool and the
* the maximum number of messages that can be loaded
on any one server
* session.
*
* @param pool the server session pool
* @param maxMessages max number of messages
it can send to down
* a server session object at any one
time.
*/
JmsConnectionConsumer(ServerSessionPool pool, int
maxMessages)
{
pool_ = pool;
maxMessages_ = (maxMessages > 0) ? maxMessages :
1;
objCount++;
}

/**
* Return a reference ot the server session pool instance
use by this
* object
* <p>
* If the object is not set or there is any other issue throw
the
* JMSException exception.
*
* @return ServerSessionPool
* @exception JMSException
*/
public ServerSessionPool getServerSessionPool()
throws JMSException
{
return pool_;
}

/**
* Since a provider may allocate some resources on behalf
of a
* ConnectionConsumer outside the JVM, clients should
close them when
* they are not needed. Relying on garbage collection to
eventually
* reclaim these resources may not be timely enough.
*
* @exception JMSException if a JMS fails to release
resources on
* behalf of ConnectionConsumer or it
fails
* to close the connection consumer.
*/
public void close()
throws JMSException
{
pool_ = null;
}

/**
* Impmentation of MessageListener.onMessage, which will
receive
* messages from the server. In this most simply case it
actually
* loads each individual message into a server session and
calls
* the start method.
* <p>
* If this methods gets an error then it will send an error
message
* to the logger and return successful
*
* @param message message send back by the
server.
*/
public void onMessage(Message message)
{
try
{
// not very sophisticated at this point. Simply get a
server
// session put the message in it and start it.
/* MWS - This looks incorrect. The App Server
implements the ServerSession pool object, therefore it's
wrong for us to assume it's one of ours
getSession().acknowledgeMessage(message);
JmsServerSession local_session = (JmsServerSession)
pool_.getServerSession();
local_session.addMessage(message);
local_session.start();
*/
activeMessage = message;
ServerSession servSession = pool_.getServerSession
();
JmsSession session = (JmsSession)
servSession.getSession();
session.setConnectionConsumer (this);
servSession.start();
}
catch (Exception exception)
{
}
}

Message
nextMessage ()
{
Message msg = activeMessage;
activeMessage = null;
return (msg);
}

/**
* Abstract mathod that returns the proxy to the server
side session attached
* to this object
*
* @return Session
*/
abstract JmsSession getSession();

/**
* Return the maximum number of messages that can be
loaded down any one
* server session
*
* @return int
*/
int getMaxMessages()
{
return maxMessages_;
}

/**
* This is a reference to the server session pool, which is
used to deliver
* messages to the actual processing client.
*/
private ServerSessionPool pool_ = null;

/**
* This attribute describes the maximum number of
messages that can be
* loaded on a server session at any one time.
*/
private int maxMessages_ = 1;
}



----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2003-10-28 00:51

Message:
Logged In: YES
user_id=557161

OpenJMS's support for MDB's is untested - if you have the
time, any contribution with respect to this would be much
appreciated.

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=474136&aid=831469&group_id=54559
Loading...