users@jax-rs-spec.java.net

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

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Wed, 18 Jan 2017 15:32:06 +0000

If the current syntax stays then it would only be a problem for
non-default RxInvokers, rx() alone would still cover for CompletionStage.

I like the new option too (JAX-RS specific TypeLiteral can be added
easily), but the question here is how .rx(CompletionStage.class) will
find the actual provider.
Losing the ability to offer RxInvoker-specific extension methods is
probably not a big deal ?

Sergey

On 18/01/17 15:18, Ondrej Mihályi wrote:
> 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
> <mailto: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 Builderextends SyncInvoker {
>
> // ...public <T> RxInvoker<T> rx(Class<T> clazz);
> }
> }
>
> The major change here is the return type. It is no longerT ?
> 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 Builderextends 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 CompletionStageRxInvokerextends 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
> <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
> <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
> <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
> <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
>> <mailto:santiago.pericasgeertsen_at_oracle.com>>:
>>
>>> On Jan 13, 2017, at 6:19 PM, Ondrej Mihályi
>>> <ondrej.mihalyi_at_gmail.com <mailto: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
>>