[ 
https://issues.apache.org/jira/browse/AMQ-3844?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Gary Tully resolved AMQ-3844.
-----------------------------

       Resolution: Fixed
    Fix Version/s: 5.6.0
         Assignee: Gary Tully

fix related to https://issues.apache.org/jira/browse/AMQ-3305
                
> 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.4.3, 5.5.1
>         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
>            Assignee: Gary Tully
>             Fix For: 5.6.0
>
>         Attachments: ActiveMQ_server.log, jBoss_server.log
>
>
> Sometimes off and on the ActiveMQ server, the KahaDB maintains some old 
> transactions that try to recovery. So at start up these transactions are 
> added to the {{xaTransactions}} map inside {{TransactionBroker}} with a null 
> {{ConnectionId}}.
> This is the stack trace of the recovery at startup:
> {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} 
> During the  runtime the client tries to add and remove connections; sometimes 
> the removeConnection throws a NPE due to these transactions without 
> ConnectionID.
> Take a look to the code fragment from {{TransactionBroker}}:
> {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. 
> When this occurs the connection isn't removed. This information isn't shared 
> with the client that believes the opposite, so 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 former server fails.
> This scenario can be found inside the attached logs.

--
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

        

Reply via email to