[jax-rs-spec users] Re: Default ExecutorService used on the client

From: Markus KARG <>
Date: Fri, 28 Apr 2017 18:35:09 +0200

The forced default to ManagedExecutorService on Java EE should stay, as it is the perfect and most expected choice on Java EE.

On Java SE it makes no sense to default to the ForkJoinPool.commonPool, as that pool is intended for CPU-bound algorithms, not for IO-bound ones like JAX-RS. Hence, we should say that the default on Java SE is decided by the vendor.

There should never be a force to manually set an executor; this should always be optional.


-----Original Message-----
From: Sergey Beryozkin []
Sent: Freitag, 28. April 2017 18:02
Subject: Re: [jax-rs-spec users] Default ExecutorService used on the client

Hi Santiago

Probably not, I'm reading

so it all looks good to me, the executor is optional, the only possible ambiguity is specific to the EE clause in which case it does appear to be non-optional (though where is the ref to ForkJoinPool ?).

IMHO it would simplify things if we just drop the EE sentence, Can the users easily access an EE container-managed executor and set it themselves if they need it ?

Thanks, Sergey

On 28/04/17 15:56, Santiago Pericas-Geertsen wrote:
> Hi Sergey,
> When running inside an EE container, the option is clear. Are you suggesting that we leave the notion of a default executor service on the client unspecified and, thus, implementation specific?
> — Santiago
>> On Apr 28, 2017, at 7:23 AM, Sergey Beryozkin <> wrote:
>> Hi Pavel
>> The use of the custom executors should be entirely optional, enforcing that some kind of the executor must be used by default would be a major restriction IMHO, ex, I'd still like to investigate how the asynchronous HTTP transport can help with its own pool, so it would be better to retain the flexibility and lift the requirement that the use of the ForkJoinPool.commonPool must be used by default in these cases
>> Thanks, Sergey
>> On 27/04/17 23:48, Pavel Bucek wrote:
>>> Dear EG members,
>>> when settable executor service on the client side was introduced in the API, there was also a default one specified - ManagedExecutorService when running on the Java EE container and ForkJoinPool.commonPool() when running on Java SE.
>>> The latter seems to be little problematic.
>>> We already have this implemented in Jersey and we noticed significant performance drop in some type of tests. After some investigation, it is caused by the ForkJoinPool.commonPool size. The default one is something like 2x number of cores, which might not be enough for multiple reactive invocations, not to mention that this pool is used by default by any CompletionStage/CompletableFuture, parallel streams and other Java SE classes/features, which makes the client performance not predictable and very much dependent on the actual environment.
>>> The obvious fix for these cases is to set ExecutorService for the client, but it seems like that would be almost required (if we keep commonPool as a default) for some usecases.
>>> Another reason why we might want to change this is that ForkJoinPool.commonPool seem to be mean for cpu intensive tasks and JAX-RS client is using these threads for I/O - which is generally not that much about CPU time. (just a summary: JAX-RS client is using that for async and reactive calls as well as for SseEventSource).
>>> What do you think about this issue? Should we lift the requirement to use ForkJoinPool.commonPool as a default one? Or should we rather highlight that fact in the documentation and examples and make super clear that using custom executor service is strongly suggested for advanced usecases?
>>> Thanks and regards,
>>> Pavel