jsr370-experts@jax-rs-spec.java.net

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

From: Ondrej Mihályi <ondrej.mihalyi_at_gmail.com>
Date: Wed, 18 Jan 2017 16:18:01 +0100

Hi Pavel,

I appreciate you have provided an example. I agree this straightforward
approach is not directly supported by Java syntax.

This is the same problem, which is solved in CDI by
javax.enterprise.util.TypeLiteral
<https://docs.jboss.org/cdi/api/1.0/javax/enterprise/util/TypeLiteral.html>.
I think we would have to use the same option. I'm not sure if JAX-RS can
use the package javax.enterprise.util and the TypeLiteral, which is defined
by the CDI spec.

I would still prefer this declarative option than having to provide the
real provider by the developer each time rx() method is called.

Ondrej

2017-01-18 10:54 GMT+01:00 Pavel Bucek <pavel.bucek_at_oracle.com>:

> Alright :)
>
> After having a chat with Santiago, I tried to prototype "real provider"
> approach, which would result in code like:
>
> Client rxClient = client.register(CompletionStageRxInvokerProvider.class);
>
> CompletionStage<UserPojo> cs =
> rxClient.target("http://foo.bar" <http://foo.bar>)
> .request()
> .rx(CompletionStage.class)
> .get(UserPojo.class);
>
> (let's not talk about built-in support for CompletionStage and consider
> this as a valid extension, provided by CompletionStageRxInvokerProvider
> registered to the client).
>
> The major change here is the "rx" method signature, which would be:
>
> public interface Invocation { // ...
>
> public static interface Builder extends SyncInvoker { // ...
>
> public <T> RxInvoker<T> rx(Class<T> clazz); } }
>
> The major change here is the return type. It is no longer T ? extends
> RxInvoker, it is RxInvoker<T>. And that brings and issue I don't know how
> to deal with. To be able to do the example code (first code snippet), we'd
> need something like:
>
> public interface RxInvoker<T> {
> // ...
>
> public <R> T<R> get(Class<R> responseType); }
>
> Problem is that this is not a valid Java syntax. We simply cannot do T<R>.
> Let's compare that to previous proposal:
>
> public interface Invocation { // ... public static interface Builder extends SyncInvoker {
>
> // ...
> public <T extends RxInvoker> T rx(Class<? extends RxInvokerProvider<T>> clazz);
>
> } }
>
> public interface RxInvoker<T> {
> // ... public <R> T get(GenericType<R> responseType);
>
> }
>
> The main difference (and the reason why it works) is the return type if
> Invocation.Builder#rx(..) is an instance of subclass of RxInvoker, not of
> a RxInvoker<T>. That allows to override return type of RxInvoker#get(..)
> method, exactly as it is done in CompletionStageRxInvoker:
>
> public interface CompletionStageRxInvoker extends RxInvoker<CompletionStage> {
> // ...
> @Override public <T> CompletionStage<T> get(Class<T> responseType);
>
> }
>
> Does anyone know how to solve this issue? (because if not, I don't see how
> we can design/support "real provider" case). I'm looking forward to any
> comments. If you want to play with latest change, feel free to clone [1],
> the example is [2], Invocation.Builder#rx [3] and RxInvoker [4]. Thanks and
> regards, Pavel [1] https://github.com/pavelbucek/jax-rs [2]
> https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-
> api/src/test/java/javax/ws/rs/core/RxClientTest.java#L110 [3]
> https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-
> api/src/main/java/javax/ws/rs/client/Invocation.java#L338 [4]
> https://github.com/pavelbucek/jax-rs/blob/rx-client/jaxrs-
> api/src/main/java/javax/ws/rs/client/RxInvoker.java#L86
> On 17/01/2017 17:41, Ondrej Mihályi wrote:
>
> +1
> 2017-01-17 16:57 GMT+01:00 Santiago Pericasgeertsen <
> santiago.pericasgeertsen_at_oracle.com>:
>>
>> On Jan 13, 2017, at 6:19 PM, Ondrej Mihályi <ondrej.mihalyi_at_gmail.com>
>> wrote:
>> Actually, I like the unwrap method more than the current proposal. It
>> makes it explicit what I want to get when I write code. The current
>> proposal is similar, but requires me to remember the name of the invoker on
>> top of the rx interface I want to get.
>> Compare:
>> *Current proposal *
>>
>> CompletionStage<List<String>> cs = client.request()
>> .rx(CompletionStageRxInvokerProvider.class)
>> .get(new GenericType<List<String>>() {
>> });
>>
>> Perhaps we should explore turning this into a "real provider”. I.e.,
>> something that is registered in the runtime and looked up by the JAX-RS
>> implementation. In which case, the param to rx() could be
>> CompletionStage.class instead. This would be more inline with, say,
>> ParamConverters.
>> — Santiago
>>
>