[jax-rs-spec users] Re: JAX-RS 2.1 - work schedule

From: Markus KARG <>
Date: Sun, 22 Jan 2017 13:51:26 +0100



besides all technical issues your proposal certainly does solve, infact I strongly dislike the idea that an application programmers has to type the word "PavelableInvoker.class" but would stronlgy love to type the word "Pavelable.class" instead. The first approach certainly is absolutely correct and logical, but the latter is, what people actually want to say: "Give me a CompletionStage". Nobody says "Give me a CompletionStageInvokerProvider" in the real world, despite the technical fact that this is what he technically has to do.


My proposal would be to make this user-oriented simplification possible if we find a technical way to solve this. If we don't then we just have to live with your proposal as-is.





From: Pavel Bucek []
Sent: Sonntag, 22. Januar 2017 12:09
Subject: Re: [jax-rs-spec users] Re: JAX-RS 2.1 - work schedule


Hi Ondrej,

just a note:

For me it is important not to pass any implementation to rx() method, and the solution of .rx(CompletionStageRxInvoker.

class) meets that. The developer jut needs to write an empty interface, jut to define proper type conversions, which is nice (except that awful number of methods to override, but I have no energy now to try to propose something better to reduce the number :) )

The developer won't be writing any interface - it won't work if he will do that. He needs to use exactly the same interface which is provide as part of the "extension implementation", so for example if there is a library with support for "org.pavel.Pavelable<T>", it contains:

* org.pavel.PavelInvoker implements RxInvoker<Pavelable>
* org.pavel.PavelProvider implements RxInvokerProvider<PavelInvoker>

and the code will always look like:


Client client = ClientBuilder.newClient();
Pavelable<Response> csResponse = <> "")

Simply because underlying client runtime does a lookup for provider for a class PavelableInvoker, which in this case would be something like:

public static class PavelableProvider implements RxInvokerProvider<PavelableInvoker> {
    public boolean provides(Class<?> clazz) {
        return Pavelable.class.equals(clazz);
    public PavelableInvoker getRxInvoker(SyncInvoker syncInvoker, ExecutorService executorService) {
        return //...;

(note the "provides" method).

hope the proposal is clearer now. Please let me know if that changed anything about how you like it :).

Best regards,


On 20/01/2017 18:07, Ondrej Mihályi wrote:

Thanks for your honesty, Pavel.


I didn't mean to propose a final solution, just a proof that the approach suggested by me and Markus can work.


What I'm after is really the consistency - Java EE API is mostly about standardizing what should be done and not how. Therefore it is more natural for me to declare that I want to use CompletionStage, RxJava or whatever, rather than to define how to do this conversion by passing a converter each time I want to use it. Even more if the converter is meant to be provided by the implementation and not by users of the API.


I accept that my solution is not perfect, I just wanted to point out that the approach is possible.


I agree that the last suggestion by Santiago is the best solution so far. For me it is important not to pass any implementation to rx() method, and the solution of .rx(CompletionStageRxInvoker.class) meets that. The developer jut needs to write an empty interface, jut to define proper type conversions, which is nice (except that awful number of methods to override, but I have no energy now to try to propose something better to reduce the number :) )


Thanks for the discussion :)



2017-01-20 15:27 GMT+01:00 Pavel Bucek <>:

Hi Ondrej,

I like your determination and consistency.

Unfortunately, I have to strongly disagree with your last proposal. GenericType is nothing more than a standardized hack, which has limited usability and should be avoided if possible. Here, we do have that option.

Ad limited usability: imagine that user of the API will wrap your code in generic method, replacing List<String> with T. Then the information passed to the rx method will be exactly CompletionStage<T>, which cannot be used by the implementation for selecting the correct provider. Also, the code is (no offense) quite hard to write and read - we don't want to force anyone to write "Foo<Bar<Baz<Qux>>>". (I always wanted to use "qux" somewhere!)

I believe that the last variant brought up by Santiago fits nicely with existing APIs and uses already established provider pattern. I'd appreciate if you could evaluate it, maybe try to use it and share your thoughts once again.

Thanks and regards,

On 20/01/2017 12:56, Ondrej Mihályi wrote:

Pavel raised a valid point, but it can really be solved by the GenericType class, just moving the usage of the GenericType from method get to method rx.


Here is a compilable and type-safe solution:"remote/forecast/{destination}")
      .resolveTemplate("destination", "mars")
      .header("Rx-User", "Java8")
      .rx(new GenericType<CompletionStage<List<String>>>())

with the new rx() method on Invocation.Builder defined simply like this:

public <T> RxInvoker<T> rx(GenericType<T> type);

You can play with the code in my fork here:

However, this solution also provides cons:

  - it is uglier at first sight (although GenericType is always necessary at some point sooner or later)

 - once converted to CompletionStage with proper type, it's not possible to retrieve the generic Response object in a typesafe way (making the methods like get(Class<R>) and get(GenericType<R> redundant - but maybe it;s a good thing and simplifies the RxInvoker interface)

The ugly part can be simplified by any developer using a class that extends GenericType like this (the code in my fork already shows that):

class CompletionStageType<T> extends GenericType<CompletionStage<T>>

And I don't think that the second drawback matters - if interested in Response, it can be retrieved by

.rx(new GenericType<CompletionStage<Response>() {})

and converted later if needed.


2017-01-19 19:31 GMT+01:00 Santiago Pericasgeertsen <>:

On Jan 19, 2017, at 1:12 PM, Markus KARG <> wrote:

Because in that "more complex" style you can write this then…


Client rxClient = client.register(Java8.class); // i. e. technically a CompletionStageRxInvokerProvider, which effectively is part of JAX-RS!!!

CompletionStage<UserPojo> cs = <> "")


…so the average programmer clearly understands that this will register Java 8 as one possible RX provider (possibly in addition to others), so he can get a CompletionStage. It feels just more correct and simple, particular for JAX-RS beginners.

 Of course, but the point raised by Pavel is that this code again cannot (at least not obviously) be accepted by the Java type checker. Hence, the less desirable suggestion. Please read the rest of the e-mail thread.

— Santiago

They will not understand why they shall repeat the provider again and again, and they will not understand why rx(T) will return not return T. But I think they will accept to repeat the stage again and again, as stages are not reusable (they are used to do that with stages already).




From: Santiago Pericasgeertsen [] Sent: Donnerstag, 19. Januar 2017 16:55 To: Subject: Re: [jax-rs-spec users] JAX-RS 2.1 - work schedule


Hi Pavel,


 Just catching up with this issue. I guess the two levels of indirection has led us into a generic wall :)



Client rxClient = client.register(CompletionStageRxInvokerProvider.class);

CompletionStage<UserPojo> cs = <> "")

 So what if we reduce indirection and write:




 as before, still keeping the provider for it? Less ideal of course.


— Santiago