94 comments

[ 2.9 ms ] story [ 173 ms ] thread
I don't see anything in there about improving interoperability with native code. Years ago there were discussions of a project to do that. Maybe that is dead - perhaps everyone interested in native code interop has already moved on.
Or value types, which would remove some of the need for native code(yes yes, I know it's coming in Java 10 which means we'll see it in 2030 or so).
C++ devs are still waiting for concepts and modules as well.

Waiting for features is not unique to Java.

Really? I'm certainly not waiting for those. If I'm using C++ it's to go wide across platforms or for performance and none of those help me much in that area.
It is planned for Java 10.

I bet Java 10 is probably going to be released earlier than ANSI C++ finally gets modules or concepts finalized.

> underscore character is reserved. A variable can no longer be named only '_'

Huh.... I wonder why that is?

To introduce pattern matching in the future?
Wildcard pattern? Wildcard variable? Dummy placeholder?
Why didn't they just use OSGi, a stable, mature (16+ years old) technology for modularity, instead of re-inventing the wheel with JPMS?
i have used OSGI in projects and find it useful to see bundles states, Camel routes/endpoints, lot's of other useful stuff. But i have never seen it working properly in PROD enterprise application. Sadly my eclipse is just confirming that from time to time with errors :(
I know. OSGi needs to die. I'll quit a job before I subject myself to that level of pain and despair ever again.
Sorry for the easy jab, but is there anything from Eclipse that is good ?

ps: user and ex plugin developer asking

CDT used to be quite good, and there are some features like makefiles and debugging capabilities that are missing from CLion.

And actually it does use less resources than either InteliJ or Android Studio, while having faster builds.

Android Studio's minimum-resource-usage-for-sane-performance is enormous. It does some things nicer than Eclipse, but there are definitely times I miss Eclipse's lean-ness, which is not a thing I would have expected myself to ever feel prior to AS.
Oh right I forgot CDT. The key to Eclipse's success.
The IDE is good. Eclipselink is fine.
I felt it was hog, slow, and the interal API is a maze. Also the virtual fs layer ...
It's big and slow, agreed, but it is very powerful. I don't know the details of the virtual FS layer but I can sympathise because that's very difficult to get right in a cross-platform way.
I don't think it's powerful. As fanatic as it seems, emacs is more powerful for real work. It's more human and more theoretical than Eclipse, which is a "usine a gaz" more than anything. It doesn't bring performance, nor ease of use, or stability. I don't get it.
The graphical views are useful, and the wide range of plugins comes in very handy. I could never get on with the emacs interface - it just wasn't discoverable enough - YMMV I guess.
Discoverability in emacs is a tiny bootstrap problem. I have to admit that for years I didn't know how to ask emacs, but when you do (C-h m, C-h k), there's no more discoverability problem.
Jetty? OpenHAB?
Did Jetty start as an Eclipse project or was it swallowed recently ? I thought it was apache incubated.

  But i have never seen it working properly in
  PROD enterprise application.
FWIW, I have programmed for and deployed OSGi-based enterprise solutions. Karaf[0] was the container using Felix[1] most of the time (Equinox[2] being the other for a brief period). These are/were production systems, so I am curious by what you experienced as "never seen it working properly in PROD ..."

0 - https://karaf.apache.org/

1 - https://felix.apache.org/

2 - https://www.eclipse.org/equinox/

Because OSGi is a pile of needless complexity for selling consulting support, the less I have to touch it the better.
Aren't you an IT consultant though? ;-)
Yes, but getting to do JEE and stuff like Websphere is already enough, I don't need to fight with OSGi as well. :)

Having written a few Eclipse plugins was already enough.

Don't let Eclipse give you a bad impression of OSGi.

There are now some very cool things that make starting a new OSGi project a lot easier:

* Declarative Services, for simplifying Component definitions (No more editing XML)

* bnd / bndtools for building your OSGified jar (No more manually editing the Manifest)

Ok, but do you think JPMS is a better alternative?
> OSGi, a stable, mature (16+ years old) technology

And hardly used in industry beyond eclipse project.

I used to work for a robotics company that made heavy use of OSGi.

We also wrapped OSGi in a services framework we created (and by that, I mean my boss wrote it, and then I added some features and bugfixes later), which we open-sourced.

What's really cool is that the Flow stuff from the article resembles a publish/subscribe library that we wrote and also open-sourced (under the name JFlux, even), which in turn was built on some interfaces that bear a resemblance to the Java 8 functional interfaces, except written for Java 6.

I don't think that this is true: OpenHAB, Nexus 3, a lot of the enterprise application servers... One can probably compile a pretty long list of things "running in production" using OSGi.
TBH, that's not the right question. I'd argue the right question was why didn't they make Jigsaw Maven-compatible?
TBH, that's not the right question. I'd argue the right question was why didn't they make Jigsaw Maven-compatible?
Simple, but I am most excited to see a REPL here -- JShell. I have written so so many Tester classes when I just wanted to run a few lines of java.
I used the Groovy shell for this. Since Groovy is Java, you can paste Java code into the Groovy REPL and it works fine.
> Since Groovy is Java, you can paste Java code into the Groovy REPL and it works fine

Did you mean Java 7 and previous versions? You certainly can't paste Java 8 code into the Apache Groovy REPL if it has lambdas because Groovy hasn't been updated for Java 8, not to speak of the new features in Java 9. My guess is the sad state of the Groovy ecosystem is probably why Oracle even created JShell.

In fact, you can't even paste Java 7 code in there and have it behave the same because of lots of little incompatibilities like the meaning of the == operator. Every Java developer should know never to paste Java code into a Groovy REPL and rely on the result for testing purposes.

Groovy isn't Java. Like Java, Groovy generates JVM code, though it typically runs slower than Java code because Groovy is a dynamically-typed language. Although it added annotations for static typing into Groovy 2, they don't work for bulk code, only isolated test cases, and the latest versions of Groovy are still written in Java, not statically-annotated Groovy.

All of this is super cool but what I really want is async/await. Every day I wish I had it. I know everyone has some pet thing they want, but I can't imagine async/await being nothing short of a game changer for Java. Why is it never mentioned? Will it ever happen?
I can only guess, but it is in general very difficult to retrofit what is essentially green threading, coroutines, and continuations into a runtime that was built without those features. Scala has tried at least a couple of times, and as is typical of the language and community, has come up short as the original contributors lost interest or decided the problem was too hard. This includes:

* Scala's CPS compiler plugin, now deprecated and unmaintained.

* Macro-based async/await library. It's neat but has many more limitations than C#'s equivalent or Kotlin's, and hasn't had any updates in a couple of yaers.

It looks like Kotlin has recently added experimental support for async/await. That language may be your best bet for now if you want to code in this style on the JVM.

Kotlin supports coroutines/async/await so I'm not sure why you think it would be so difficult to add it to Java.
And it's actually a library, so it should be portable to java
What's the difference between async/await and a future? I've only used futures, but async/await looks like exactly the same thing: You're forking a thread (green or otherwise) to do some stuff and to set a flag of some sort when it's done so you can check on it. Right?
At a high-level, async/await lets you write non-blocking code as if it were blocking. Golang has a huge advantage here because the runtime was built from the ground up so that everything is non-blocking and the language has built-in support for operations that look like they block, but underneath the hood they don't actually block a thread.

Futures are interesting, but at the end of the day they are basically not that different from callbacks. Instead of writing a function that takes a callback, you write a function that returns a future that you essentially register callbacks onto. In Java 8 this type is called a CompletionStage. In fact, in one of Scala's coursera courses they teach you how to take callback-oriented code and convert it into code that returns futures. The fact that it is so easy to convert between the two helps illustrate that futures aren't really adding much. Yes you can compose using flatMap, but, again, I don't think this makes the code that much easier to write, or, more importantly, debug and maintain.

As an example, at $lastjob I converted a blocking networking library to a non-blocking one. I started out using futures but I found that it generated a lot of Lambdas, which made debugging much harder because the stacktraces were long and incomprehensible. I ended up switching to callbacks and used named, not anonymous classes to improve readability. Not only did the code feel easier to read and debug but I got better performance out of the library due to reduced memory pressure.

It's the same but you just write top-down linearly as though all the code is on one stack frame, but the runtime performs the stack continuations when async calls return.

If you're familiar with JS, read about how babel implements ES7's async/await by wrapping promises. And then try it out. It's awesome.

isn't kotlin an option if you want async/await on the JVM ?
I didn't know Kotlin had async/await. Thanks, I will have a look.
Is this the same like following?:

Future<Long> f = executor.execute(() -> myFunc());

Has there been any hints of adding default parameters to Java at some point? It's one of those things I find really useful in Python or C#, but for some reason never seems to find its way into Java.
I second this. Java needs default parameter values.
I am a C# developer. My thoughts:

- I love that they are adding REPL. I really wish C# had this. I use IPython all the time for Python. It is very helpful to mock something up quickly or try out different features.

- Adding private methods to an interface seems very wrong to me. An interface is just a contract without any implementation at all. I am not sure the reason behind this. Aren't abstract classes a thing in Java?

- I was sad to see that they have not included type inference to Java yet. It is just a syntax thing, but it makes writing code feel so much less wordy. Here's an open JEP for it: http://openjdk.java.net/jeps/286

As a long-time Java developer, I really hope they won't implement JEP 286. I think type inference by the compiler is a bad idea, as it results in less readable code, more bugs, and an unnecessary burden on the compiler. I think all the examples where type inference is convenient are trivial cases, but the downsides start to crop up in real-world, large code bases. So it's something that makes the easy things slightly easier and the hard the things harder.

Type inference already happens for you when you are using a good IDE, like IntelliJ IDEA. You can just use the "Introduce Variable" refactoring. And better yet, it self-documents your code with the variable's type.

(comment deleted)
I think you're suffering from Stockholm syndrome. I have never experienced a bug using scala's type inference that could have been prevented by more required boilerplate. Type inference is 100% benefit with zero drawback.

If you really want to know what a type is resolved to, you have both compilers and IDEs there to tell you. Relying on an IDE to write code is just hacking over a weak or broken language.

To be fair, the compiler errors you get with inferenced types will often lead you to write in the types anyway, to ringfence the bugs. Type inference often gives you really messed up error messages when you've done a mistake.
> Less readable code

Maybe it is because we are used to our own paradigms, but the following is no less readable to me because of inference. And these are the 95% of cases.

  var index = 0;
  var name = "pwaivers";
  var names = new List<string>();
  var nameMap = new List<string, Dictionary<int, Address>>();
> more bugs

I have never seen a bug arise because of type inference. Do you have an example?

> unnecessary burden on the compiler

The compiler does a lot of work and this would probably be insignificant to add to it. However, I am totally open to learning more about this.

Yea, I remember the same was said when C# was introducing var, it's a valid concern but in reality it really isn't
The only people I've seen complain much about this were converted VB devs, who mistakenly thought it was shorthand for the godawful VB Variant type, with all of its unintuitive type coercion rules that make JavaScript seem sane.
The examples you've given have direct values. Try:

  var index = getIndexFromSomewhere();
  var name = getHandleFromUser("peter", "waivers")
The type isn't as clear anymore.

*Edit: I'm absolutely a fan of the var syntax, having dabbled with scala. I'm just expressing what I think the original author's complaint is.

>The type isn't as clear anymore.

It doesn't have to be, as the compiler (and linter) will inform of any misuse of the type later on. And any editor worth its salt could even annotate the type right there.

Isn't Java generally considered to be unusable without a decent IDE anyway? I feel like if you need to know what the return type is, the editor should be able to tell you that in these cases.
a) You can optionally include the type if you want. I do this in some rare circumstances where it does create more readable code.

  string name = getHandleFromUser("peter", "waivers")
b) It is usually not necessary to know what the type is while reading code, and if you need to know you can just hover over the variable.
I think the code is much more readable and less annoying with inference. And as for your examples, you don't need to know the types - the compiler will complain if you try and use them inappropriately whether the type was explicit or not.

But the issue you have glossed over is that sometimes there is no nominal type - there is only an anonymous type, as for example returned by a LINQ query using new{}, or via monad-style combinators where you really don't want to see the type for fear of your eyes bleeding.

> I think the code is much more readable and less annoying with inference.

I concur. I've been dabbling with Java a bit again (mainly because of a hobby project in order to learn Clojure) after a pause of multiple years.

It boggles my mind that compiler inference didn't make it into the language yet. Everytime I have to declare a totally obvious type, I cringe.

>As a long-time Java developer, I really hope they won't implement JEP 286. I think type inference by the compiler is a bad idea, as it results in less readable code, more bugs, and an unnecessary burden on the compiler.

It is already the case in lots of languages since 1990s and the sky has not fallen...

It's not a compiler burden because it already has to determine the type of the right-hand side for typechecking purposes. So, the compiler actually does less work in the 'var' case, simply assigning the calculated type to the left-hand side rather than checking against a user-supplied type.
Not really. Without type inference, there's always a pretty short path to the type: For "int x = y" you only have to check that the type of y is int. If you have type inference "int x = y" is a lot harder to validate, because y may have been defined like so "var y = z". So now you have to create some kind of list of variables and their types, start at the ones that are explicitly defined like "int a = b" or "c = 5" and then fill in the types of the rest as you find a reference to the ones you know.
Intellij: View type info [on Mac: Ctrl + Shift + P]. Of any [sub]expression. Whenever you care about that level of detail. On-demand self-documented code.
Rust, ML, Coq and Haskell have type inference and if those four are known for anything it's reliability and bug-free code.
I like the private interfaces thing. It's getting us closer to having "mixin" ability through interfaces. I think if we had "protected" methods, we'd be there (assuming protected methods played nice with interface inheritance).
So at Java 8 they added the ability for interfaces to have default implementations - this was so that the collections API (among others) could be expanded with lots of support for the new lambda features without breaking compatibility.

Allowing private methods means default implementations can be easily refactored to move common code to private methods without those internal methods themselves becoming part of the interface. Yes Java does have abstract types, but multiple inheritance is allowed from interfaces (which aren't structural) but not abstract types so interfaces are very widely implemented across the standard and other libraries.

I did not realize that Java had implementations in interfaces already. This makes perfect sense why they would add the private method then. Thanks for answer!
(comment deleted)
(comment deleted)
Interface methods is an attempt to add traits to Java. I find it especially nice that interface methods are insulated between interfaces. I find traits a much better approach than traditional inheritance.

You can inherit from only one base class; if Java had multiple inheritance, as C++ has, a number of other problems would arise.

on your last point: they did, and it's called Scala. ;)
One additional thing which is missing in the post is that AES-GCM is (finally!!) becoming usable: http://openjdk.java.net/jeps/246

> performance increase is large compared to JDK 8 GA, ranging from 34x to 150x

List<String> list = new ArrayList<>(){ };
Yeah, worst example ever. They should make it harder to make inner anonymous classes, not easier. When such code is used inside JEE/CDI/Spring Beans it leads to some annoying leaks or issues with serialization.
The HTTP/2 client is incubator only [1]. Strictly speaking it's not part of Java 9. But that's not a big deal because ALPN is part of Java 9 so you can use 3rd party clients.

[1] http://openjdk.java.net/jeps/110