Skip to content

Create RS <-> JDK9 bridge jar #294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
viktorklang opened this issue Nov 2, 2015 · 27 comments
Closed

Create RS <-> JDK9 bridge jar #294

viktorklang opened this issue Nov 2, 2015 · 27 comments

Comments

@viktorklang
Copy link
Contributor

Reactive Streams are available in JDK9 inside: java.util.concurrent.Flow.
Providing converters between org.reactivestreams.* and java.util.concurrent.Flow.* would be quite useful.

I propose to add a subproject/jar to the reactive streams project.

@akarnokd
Copy link
Contributor

akarnokd commented Nov 2, 2015

Sounds good but IDE support for JDK 9 is limited, at least Eclipse can't properly use a JDK 9 installment. Same may be true with travis: no oraclejdk9 yet therefore some sudo trickery may be required.

@viktorklang
Copy link
Contributor Author

@akarnokd That's a good point, it ought to be possible to install the jdk9 from java.net and compile-package-publish locally.

@ktoso
Copy link
Contributor

ktoso commented Nov 2, 2015

Figuring out how to use JDK9 with gradle may be tricky as well, though there is some support coming already https://github.com/gradle/gradle/blob/master/design-docs/jdk9-support.md
I gave it a shot for an hour but wasn't yet able to make it work yet, needs some more research how to use it.
Help from gradle gurus would be most helpful I guess :)

@viktorklang
Copy link
Contributor Author

I wonder if sbt will be able to use jdk9 OOTB.

@ktoso
Copy link
Contributor

ktoso commented Nov 3, 2015

I wonder if sbt will be able to use jdk9 OOTB.

Currently I don't think it will...

And it's a bit more than "using jdk9", we need to be able to compile module-info.java into module-info.class, AFAICS this needs additional command line params, for javac to know where to look for modules. Here's a sample project and how to use javac to compile: https://github.com/ktoso/jdk9-module-sandbox

@smaldini
Copy link
Contributor

smaldini commented Nov 3, 2015

Good idea we already do that with reactor and it actually passes the normal TCK: Publishers.convert(Flow.Publisher) (not sure the other way is that useful). That would be great to get that in some common jar indeed. However I failed a few tests with SubmissionPublisher so worth having a common look!

Sent from my iPhone

On 2 Nov 2015, at 8:43 p.m., Viktor Klang (√) [email protected] wrote:

Reactive Streams are available in JDK9 inside: java.util.concurrent.Flow.
Providing converters between org.reactivestreams.* and java.util.concurrent.Flow.* would be quite useful.

I propose to add a subproject/jar to the reactive streams project.


Reply to this email directly or view it on GitHub.

@akarnokd
Copy link
Contributor

akarnokd commented Nov 3, 2015

However I failed a few tests with SubmissionPublisher so worth having a common look!

Is there something wrong with SubmissionPublisher?

@akarnokd
Copy link
Contributor

Here is a single utility class that does the conversions.

@viktorklang
Copy link
Contributor Author

Nice one, David!

It would be useful having the converters also introspected the parameters
to avoid nesting.

if (rsPublisher instanceof Flow.Publisher) return
(Flow.Publisher)rsPublisher;
else …

On Wed, Nov 11, 2015 at 4:58 PM, David Karnok [email protected]
wrote:

Here is https://gist.github.com/akarnokd/8f1a3e31882c076c704f a single
utility class that does the conversions.


Reply to this email directly or view it on GitHub
#294 (comment)
.

Cheers,

@akarnokd
Copy link
Contributor

If one implements both APIs, it should show up in the type and there is no need to call the conversion methods.

@viktorklang
Copy link
Contributor Author

toFlow(toReactive(flowA)) should return flowA

Cheers,

On 14 Nov 2015 15:21, "David Karnok" [email protected] wrote:

If one implements both APIs, it should show up in the type and there is no
need to call the conversion methods.


Reply to this email directly or view it on GitHub
#294 (comment)
.

@akarnokd
Copy link
Contributor

In this case, toFlow has to check if Publisher is the bridge's own type, look into it and extract the original flow. This is not available with the current lambda form. Since both wrappings are really thin, it doesn't really matter if one goes instanceof + cast or let the JIT inline the calls.

@viktorklang
Copy link
Contributor Author

Does the HotSpot JIT inline N-level nestings? And how would it trace this
when you pass the instance around?

On Sat, Nov 14, 2015 at 3:54 PM, David Karnok [email protected]
wrote:

In this case, toFlow has to check if Publisher is the bridge's own type,
look into it and extract the original flow. This is not available with the
current lambda form. Since both wrappings are really thin, it doesn't
really matter if one goes instanceof + cast or let the JIT inline the calls.


Reply to this email directly or view it on GitHub
#294 (comment)
.

Cheers,

@akarnokd
Copy link
Contributor

By default, HS inlines something like 20 levels deep as far as I remember but this can be increased with command line parameters. But why would you want to have such pass-through wrap-unwrap in a codebase? I think the dev should recognize this as being unnecessary and simply not do it.

@viktorklang
Copy link
Contributor Author

Having written a couple of these converters in the past, you'll be amazed
how people use them. Having things end up like a N-level nested data
structure which could be prevented with a simple branch is a cheap price to
pay in order to avoid some pretty weird error reports. :)

On Sat, Nov 14, 2015 at 8:27 PM, David Karnok [email protected]
wrote:

By default, HS inlines something like 20 levels deep as far as I remember
but this can be increased with command line parameters. But why would you
want to have such pass-through wrap-unwrap in a codebase? I think the dev
should recognize this as being unnecessary and simply not do it.


Reply to this email directly or view it on GitHub
#294 (comment)
.

Cheers,

@He-Pin
Copy link

He-Pin commented Nov 14, 2015

@akarnokd It is needed,as you can take a look at the ForkJoinPool 's code.

@akarnokd
Copy link
Contributor

Fine, I've updated the bridge to do the checks, casts and unwrapping if necessary.

@viktorklang
Copy link
Contributor Author

@akarnokd Excellent! Thank you

@viktorklang
Copy link
Contributor Author

@akarnokd Would you like to contribute it to reactive-streams-jvm?

@akarnokd
Copy link
Contributor

Sure.

@viktorklang
Copy link
Contributor Author

Fantastic! Would you mind opening a PR?

@akarnokd
Copy link
Contributor

I know very little about Gradle, subprojects or how to setup a JDK 9 environment.

@viktorklang
Copy link
Contributor Author

Same here, but having a PR means that more people can help out.
Collaborating via Gists is slightly less fun :)

On Sat, Nov 21, 2015 at 10:15 PM, David Karnok [email protected]
wrote:

I know very little about Gradle, subprojects or how to setup a JDK 9
environment.


Reply to this email directly or view it on GitHub
#294 (comment)
.

Cheers,

@akarnokd
Copy link
Contributor

akarnokd commented May 9, 2017

There is already a bridge PR waiting for Java 9/Travis/Gradle to be operational.

Also implementing both interfaces at the same time causes ambiguities, plus requires internal bridging if you don't want to duplicate logic.

interface MixPublisher<T> extends 
org.reactivestreams.Publisher<T>, java.util.concurrent.Flow.Publisher<T> { }

interface MixSubscriber<T> extends
org.reactivestreams.Subscriber<T>, java.util.concurrent.Flow.Subscriber<T> { }

MixPublisher<T> p = ...
MixSubscriber<T> s = ...

p.subscribe(s);
 ^               
  ambiguous overload

@rotilho
Copy link

rotilho commented May 9, 2017

Sorry I deleted my previous comment by mistake. I already took a look however add the bridge IMO will make things more complicate. My idea is make the reactive-streams extends the java9 classes, like

interface Publisher<T> extends Flow.Publisher<T> {}

and release a new module with org.reactivestreams:reactive-streams-java9

In this way we are not going to have ambiguities and it will allow all current implementation compatible with java 9 if running in java 9 environment.

The downside it will be the dependency management.

@viktorklang
Copy link
Contributor Author

@rotilho That solution will not fly: jigsaw will choke on it and it will create classpath-order issues.

@viktorklang
Copy link
Contributor Author

Awesome to be able to close this issue, @akarnokd! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants