Issue Details (XML | Word | Printable)

Key: AMQ-1438
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: David Jencks
Reporter: Manu T George
Votes: 2
Watchers: 1
Operations

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

When in XA Transaction Active-MQ integrated with OpenEJB hangs in the isSameRM method of LocalAndXATransaction.

Created: 03/Oct/07 12:29 AM   Updated: 07/Apr/08 03:16 PM
Return to search
Component/s: Connector, Transport
Affects Version/s: 4.1.1
Fix Version/s: 4.1.2

Time Tracking:
Not Specified

File Attachments:
  Size
Text File Licensed for inclusion in ASF works AMQ-1438.patch 2007-10-09 11:45 PM Manu T George 2 kB
Environment: All


 Description  « Hide
I was facing a problem with the AMQ 4.1 with the LocalAndXATransaction class's isSameRM waiting indefinitely. The wait is because waitForBrokerInfo calls brokerInfoReceived.await()
where brokerInfoReceived is a countdown latch. Once this is waiting it
never gets resumed.

To trigger it the method onCommand(final Object o) has to be called on
org.apache.activemq.ActiveMQConnection.



 All   Comments   Work Log   Change History   Subversion Commits   FishEye   Crucible      Sort Order: Ascending order - Click to sort in descending order
Manu T George added a comment - 03/Oct/07 12:45 AM

Manu T George added a comment - 03/Oct/07 12:47 AM

Manu T George added a comment - 09/Oct/07 11:45 PM
This fixes the issue. Running the tests shows the same no of failures as before applying the patch so assuming it doesn't break anything.

Manu T George added a comment - 11/Oct/07 03:43 AM
I believe I owe an explanation for the JIRA.

The problem faced is a hang in the method below when the Geronimo TM calls it.

public boolean isSameRM(XAResource other) throws XAException {
if (other instanceof WrapperNamedXAResource) { return xaResource.isSameRM(((WrapperNamedXAResource)other).xaResource); }
return false;
}

The hang is because this method invokes org,apache.activemq.ActiveMQConnection.getResourceManagerId()

This method is shown below

public String getResourceManagerId() throws JMSException { waitForBrokerInfo(); if( brokerInfo==null ) throw new JMSException("Connection failed before Broker info was received."); return brokerInfo.getBrokerId().getValue(); }

The waitForBrokerInfo() method is shown below

private void waitForBrokerInfo() throws JMSException {
try { brokerInfoReceived.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw JMSExceptionSupport.create(e); }
}

Once await is called on brokerInfoReceived which is a countdown latch currently brokerInfoReceived.countDown() never gets called. Actually this should get called on the
else if ( command.isBrokerInfo() ) { this.brokerInfo = (BrokerInfo)command; brokerInfoReceived.countDown(); this.optimizeAcknowledge &= !this.brokerInfo.isFaultTolerantConfiguration(); }

block of the onCommand method of org.apache.activemq.ActiveMQConnection.

This is not getting called.

On investigating and with some help from AMQ IRC , I found that there are two methods in org.apache.activemq.transport.vm.VMTransport. They are given below

protected void syncOneWay(Object command){
final TransportListener tl=peer.transportListener;
prePeerSetQueue=peer.prePeerSetQueue;
if(tl==null){ prePeerSetQueue.add(command); }else{ tl.onCommand(command); }
}

protected void asyncOneWay(Object command) throws IOException{
messageQueue=getMessageQueue();
try{ messageQueue.put(command); wakeup(); }catch(final InterruptedException e){ log.error("messageQueue interupted",e); throw new IOException(e.getMessage()); }
}

The problem here is even when i set async=true for the VMTransport when the command BrokerInfo is sent syncOneWay is called. At that time TransportListener tl=null. So it gets added to prePeerSetQueue. The reason for this happening is that in org.apache.activemq.transport.vm.VMTransportFactory when the below lines are called a brokerInfo is sent as server.connect() is called. The async=true is not yet set resulting in the syncOneWay getting called. Only after that IntrospectionSupport.setProperties(vmtransport,options); is called and async is set to true. Due to this inconsistency the BrokerInfo command gets lost.

VMTransport vmtransport=server.connect();
IntrospectionSupport.setProperties(vmtransport,options);

I hope I made the issue clear. Can someone verify the patch or make a fix for this.


David Jencks added a comment - 24/Mar/08 12:59 AM
Applied modified version of the patch in rev 640340. Passed options into server.connect method so that correct TransportAcceptListener is sure to be used.

David Jencks added a comment - 07/Apr/08 03:16 PM
Would be a good idea to check if it works in 5.1