Bugs item #974752, was opened at 2004-06-17 13:58
Message generated for change (Comment added) made by ejort
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=974752&group_id=22866

>Category: JBossCX
Group: v3.2
>Status: Closed
>Resolution: Fixed
Priority: 7
Submitted By: Mark Little (marklittle)
>Assigned to: Adrian Brock (ejort)
Summary: afterCompletion potential NullPointerException

Initial Comment:
The afterCompletion method of the Synchronization 
implementation TxRemover (in TxConnectionManager) 
uses currentTx from the TxConnectionEventListener to 
determine the current transaction:

// Are we still in the original transaction?
            if (currentTx.equals(tx) == false)
            {

However, currentTx is set to null in delist() when the 
XAResource is delisted from the transaction. This 
happens prior to transaction termination, which is when 
the synchronization gets to run. So obviously it's going 
to find that currentTx is null at this point and die with a 
NullPointerException.

Mark.


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

>Comment By: Adrian Brock (ejort)
Date: 2004-06-19 10:17

Message:
Logged In: YES 
user_id=9459

It should just check for a null current transaction,
i.e. the user already closed the connection and we aren't
doing track-connection-by-tx
            // Are we still in the original transaction?
            if (currentTx == null || currentTx.equals(tx) ==
false)

Your fix doesn't work in the following circumstance:

Connection conn = mcf.getConnection();
UserTransaction ut = ...
ut.begin();
//do work
ut.commit(); // invokes TxRemover
ut.begin(); // will fail if the previous tx wasn't removed
from the connection

The problem isn't seen with JBoss/JTA because it catches
all Throwables from afterCompletion and just logs a trace
message.

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

Comment By: Mark Little (marklittle)
Date: 2004-06-17 14:13

Message:
Logged In: YES 
user_id=754951

It looks to me that the problem is that the test for 
isTrackByTx is in the wrong place.

When the Synchronization is created:

try
            {
               currentTx.registerSynchronization(new TxRemover
(currentTx, isTrackByTx()));
            }
            catch (RollbackException re)
            {
               throw new SystemException("Could not register 
synchronization with tx: " + re);
            }

So the instance knows the value of isTrackByTx at this stage.

Now, in delist, the currentTx is set to null based on this value:

if (isTrackByTx() == false)
            {
               currentTx = null;

But then the afterCompletion implementation does:

// Are we still in the original transaction?
            if (currentTx.equals(tx) == false)
            {
               // If we are interleaving transactions we have 
nothing to do
               if (wasTrackByTx == false)
                  return;
               else
               {

The else clause for if the two transactions aren't the same 
will do nothing as well if wasTrackByTx is false. So, I suggest 
that a possible fix would be to move the wasTrackByTx test 
to the start of the method:

public void afterCompletion(int status)
{
    if (!wasTrackByTx)
        return;
    ...
}

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

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=974752&group_id=22866


-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
_______________________________________________
JBoss-Development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to