By default, IBM Integration Toolkit 9 (from IBM Integration Bus) UI language is determined by the computer locale. My OS is installed and configured to use Spanish, but I prefer to use the development tools in English (error messages, tutorials, etc.)
To force IBM Integration Toolkit 9 to use English, add the following line
-nl en_US
to INSTALLATION_PATH\mb.ini (for example, C:\Program Files\IBM\IntegrationToolkit90\mb.ini)
lunes, 9 de junio de 2014
viernes, 7 de marzo de 2014
Notes about Oracle AQ default exception queues
- All AQ Queues have a default associated exception queue where messages that "may not be consumed within given constraints" are moved.
- By default the exception queue name is called AQ$_[ORIGINAL_QUEUE_NAME]_E. For example, if the original normal queue is called MYQUEUE, its default exception queue is called AQ$_MYQUEUE_E. I notice that for example, in SQL Developer, I can't see the exception queue in the "Queues" tree (but it "exists"). Also by default, the default exception queues are not enabled for dequeuing. Yoy can use this instruction to enable dequeuing: dbms_aqadm.start_queue(queue_name=>'MYQUEUE', enqueue=>FALSE,dequeue=>TRUE). You can't enable an exception queue for enqueuing. Here is additional information about the exception queues.
- By default, both queues (the normal queue and the exception queue), are supported by the same queue table. You can check it by directly querying the queue table (MYQUEUETABLE) and looking the Q_NAME column or by querying the queue table AQ view (AQ$MYQUEUETABLE) and looking the QUEUE column (this is the prefered way). The value for the "expired" messages is AQ$_MYQUEUE_E and the value for the normal messages is MYQUEUE.
- You can use an "user-defined exception queue", but it is set through a message header; that is, at message level and not at queue level. At the message enqueue time, you can set the exception queue for that message through a header (JMS_OracleExcpQ); if that message expires, it will be moved to that user-defined exception queue. Here, you can check some good instructions to use it in PL/SQL or Java JMS.
Here are some references in My Oracle Support:
Using JMS message selectors in a message consumer using an Oracle AQ (exception) queue
I was testing JMS selectors in a Message Consumer based on an Oracle AQ (exception) queue; I needed to dequeue only the messages with certain message ID's; at first, I tried with this syntax, but found an unexpected behavior:
"JMSMessageID='ID:XXX' OR JMSMessageID='ID:YYY'"
For example, let's say we have this messages in the queue (this specific messages are in the queue's default exception queue):
If I use the following selector,
String selector =
"JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR
JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR
JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR
JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD'";
the first receive() works OK, returning one of the matching messages (consistently, the first in the selector):
[TestServlet][doGet]selector=JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD
[TestServlet][doGet]messageID=ID:4A3966F3C0604B6DAED6D6E7FC62705A
But, from the second, and so on, the receive() method behaves as if there aren't messages matching the selector. In the end, just one message got processed:
I enabled the jdbc and jms debug on the managed server (I'm working on Weblogic 12c), and found this, starting from the second receive(): "java.sql.SQLException: ORA-25263: no message in queue PRUEBAS.AQ$_MYQUEUETABLE_E with message ID 4A3966F3C0604B6DAED6D6E7FC62705A".
[[oracle.jdbc.driver.T4CXAConnection@29cccbf, owner=[weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection-myQueuePruebas_DS-17, oracle.jdbc.driver.LogicalConnection@29d1486], rmConn=oracle.jdbc.driver.LogicalConnection@29d1486]] dequeue(unknown) throws: java.sql.SQLException: ORA-25263: no message in queue PRUEBAS.AQ$_MYQUEUETABLE_E with message ID 4A3966F3C0604B6DAED6D6E7FC62705A
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:389)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:382)
at oracle.jdbc.driver.T4Caqdq.processError(T4Caqdq.java:488)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4Caqdq.doOAQDQ(T4Caqdq.java:180)
at oracle.jdbc.driver.T4CConnection.doDequeue(T4CConnection.java:3976)
at oracle.jdbc.driver.PhysicalConnection.dequeue(PhysicalConnection.java:10106)
at oracle.jdbc.driver.PhysicalConnection.dequeue(PhysicalConnection.java:10153)
at oracle.jdbc.OracleConnectionWrapper.dequeue(OracleConnectionWrapper.java:1525)
at weblogic.jdbc.wrapper.XAConnection_oracle_jdbc_driver_LogicalConnection.dequeue(Unknown Source)
at weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection.dequeue(Unknown Source)
at oracle.jms.AQjmsConsumer.jdbcConnectionDequeueCheck25242(AQjmsConsumer.java:1713)
at oracle.jms.AQjmsConsumer.jdbcDequeue(AQjmsConsumer.java:1295)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1035)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:960)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:938)
at oracle.jms.AQjmsConsumer.receive(AQjmsConsumer.java:790)
at test.PruebaConsumerSelectorServlet.doGet(PruebaConsumerSelectorServlet.java:55)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Am I doing somethig wrong? is this a bug? my test code is pretty straighfoward; something like this:
String selector =
"JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR
JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR
JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR
JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD'";
messageConsumer = session.createConsumer(queue, selector);
Message msg = null;
System.out.println("[TestServlet][doGet]selector=" + messageConsumer.getMessageSelector());
while((msg = messageConsumer.receive(10000)) != null) {
if(msg != null) {
System.out.println("[TestServlet][doGet]messageID=" + msg.getJMSMessageID());
}
}
Fortunately, trying with other selector syntax, the test worked OK. The syntax is:
"JMSMessageID IN ('ID:XXX', 'ID:YYY')"
For example, having this messages in the queue
And this selector
String selector =
"JMSMessageID IN (
'ID:ED976B4A41F241F594F570A8F2250D26'
'ID:724794DE2C4648AF9EF7EB1CE3B0BC22'
'ID:33CF68A695E04F6B89F1024F7DFE5925'
'ID:3E7059E3489C472096C58A833434893C')"
The test works as expected:
[TestServlet][doGet]messageID=ID:724794DE2C4648AF9EF7EB1CE3B0BC22
[TestServlet][doGet]messageID=ID:3E7059E3489C472096C58A833434893C
[TestServlet][doGet]messageID=ID:33CF68A695E04F6B89F1024F7DFE5925
[TestServlet][doGet]messageID=ID:ED976B4A41F241F594F570A8F2250D26
The final result in the table is:
I found some (un)related cases in My Oracle Support.
"JMSMessageID='ID:XXX' OR JMSMessageID='ID:YYY'"
For example, let's say we have this messages in the queue (this specific messages are in the queue's default exception queue):
If I use the following selector,
String selector =
"JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR
JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR
JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR
JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD'";
the first receive() works OK, returning one of the matching messages (consistently, the first in the selector):
[TestServlet][doGet]selector=JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD
[TestServlet][doGet]messageID=ID:4A3966F3C0604B6DAED6D6E7FC62705A
But, from the second, and so on, the receive() method behaves as if there aren't messages matching the selector. In the end, just one message got processed:
I enabled the jdbc and jms debug on the managed server (I'm working on Weblogic 12c), and found this, starting from the second receive(): "java.sql.SQLException: ORA-25263: no message in queue PRUEBAS.AQ$_MYQUEUETABLE_E with message ID 4A3966F3C0604B6DAED6D6E7FC62705A".
[[oracle.jdbc.driver.T4CXAConnection@29cccbf, owner=[weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection-myQueuePruebas_DS-17, oracle.jdbc.driver.LogicalConnection@29d1486], rmConn=oracle.jdbc.driver.LogicalConnection@29d1486]] dequeue(unknown) throws: java.sql.SQLException: ORA-25263: no message in queue PRUEBAS.AQ$_MYQUEUETABLE_E with message ID 4A3966F3C0604B6DAED6D6E7FC62705A
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:389)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:382)
at oracle.jdbc.driver.T4Caqdq.processError(T4Caqdq.java:488)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4Caqdq.doOAQDQ(T4Caqdq.java:180)
at oracle.jdbc.driver.T4CConnection.doDequeue(T4CConnection.java:3976)
at oracle.jdbc.driver.PhysicalConnection.dequeue(PhysicalConnection.java:10106)
at oracle.jdbc.driver.PhysicalConnection.dequeue(PhysicalConnection.java:10153)
at oracle.jdbc.OracleConnectionWrapper.dequeue(OracleConnectionWrapper.java:1525)
at weblogic.jdbc.wrapper.XAConnection_oracle_jdbc_driver_LogicalConnection.dequeue(Unknown Source)
at weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection.dequeue(Unknown Source)
at oracle.jms.AQjmsConsumer.jdbcConnectionDequeueCheck25242(AQjmsConsumer.java:1713)
at oracle.jms.AQjmsConsumer.jdbcDequeue(AQjmsConsumer.java:1295)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1035)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:960)
at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:938)
at oracle.jms.AQjmsConsumer.receive(AQjmsConsumer.java:790)
at test.PruebaConsumerSelectorServlet.doGet(PruebaConsumerSelectorServlet.java:55)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Am I doing somethig wrong? is this a bug? my test code is pretty straighfoward; something like this:
String selector =
"JMSMessageID='ID:4A3966F3C0604B6DAED6D6E7FC62705A' OR
JMSMessageID='ID:01AF9624372C4D8A88CFAFD37D4395E7' OR
JMSMessageID='ID:42C32FA9BBCB48ABA074EB69C94D1A82' OR
JMSMessageID='ID:4973147F8AC54BD1A5DA2CE81F9622CD'";
messageConsumer = session.createConsumer(queue, selector);
Message msg = null;
System.out.println("[TestServlet][doGet]selector=" + messageConsumer.getMessageSelector());
while((msg = messageConsumer.receive(10000)) != null) {
if(msg != null) {
System.out.println("[TestServlet][doGet]messageID=" + msg.getJMSMessageID());
}
}
Fortunately, trying with other selector syntax, the test worked OK. The syntax is:
"JMSMessageID IN ('ID:XXX', 'ID:YYY')"
For example, having this messages in the queue
And this selector
String selector =
"JMSMessageID IN (
'ID:ED976B4A41F241F594F570A8F2250D26'
'ID:724794DE2C4648AF9EF7EB1CE3B0BC22'
'ID:33CF68A695E04F6B89F1024F7DFE5925'
'ID:3E7059E3489C472096C58A833434893C')"
The test works as expected:
[TestServlet][doGet]messageID=ID:724794DE2C4648AF9EF7EB1CE3B0BC22
[TestServlet][doGet]messageID=ID:3E7059E3489C472096C58A833434893C
[TestServlet][doGet]messageID=ID:33CF68A695E04F6B89F1024F7DFE5925
[TestServlet][doGet]messageID=ID:ED976B4A41F241F594F570A8F2250D26
The final result in the table is:
I found some (un)related cases in My Oracle Support.
- Unable to dequeue messages from an Exception Queue when using a JMS Message Selector (Doc ID 746891.1): this, however, applies to old versions of OAS and the database.
- Slow Dequeue using JMS message selectors (Doc ID 849986.1): this has a somewhat funny solution. See for yourself if you have MOS access.
I found also an Hermes bug report discusing the same case:
martes, 4 de marzo de 2014
Weblogic: setRollbackOnly called on transaction
Exception: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction.
This exception can happen when you invoke transactional methods after calling MessageDrivenContext.setRollbackonly():
For example, given this (default: container, required) transactional MDB:
@MessageDriven
public class PruebaMdbA implements MessageListener {
@EJB
private PruebaSessionNoIntA pruebaSessionNoIntA;
@Resource
MessageDrivenContext mdc;
public void onMessage(Message message) {
//...
mdc.setRollbackOnly();
//...
pruebaSessionNoIntA.testTx();
}
//...
}
And this (default: container, required) transactional session EJB:
@Stateless
@LocalBean
public class PruebaSessionNoIntA {
public void testTx() {
//...
}
}
If you invoke the onMessage() MDB method, it starts a transaction; when you invoke the session EJB method (pruebaSessionNoIntA.testTx()) after marking the transaction as rollbak only, you get the exception:
... <BEA-010080> <An error occurred while attempting to process a message inside a Message-Driven Bean: javax.ejb.EJBTransactionRolledbackException: EJB Exception:
Nested exception: javax.ejb.TransactionRolledbackLocalException: EJB Exception:
Nested exception: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction
Exception is : javax.ejb.EJBTransactionRolledbackException: EJB Exception:
at weblogic.ejb.container.internal.BaseLocalObject.handleSystemException(BaseLocalObject.java:453)
at weblogic.ejb.container.internal.BaseLocalObject.getBeanInstance(BaseLocalObject.java:162)
at weblogic.ejb.container.internal.BaseLocalObject.preInvoke(BaseLocalObject.java:103)
at weblogic.ejb.container.internal.BaseLocalObject.__WL_preInvoke(BaseLocalObject.java:67)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:20)
at test.PruebaSessionNoIntA_uae4n4_NoIntfViewImpl.testTx(Unknown Source)
at test.PruebaMdbA.onMessage(PruebaMdbA.java:40)
at weblogic.ejb.container.internal.MDListener.execute(MDListener.java:585)
at weblogic.ejb.container.internal.MDListener.transactionalOnMessage(MDListener.java:488)
at weblogic.ejb.container.internal.NewJMSMessagePoller.processOneMessage(NewJMSMessagePoller.java:290)
at weblogic.ejb.container.internal.NewJMSMessagePoller.run(NewJMSMessagePoller.java:126)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:545)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: javax.ejb.TransactionRolledbackLocalException: EJB Exception:
at weblogic.ejb.container.internal.EJBRuntimeUtils.throwTransactionRolledbackLocal(EJBRuntimeUtils.java:236)
at weblogic.ejb.container.internal.EJBRuntimeUtils.throwWrappedTransactionRolledbackLocal(EJBRuntimeUtils.java:255)
at weblogic.ejb.container.manager.BaseEJBManager.handleSystemException(BaseEJBManager.java:348)
at weblogic.ejb.container.manager.BaseEJBManager.setupTxListener(BaseEJBManager.java:276)
at weblogic.ejb.container.manager.StatelessManager.preInvoke(StatelessManager.java:171)
at weblogic.ejb.container.internal.BaseLocalObject.getBeanInstance(BaseLocalObject.java:146)
... 12 more
Caused by: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction
at weblogic.transaction.internal.TransactionImpl.setRollbackOnly(TransactionImpl.java:555)
at weblogic.ejb.container.internal.BaseEJBContext.setRollbackOnly(BaseEJBContext.java:242)
at test.PruebaMdbA.onMessage(PruebaMdbA.java:36)
... 7 more
This exception can happen when you invoke transactional methods after calling MessageDrivenContext.setRollbackonly():
For example, given this (default: container, required) transactional MDB:
@MessageDriven
public class PruebaMdbA implements MessageListener {
@EJB
private PruebaSessionNoIntA pruebaSessionNoIntA;
@Resource
MessageDrivenContext mdc;
public void onMessage(Message message) {
//...
mdc.setRollbackOnly();
//...
pruebaSessionNoIntA.testTx();
}
//...
}
And this (default: container, required) transactional session EJB:
@Stateless
@LocalBean
public class PruebaSessionNoIntA {
public void testTx() {
//...
}
}
If you invoke the onMessage() MDB method, it starts a transaction; when you invoke the session EJB method (pruebaSessionNoIntA.testTx()) after marking the transaction as rollbak only, you get the exception:
... <BEA-010080> <An error occurred while attempting to process a message inside a Message-Driven Bean: javax.ejb.EJBTransactionRolledbackException: EJB Exception:
Nested exception: javax.ejb.TransactionRolledbackLocalException: EJB Exception:
Nested exception: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction
Exception is : javax.ejb.EJBTransactionRolledbackException: EJB Exception:
at weblogic.ejb.container.internal.BaseLocalObject.handleSystemException(BaseLocalObject.java:453)
at weblogic.ejb.container.internal.BaseLocalObject.getBeanInstance(BaseLocalObject.java:162)
at weblogic.ejb.container.internal.BaseLocalObject.preInvoke(BaseLocalObject.java:103)
at weblogic.ejb.container.internal.BaseLocalObject.__WL_preInvoke(BaseLocalObject.java:67)
at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:20)
at test.PruebaSessionNoIntA_uae4n4_NoIntfViewImpl.testTx(Unknown Source)
at test.PruebaMdbA.onMessage(PruebaMdbA.java:40)
at weblogic.ejb.container.internal.MDListener.execute(MDListener.java:585)
at weblogic.ejb.container.internal.MDListener.transactionalOnMessage(MDListener.java:488)
at weblogic.ejb.container.internal.NewJMSMessagePoller.processOneMessage(NewJMSMessagePoller.java:290)
at weblogic.ejb.container.internal.NewJMSMessagePoller.run(NewJMSMessagePoller.java:126)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:545)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: javax.ejb.TransactionRolledbackLocalException: EJB Exception:
at weblogic.ejb.container.internal.EJBRuntimeUtils.throwTransactionRolledbackLocal(EJBRuntimeUtils.java:236)
at weblogic.ejb.container.internal.EJBRuntimeUtils.throwWrappedTransactionRolledbackLocal(EJBRuntimeUtils.java:255)
at weblogic.ejb.container.manager.BaseEJBManager.handleSystemException(BaseEJBManager.java:348)
at weblogic.ejb.container.manager.BaseEJBManager.setupTxListener(BaseEJBManager.java:276)
at weblogic.ejb.container.manager.StatelessManager.preInvoke(StatelessManager.java:171)
at weblogic.ejb.container.internal.BaseLocalObject.getBeanInstance(BaseLocalObject.java:146)
... 12 more
Caused by: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction
at weblogic.transaction.internal.TransactionImpl.setRollbackOnly(TransactionImpl.java:555)
at weblogic.ejb.container.internal.BaseEJBContext.setRollbackOnly(BaseEJBContext.java:242)
at test.PruebaMdbA.onMessage(PruebaMdbA.java:36)
... 7 more
lunes, 3 de marzo de 2014
Maximum redelivery retries and retry delay in AQ backed MDB in Weblogic
When working with AQ backed MDB in Weblogic, the maximum redelivery retry count and retry delay can be configured at AQ queue level. The two related parameters, are:
it should print something like
[onMessage][START]time: Mon Mar 03 13:13:16 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : false
JMSXDeliveryCount: 1
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:13:26 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : true
JMSXDeliveryCount: 2
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:13:37 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : true
JMSXDeliveryCount: 3
[onMessage][END]
References:
- max_retries
- retry_delay
They can be configured at queue creation time (DBMS_AQADM.CREATE_QUEUE) or can be updated in a existent queue (DBMS_AQADM.ALTER_QUEUE). The default values are 5 for max_retries and 0 for retry (as soon as possible). The complete set of parameters can be found here.
In Weblogic, you can verify the parameter's operation with something like this:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName = "ConnectionFactoryJndiName", propertyValue = "..."),
@ActivationConfigProperty(propertyName = "DestinationJndiName", propertyValue = "..."),
@ActivationConfigProperty(propertyName = "DestinationType", propertyValue = "javax.jms.Queue")
})
public class TestMyQueueMDB implements MessageListener {
@Resource
private MessageDrivenContext mdc;
public void onMessage(Message message) {
try {
System.out.println("onMessage][START]time=" + new Date());
System.out.println("JMSMessageID : " + message.getJMSMessageID());
System.out.println("JMSRedelivered : " + message.getJMSRedelivered());
System.out.println("JMSXDeliveryCount: " + message.getIntProperty("JMSXDeliveryCount"));
//force retry
mdc.setRollbackOnly();
} catch(Exception e) {
//...
} finally {
System.out.println("[onMessage][END]");
System.out.println();
}
}
//...
}
With an queue created with the default values,
dbms_aqadm.create_queue(
queue_name=>'myQueue',
queue_table=>'myQueueTable'
);
it should print something like this:
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : false
JMSXDeliveryCount: 1
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : true
JMSXDeliveryCount: 2
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : true
JMSXDeliveryCount: 3
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : true
JMSXDeliveryCount: 4
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : true
JMSXDeliveryCount: 5
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:18:26 COT 2014
JMSMessageID : ID:205BD8B6042C4348A778FC5D467D2581
JMSRedelivered : true
JMSXDeliveryCount: 6
[onMessage][END]
After doing an update like the following,
BEGIN
DBMS_AQADM.ALTER_QUEUE (
queue_name => 'MYQUEUE',
max_retries => 2,
retry_delay => 10);
END;
/
it should print something like
[onMessage][START]time: Mon Mar 03 13:13:16 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : false
JMSXDeliveryCount: 1
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:13:26 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : true
JMSXDeliveryCount: 2
[onMessage][END]
[onMessage][START]time: Mon Mar 03 13:13:37 COT 2014
JMSMessageID : ID:61819BE03F7942DE92B2FA196EF13888
JMSRedelivered : true
JMSXDeliveryCount: 3
[onMessage][END]
References:
- Working with JMS and the standard issues in JMS
- Oracle® Database PL/SQL Packages and Types Reference 11g Release 1 (11.1), 22. DBMS_AQADM
miércoles, 12 de febrero de 2014
NoClassDefFoundError: org/apache/cxf/jaxrs/impl/MetadataMap in REST invokation from WebLogic with Jersey, CXF
Complete stack trace:
java.lang.NoClassDefFoundError: org/apache/cxf/jaxrs/impl/MetadataMap
at org.apache.cxf.jaxrs.impl.UriBuilderImpl.(UriBuilderImpl.java:54)
at org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl.createUriBuilder(RuntimeDelegateImpl.java:87)
at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:80)
at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:99)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
The WebLogic environment in which the error is generated contains the big bundle CXF jar (cxf-x.y.z.jar) in the classpath (which can't be removed right now).
As can be seen in the stack trace, the execution jumps from Jersey code to CXF code.
In this Jersey mailing list't thread, a similar problem is discused; one of the proposed solutions worked for me.
I created a ServletContextListener containing the following line in the contextInitialized method:
RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());
Complete code:
package xyz;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.ext.RuntimeDelegate;
public class JerseyRuntimeDelegateEarlyRegistrationContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());
}
}
java.lang.NoClassDefFoundError: org/apache/cxf/jaxrs/impl/MetadataMap
at org.apache.cxf.jaxrs.impl.UriBuilderImpl.
at org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl.createUriBuilder(RuntimeDelegateImpl.java:87)
at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:80)
at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:99)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:662)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:844)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:242)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:216)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:132)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:338)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3284)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3254)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2163)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2089)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2074)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1513)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
The WebLogic environment in which the error is generated contains the big bundle CXF jar (cxf-x.y.z.jar) in the classpath (which can't be removed right now).
As can be seen in the stack trace, the execution jumps from Jersey code to CXF code.
In this Jersey mailing list't thread, a similar problem is discused; one of the proposed solutions worked for me.
I created a ServletContextListener containing the following line in the contextInitialized method:
RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());
Complete code:
package xyz;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.ws.rs.ext.RuntimeDelegate;
public class JerseyRuntimeDelegateEarlyRegistrationContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
RuntimeDelegate.setInstance(new com.sun.jersey.server.impl.provider.RuntimeDelegateImpl());
}
}
Web.xml registration:
<web-app>
<listener>
<listener-class>xyz.JerseyRuntimeDelegateEarlyRegistrationContextListener</listener-class>
</listener>
jueves, 21 de noviembre de 2013
"An invalid security token was provided..." invoking CXF Web Services
Error: An invalid security token was provided (An error happened processing a Username Token "{0}")
Complete SOAP fault response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">ns1:InvalidSecurityToken</faultcode>
<faultstring>An invalid security token was provided (An error happened processing a Username Token "{0}")</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
There are lots of reasons which can cause this error. As stated by the message, there's a problem in the security token included in the SOAP request.
In my case, the Web service client was not sending the Type attribute for the Password element of the UsernameToken's Security element.
The error was introduced after upgrading the used CXF version (from an very old version to 2.6.1). The underlying project which implements WS Security in CXF is WSS4J. CXF 2.6.1 ships WSS4J 1.6.6. WSS4J 1.6 enforces compliance to the Basic Security Profile 1.1 (BSP) specification by default. The older CXF version shipped an older WSS4J version which did not enforce compliance to the BSP spec.
It seems the Type attribute for the password element is optional in WS-Security but mandatory in the BSP spec.
In this case we choosed not to demand the clients to include the attribute but to configure the service to not to be compliant with the BSP spec. We use Spring configuration for CXF; this can be easily done in the XML configuration file:
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
...
<entry key="isBSPCompliant" value="false"/>
...
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
This error also usually happens with the EncodingType attribute.
This conversation proposes an alternative configuration parameter: ws-security.is-bsp-compliant.
References:
Complete SOAP fault response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">ns1:InvalidSecurityToken</faultcode>
<faultstring>An invalid security token was provided (An error happened processing a Username Token "{0}")</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
There are lots of reasons which can cause this error. As stated by the message, there's a problem in the security token included in the SOAP request.
In my case, the Web service client was not sending the Type attribute for the Password element of the UsernameToken's Security element.
The error was introduced after upgrading the used CXF version (from an very old version to 2.6.1). The underlying project which implements WS Security in CXF is WSS4J. CXF 2.6.1 ships WSS4J 1.6.6. WSS4J 1.6 enforces compliance to the Basic Security Profile 1.1 (BSP) specification by default. The older CXF version shipped an older WSS4J version which did not enforce compliance to the BSP spec.
It seems the Type attribute for the password element is optional in WS-Security but mandatory in the BSP spec.
In this case we choosed not to demand the clients to include the attribute but to configure the service to not to be compliant with the BSP spec. We use Spring configuration for CXF; this can be easily done in the XML configuration file:
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
...
<entry key="isBSPCompliant" value="false"/>
...
</map>
</constructor-arg>
</bean>
</jaxws:inInterceptors>
This error also usually happens with the EncodingType attribute.
This conversation proposes an alternative configuration parameter: ws-security.is-bsp-compliant.
References:
- WSS4J configuration
- altering wsse security header
- Re: Compatibility problems with the TokenType in the SecurityTokenReference
Suscribirse a:
Entradas (Atom)





