Nope. The JMSConnectionFactory class has changed quite a lot over the past months and can't be considered as a stable API. It is therefore not appropriate as an extension point. Also, its responsibility is much broader than looking up the (Queue|Topic)?ConnectionFactory. If the purpose is to make the lookup strategy configurable, then we should introduce an appropriate abstraction just for that.
Andreas On Wed, May 27, 2009 at 17:44, Amila Suriarachchi <[email protected]> wrote: > On Tue, May 26, 2009 at 9:58 PM, Andreas Veithen > <[email protected]>wrote: > >> Sounds really cool :-) >> >> You are right that JNDI is not necessary to get distributed >> transaction working. However it will still be required because it is >> the only way the JMS transport can acquire the connection factory. So >> you have two options: >> >> 1. Propose a clean way how to modify the JMS transport so that it can >> get the connection factory without JNDI. > > > I think this is possible. In fact at jms transport connection factory access > methods are abstracted out to JMSConnectionFactory. However there is small > code duplication at this class and JMSUtils class. > So if we can use only JMSConnectionFactory class then it can be overrid with > a custom class. > > attached a patch with some modifications. > > thanks, > Amila. > >> >> >> 2. Use a simple JNDI implementation. This is actually not difficult at >> all and can be done with a few lines of code. This is exactly how I >> implemented the unit tests for the JMS transport. There I use mockejb >> and the code basically does the following: >> >> MockContextFactory.setAsInitial(); >> context = new InitialContext(); >> context.bind(jndiName, connectionFactory); >> >> >> Andreas >> >> On Tue, May 26, 2009 at 18:12, Amila Suriarachchi >> <[email protected]> wrote: >> > On Sun, May 24, 2009 at 5:15 AM, Andreas Veithen >> > <[email protected]>wrote: >> > >> >> Amila, >> >> >> >> AFAIK there is only a single requirement to make the JMS transport >> >> work with JTA, namely that there is a connection factory which >> >> participates in distributed transactions and which can be looked up >> >> using JNDI. This is something that should also be provided by >> >> standalone JTA implementations. >> > >> > >> > thanks for your reply. >> > >> > Is it a requirement to have a JNDI look up for transaction libraries? >> > >> > Please have look at these two code samples. >> > >> > private void sendMessage() { >> > >> > UserTransactionManager userTransactionManager = new >> > UserTransactionManager(); >> > String uri = "tcp://amila:61616"; >> > Connection connection = null; >> > >> > try { >> > userTransactionManager.init(); >> > >> > // creating a jms XA Connection factor >> > ActiveMQXAConnectionFactory xaConnectionFactory = new >> > ActiveMQXAConnectionFactory(); >> > xaConnectionFactory.setBrokerURL(uri); >> > >> > AtomikosConnectionFactoryBean connectionFactoryBean = new >> > AtomikosConnectionFactoryBean(); >> > connectionFactoryBean.setUniqueResourceName("JMSFactory"); >> > >> > connectionFactoryBean.setXaConnectionFactory(xaConnectionFactory); >> > connectionFactoryBean.setMaxPoolSize(5); >> > >> > // doing the transaction >> > userTransactionManager.begin(); >> > >> > connection = connectionFactoryBean.createConnection(); >> > // send the message to jms queue >> > connection.start(); >> > >> > Session session = connection.createSession(true, >> > Session.SESSION_TRANSACTED); >> > Destination orderQueue = session.createQueue("SampleQueue"); >> > MessageProducer producer = session.createProducer(orderQueue); >> > >> > >> > //get the message from the data base >> > AtomikosDataSourceBean dataSourceBean = new >> > AtomikosDataSourceBean(); >> > dataSourceBean.setUniqueResourceName("MyDataSource"); >> > >> > >> dataSourceBean.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); >> > Properties properties = new Properties(); >> > properties.put("databaseName", >> > "/home/amila/msc/project/atomikos/db/TEST_DB"); >> > dataSourceBean.setXaProperties(properties); >> > >> > java.sql.Connection sqlConnection = >> > dataSourceBean.getConnection(); >> > >> > Statement statement = sqlConnection.createStatement(); >> > >> > ResultSet resultSet = statement.executeQuery("select * from >> > message_to_send"); >> > while (resultSet.next()) { >> > // send the message to jms queue >> > System.out.println("Value ==> " + resultSet.getString(2)); >> > TextMessage textMessage = >> session.createTextMessage("Testing >> > message to send"); >> > producer.send(textMessage); >> > System.out.println("Send the message ... "); >> > >> > } >> > >> > statement.close(); >> > statement = sqlConnection.createStatement(); >> > statement.execute("delete from message_to_send"); >> > statement.close(); >> > >> > userTransactionManager.commit(); >> > >> > >> > sqlConnection.close(); >> > >> > producer.close(); >> > connection.close(); >> > userTransactionManager.close(); >> > System.out.println("Closed the connections"); >> > connectionFactoryBean.close(); >> > >> > } catch (SystemException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (JMSException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (NotSupportedException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (HeuristicMixedException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (HeuristicRollbackException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (RollbackException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (SQLException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } >> > >> > >> > } >> > >> > >> > private void receiveMessage() { >> > >> > UserTransactionManager userTransactionManager = new >> > UserTransactionManager(); >> > String uri = "tcp://amila:61616"; >> > Connection connection = null; >> > >> > try { >> > userTransactionManager.init(); >> > >> > // creating a jms XA Connection factor >> > ActiveMQXAConnectionFactory xaConnectionFactory = new >> > ActiveMQXAConnectionFactory(); >> > xaConnectionFactory.setBrokerURL(uri); >> > >> > AtomikosConnectionFactoryBean connectionFactoryBean = new >> > AtomikosConnectionFactoryBean(); >> > connectionFactoryBean.setUniqueResourceName("JMSFactory"); >> > >> > connectionFactoryBean.setXaConnectionFactory(xaConnectionFactory); >> > connectionFactoryBean.setMaxPoolSize(5); >> > >> > // doing the transaction >> > userTransactionManager.begin(); >> > >> > connection = connectionFactoryBean.createConnection(); >> > // send the message to jms queue >> > connection.start(); >> > >> > Session session = connection.createSession(true, >> > Session.SESSION_TRANSACTED); >> > Destination orderQueue = session.createQueue("SampleQueue"); >> > >> > MessageConsumer messageConsumer = >> > session.createConsumer(orderQueue); >> > >> > //get the message from the data base >> > AtomikosDataSourceBean dataSourceBean = new >> > AtomikosDataSourceBean(); >> > dataSourceBean.setUniqueResourceName("MyDataSource"); >> > >> > >> dataSourceBean.setXaDataSourceClassName("org.apache.derby.jdbc.EmbeddedXADataSource"); >> > Properties properties = new Properties(); >> > properties.put("databaseName", >> > "/home/amila/msc/project/atomikos/db/TEST_DB"); >> > dataSourceBean.setXaProperties(properties); >> > >> > java.sql.Connection sqlConnection = >> > dataSourceBean.getConnection(); >> > >> > Message message = messageConsumer.receiveNoWait(); >> > >> > while (message != null){ >> > TextMessage textMessage = (TextMessage) message; >> > System.out.println("Got the message " + >> > textMessage.getText()); >> > Statement statement = sqlConnection.createStatement(); >> > statement.execute("insert into received_messages >> > (message_id,message) values ('2','" + textMessage.getText() + "')"); >> > statement.close(); >> > message = messageConsumer.receiveNoWait(); >> > >> > } >> > // >> > userTransactionManager.commit(); >> > >> > sqlConnection.close(); >> > >> > messageConsumer.close(); >> > connection.close(); >> > userTransactionManager.close(); >> > System.out.println("Closed the connections"); >> > connectionFactoryBean.close(); >> > >> > } catch (SystemException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (JMSException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (NotSupportedException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (HeuristicMixedException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (HeuristicRollbackException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (RollbackException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } catch (SQLException e) { >> > e.printStackTrace(); //To change body of catch statement use >> > File | Settings | File Templates. >> > } >> > >> > } >> > >> > At the send method it reads some data base records and put them to a jms >> > queue. Then delete the records. I want all these actions happen in one >> > transaction. So it has to use a distributed transaction. >> > >> > To have distributed transaction I have used the Atomikos library and >> there >> > is no JNDI look up. So users can run this in their jvm without running an >> > Application server. >> > >> > The real thing I want to have is to read the database records and send >> them >> > as soap messages using the jms transport. And read the message at the >> server >> > side. Since reading the message is also done in a distributed transaction >> we >> > can achive application to application reliability. >> > >> > Can this be done with the existing jms transport JTA support. I think it >> has >> > to change to support these types of libraries. >> > >> > thanks, >> > Amila. >> > >> > >> > >> > >> > >> >> >> >> Andr >> >> >> >> On Wed, May 20, 2009 at 07:09, Amila Suriarachchi >> >> <[email protected]> wrote: >> >> > hi, >> >> > >> >> > I am trying to write a sample code using JMS transport to send a >> message >> >> > reliably from application to application. >> >> > >> >> > At the client side, >> >> > Axis2 client should be able to update a database and write to a jms >> queue >> >> in >> >> > a same distributed transaction and >> >> > >> >> > At the server side >> >> > it should be able to read the message from jms transport and update a >> >> data >> >> > base in a same distributed transaction. >> >> > >> >> > >> >> > Here I am planing to use a standalone jta implementation like >> atomikos[1] >> >> or >> >> > bitronix[2]. >> >> > >> >> > As I saw current JMS transport do support JTA. But As I saw it is >> >> required >> >> > to use a Application container (eg. jboss) >> >> > which has inbuilt JTA support. Is this correct or is there are a way >> to >> >> > configure standalone libraries. >> >> > >> >> > When Axis2 point of view people run the client in a stanalone >> >> applications >> >> > and server most of the time in tomcat. So it is usefull to have >> >> > support these standalone libraries as well. >> >> > >> >> > thanks, >> >> > Amila. >> >> > >> >> > >> >> > [1]http://www.atomikos.com/Main/ProductsOerview#ate >> >> > [2]http://docs.codehaus.org/display/BTM/Home >> >> > -- >> >> > Amila Suriarachchi >> >> > WSO2 Inc. >> >> > blog: http://amilachinthaka.blogspot.com/ >> >> > >> >> >> > >> > >> > >> > -- >> > Amila Suriarachchi >> > WSO2 Inc. >> > blog: http://amilachinthaka.blogspot.com/ >> > >> > > > > -- > Amila Suriarachchi > WSO2 Inc. > blog: http://amilachinthaka.blogspot.com/ >
