|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
Oracle JMS AQHi all,
is possibile to integrate Oracle JMS AQ with BTM and Tomcat? I made a lot of experimental configuration with resource loader, context.xml ecc... without success... I'm bit confusing.... Has someone did it? An example or guideline? Thanks all! |
|
|
Re: Oracle JMS AQOracle AQ really is a special JMS implementation, to say the least.
You first need to get some queues created with the DBMS_AQJMS PL/SQL package. You then need some privileges: * ENQUEUE rights on all queues you're going to send to * DEQUEUE rights on all queuse you're going to receive from * EXECUTE rights on DBMS_AQJMS * EXECUTE rights on DBMS_AQIN After that's done you're still facing a dilemma: Oracle provides a weird way to get a XAConnectionFactory, via a AQjmsFactory helper class' static method (see: http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b12023/oracle/jms/AQjmsFactory.html) and BTM unfortunately has no support for such an exotic mechanism. So you basically have two choices: - Write your own XAConnectionFactory implementation, make it use AQjmsFactory and configure it in BTM. It shouldn't be very hard as there are only two methods to implement (http://www.j2ee.me/j2ee/1.4/docs/api/javax/jms/XAConnectionFactory.html) plus a few getters/setters for configurable data you'll need to call getXAQueueConnectionFactory(). Have a look at the source code of JndiXAConnectionFactory to get an example of how to do this: http://fisheye.codehaus.org/browse/btm/branches/1.3.3/src/bitronix/tm/resource/jms/JndiXAConnectionFactory.java?r=HEAD - Wrap the non-XA AQjmsConnectionFactory (http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b12023/oracle/jms/AQjmsConnectionFactory.html)in a LrcXAConnectionFactory (see: http://docs.codehaus.org/display/BTM/LastResourceCommitJms13) Let me know if that helps. |
|
|
Re: Oracle JMS AQThanks for your replay Ludovic!
I decided to follow the first choice so I implemented XAConnectionFactory, configure it in resource loader propery file, bind it in context.xml (tomcat integration) and write some line of code in my utility class to get Pooling connection from jndi and create session and publisher..... at end of this post I'll publish my solution. But I have encuntered a problem... I'think XAConnection that I retrive from pool isn't an enlisted resources... the BTM warning log is explicity when I try to ut.commit() a user transaction: 29-Oct-2009 23:45:19 bitronix.tm.twopc.Preparer prepare WARNING: executing transaction with 0 enlisted resource the only logical difference between JndiXAConnectionFactory and my OracleXATopicConnectionFactory is that mine solution implements XATopicConnectionFactory, beacuse I need a topic in my app. In my numerous tests I have try to insert the correponding XAResource in transaction manager in this way: BitronixTransactionManager btm = (BitronixTransactionManager) ut; btm.getTransaction().enlistResource(xaTopicSession.getXAResource()); and btm throw bitronix.tm.internal.BitronixSystemException: unknown XAResource oracle.jms.AQjmsXAResource@112bc7b, it does not belong to a registered resource I don't know why this is not registered in btm... can you tell me something about it? Follow what I did.... 1) IMPLEMENTATION OF XATopicConnectionFactory public class OracleXATopicConnectionFactory implements XATopicConnectionFactory { private String driver; private String url; private String user; private String pwd; private OracleXADataSource oracleXADataSource = null; protected void init() throws SQLException { if (oracleXADataSource == null) { oracleXADataSource = new OracleXADataSource(); oracleXADataSource.setURL(url); oracleXADataSource.setUser(user); oracleXADataSource.setPassword(pwd); } } @Override public XAConnection createXAConnection() throws JMSException { try { init(); XATopicConnectionFactory xaConnectionFactory = AQjmsFactory.getXATopicConnectionFactory(oracleXADataSource); XATopicConnection xaConnection = xaConnectionFactory.createXATopicConnection(); return xaConnection; } catch (SQLException e) { e.printStackTrace(); throw new JMSException(e.getMessage()); } } @Override public XAConnection createXAConnection(String userName, String password) throws JMSException { // I don't use userName and password beacuse I have oracleXADataSource.... return createXAConnection(); } @Override public XATopicConnection createXATopicConnection() throws JMSException { return (XATopicConnection) createXAConnection(); } @Override public XATopicConnection createXATopicConnection(String userName, String password) throws JMSException { return (XATopicConnection) createXAConnection(userName, password); } @Override public TopicConnection createTopicConnection() throws JMSException { return (XATopicConnection) createXAConnection(); } @Override public TopicConnection createTopicConnection(String userName, String password) throws JMSException { return (XATopicConnection) createXAConnection(userName, password); } @Override public Connection createConnection() throws JMSException { return (XATopicConnection) createXAConnection(); } @Override public Connection createConnection(String userName, String password) throws JMSException { return (XATopicConnection) createXAConnection(userName, password); } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } } 2) RESOURCE.PROPERTIES # used in iBatis is OK resource.ds.className=oracle.jdbc.xa.client.OracleXADataSource resource.ds.uniqueName=jdbc/oracle resource.ds.maxPoolSize=5 resource.ds.driverProperties.user=JDBC_USER resource.ds.driverProperties.password=JDBC_PWD resource.ds.driverProperties.URL=jdbc:oracle:thin:@localhost:1521:XE # this is for Oracle JMS impl. resource.t.className=it.inera.oracle.jms.OracleXATopicConnectionFactory resource.t.uniqueName=jms/oracle resource.t.maxPoolSize=5 resource.t.driverProperties.driver=oracle.jdbc.xa.client.OracleXADataSource resource.t.driverProperties.user=AQ_USER resource.t.driverProperties.pwd=AQ_PWD resource.t.driverProperties.url=jdbc:oracle:thin:@localhost:1521:XE 3) CONTEXT.XML <?xml version="1.0" encoding="UTF-8"?> <Context docBase="MyApp" path="/MyApp" reloadable="true"> <Resource name="jdbc/oracle" auth="Container" type="javax.sql.DataSource" factory="bitronix.tm.resource.ResourceObjectFactory" uniqueName="jdbc/oracle" /> <Resource name="jms/oracle" auth="Container" type="javax.sql.DataSource" factory="bitronix.tm.resource.ResourceObjectFactory" uniqueName="jms/oracle" /> </Context> 4) WEB.XML ENTRY (isn't necessary in tomcat 5.5.X <resource-env-ref> <resource-env-ref-name>jdbc/oracle</resource-env-ref-name> <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type> </resource-env-ref> <resource-env-ref> <resource-env-ref-name>jms/oracle</resource-env-ref-name> <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type> </resource-env-ref> 5) CODE TO OBTAIN XATOPIC IN SERVLET-TOMCAT ENVIRONMENT Context initContext = new InitialContext(); PoolingConnectionFactory myConnectionFactory = (PoolingConnectionFactory) initContext.lookup("java:comp/env/jms/oracle"); UserTransaction ut = (UserTransaction) initContext.lookup("java:comp/UserTransaction"); ut.begin(); Connection connection = myConnectionFactory.createConnection(); JmsConnectionHandle btmJCH = (JmsConnectionHandle) connection; XAConnection xaConnection = btmJCH.getXAConnection(); xaConnection.start(); // start connection AQjmsXAConnection aQjmsXAConnection = (AQjmsXAConnection) xaConnection; XATopicSession xaTopicSession = aQjmsXAConnection.createXATopicSession(); AQjmsXASession qjmsXASession = (AQjmsXASession) xaTopicSession; Topic t = qjmsXASession.createTopic(Configuration.getJmsOracleXmlMessageTopic()); /* * CREATE PAYLOAD IN ORACLE FASHION */ StringWriter stringWriter = ....; // contain my XML Payload.... XMLType xml = new XMLType(qjmsXASession.getDBConnection(), stringWriter.toString()); AdtMessage message = ((AQjmsXASession)xaTopicSession).createAdtMessage(); message.setAdtPayload(xml); TopicPublisher messageProducer = (TopicPublisher) xaTopicSession.createProducer(t); messageProducer.publish(t,message); connection.close(); xaTopicSession.close(); ut.commit(); Against ut.commit(); BTM log a WARNING: executing transaction with 0 enlisted resource I think that BTM don't register the XAOracleDataSource or somthing about it.... thank you in advance for your patience :) |
|
|
Re: Oracle JMS AQSOLVED!
Now I have jdbc/iBatis + jms/oracle + tomcat in BTM-JTA fashion!!! :) The problem was in code where I have create xaconnection... if I call it directly (point 5 of my previus post) I obtain an unregister XAResource... #################### WRONG WAY ########################## XAConnection xaConnection = btmJCH.getXAConnection(); xaConnection.start(); // start connection AQjmsXAConnection aQjmsXAConnection = (AQjmsXAConnection) xaConnection; XATopicSession xaTopicSession = aQjmsXAConnection.createXATopicSession(); #################### WRONG WAY ########################## I'll post my solution (the modified point 5 of my previous post), if you want, I can write it in a how-to/wiki article style for publish this experience in BTM wiki.... tell me... point 1, 2, 3, 4 was correct and wasn't modified... the point 5 was correct in this way 5) #################### RIGHT WAY ########################## Context initContext = new InitialContext(); PoolingConnectionFactory myConnectionFactory = (PoolingConnectionFactory) initContext.lookup("java:comp/env/jms/oracle"); UserTransaction ut = (UserTransaction) initContext.lookup("java:comp/UserTransaction"); ut.begin(); Connection connection = myConnectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic topic = session.createTopic(Configuration.getJmsOracleXmlMessageTopic()); DualSessionWrapper dualSessionWrapper = (DualSessionWrapper)session; AQjmsXASession aQjmsXASession = (AQjmsXASession) dualSessionWrapper.getSession(); StringWriter stringWriter = ....; // contain my XML Payload.... XMLType xml = new XMLType(qjmsXASession.getDBConnection(), stringWriter.toString()); AdtMessage message = ((AQjmsXASession)xaTopicSession).createAdtMessage(); message.setAdtPayload(xml); MessageProducer publisher = session.createProducer(topic); publisher.send(message); ut.commit(); // ut.rollback(); //if somethig was wrong........ Thanks Ludovic!!!!! Thanks BTM! |
|
|
Re: Oracle JMS AQSorry, I have post wrong code in AdtMessage creation line, this is corrected code
5) #################### RIGHT WAY ########################## Connection connection = myConnectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Topic topic = session.createTopic(Configuration.getJmsOracleXmlMessageTopic()); DualSessionWrapper dualSessionWrapper = (DualSessionWrapper)session; AQjmsXASession aQjmsXASession = (AQjmsXASession) dualSessionWrapper.getSession(); StringWriter stringWriter = new StringWriter(); XMLType xml = new XMLType(aQjmsXASession.getDBConnection(), stringWriter.toString()); AdtMessage message = aQjmsXASession.createAdtMessage(); message.setAdtPayload(xml); MessageProducer publisher = session.createProducer(topic); publisher.send(message); ut.commit(); // ut.rollback(); //if somethig was wrong........ |
|
|
Re: Oracle JMS AQI'm happy to hear you finally managed to get Oracle AQ working.
If you write a short tutorial on things one need to do I'll happily include that in the wiki. Thanks, Ludovic |
| Free embeddable forum powered by Nabble | Forum Help |