Especially Project Loom. Virtual threads will be a game changer. A return to original Java's rallying cry of programmer productivity.
There's always been steady progress, sure. But it seems like Oracle is much less risk adverse. Or maybe the governance changed. Or maybe Sun, IBM, other had been holding back a lot of progress. I'd love to know the backstories. To better inform future efforts.
Regardless, Java today is amazing and rapidly getting better.
There are lots of reasons for the continual stream of innovation but the biggest change has been the 6-month release cadence.
I never really understand this. Tasks and threadpools work great. Are you excited that you can reduce memory usage? I have never been restricted before.
Your answer might be to use async, event-driven IO instead, but the central thesis behind virtual threads is that this is a terrible programming model, and there's no reason the programming language can't help you write your code top to bottom, but still get the desired performance.
https://youtu.be/23HjZBOIshY?t=152
This is good too.
https://archive.fosdem.org/2020/schedule/event/loom/
I'll butcher it, but my TLDR is: Program sequentially, get threading for free. Any blocking calls are now async under the hood.
[1] aka @pron or https://news.ycombinator.com/user?id=pron
The first versions of Java only had green threads. That was a cooperative threading model where only a single OS thread was used and the VM did a context switch while blocking for IO (in essence, every method declared as throwing InterruptedException could potentially context switch).
The mixed model you were talking about is most likely the threading model of Solaris where threads were split into a userspace part and a kernel part. It was possible to configure pthreads so as to use a multiple userspace threads on top of a single kernel thread (in a similar way as green threads worked in Java). It was also possible to run it in a one-to-one configuration or a version where you had a large number of userspace threads mapped to a smaller number of kernel threads. The last model was default in Solaris for a long time.
Eventually it was discovered that kernel threads were so fast in Solaris that there was practically never any benefit to the thread-pool model, and by Solaris 2.6 (I think, it's been a while so I could be wrong about the version) they changed it so that the default thread model was one-to-one.
No. All automagically handled for you. Just write what looks a lot like regular code.
Now, can you change the default behavior? Yes, but now you're on your own.
My impression is that languages such as JavaScript and Go gain more and more track for enterprise software stacks. They are much more multi-paradigm at heart then the Java language could be. I wonder why Java doesn't learn from C++, which reinvents itself every few years. The lambda notation in C++ is really a thing Java could easily have.
Java has had lambda expressions, with what I would describe as cleaner syntax than C++'s, since JDK 8. Is there something I'm missing that C++'s have over Java's?
This has also lead to a lot of Java becoming much more functional, see especially the Stream API[0] (also added in JDK 8). I would say it's much, much easier to write functional-style code in Java than it is in Go.
[0]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/S...
Check out Brian's talk on Stewardship: https://www.youtube.com/watch?v=2y5Pv4yN0b0
I kid!
My bro is a C++ partisan. We've been arguing about this for 25+ years. Every time I'm about to use my crushing grip of reason to submit him, he wiggles free.
He's made a pretty good career from fighting misc compilers over the years. So who am I to judge?
I've just recently been able to upgrade some things to JDK 11.
I got the impression (but please correct me if I'm wrong) that only this year most major libraries got all the kinks worked out for Java 11. In particular, when using them together.
Guice is one that only recently got the nasty (but relatively harmless) warning you get when using it with Java 11 under control.
Java 17 is the next long term support release, so most of us working on longer lived code bases will probably skip all the releases in between. It doesn't seem worth the effort, because if the Java 9 and 10 experience is anything to go by, you will be hunting down issues with Maven plugins, transitive dependencies, and libraries holding back for now all day.
Plus, keep in mind that LTS is a paid service. What appears to be "free LTS" isn't really LTS, but builds of the OpenJDK Updates projects. Those builds serve as the basis for various paid LTS offerings, but in themselves they don't actually maintain the full JDK. OpenJDK Updates just backports stuff from the mainline version. If you're using a component that's been removed from the mainline -- and you probably do or else you'd upgrade -- then that component is not maintained in OpenJDK Updates (so-called "free LTS") because there's nothing to backport from.
The only version that's 100% maintained for free is the current JDK (15 as of today).
By now, I'd say if you depend on a library that still doesn't work on JDK9+ you should replace it, but depending on your requirements that may not be so easy and so some people are still stuck on JDK8.
I have tests that use JSON serialization and deserialization (and then some), and they pass perfectly fine on Java 8 runtime, but fail in exactly same place on Java 11, without recompilation. I have spent some non-zero time trying to get to the bottom, but so far without much luck.
For example, in addition to the module system, Java 9 changed the implementation of some of its XML rendering libraries and caused meaningful behavior changes.
https://github.com/CodeFX-org/java-9-wtf has a list of some of the stuff that broke.
That said, 8 -> 9 was the only really painful transition in my experience. Since then the upgrades have been smoother.
And in the particular case of Java 9, they decided to deprecate several things, and quickly removed them in Java 11 (that is: with less than a year warning, and no warning if you follow only the long-term versions). That includes a lot of J2EE classes which previously came with the JRE, and now became external dependencies (with the most recent version of these external dependencies sometimes having slightly different behavior).
In theory yes.
In practice the plugin and scanning systems the software I use has had a multitude of failures between JDK8 and 11.
That might not sound too important but it has an effect on GC chosen amd obviously how you might have tuned your thread pools.
The only free of charge LTS is the latest java version, all versions n-1, n-2 are out of free support, you can only buy one.
Why is that useful? Because now you can do a switch statement that matches on type:
int getCenter(Shape shape) {
return switch (shape) {
case Circle c -> ... c.center() ...
case Rectangle r -> ... r.length() ...
case Square s -> ... s.side() ...
};
}
As long as Shape is sealed, the compiler can be confident that these are all the possible subclasses of Shape.> The ability to reason clearly and conclusively about permitted subclasses will be realized in a future release that supports pattern matching.
But http://openjdk.java.net/jeps/360 says:
> Release 15
Have they lied to me? Those monsters.
The benefits of enums (as these are referred to in some languages) is that after the safe downcast you have access to the fields and methods of the specific type just by invoking them.
Pattern matching also makes this construct even nicer to use (and I would argue that having one without the other is worse than not having either), but that doesn't seem to be included in the language yet, very probably for good reasons (I just don't follow Java development closely so I don't know about them).
public int countNodes(JsonElement el) {
return switch(el) {
case JsonObject obj ->
obj.entrySet().stream()
.mapToInt(e -> countNodes(e.getValue())).sum()
case JsonArray arr ->
arr.stream().mapToInt(::countNodes).sum()
default -> 1
}
}
[0] https://www.javadoc.io/doc/com.google.code.gson/gson/latest/...Where are these used? Well, they are used in a sense all over the Java language already in the form of methods with checked exceptions, which say in their contract that they return either a successful result or any of the declared errors but nothing else.
Too bad it doesn't appear to be coming in 15 :(
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
It's one more step closer to scala/kotlin/etc.Directly from http://openjdk.java.net/jeps/378:
Another alternative involves the introduction of a new instance method, String::formatted, which could be used as follows:
String source = """
public void print(%s object) {
System.out.println(Objects.toString(object));
}
""".formatted(type);[1] https://github.com/manifold-systems/manifold/tree/master/man...
(Sorry, being somewhat lazy, I could pull up the spec).
> Incidental white space surrounding the content, introduced to match the indentation of Java source code, is removed.
Ultimately the issue isn't the presence or absence of those classes (because they aren't hard to write minimal versions of as a one-off if you need them and can't allow the dependency), it's the pervasiveness of use (or lack thereof) by libraries and especially the standard library.
If Try and Either were added to the Java stdlib tomorrow, the rest of the stdlib would still be stuck throwing exceptions for error propagation, because they can't change the return types of existing methods. The only benefit would be that third-party libraries could feel comfortable enough to use them in their type signatures. But, in practice, most libraries still target Java 8, so I wouldn't hold my breath for that, either.
[0] https://vavr.io
Java still makes the GC work harder than other languages. In some of my testing, idiomatic "microservice" Java code makes ~10x as much garbage per request as equivalent idiomatic Go code. Some of that is the language, and some is just that libraries and frameworks are super allocation-heavy. If the ecosystem can tighten that up, then these great GCs will have even more impact.
While the JVM also has escape analysis, because everything is a pointer the chances of an object escaping is considerably higher.
I'm hoping that when Project Valhalla eventually lands, it'll help greatly with allocations and reduce memory pressure even further.
I'd love to see a jvm or graal implementation of ASAP memory management. The idea generally being having extremely aggressive analysis on your code, reducing heap allocations where possible, statically managing objects where they can provably infer object lifetimes, reference counting everything left over that provably can't result in cycles, and then garbage collecting everything else.
Much to the chagrin of Martin Thompson, even the standard library is affected. Avoiding allocations is something most Java programmers don't even think about, because they are not aware it might be an issue and because there is no alternative - in Go and Rust you can stack-allocate instead, in Java you can't (not really).
Do you mean this?
ASAP: As Static As Possible memory management
This is interesting. I skimmed some introductory parts of https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-908.pdf as well as the definition of the SCAN function and searched the PDF for "reference count" to see how it does what you propose. At the moment I don't have the impression that ASAP dynamically reference counts anything. Let alone selectively reference count certain objects but use a tracing GC for others. Could you tell me where exactly to look for details? Wouldn't references from RC objects to GC objects, and vice versa, be an absolute pain to deal with?
A lot of my recent projects have actually been fairly modest in terms of memory requirements compared to a few years ago where I'd have thought nothing of using 4GB heap on a simple spring app.
You want an List<T> of objects? It's now a list of pointers to individual allocations. You want a Path class instead of just passing strings around, for type safety? One extra allocation per object.
anybody know why a javascript engine was ever included in core java in the first place? seems... niche. and yet core java never included a simple web server (officially).
GraalVM offers interop between JavaScript, Python, Ruby, R, C/C++ and of course Java and other JVM languages.
I think GraalVM has the potential to make the JVM something of a universal platform. I guess that was the goal with Nashorn as well, but now it seems much closer to fruition.
In my limited experience writing web code, the client side concerns itself with rendering and user interaction, the server side concerns itself with efficiently supplying dynamic data to the client, and other than request payload definitions the two have no logic in common.
In practical terms, unless you want to test out Java features (which can be removed with the next release), you only need to track the LTS-releases every 3 years and actively upgrade every 6 years to stay on a supported version.
I've been writing Java for longer than I've been driving, and way longer than drinking actual java. Geez. There's a certain fluency I have with this language that I don't have with any other language, not even Python/PHP/JavaScript/C#, all languages that I have 1k+ hours experience in.
Release GA Date Premier Support Until
11 (LTS) September 2018 September 2023
12 (non‑LTS) March 2019 September 2019
13 (non‑LTS) September 2019 March 2020
14 (non‑LTS) March 2020 September 2020
15 (non‑LTS) September 2020 March 2021
Ref https://www.oracle.com/java/technologies/java-se-support-roa...https://openjdk.java.net/jeps/381
Wow this is the end of an era.