Skip to content

Commit 5a362b6

Browse files
artembilangaryrussell
authored andcommitted
Destroy RmiInboundGateway.RmiServiceExporter (#2481)
* Destroy RmiInboundGateway.RmiServiceExporter The internal instance `RmiServiceExporter` of the `RmiInboundGateway` has to be destroyed together with the outer instance to unbind `service` from the RMI registry * Perform some polishing for the `RmiInboundGateway` and optimize a `AbstractInboundGatewayParser` for late channels binding * * Polishing some tests * Expose getters for channels on the `MessagingGatewaySupport` * Fix RMI tests to use random port
1 parent ad4dc11 commit 5a362b6

File tree

12 files changed

+136
-117
lines changed

12 files changed

+136
-117
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/xml/AbstractInboundGatewayParser.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,12 +31,14 @@
3131
*
3232
* @author Mark Fisher
3333
* @author Gary Russell
34+
* @author Artem Bilan
3435
*/
3536
public abstract class AbstractInboundGatewayParser extends AbstractSimpleBeanDefinitionParser {
3637

3738
@Override
3839
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
3940
throws BeanDefinitionStoreException {
41+
4042
String id = super.resolveId(element, definition, parserContext);
4143
if (!StringUtils.hasText(id)) {
4244
id = element.getAttribute("name");
@@ -58,21 +60,20 @@ protected boolean isEligibleAttribute(String attributeName) {
5860
protected final void postProcess(BeanDefinitionBuilder builder, Element element) {
5961
String requestChannelRef = element.getAttribute("request-channel");
6062
Assert.hasText(requestChannelRef, "a 'request-channel' reference is required");
61-
builder.addPropertyReference("requestChannel", requestChannelRef);
63+
builder.addPropertyValue("requestChannelName", requestChannelRef);
6264
String replyChannel = element.getAttribute("reply-channel");
6365
if (StringUtils.hasText(replyChannel)) {
64-
builder.addPropertyReference("replyChannel", replyChannel);
66+
builder.addPropertyValue("replyChannelName", replyChannel);
6567
}
6668
String errorChannel = element.getAttribute("error-channel");
6769
if (StringUtils.hasText(errorChannel)) {
68-
builder.addPropertyReference("errorChannel", errorChannel);
70+
builder.addPropertyValue("errorChannelName", errorChannel);
6971
}
7072
this.doPostProcess(builder, element);
7173
}
7274

7375
/**
7476
* Subclasses may add to the bean definition by overriding this method.
75-
*
7677
* @param builder The builder.
7778
* @param element The element.
7879
*/

spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -372,7 +372,12 @@ public MessageChannel getRequestChannel() {
372372
return this.requestChannel;
373373
}
374374

375-
protected MessageChannel getReplyChannel() {
375+
/**
376+
* Return this gateway's reply channel if any.
377+
* @return the reply channel instance
378+
* @since 5.1
379+
*/
380+
public MessageChannel getReplyChannel() {
376381
if (this.replyChannelName != null) {
377382
synchronized (this) {
378383
if (this.replyChannelName != null) {

spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -444,7 +444,7 @@ public void testInGateway1() {
444444
assertEquals(456L, dfa.getPropertyValue("replyTimeout"));
445445
assertEquals("inGateway1", tcpInboundGateway1.getComponentName());
446446
assertEquals("ip:tcp-inbound-gateway", tcpInboundGateway1.getComponentType());
447-
assertEquals(errorChannel, dfa.getPropertyValue("errorChannel"));
447+
assertEquals(errorChannel, tcpInboundGateway1.getErrorChannel());
448448
assertTrue(cfS2.isLookupHost());
449449
assertFalse(tcpInboundGateway1.isAutoStartup());
450450
assertEquals(126, tcpInboundGateway1.getPhase());

spring-integration-jms/src/main/java/org/springframework/integration/jms/ChannelPublishingJmsMessageListener.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -501,11 +501,6 @@ private class GatewayDelegate extends MessagingGatewaySupport {
501501
super();
502502
}
503503

504-
@Override
505-
public MessageChannel getErrorChannel() {
506-
return super.getErrorChannel();
507-
}
508-
509504
@Override
510505
protected void send(Object request) {
511506
super.send(request);

spring-integration-redis/src/test/java/org/springframework/integration/redis/config/RedisQueueInboundGatewayParserTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ public void testDefaultConfig() throws Exception {
7373
assertFalse(TestUtils.getPropertyValue(this.defaultGateway, "extractPayload", Boolean.class));
7474
assertSame(this.serializer, TestUtils.getPropertyValue(this.defaultGateway, "serializer"));
7575
assertTrue(TestUtils.getPropertyValue(this.defaultGateway, "serializerExplicitlySet", Boolean.class));
76-
assertSame(this.receiveChannel, TestUtils.getPropertyValue(this.defaultGateway, "replyChannel"));
77-
assertSame(this.requestChannel, TestUtils.getPropertyValue(this.defaultGateway, "requestChannel"));
76+
assertSame(this.receiveChannel, this.defaultGateway.getReplyChannel());
77+
assertSame(this.requestChannel, this.defaultGateway.getRequestChannel());
7878
assertEquals(2000L, TestUtils.getPropertyValue(this.defaultGateway, "replyTimeout"));
7979
assertNotNull(TestUtils.getPropertyValue(this.defaultGateway, "taskExecutor"));
8080
assertFalse(TestUtils.getPropertyValue(this.defaultGateway, "autoStartup", Boolean.class));

spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiInboundGateway.java

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,25 +33,25 @@
3333
* An inbound Messaging Gateway for RMI-based remoting.
3434
*
3535
* @author Mark Fisher
36+
* @author Artem Bilan
3637
*/
37-
public class RmiInboundGateway extends MessagingGatewaySupport implements RequestReplyExchanger, InitializingBean {
38+
public class RmiInboundGateway extends MessagingGatewaySupport
39+
implements RequestReplyExchanger, InitializingBean {
3840

3941
public static final String SERVICE_NAME_PREFIX = "org.springframework.integration.rmiGateway.";
4042

4143

42-
private volatile String requestChannelName;
44+
private final RmiServiceExporter exporter = new RmiServiceExporter();
4345

44-
private volatile String registryHost;
46+
private String requestChannelName;
4547

46-
private volatile int registryPort = Registry.REGISTRY_PORT;
48+
private String registryHost;
4749

48-
private volatile boolean expectReply = true;
50+
private int registryPort = Registry.REGISTRY_PORT;
4951

50-
private volatile RemoteInvocationExecutor remoteInvocationExecutor;
52+
private boolean expectReply = true;
5153

52-
private volatile RmiServiceExporter exporter;
53-
54-
private final Object initializationMonitor = new Object();
54+
private RemoteInvocationExecutor remoteInvocationExecutor;
5555

5656

5757
/**
@@ -62,16 +62,21 @@ public class RmiInboundGateway extends MessagingGatewaySupport implements Reques
6262
public void setRequestChannel(MessageChannel requestChannel) {
6363
Assert.notNull(requestChannel, "requestChannel must not be null");
6464
Assert.isTrue(requestChannel instanceof NamedComponent &&
65-
StringUtils.hasText(((NamedComponent) requestChannel).getComponentName()),
65+
StringUtils.hasText(((NamedComponent) requestChannel).getComponentName()),
6666
"RmiGateway's request channel must have a name.");
6767
this.requestChannelName = ((NamedComponent) requestChannel).getComponentName();
6868
super.setRequestChannel(requestChannel);
6969
}
7070

71+
@Override
72+
public void setRequestChannelName(String requestChannelName) {
73+
this.requestChannelName = requestChannelName;
74+
super.setRequestChannelName(requestChannelName);
75+
}
76+
7177
/**
7278
* Specify whether the gateway should be expected to return a reply.
7379
* The default is '<code>true</code>'.
74-
*
7580
* @param expectReply true when a reply is expected.
7681
*/
7782
public void setExpectReply(boolean expectReply) {
@@ -97,33 +102,36 @@ public String getComponentType() {
97102

98103
@Override
99104
protected void onInit() throws Exception {
100-
synchronized (this.initializationMonitor) {
101-
if (this.exporter == null) {
102-
RmiServiceExporter exporter = new RmiServiceExporter();
103-
if (this.registryHost != null) {
104-
exporter.setRegistryHost(this.registryHost);
105-
}
106-
exporter.setRegistryPort(this.registryPort);
107-
if (this.remoteInvocationExecutor != null) {
108-
exporter.setRemoteInvocationExecutor(this.remoteInvocationExecutor);
109-
}
110-
exporter.setService(this);
111-
exporter.setServiceInterface(RequestReplyExchanger.class);
112-
exporter.setServiceName(SERVICE_NAME_PREFIX + this.requestChannelName);
113-
exporter.afterPropertiesSet();
114-
this.exporter = exporter;
115-
}
116-
}
117105
super.onInit();
106+
107+
if (this.registryHost != null) {
108+
this.exporter.setRegistryHost(this.registryHost);
109+
}
110+
this.exporter.setRegistryPort(this.registryPort);
111+
if (this.remoteInvocationExecutor != null) {
112+
this.exporter.setRemoteInvocationExecutor(this.remoteInvocationExecutor);
113+
}
114+
this.exporter.setService(this);
115+
this.exporter.setServiceInterface(RequestReplyExchanger.class);
116+
this.exporter.setServiceName(SERVICE_NAME_PREFIX + this.requestChannelName);
117+
this.exporter.afterPropertiesSet();
118118
}
119119

120120
@Override
121121
public Message<?> exchange(Message<?> message) {
122122
if (this.expectReply) {
123-
return this.sendAndReceiveMessage(message);
123+
return sendAndReceiveMessage(message);
124+
}
125+
else {
126+
send(message);
127+
return null;
124128
}
125-
this.send(message);
126-
return null;
129+
}
130+
131+
@Override
132+
public void destroy() throws Exception {
133+
super.destroy();
134+
this.exporter.destroy();
127135
}
128136

129137
}

spring-integration-rmi/src/test/java/org/springframework/integration/rmi/BackToBackTests-context.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</int:channel>
3030

3131
<bean id="port" class="java.lang.Integer">
32-
<constructor-arg value="#{T(org.springframework.integration.test.util.SocketUtils).findAvailableServerSocket(11099)}" />
32+
<constructor-arg value="#{T(org.springframework.integration.test.util.SocketUtils).findAvailableServerSocket()}" />
3333
</bean>
3434

3535
<!-- Bad -->
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<beans:beans xmlns="http://www.springframework.org/schema/integration"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xmlns:beans="http://www.springframework.org/schema/beans"
5-
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
6-
xsi:schemaLocation="http://www.springframework.org/schema/beans
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:beans="http://www.springframework.org/schema/beans"
5+
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
6+
xsi:schemaLocation="http://www.springframework.org/schema/beans
77
http://www.springframework.org/schema/beans/spring-beans.xsd
88
http://www.springframework.org/schema/integration
99
http://www.springframework.org/schema/integration/spring-integration.xsd
@@ -16,18 +16,22 @@
1616

1717
<channel id="testErrorChannel"/>
1818

19-
<rmi:inbound-gateway id="gatewayWithDefaults" request-channel="testChannel"/>
19+
<rmi:inbound-gateway id="gatewayWithDefaults" request-channel="testChannel" auto-startup="false"/>
2020

2121
<rmi:inbound-gateway id="gatewayWithCustomProperties" request-channel="testChannel"
22-
expect-reply="false" request-timeout="123" reply-timeout="456"/>
22+
expect-reply="false" request-timeout="123" reply-timeout="456" auto-startup="false"/>
2323

2424
<rmi:inbound-gateway id="gatewayWithHostAndErrorChannel" request-channel="testChannel" registry-host="localhost"
25-
error-channel="testErrorChannel"/>
25+
error-channel="testErrorChannel" auto-startup="false"/>
2626

27-
<rmi:inbound-gateway id="gatewayWithPort" request-channel="testChannel" registry-port="1234"/>
27+
<rmi:inbound-gateway id="gatewayWithPort" request-channel="testChannel" registry-port="1234" auto-startup="false"/>
2828

29-
<rmi:inbound-gateway id="gatewayWithExecutorRef" request-channel="testChannel" remote-invocation-executor="invocationExecutor"/>
29+
<rmi:inbound-gateway id="gatewayWithExecutorRef"
30+
request-channel="testChannel"
31+
remote-invocation-executor="invocationExecutor"
32+
auto-startup="false"/>
3033

31-
<beans:bean id="invocationExecutor" class="org.springframework.integration.rmi.config.StubRemoteInvocationExecutor"/>
34+
<beans:bean id="invocationExecutor"
35+
class="org.springframework.integration.rmi.config.StubRemoteInvocationExecutor"/>
3236

3337
</beans:beans>

spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiInboundGatewayParserTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@ public void gatewayWithDefaultsAndHistory() {
5959
assertEquals("gatewayWithDefaults", gateway.getComponentName());
6060
assertEquals("rmi:inbound-gateway", gateway.getComponentType());
6161
assertTrue(TestUtils.getPropertyValue(gateway, "expectReply", Boolean.class));
62-
assertSame(this.channel, TestUtils.getPropertyValue(gateway, "requestChannel"));
62+
assertSame(this.channel, gateway.getRequestChannel());
6363
assertEquals(1000L, TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout"));
6464
assertEquals(1000L, TestUtils.getPropertyValue(gateway, "messagingTemplate.receiveTimeout"));
6565
}
@@ -69,7 +69,7 @@ public void gatewayWithCustomProperties() {
6969
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithCustomProperties");
7070

7171
assertFalse(TestUtils.getPropertyValue(gateway, "expectReply", Boolean.class));
72-
assertSame(this.channel, TestUtils.getPropertyValue(gateway, "requestChannel"));
72+
assertSame(this.channel, gateway.getRequestChannel());
7373
assertEquals(123L, TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout"));
7474
assertEquals(456L, TestUtils.getPropertyValue(gateway, "messagingTemplate.receiveTimeout"));
7575
}
@@ -78,7 +78,7 @@ public void gatewayWithCustomProperties() {
7878
public void gatewayWithHost() {
7979
RmiInboundGateway gateway = (RmiInboundGateway) context.getBean("gatewayWithHostAndErrorChannel");
8080
assertEquals("localhost", TestUtils.getPropertyValue(gateway, "registryHost"));
81-
assertSame(context.getBean("testErrorChannel"), TestUtils.getPropertyValue(gateway, "errorChannel"));
81+
assertSame(context.getBean("testErrorChannel"), gateway.getErrorChannel());
8282
}
8383

8484
@Test

spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,42 @@
1717
request-channel="localChannel"
1818
remote-channel="testChannel"
1919
configurer="configurer"
20-
host="localhost"/>
20+
host="localhost"
21+
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
2122

2223
<channel id="advisedChannel"/>
2324

2425
<rmi:outbound-gateway id="advised"
2526
request-channel="advisedChannel"
2627
remote-channel="testChannel"
2728
requires-reply="false"
28-
host="localhost">
29+
host="localhost"
30+
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}">
2931
<rmi:request-handler-advice-chain>
30-
<beans:ref bean="advice" />
32+
<beans:ref bean="advice"/>
3133
</rmi:request-handler-advice-chain>
3234
</rmi:outbound-gateway>
3335

3436
<beans:bean id="configurer" class="org.mockito.Mockito" factory-method="mock">
3537
<beans:constructor-arg
36-
value="org.springframework.integration.rmi.RmiOutboundGateway$RmiProxyFactoryBeanConfigurer" />
38+
value="org.springframework.integration.rmi.RmiOutboundGateway$RmiProxyFactoryBeanConfigurer"/>
3739
</beans:bean>
3840

3941
<beans:bean id="advice"
40-
class="org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests$FooAdvice" />
42+
class="org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests$FooAdvice"/>
4143

4244
<chain input-channel="rmiOutboundGatewayInsideChain">
43-
<rmi:outbound-gateway remote-channel="testChannel" host="localhost" requires-reply="false"/>
45+
<rmi:outbound-gateway remote-channel="testChannel"
46+
host="localhost"
47+
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"
48+
requires-reply="false"/>
4449
</chain>
4550

4651

4752
<channel id="remoteChannel"/>
4853

49-
<rmi:inbound-gateway request-channel="remoteChannel"/>
54+
<rmi:inbound-gateway request-channel="remoteChannel"
55+
registry-port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
5056

5157
<service-activator input-channel="remoteChannel" expression="payload.toUpperCase()"/>
5258

@@ -56,7 +62,9 @@
5662
</channel>
5763

5864
<chain input-channel="requestReplyRmiWithChainChannel" output-channel="replyChannel">
59-
<rmi:outbound-gateway remote-channel="remoteChannel" host="localhost"/>
65+
<rmi:outbound-gateway remote-channel="remoteChannel"
66+
host="localhost"
67+
port="#{T(org.springframework.integration.rmi.config.RmiOutboundGatewayParserTests).port}"/>
6068
</chain>
6169

6270
</beans:beans>

0 commit comments

Comments
 (0)