Spring Integration集成Oracle AQ时出列后Service Activator调用不一致问题
Let's break down your problem and walk through actionable troubleshooting steps to resolve the inconsistency between Oracle's confirmed dequeue and your application's missing Service Activator invocation.
Problem Recap
You've set up Spring Integration with Oracle AQ, and while Oracle's health checks confirm messages are successfully dequeued, your Service Activator never runs. No related success or error logs appear in your app—even after enabling debug/trace logging for JMS adapters. The Oracle team has verified enqueue/dequeue operations work as expected, so the issue lies in how your Spring Integration setup is handling the dequeued messages.
Your Configuration
<int:logging-channel-adapter id="jmslogger" log-full-message="true" level="TRACE"/> <!-- Oracle Advanced Queue Integration --> <bean id="jdbc4NativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.Jdbc4NativeJdbcExtractor" p:connectionType="oracle.jdbc.driver.OracleConnection" /> <orcl:aq-jms-connection-factory id="oracleAqConnectionFactory" use-local-data-source-transaction="true" native-jdbc-extractor="jdbc4NativeJdbcExtractor" data-source="dataSource"/> <!-- Siebel Atlas Service Request - Oracle Advanced Queue Integration --> <bean id="jmsJsonMessageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter" p:typeIdPropertyName="javaDtoClass" /> <int:channel id="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel" ></int:channel> <int:channel id="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel" > <int:interceptors> <int:wire-tap channel="jmslogger"/> </int:interceptors> </int:channel> <int:channel id="createSiebelAtlasCreateServiceRequestOutboundReplyChannel" /> <int:logging-channel-adapter id="createSiebelAtlasCreateServiceRequestOutboundReplyChannelLogger" channel="createSiebelAtlasCreateServiceRequestOutboundReplyChannel" /> <int:gateway id="submitSiebelAtlasCreateServiceRequestMessagingService" service-interface="ServiceRequestOutboundGatewayMessagingService" default-request-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel" default-reply-channel="submitSiebelAtlasCreateServiceRequestOutboundReplyChannel" /> <int:header-enricher input-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestChannel" output-channel="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel"> <int:correlation-id expression="payload.getRequestId()"/> </int:header-enricher> <!-- Outbound driven channel adapter, meaning messagings are being sent to / queued in AQ --> <int-jms:outbound-channel-adapter id="siebelAtlasCreateServiceRequestJmsOutboundChannelAdapter" destination-name="Q_NAME" channel="submitSiebelAtlasCreateServiceRequestOutboundRequestEnrichedChannel" connection-factory="oracleAqConnectionFactory" message-converter="jmsJsonMessageConverter" auto-startup="true"> </int-jms:outbound-channel-adapter> <int:service-activator output-channel="createSiebelAtlasCreateServiceRequestOutboundReplyChannel" input-channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel" ref="createCustomerRelationshipsSiebelAtlasServiceRequestService" method="create"> </int:service-activator> <int:channel id="createSiebelAtlasCreateServiceRequestInboundRequestChannel"> <int:interceptors> <int:wire-tap channel="jmslogger"/> </int:interceptors> </int:channel> <!-- Inbound message driven channel adapter, meaning messagings are being consumed / dequeued from AQ --> <int-jms:message-driven-channel-adapter connection-factory="oracleAqConnectionFactory" message-converter="jmsJsonMessageConverter" destination-name="Q_NAME" channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel" acknowledge="transacted" max-concurrent-consumers="5" transaction-manager="transactionManager" auto-startup="true" concurrent-consumers="2" />
Key Troubleshooting Steps & Fixes
1. Check Transaction Rollback (Silent Failure)
Your inbound adapter uses acknowledge="transacted" and a transaction-manager. If the transaction rolls back silently, Oracle will dequeue the message then immediately requeue it (since the commit never happens)—and your app won't show any signs of processing.
- Enable debug logging for
org.springframework.transactionto track if transactions are committing or rolling back. - Wrap your service's
createmethod in a try-catch block to log any exceptions (even unchecked ones likeNullPointerExceptionthat trigger rollbacks). - Verify your
transactionManageruses the samedataSourceas the AQ connection factory—mismatched sources can cause hidden transaction issues.
2. Validate Message Converter Behavior
Your MappingJackson2MessageConverter relies on a javaDtoClass property to deserialize JSON. If this property is missing or incorrect, the converter might fail silently and drop the message.
- Enable debug logging for
org.springframework.jms.support.converterto see if deserialization succeeds. - Confirm the outbound adapter sets the
javaDtoClassheader correctly (it should be the fully qualified name of your payload DTO). If not, add it to your header enricher or configure explicittypeIdMappingson the converter:<bean id="jmsJsonMessageConverter" class="org.springframework.jms.support.converter.MappingJackson2MessageConverter"> <property name="typeIdPropertyName" value="javaDtoClass"/> <property name="typeIdMappings"> <map> <entry key="serviceRequest" value="com.yourpackage.YourServiceRequestDto"/> </map> </property> </bean>
3. Verify Channel & Wire Tap Logging
Your inbound channel has a wire-tap to jmslogger, but no logs mean messages might not be reaching the channel at all.
- Double-check your logging framework config (Logback/Log4j) to ensure TRACE-level logs are enabled for
org.springframework.integration—the wire-tap uses TRACE, so if that level is disabled, you'll see nothing. - Add a direct logging adapter to the inbound channel to confirm message arrival:
<int:logging-channel-adapter id="inboundLogger" channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel" level="TRACE" log-full-message="true"/> - Ensure the channel is a direct channel (default) and not a queue channel with no consumers—queue channels require a poller or consumer to process messages.
4. Confirm Inbound Adapter Startup
Even with auto-startup="true", the message listener container might fail to start silently.
- Enable debug logging for
org.springframework.jms.listenerto check if the container starts and creates consumers. - Check your app context initialization logs for bean creation errors related to the inbound adapter or connection factory.
- If using Spring Boot, use Actuator's
/actuator/jmsendpoint (if enabled) to check listener container status. You can also injectJmsMessageDrivenEndpointand callisRunning()programmatically to verify.
5. Oracle AQ-Specific Checks
Since Oracle confirms dequeue, ensure your app is interacting with the same queue correctly:
- Verify the inbound adapter uses the exact queue name (
Q_NAME) and schema as the outbound adapter—typos or schema mismatches can cause silent misses. - Check Oracle AQ's queue configuration for retention policies or visibility timeouts—messages might be dequeued but hidden from your app temporarily.
- Confirm
use-local-data-source-transactionis set correctly:truefor local transaction managers (likeDataSourceTransactionManager),falsefor JTA managers. A mismatch can break transaction handling.
6. Test with a Minimal Service Activator
Rule out issues with your service implementation by replacing it with a simple logger:
<int:service-activator input-channel="createSiebelAtlasCreateServiceRequestInboundRequestChannel" expression="T(org.slf4j.LoggerFactory).getLogger('TestLogger').info('Received message: ' + payload)"> </int:service-activator>
If this logs messages, the problem is in your original service (silent exceptions, transaction rollbacks). If not, the issue is upstream in the message flow.
内容的提问来源于stack exchange,提问作者Vijayalatha palakurthy




