react + java 8

35 views
Skip to first unread message

Andres Q

unread,
Nov 7, 2017, 10:00:19 AM11/7/17
to pl...@googlegroups.com
Hello all,

Out of curiosity (and some boredom) I took a morning off and updated
React to Java 8.

Most of it was straightforward, although I took a significant decision
by making Slot a functional interface so that it can be created by
just a lambda, but it complicates things when a method requires a
Listener and the caller wants to pass a Slot (it needs casting).

Anyhow, the code is at
https://github.com/tulsidas/react/commit/c281913588b63b8edfc6529b5e16372ab6734638

Any feedback is welcome!

Andrés

Michael Bayne

unread,
Nov 9, 2017, 11:54:55 AM11/9/17
to pl...@googlegroups.com
Cool. I did some work a while back to make things more lambda friendly. Mainly in this commit:


But there were a couple of TODOs left in which were necessary to keep things working well on Java 7.

It was a long time ago, so I don't remember the exact details, but I think Slot would just go away in a lambda-based world. It only exists to make it easier and less verbose to create ValueView.Listener and SignalView.Listener instances. But that's not a problem with Java 8 because you just use -> notation to create them with no boilerplate.

Anyway, slim chance that I'm going to drop support for Java 7 in React any time soon, so we have to live with the crufty old Java 7 compatible approach for longer. :)

I guess I could do a React 2.0 release that was Java 8 only and maintain the 1.x branch with any fixes/additions for Java 7. Maybe I'll do that.

--

---
You received this message because you are subscribed to the Google Groups "PlayN" group.
To unsubscribe from this group and stop receiving emails from it, send an email to playn+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Andres Q

unread,
Nov 9, 2017, 12:00:40 PM11/9/17
to pl...@googlegroups.com
I did a new commit which effectively deleted Slot and renamed
SignalView.Listener to it

https://github.com/tulsidas/react/commit/465c5f20b3012d6544fb685a3fad0a2e5b42c1be

What I *don't* like at all is that whenever a method takes a
ValueView.Listener and you want to supply a lambda, you need to cast
the lambda to Slot if you want to use the 1 parameter version

I couldn't find a nice way around that yet

Michael Bayne

unread,
Nov 10, 2017, 10:50:09 PM11/10/17
to pl...@googlegroups.com
Inspired by your 1.8 experiment, I did my own, converting React, PlayN and TriplePlay all over to 1.8 idioms (which would abandon Java 1.7 if adopted):


I took the opportunity to tidy some things up, most of which is probably not going to impact anyone. The only likely migration pain point is that I removed UnitSlot because it's harder to support that kind of arity overloading with lambdas. It's pretty easy to write:

  button.onClick(b -> { body of handler which ignores b })

so I don't feel like it's a terrible burden not to have an "argument forgetting" version of slot.

The way I structured things avoids the need to cast ValueView.Listener to Slot when you don't care about the second argument. So you can write:

  someValue.connect((newValue, oldValue) -> ...);

or

  someValue.connect(newValue -> ...);

and no casts are necessary. Not sure why you ran into that problem.

Anyhow, I'm wondering if this is worthwhile to move forward with. All of the supported backends support Java 1.8, so in theory this shouldn't cause trouble, but if the majority of (the dwindling number of) PlayN users are still forced to use Java 1.7 for some reason or other, I don't want to cause them a bunch of pain just for the joy of simplifying a bunch of code.

The diffs tell the tale of all the boilerplate that goes away:

React:
 33 files changed, 349 insertions(+), 908 deletions(-)

PlayN:

 38 files changed, 507 insertions(+), 740 deletions(-)


TriplePlay:

 56 files changed, 267 insertions(+), 502 deletions(-)


If I do go forward with this, I'll publish the 1.8-only code as React 2.0 and PlayN/TP 2.1, and I'll try to backport any important fixes to the React 1.x, PlayN/TP 2.0.x branches, with releases for those as appropriate.

So anyone who would be greatly pained by being stuck on old releases because they have to use Java 1.7, let me know.

Otherwise I'll probably go ahead with these lambda funs. I'll probably update and ship an old game with all the new stuff just to make sure that the full pipeline isn't hampered by requiring 1.8, but AFAIK Android tools are OK with 1.8 finally, and RoboVM thankfully had full 1.8 support before spiraling into oblivion.

Andrey Kleshchenko

unread,
Nov 11, 2017, 4:03:23 AM11/11/17
to PlayN
Wow. Great stuff!

Thank you!

guille.r...@gmail.com

unread,
Nov 14, 2017, 8:26:44 AM11/14/17
to PlayN
On Saturday, November 11, 2017 at 4:50:09 AM UTC+1, Michael Bayne wrote:
Anyhow, I'm wondering if this is worthwhile to move forward with. All of the supported backends support Java 1.8, so in theory this shouldn't cause trouble, but if the majority of (the dwindling number of) PlayN users are still forced to use Java 1.7 for some reason or other, I don't want to cause them a bunch of pain just for the joy of simplifying a bunch of code.
[...] 
 
If I do go forward with this, I'll publish the 1.8-only code as React 2.0 and PlayN/TP 2.1, and I'll try to backport any important fixes to the React 1.x, PlayN/TP 2.0.x branches, with releases for those as appropriate.
 
So anyone who would be greatly pained by being stuck on old releases because they have to use Java 1.7, let me know.

Otherwise I'll probably go ahead with these lambda funs. I'll probably update and ship an old game with all the new stuff just to make sure that the full pipeline isn't hampered by requiring 1.8, but AFAIK Android tools are OK with 1.8 finally, and RoboVM thankfully had full 1.8 support before spiraling into oblivion.

I am not in the "stuck with Java 1.7" group but I have two concerns.

1. For (live) projects that are using the current versions of the libraries, I guess there are two options: Either migrate to the new 1.8-only libraries, or to stick with the React 1.x, PlayN/TP 2.0.x branches. Depending on the state of the project (how large is the codebase, available resources, deadlines etc), option 1 might be far from ideal. Option 2 on the other hand means the project will be stuck on branches that (I assume) will see less and less updates over time, as (from your comments) only important fixes will be backported.

2. You mention backends have now good Java 1.8 support but this has not always been the case. So there's always a risk of exposing new problems and bugs.

Obviously none of the above is a showstopper but still I wonder, is this worth the trouble? What is the actual problem being solved?

Best,

Guillermo

Michael Bayne

unread,
Nov 15, 2017, 7:14:10 PM11/15/17
to pl...@googlegroups.com
Such pessimism! :)

The problem being solved is the same problem that motivated the Java 1.8 improvements in the first place. There are myriad places where it is much less cumbersome to use lambdas than anonymous inner classes. This is especially true when writing code with React.

From my perspective, neither branch of the libraries is going to see a huge number of changes, so the downside to someone staying with the 1.7 versions of the libraries is effectively zero. React, PlayN and TriplePlay are very stable and none of them are under active development, so it's not like someone will be missing out on major new features.

It is true that migrating to the 1.8 versions of things could be a pain for large code bases, but the 1.7 versions aren't going away. I just don't want people who are starting a game today to have to use a version of Java that is six years old and to have to miss out on the joy of the many ergonomic improvements provided by Java 1.8.

It doesn't sound like there are many other opinions coming out of the woods, so I'll probably go ahead with this migration.

--

---
You received this message because you are subscribed to the Google Groups "PlayN" group.
To unsubscribe from this group and stop receiving emails from it, send an email to playn+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Michael Bayne

unread,
Nov 15, 2017, 9:03:05 PM11/15/17
to pl...@googlegroups.com
Ha, well, that plan was dashed on the rocks. Both Android and RoboVM are running into problems with the 1.8 code.

On Android (where I had previously always used Retrolamda, so this was my first attempt to get the native toolchain to actually process 1.8 bytecodes), it fails claiming that invokedynamic is not supported. In theory it is supposed to 'desugar' these calls into anonymous class instantiations, but for some reason Dex is failing to do so.

RoboVM fails to include the entire java.util.function package, which I was using with the new React code. RoboVM does support lambdas (and I've used them directly) but apparently they never included that package.

I could probably actually get a patch into RoboVM to add java.util.function from the Harmony project where they got the rest of their Java core classes. But Android requires API level 24 or higher to use java.util.function, which is a pretty onerous requirement since only 20% of devices have >=24 installed.

Oh well...


--

guille.r...@gmail.com

unread,
Nov 16, 2017, 3:33:33 AM11/16/17
to PlayN
Hi Michael,


On Thursday, November 16, 2017 at 3:03:05 AM UTC+1, Michael Bayne wrote:
Ha, well, that plan was dashed on the rocks. Both Android and RoboVM are running into problems with the 1.8 code.

On Android (where I had previously always used Retrolamda, so this was my first attempt to get the native toolchain to actually process 1.8 bytecodes), it fails claiming that invokedynamic is not supported. In theory it is supposed to 'desugar' these calls into anonymous class instantiations, but for some reason Dex is failing to do so.

Isn't desugaring actually done by a separate 'desugar' tool which runs before dex?
 

RoboVM fails to include the entire java.util.function package, which I was using with the new React code. RoboVM does support lambdas (and I've used them directly) but apparently they never included that package.

I could probably actually get a patch into RoboVM to add java.util.function from the Harmony project where they got the rest of their Java core classes. But Android requires API level 24 or higher to use java.util.function, which is a pretty onerous requirement since only 20% of devices have >=24 installed.

Uh, that's not good.

Guillermo

Michael Bayne

unread,
Nov 16, 2017, 11:42:05 AM11/16/17
to pl...@googlegroups.com
On Thu, Nov 16, 2017 at 12:33 AM <guille.r...@gmail.com> wrote:
Isn't desugaring actually done by a separate 'desugar' tool which runs before dex?

So it seems. I assumed it was built into Dex. I suppose then the Maven Android Plugin is just not running desugar when it should, and looking at the commit history of the plugin it makes no mention of adding desugar, so that's probably the case. I'll file an issue, but I don't think I'm motivated enough to add support myself.

I'd rather put the effort into making a template Gradle build for PlayN games, since libGDX moved to Gradle a while ago and I've had to manually keep the RoboVM Maven plugin working because the guys who maintain that don't use it.

I could also just move React back to react.Function and not use java.util.function which would then solve the Android API >=24 problem and the RoboVM problem, which would make all of this feasible for people who used Gradle to build their games.

Maybe I'll just do that and leave it in a branch and ambitious people can play around with it. I've far exceeded my budget of time lying around to fool around with PlayN stuff.
--
Reply all
Reply to author
Forward
0 new messages