Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reuse the same WebClient instance and fix CXF-8992 if it's threadsafe #1781

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public class WebTargetImpl implements WebTarget {
private Configurable<WebTarget> configImpl;
private UriBuilder uriBuilder;
private WebClient targetClient;
private boolean threadSafeTargetClient;


public WebTargetImpl(UriBuilder uriBuilder,
Expand Down Expand Up @@ -310,7 +311,7 @@ public Builder request() {
cxfFeature.initialize(clientCfg, clientCfg.getBus());
}
// Start building the invocation
return new InvocationBuilderImpl(WebClient.fromClient(targetClient),
return new InvocationBuilderImpl(threadSafeTargetClient ? targetClient : WebClient.fromClient(targetClient),
getConfiguration());
}
private void setConnectionProperties(Map<String, Object> configProps, ClientConfiguration clientCfg) {
Expand Down Expand Up @@ -361,6 +362,7 @@ private void initTargetClientIfNeeded(Map<String, Object> configProps) {
}
}
targetClient = bean.createWebClient();
threadSafeTargetClient = threadSafe;
ClientImpl.this.baseClients.add(targetClient);
} else if (!targetClient.getCurrentURI().equals(uri)) {
targetClient.to(uri.toString(), false);
Expand Down Expand Up @@ -470,7 +472,7 @@ public WebTarget resolveTemplatesFromEncoded(Map<String, Object> templatesMap) {
private WebTarget newWebTarget(UriBuilder newBuilder) {
WebClient newClient;
if (targetClient != null) {
newClient = WebClient.fromClient(targetClient);
newClient = threadSafeTargetClient ? targetClient : WebClient.fromClient(targetClient);
Copy link
Member

@reta reta Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dennis-yemelyanov the usage of the new client instance is not accidental and is not about thread safety as much as the following the JAX-RS specification (please consult section "5.3 Client Targets" of the JSR-339).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah WebTarget must be immutable, I missed that part... I might think more if it's possible to separate the externally visible part of it (like the target URL) from internal details, so the closeable (and finalizable) part can still be reused. But I guess it won't be trivial (if possible at all).

Or we need to adjust some logic from this commit, to ensure different instances don't affect each other when finalized 5ffdb90#diff-660ab7b7b6a7b75d899f2a1cd889b168aadd5a194d2aa9fbae875c1b56891c6c

} else {
newClient = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.client.Client;
import org.apache.cxf.jaxrs.client.ClientProperties;
import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
Expand Down Expand Up @@ -77,6 +80,18 @@ public void testSimpleWebClient() throws Exception {
runWebClients(client, 10, true, false);
}

@Test
public void testWebTargetGC() throws Exception {
WebTarget target = ClientBuilder.newClient().target("http://localhost:" + PORT + "/bookstore/booksecho")
.property(ClientProperties.THREAD_SAFE_CLIENT_PROP, true);

target.request().get().getStatus();

System.gc();

target.request().get().getStatus();
}

@Test
public void testSimpleProxy() throws Exception {
BookStore proxy = JAXRSClientFactory.create("http://localhost:" + PORT, BookStore.class);
Expand Down