[
https://issues.apache.org/activemq/browse/SM-1850?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Robert H. Pollack resolved SM-1850.
-----------------------------------
Resolution: Duplicate
I agree completely. This is indeed a duplicate of
[SMXCOMP-488|https://issues.apache.org/activemq/browse/SMXCOMP-488]. I have not
yet tested the snapshot distribution (I'm not yet sure how to get it), but when
I look at the source code changes, they are pretty much exactly the changes I
made to my own copy--which I have tested.
So I'm confident that this fix will work and I'm going to mark this issue
resolved. Thank you for your prompt reply.
> Some Send Errors Can Cause Undeployment to Wait Forever
> -------------------------------------------------------
>
> Key: SM-1850
> URL: https://issues.apache.org/activemq/browse/SM-1850
> Project: ServiceMix
> Issue Type: Bug
> Components: servicemix-camel, servicemix-common
> Affects Versions: 3.3
> Reporter: Robert H. Pollack
> Attachments: ServiceMixUndeployProblem.zip, undeployTestSA.jar
>
>
> If a component causes an exception to be thrown in
> {{org.apache.servicemix.common.EndpointDeliveryChannel.send()}}, the exchange
> is nevertheless entered into a hashmap called {{knownExchanges}}. Later, when
> the component shuts down, the shutdown code in
> {{org.apache.servicemix.common.AsyncBaseLifeCycle.prepareShutdown()}} will
> wait for this exchange to be processed--but this will never happen. The
> result is that the JBI container completely stops.
> Reproducing this problem is easy in Camel (which is where I discovered it);
> it requires only a one-line Camel route such as this one:
> {{from ("timer:dmftimer1?period=60000").to
> ("jbi:service:alpha:beta:gamma");}}
> To reproduce this problem:
> # Create a service assembly containing this route.
> # Copy the service assembly to the {{hotdeploy}} directory.
> # After the exception is thrown, attempt to shut down the assembly (the
> simplest way is to control-C the ServiceMix window). The service assembly
> will not undeploy and the JBI container will not shut down.
> I will attach two zip files to assist in reproducing this error:
> # A pre-built service assembly that you can just copy to {{hotdeploy}}.
> # Source code and a build script to assist experimentation.
> (The build script is an Ant file that requires you to point the property
> {{camel-dir}} at a directory that contains the Camel core jar.
> The relevant code in {{EndpointDeliveryChannel}} is this:
> {noformat}
> public void send(MessageExchange exchange) throws MessagingException {
> prepareExchange(exchange);
> handleExchange(exchange, exchange.getStatus() ==
> ExchangeStatus.ACTIVE);
> channel.send(exchange);
> }
> {noformat}
> The call to {{handleExchange()}} enters the exchange into the hashmap. But if
> {{channel.send()}} throws an exception, the exchange is never removed from
> the hashmap.
> The relevant code in {{AsyncBaseLifeCycle}} is this:
> {noformat}
> public void prepareShutdown(Endpoint endpoint) throws
> InterruptedException {
> Set<String> exchanges = getKnownExchanges(endpoint);
> synchronized (exchanges) {
> if (!exchanges.isEmpty()) {
> exchanges.wait();
> }
> }
> }
> {noformat}
> I do not know if all send problems cause this behavior. I discovered it by
> running a Camel application that attempts to send a message to a non-existent
> JBI endpoint. When the Camel program does this, I get a stack trace that (in
> part) looks like this:
> {noformat}
> ...
> Caused by: javax.jbi.messaging.MessagingException: Could not find route
> for exchange: InOnly[
> id: ID:10.6.10.123-120d97c610d-3:0
> status: Active
> role: provider
> service: {alpha:beta}gamma
> in: null
> ] for service: {alpha:beta}gamma and interface: null
> at
> org.apache.servicemix.jbi.nmr.DefaultBroker.sendExchangePacket(DefaultBroker.java:297)
> at
> org.apache.servicemix.jbi.security.SecuredBroker.sendExchangePacket(SecuredBroker.java:88)
> at
> org.apache.servicemix.jbi.container.JBIContainer.sendExchange(JBIContainer.java:894)
> at
> org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.doSend(DeliveryChannelImpl.java:395)
> at
> org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.send(DeliveryChannelImpl.java:431)
> at
> org.apache.servicemix.common.EndpointDeliveryChannel.send(EndpointDeliveryChannel.java:88)
> at
> org.apache.servicemix.common.endpoints.SimpleEndpoint.send(SimpleEndpoint.java:66)
> at
> org.apache.servicemix.camel.CamelConsumerEndpoint.process(CamelConsumerEndpoint.java:89)
> ... 13 more
> {noformat}
> Later, when attempting to shut down, a thread dump includes the following:
> {noformat}
> "Thread-16" daemon prio=6 tid=0x2bb34400 nid=0x1398 in Object.wait()
> [0x2ddff000..0x2ddffc94]
> java.lang.Thread.State: WAITING (on object monitor)
> at java.lang.Object.wait(Native Method)
> - waiting on <0x25aed9f8> (a java.util.HashSet)
> at java.lang.Object.wait(Object.java:485)
> at
> org.apache.servicemix.common.AsyncBaseLifeCycle.prepareShutdown(AsyncBaseLifeCycle.java:657)
> - locked <0x25aed9f8> (a java.util.HashSet)
> at
> org.apache.servicemix.common.DefaultServiceUnit.removeEndpoint(DefaultServiceUnit.java:205)
> - locked <0x0826a048> (a
> org.apache.servicemix.common.xbean.XBeanServiceUnit)
> at
> org.apache.servicemix.common.DefaultComponent.removeEndpoint(DefaultComponent.java:301)
> - locked <0x08269958> (a
> org.apache.servicemix.camel.CamelJbiComponent)
> at
> org.apache.servicemix.camel.JbiEndpoint$JbiProducer.stop(JbiEndpoint.java:82)
> ...
> {noformat}
> My proposed fix is to change the code in {{EndpointDeliveryChannel}} to a
> try-catch block, as shown below. But I defer to those who know ServiceMix
> better than I to say whether this needs to be more sophisticated. My change,
> which I have tested and which works fine for me, is as follows:
> {noformat}
> public void send(MessageExchange exchange) throws MessagingException {
> prepareExchange(exchange);
> handleExchange(exchange, exchange.getStatus() ==
> ExchangeStatus.ACTIVE);
> try {
> channel.send(exchange);
> } catch (MessagingException me) {
> // If something goes wrong with the send, remove this exchange
> // from the list of known exchanges or else the caller will
> // never be able to undeploy
> // (see AsyncBaseLifeCycle.prepareShutdown()).
> handleExchange (exchange, false);
> throw me;
> } catch (Throwable t) {
> handleExchange (exchange, false);
> throw new MessagingException (t.getMessage(), t);
> }
> }
> {noformat}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.