Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 86e5d92

Browse files
committedMay 12, 2023
Polishing.
Related: #1164.
1 parent 05daff5 commit 86e5d92

File tree

4 files changed

+120
-74
lines changed

4 files changed

+120
-74
lines changed
 

‎spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpComponents5ClientFactory.java

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
import java.net.URI;
2020
import java.net.URISyntaxException;
21+
import java.time.Duration;
2122
import java.util.Map;
22-
import java.util.concurrent.TimeUnit;
2323

2424
import org.apache.hc.client5.http.HttpRoute;
2525
import org.apache.hc.client5.http.auth.AuthScope;
@@ -31,25 +31,28 @@
3131
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
3232
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
3333
import org.apache.hc.core5.http.HttpHost;
34-
34+
import org.apache.hc.core5.util.Timeout;
3535
import org.springframework.beans.factory.FactoryBean;
3636

3737
/**
38-
* {@code FactoryBean} to set up a <a href="http://hc.apache.org/httpcomponents-client">Apache
39-
* CloseableHttpClient</a>
38+
* {@link FactoryBean} to set up a {@link CloseableHttpClient} using HttpComponents HttpClient 5.
4039
*
40+
* @see http://hc.apache.org/httpcomponents-client
4141
* @author Lars Uffmann
4242
* @since 4.0.5
4343
*/
4444
public class HttpComponents5ClientFactory implements FactoryBean<CloseableHttpClient> {
45-
private static final int DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS = (60 * 1000);
4645

47-
private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS;
48-
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
46+
private static final Duration DEFAULT_CONNECTION_TIMEOUT = Duration.ofSeconds(60);
47+
48+
private static final Duration DEFAULT_READ_TIMEOUT = Duration.ofSeconds(60);
49+
50+
private Duration connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
4951

50-
private int readTimeout = DEFAULT_READ_TIMEOUT_MILLISECONDS;
52+
private Duration readTimeout = DEFAULT_READ_TIMEOUT;
5153

5254
private int maxTotalConnections = -1;
55+
5356
private AuthScope authScope = null;
5457

5558
private Credentials credentials = null;
@@ -86,24 +89,28 @@ public void setAuthScope(AuthScope authScope) {
8689
/**
8790
* Sets the timeout until a connection is established. A value of 0 means <em>never</em> timeout.
8891
*
89-
* @param timeout the timeout value in milliseconds
92+
* @param timeout the timeout value
9093
*/
91-
public void setConnectionTimeout(int timeout) {
92-
if (timeout < 0) {
94+
public void setConnectionTimeout(Duration timeout) {
95+
96+
if (timeout.isNegative()) {
9397
throw new IllegalArgumentException("timeout must be a non-negative value");
9498
}
99+
95100
this.connectionTimeout = timeout;
96101
}
97102

98103
/**
99104
* Set the socket read timeout for the underlying HttpClient. A value of 0 means <em>never</em> timeout.
100105
*
101-
* @param timeout the timeout value in milliseconds
106+
* @param timeout the timeout value
102107
*/
103-
public void setReadTimeout(int timeout) {
104-
if (timeout < 0) {
108+
public void setReadTimeout(Duration timeout) {
109+
110+
if (timeout.isNegative()) {
105111
throw new IllegalArgumentException("timeout must be a non-negative value");
106112
}
113+
107114
this.readTimeout = timeout;
108115
}
109116

@@ -114,9 +121,11 @@ public void setReadTimeout(int timeout) {
114121
* @see PoolingHttpClientConnectionManager...
115122
*/
116123
public void setMaxTotalConnections(int maxTotalConnections) {
124+
117125
if (maxTotalConnections <= 0) {
118126
throw new IllegalArgumentException("maxTotalConnections must be a positive value");
119127
}
128+
120129
this.maxTotalConnections = maxTotalConnections;
121130
}
122131

@@ -142,14 +151,14 @@ public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost)
142151
void applyMaxConnectionsPerHost(PoolingHttpClientConnectionManager connectionManager) throws URISyntaxException {
143152

144153
for (Map.Entry<String, String> entry : maxConnectionsPerHost.entrySet()) {
154+
145155
URI uri = new URI(entry.getKey());
146156
HttpHost host = new HttpHost(uri.getScheme(), uri.getHost(), getPort(uri));
147157
final HttpRoute route;
148158

149159
if (uri.getScheme().equals("https")) {
150160
route = new HttpRoute(host, null, true);
151-
}
152-
else {
161+
} else {
153162
route = new HttpRoute(host);
154163
}
155164
int max = Integer.parseInt(entry.getValue());
@@ -158,14 +167,17 @@ void applyMaxConnectionsPerHost(PoolingHttpClientConnectionManager connectionMan
158167
}
159168

160169
static int getPort(URI uri) {
170+
161171
if (uri.getPort() == -1) {
172+
162173
if ("https".equalsIgnoreCase(uri.getScheme())) {
163174
return 443;
164175
}
165176
if ("http".equalsIgnoreCase(uri.getScheme())) {
166177
return 80;
167178
}
168179
}
180+
169181
return uri.getPort();
170182
}
171183

@@ -176,34 +188,38 @@ public boolean isSingleton() {
176188

177189
@Override
178190
public CloseableHttpClient getObject() throws Exception {
179-
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
191+
192+
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder
193+
.create();
194+
180195
if (this.maxTotalConnections != -1) {
181196
connectionManagerBuilder.setMaxConnTotal(this.maxTotalConnections);
182197
}
183198

184-
if (null != this.connectionManagerBuilderCustomizer) {
199+
if (this.connectionManagerBuilderCustomizer != null) {
185200
this.connectionManagerBuilderCustomizer.customize(connectionManagerBuilder);
186201
}
187202

188203
this.connectionManager = connectionManagerBuilder.build();
189204

190205
applyMaxConnectionsPerHost(connectionManager);
191206

192-
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
193-
.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
194-
.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS);
207+
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() //
208+
.setConnectionRequestTimeout(Timeout.of(connectionTimeout)) //
209+
.setResponseTimeout(Timeout.of(readTimeout));
195210

196-
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
197-
.setDefaultRequestConfig(requestConfigBuilder.build())
211+
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create() //
212+
.setDefaultRequestConfig(requestConfigBuilder.build()) //
198213
.setConnectionManager(connectionManager);
199214

200-
if (null != credentials && null != authScope) {
215+
if (credentials != null && authScope != null) {
216+
201217
BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
202218
basicCredentialsProvider.setCredentials(authScope, credentials);
203219
httpClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider);
204220
}
205221

206-
if (null != this.clientBuilderCustomizer) {
222+
if (this.clientBuilderCustomizer != null) {
207223
clientBuilderCustomizer.customize(httpClientBuilder);
208224
}
209225

@@ -223,7 +239,8 @@ public void setClientBuilderCustomizer(HttpClientBuilderCustomizer clientBuilder
223239
this.clientBuilderCustomizer = clientBuilderCustomizer;
224240
}
225241

226-
public void setConnectionManagerBuilderCustomizer(PoolingHttpClientConnectionManagerBuilderCustomizer connectionManagerBuilderCustomizer) {
242+
public void setConnectionManagerBuilderCustomizer(
243+
PoolingHttpClientConnectionManagerBuilderCustomizer connectionManagerBuilderCustomizer) {
227244
this.connectionManagerBuilderCustomizer = connectionManagerBuilderCustomizer;
228245
}
229246

‎spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpComponents5Connection.java

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,19 @@
2828
import org.apache.hc.client5.http.classic.HttpClient;
2929
import org.apache.hc.client5.http.classic.methods.HttpPost;
3030
import org.apache.hc.core5.http.ClassicHttpResponse;
31-
import org.apache.hc.core5.http.Header;
3231
import org.apache.hc.core5.http.HttpEntity;
3332
import org.apache.hc.core5.http.HttpResponse;
33+
import org.apache.hc.core5.http.NameValuePair;
3434
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
3535
import org.apache.hc.core5.http.io.entity.EntityUtils;
3636
import org.apache.hc.core5.http.protocol.HttpContext;
37-
3837
import org.springframework.util.Assert;
3938
import org.springframework.ws.WebServiceMessage;
4039
import org.springframework.ws.transport.WebServiceConnection;
4140

4241
/**
43-
* Implementation of {@link WebServiceConnection} that is based on Apache HttpClient. Exposes a {@link org.apache.hc.client5.http.classic.methods.HttpPost} and
44-
* {@link org.apache.hc.core5.http.HttpResponse
42+
* Implementation of {@link WebServiceConnection} that is based on Apache HttpClient 5. Exposes a {@link HttpPost} and
43+
* {@link HttpResponse}.
4544
*
4645
* @author Alan Stewart
4746
* @author Barry Pitman
@@ -63,8 +62,10 @@ public class HttpComponents5Connection extends AbstractHttpSenderConnection {
6362
private ByteArrayOutputStream requestBuffer;
6463

6564
protected HttpComponents5Connection(HttpClient httpClient, HttpPost httpPost, HttpContext httpContext) {
65+
6666
Assert.notNull(httpClient, "httpClient must not be null");
6767
Assert.notNull(httpPost, "httpPost must not be null");
68+
6869
this.httpClient = httpClient;
6970
this.httpPost = httpPost;
7071
this.httpContext = httpContext;
@@ -80,8 +81,9 @@ public HttpResponse getHttpResponse() {
8081

8182
@Override
8283
public void onClose() throws IOException {
83-
//XXX:
84+
8485
if (httpResponse instanceof ClassicHttpResponse response) {
86+
8587
if (response.getEntity() != null) {
8688
EntityUtils.consume(response.getEntity());
8789
}
@@ -117,9 +119,10 @@ protected OutputStream getRequestOutputStream() throws IOException {
117119

118120
@Override
119121
protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
120-
//XXX
122+
121123
httpPost.setEntity(new ByteArrayEntity(requestBuffer.toByteArray(), null));
122124
requestBuffer = null;
125+
123126
if (httpContext != null) {
124127
httpResponse = httpClient.execute(httpPost, httpContext);
125128
} else {
@@ -143,8 +146,9 @@ protected String getResponseMessage() throws IOException {
143146

144147
@Override
145148
protected long getResponseContentLength() throws IOException {
146-
//XXX:
149+
147150
if (httpResponse instanceof ClassicHttpResponse response) {
151+
148152
HttpEntity entity = response.getEntity();
149153
if (entity != null) {
150154
return entity.getContentLength();
@@ -155,32 +159,31 @@ protected long getResponseContentLength() throws IOException {
155159

156160
@Override
157161
protected InputStream getRawResponseInputStream() throws IOException {
162+
158163
if (httpResponse instanceof ClassicHttpResponse response) {
164+
159165
HttpEntity entity = response.getEntity();
160166
if (entity != null) {
161167
return entity.getContent();
162168
}
163169
}
170+
164171
throw new IllegalStateException("Response has no enclosing response entity, cannot create input stream");
165172
}
166173

167174
@Override
168175
public Iterator<String> getResponseHeaderNames() throws IOException {
169-
Header[] headers = httpResponse.getHeaders();
170-
String[] names = new String[headers.length];
171-
for (int i = 0; i < headers.length; i++) {
172-
names[i] = headers[i].getName();
173-
}
174-
return Arrays.asList(names).iterator();
176+
177+
return Arrays.stream(httpResponse.getHeaders()) //
178+
.map(NameValuePair::getName) //
179+
.iterator();
175180
}
176181

177182
@Override
178183
public Iterator<String> getResponseHeaders(String name) throws IOException {
179-
Header[] headers = httpResponse.getHeaders(name);
180-
String[] values = new String[headers.length];
181-
for (int i = 0; i < headers.length; i++) {
182-
values[i] = headers[i].getValue();
183-
}
184-
return Arrays.asList(values).iterator();
184+
185+
return Arrays.stream(httpResponse.getHeaders(name)) //
186+
.map(NameValuePair::getValue) //
187+
.iterator();
185188
}
186189
}

‎spring-ws-core/src/main/java/org/springframework/ws/transport/http/HttpComponents5MessageSender.java

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.net.URI;
21+
import java.time.Duration;
2122
import java.util.Map;
2223

2324
import org.apache.hc.client5.http.auth.AuthScope;
@@ -33,7 +34,6 @@
3334
import org.apache.hc.core5.http.HttpRequest;
3435
import org.apache.hc.core5.http.HttpRequestInterceptor;
3536
import org.apache.hc.core5.http.protocol.HttpContext;
36-
3737
import org.springframework.beans.factory.DisposableBean;
3838
import org.springframework.beans.factory.InitializingBean;
3939
import org.springframework.util.Assert;
@@ -57,7 +57,9 @@
5757
*/
5858
public class HttpComponents5MessageSender extends AbstractHttpWebServiceMessageSender
5959
implements InitializingBean, DisposableBean {
60+
6061
private static final String HTTP_CLIENT_ALREADY_SET = "httpClient already set";
62+
6163
private HttpClient httpClient;
6264

6365
private HttpComponents5ClientFactory clientFactory;
@@ -67,22 +69,23 @@ public class HttpComponents5MessageSender extends AbstractHttpWebServiceMessageS
6769
* {@link PoolingHttpClientConnectionManager}.
6870
*/
6971
public HttpComponents5MessageSender() {
72+
7073
this.clientFactory = new HttpComponents5ClientFactory();
71-
this.clientFactory.setClientBuilderCustomizer(httpClientBuilder ->
72-
httpClientBuilder.addRequestInterceptorFirst(new RemoveSoapHeadersInterceptor()));
74+
this.clientFactory.setClientBuilderCustomizer(
75+
httpClientBuilder -> httpClientBuilder.addRequestInterceptorFirst(new RemoveSoapHeadersInterceptor()));
7376
}
7477

7578
/**
76-
* Create a new instance of the {@code HttpClientMessageSender} with the given {@link HttpClient} instance.
79+
* Create a new instance of the {@link HttpComponents5MessageSender} with the given {@link HttpClient} instance.
7780
* <p>
7881
* This constructor does not change the given {@code HttpClient} in any way. As such, it does not set timeouts, nor
79-
* does it
80-
* {@linkplain HttpClientBuilder#addRequestInterceptorFirst(HttpRequestInterceptor)
81-
* add} the {@link RemoveSoapHeadersInterceptor}.
82+
* does it {@linkplain HttpClientBuilder#addRequestInterceptorFirst(HttpRequestInterceptor) add} the
83+
* {@link RemoveSoapHeadersInterceptor}.
8284
*
8385
* @param httpClient the HttpClient instance to use for this sender
8486
*/
8587
public HttpComponents5MessageSender(HttpClient httpClient) {
88+
8689
Assert.notNull(httpClient, "httpClient must not be null");
8790
this.httpClient = httpClient;
8891
}
@@ -91,19 +94,23 @@ public HttpComponents5MessageSender(HttpClient httpClient) {
9194
* @see HttpComponents5ClientFactory#setAuthScope(AuthScope)
9295
*/
9396
public void setAuthScope(AuthScope authScope) {
94-
if (null != getHttpClient()) {
97+
98+
if (getHttpClient() != null) {
9599
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
96100
}
101+
97102
this.clientFactory.setAuthScope(authScope);
98103
}
99104

100105
/**
101106
* @see HttpComponents5ClientFactory#setCredentials(Credentials)
102107
*/
103108
public void setCredentials(Credentials credentials) {
104-
if (null != getHttpClient()) {
109+
110+
if (getHttpClient() != null) {
105111
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
106112
}
113+
107114
this.clientFactory.setCredentials(credentials);
108115
}
109116

@@ -122,42 +129,50 @@ public void setHttpClient(HttpClient httpClient) {
122129
}
123130

124131
/**
125-
* @see HttpComponents5ClientFactory#setConnectionTimeout(int)
132+
* @see HttpComponents5ClientFactory#setConnectionTimeout(Duration)
126133
*/
127-
public void setConnectionTimeout(int timeout) {
128-
if (null != getHttpClient()) {
134+
public void setConnectionTimeout(Duration timeout) {
135+
136+
if (getHttpClient() != null) {
129137
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
130138
}
139+
131140
this.clientFactory.setConnectionTimeout(timeout);
132141
}
133142

134143
/**
135-
* @see HttpComponents5ClientFactory#setReadTimeout(int)
144+
* @see HttpComponents5ClientFactory#setReadTimeout(Duration)
136145
*/
137-
public void setReadTimeout(int timeout) {
138-
if (null != getHttpClient()) {
146+
public void setReadTimeout(Duration timeout) {
147+
148+
if (getHttpClient() != null) {
139149
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
140150
}
151+
141152
this.clientFactory.setReadTimeout(timeout);
142153
}
143154

144155
/**
145156
* @see HttpComponents5ClientFactory#setMaxTotalConnections(int)
146157
*/
147158
public void setMaxTotalConnections(int maxTotalConnections) {
148-
if (null != getHttpClient()) {
159+
160+
if (getHttpClient() != null) {
149161
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
150162
}
163+
151164
this.clientFactory.setMaxTotalConnections(maxTotalConnections);
152165
}
153166

154167
/**
155168
* @see HttpComponents5ClientFactory#setMaxConnectionsPerHost(Map)
156169
*/
157170
public void setMaxConnectionsPerHost(Map<String, String> maxConnectionsPerHost) {
158-
if (null != getHttpClient()) {
171+
172+
if (getHttpClient() != null) {
159173
throw new IllegalStateException(HTTP_CLIENT_ALREADY_SET);
160174
}
175+
161176
this.clientFactory.setMaxConnectionsPerHost(maxConnectionsPerHost);
162177
}
163178

@@ -168,16 +183,20 @@ public void afterPropertiesSet() throws Exception {
168183

169184
@Override
170185
public WebServiceConnection createConnection(URI uri) throws IOException {
186+
171187
HttpPost httpPost = new HttpPost(uri);
188+
172189
if (isAcceptGzipEncoding()) {
173190
httpPost.addHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING, HttpTransportConstants.CONTENT_ENCODING_GZIP);
174191
}
192+
175193
HttpContext httpContext = createContext(uri);
194+
176195
return new HttpComponents5Connection(getHttpClient(), httpPost, httpContext);
177196
}
178197

179198
/**
180-
* Template method that allows for creation of a {@link HttpContext} for the given uri. Default implementation returns
199+
* Template method that allows for creation of an {@link HttpContext} for the given uri. Default implementation returns
181200
* {@code null}.
182201
*
183202
* @param uri the URI to create the context for
@@ -189,7 +208,8 @@ protected HttpContext createContext(URI uri) {
189208

190209
@Override
191210
public void destroy() throws Exception {
192-
if (getHttpClient() instanceof CloseableHttpClient client) {
211+
212+
if (getHttpClient()instanceof CloseableHttpClient client) {
193213
client.close();
194214
}
195215
}
@@ -200,11 +220,15 @@ public void destroy() throws Exception {
200220
* these headers themselves, and HttpClient throws an exception if they have been set.
201221
*/
202222
public static class RemoveSoapHeadersInterceptor implements HttpRequestInterceptor {
223+
203224
@Override
204-
public void process(HttpRequest request, EntityDetails entityDetails, HttpContext httpContext) throws HttpException, IOException {
225+
public void process(HttpRequest request, EntityDetails entityDetails, HttpContext httpContext)
226+
throws HttpException, IOException {
227+
205228
if (request.containsHeader(HttpHeaders.TRANSFER_ENCODING)) {
206229
request.removeHeaders(HttpHeaders.TRANSFER_ENCODING);
207230
}
231+
208232
if (request.containsHeader(HttpHeaders.CONTENT_LENGTH)) {
209233
request.removeHeaders(HttpHeaders.CONTENT_LENGTH);
210234
}

‎spring-ws-core/src/test/java/org/springframework/ws/transport/http/HttpComponents5MessageSenderIntegrationTest.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@
1616

1717
package org.springframework.ws.transport.http;
1818

19-
import java.io.IOException;
20-
import java.net.URI;
21-
import java.util.HashMap;
22-
import java.util.Map;
19+
import static org.assertj.core.api.AssertionsForClassTypes.*;
20+
import static org.springframework.ws.transport.http.HttpComponents5ClientFactory.*;
2321

2422
import jakarta.servlet.http.HttpServlet;
2523
import jakarta.servlet.http.HttpServletRequest;
2624
import jakarta.servlet.http.HttpServletResponse;
2725
import jakarta.xml.soap.MessageFactory;
26+
27+
import java.io.IOException;
28+
import java.net.URI;
29+
import java.util.HashMap;
30+
import java.util.Map;
31+
2832
import org.apache.hc.client5.http.HttpRoute;
2933
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
3034
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
@@ -34,15 +38,12 @@
3438
import org.eclipse.jetty.server.ServerConnector;
3539
import org.eclipse.jetty.servlet.ServletContextHandler;
3640
import org.junit.jupiter.api.Test;
37-
3841
import org.springframework.context.support.StaticApplicationContext;
3942
import org.springframework.util.FileCopyUtils;
4043
import org.springframework.ws.soap.saaj.SaajSoapMessage;
4144
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
4245
import org.springframework.ws.transport.WebServiceConnection;
4346
import org.springframework.ws.transport.support.FreePortScanner;
44-
import static org.assertj.core.api.AssertionsForClassTypes.*;
45-
import static org.springframework.ws.transport.http.HttpComponents5ClientFactory.*;
4647

4748
class HttpComponents5MessageSenderIntegrationTest
4849
extends AbstractHttpWebServiceMessageSenderIntegrationTestCase<HttpComponents5MessageSender> {
@@ -52,7 +53,7 @@ protected HttpComponents5MessageSender createMessageSender() {
5253
return new HttpComponents5MessageSender();
5354
}
5455

55-
@Test
56+
@Test // GH-1164
5657
void testMaxConnections() throws Exception {
5758

5859
final String url1 = "https://www.example.com";
@@ -103,7 +104,7 @@ void testMaxConnections() throws Exception {
103104
assertThat(poolingHttpClientConnectionManager.getMaxPerRoute(route3)).isEqualTo(10);
104105
}
105106

106-
@Test
107+
@Test // GH-1164
107108
void testContextClose() throws Exception {
108109

109110
MessageFactory messageFactory = MessageFactory.newInstance();
@@ -138,6 +139,7 @@ void testContextClose() throws Exception {
138139

139140
appContext.close();
140141
} finally {
142+
141143
if (connection != null) {
142144
try {
143145
connection.close();

0 commit comments

Comments
 (0)
Please sign in to comment.