Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java CompletableFuture + Resteasy

I have been using Java's CompletableFuture like this

CompletableFuture.runAsync(() -> {//Some code here });

When I try to use a Resteasy Client inside this block of code I get a

javax.ws.rs.ProcessingException: Unable to find a MessageBodyReader of content-type application/json;charset=utf-8 and type class java.lang.String

If i use the client outside of the completablefuture it works. The Resteasy code looks something like this

        ResteasyClient client = new ResteasyClientBuilder().build();
        client.register(new AcceptEncodingFilter("gzip"));
        ResteasyWebTarget target = client.target(exampleURL);

        target = target.queryParam("1", 1)
                .queryParam("2", "1")
                .queryParam("3", 3)
                .queryParam("4", 4)
                .queryParam("5", "5");

        Response response = target.request().get();
        resultString = response.readEntity(String.class);

I will run the resteasy code outisde of the completablefuture to "fix" the problem but would like to understand why this happens.

The resteasy code inside the CompletableFuture looks like this:

CompletableFuture.runAsync(() -> {
            try {
                ResteasyClient client = new ResteasyClientBuilder().build();
                client.register(new AcceptEncodingFilter("gzip"));
                ResteasyWebTarget target = client.target("http://test.com");

                target = target.queryParam("1", "1")
                        .queryParam("2", "2")
                        .queryParam("3", "3")
                        .queryParam("4", "4")
                        .queryParam("5", "5");

                Response response = target.request().get();
                String resultString = response.readEntity(String.class);

                response.close();
                client.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        });

the same code outside the CompletableFuture works

like image 860
m1416 Avatar asked Jul 04 '26 12:07

m1416


1 Answers

I had this exact issue in Wildfly 26.1.3, which I believe uses RestEasy 4.7.7. If RestEasy was used in a "normal" method, it worked. If it was used in a thread created by CompletableFuture.runAsync, it failed with the "Unable to find a MessageBodyReader" error message.

I used a debugger to see what was happening and I found that the RestEasy client was not properly configured when it was created in the thread. I was able to work around the problem by creating the client as follows:

Configuration configuration = LocalResteasyProviderFactory.getInstance().getConfiguration();
Client client = ClientBuilder.newClient(configuration);

Adding this code resulted in a warning in the Wildfly server.log:

RESTEASY002155: Provider class org.jboss.resteasy.plugins.providers.jackson.PatchMethodFilter is already registered.  2nd registration is being ignored

EDIT: after further research, the correct answer is to use ManagedScheduledExecutorService to execute the asynchronous task, not CompletableFuture. This ensures that the RestEasy configuration is correctly initialized.

like image 179
kensei62 Avatar answered Jul 07 '26 01:07

kensei62