Antonio D'Errico created AMQ-3844:
-------------------------------------
Summary: NullPointerException when removing connection info
Key: AMQ-3844
URL: https://issues.apache.org/jira/browse/AMQ-3844
Project: ActiveMQ
Issue Type: Bug
Components: Broker
Affects Versions: 5.5.1, 5.4.3
Environment: Linux 2.6.18-274.12.1.el5 #1 SMP Tue Nov 29 13:37:35 EST
2011 i686 athlon i386 GNU/Linux, Java(TM) SE Runtime Environment (build
1.6.0_29-b11)
Reporter: Antonio D'Errico
Sometimes off and on the KahaDB maintains some old transactions that try to
recovery. So at start up these transactions are added to the {{xaTransactions}}
inside {{TransactionBroker}} with a null {{ConnectionId}}.
This is the stack trace of the recovery
{code:none}
TransactionBroker.beginTransaction(ConnectionContext, TransactionId)
line: 152
TransactionBroker$1.recover(XATransactionId, Message[], MessageAck[])
line: 92
KahaDBTransactionStore.recover(TransactionRecoveryListener) line: 317
TransactionBroker.start() line: 89
BrokerService$3.start() line: 1781
XBeanBrokerService(BrokerService).start() line: 489
XBeanBrokerService.afterPropertiesSet() line: 60
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeCustomInitMethod(String,
Object, RootBeanDefinition) line: 1536
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String,
Object, RootBeanDefinition) line: 1477
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String,
Object, RootBeanDefinition) line: 1409
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String,
RootBeanDefinition, Object[]) line: 519
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String,
RootBeanDefinition, Object[]) line: 456
AbstractBeanFactory$1.getObject() line: 291
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String,
ObjectFactory) line: 222
DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String,
Class<T>, Object[], boolean) line: 288
DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line:
190
DefaultListableBeanFactory.preInstantiateSingletons() line: 574
XBeanBrokerFactory$1(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory)
line: 895
XBeanBrokerFactory$1(AbstractApplicationContext).refresh() line: 425
XBeanBrokerFactory$1(ResourceXmlApplicationContext).<init>(Resource,
List) line: 64
XBeanBrokerFactory$1(ResourceXmlApplicationContext).<init>(Resource)
line: 52
XBeanBrokerFactory$1.<init>(XBeanBrokerFactory, Resource) line: 115
XBeanBrokerFactory.createApplicationContext(String) line: 115
XBeanBrokerFactory.createBroker(URI) line: 71
BrokerFactory.createBroker(URI, boolean) line: 71
BrokerFactory.createBroker(URI) line: 54
StartCommand.startBroker(URI) line: 115
StartCommand.runTask(List<String>) line: 74
StartCommand(AbstractCommand).execute(List<String>) line: 57
ShellCommand.runTask(List<String>) line: 143
ShellCommand(AbstractCommand).execute(List<String>) line: 57
ShellCommand.main(String[], InputStream, PrintStream) line: 85
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
Main.runTaskClass(List<String>) line: 251
Main.main(String[]) line: 107
{code}
after during execution the client add and remove connection and sometimes the
removeConnection throws a NPE because there are these transactions without
ConnectionID
{code:java}
public void removeConnection(ConnectionContext context, ConnectionInfo
info, Throwable error) throws Exception {
for (Iterator<Transaction> iter =
context.getTransactions().values().iterator(); iter.hasNext();) {
try {
Transaction transaction = iter.next();
transaction.rollback();
} catch (Exception e) {
LOG.warn("ERROR Rolling back disconnected client's
transactions: ", e);
}
iter.remove();
}
synchronized (xaTransactions) {
// first find all txs that belongs to the connection
ArrayList<XATransaction> txs = new ArrayList<XATransaction>();
for (XATransaction tx : xaTransactions.values()) {
if (tx.getConnectionId().equals(info.getConnectionId()) &&
!tx.isPrepared()) {
txs.add(tx);
}
}
// then remove them
// two steps needed to avoid ConcurrentModificationException, from
removeTransaction()
for (XATransaction tx : txs) {
try {
tx.rollback();
} catch (Exception e) {
LOG.warn("ERROR Rolling back disconnected client's xa
transactions: ", e);
}
}
}
next.removeConnection(context, info, error);
}
{code}
as you can see inside the loop there is a check for
{{tx.getConnectionId().equals(info.getConnectionId())}} that throws the NPE so
the connection isn't removed but this information isn't shared with the client
that the next time that try to resend client information to server obtain
(under jBoss) this error {{javax.transaction.xa.XAException: Broker: AMQ -
Client: ID:srv001-47592-1336730655955-64:2 already connected from
/127.0.0.1:49806}}
that can be bound to the server fails.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira