return to table of content

Java 22 Released

jimbokun
56 replies
1d

Maybe my favorite feature in this release:

https://openjdk.org/jeps/463

Finally solves the inscrutable Hello World program!

Yes, it's just ergonomics for early beginners. But could be the difference in whether or not someone new to programming sticks with Java or not.

AtlasBarfed
16 replies
23h7m

Java continues to evolve to a bad Groovy.

ulrikrasmussen
8 replies
22h37m

How so? I don't think there are many good things to say about Groovy, but I generally agree with most new features introduced to Java. What do you think Groovy does better?

AtlasBarfed
7 replies
20h42m

- String interpolation

- triple-quote strings / blocks

- minimal class boilerplate (this posting)

- closures (Java closures are worse IMO)

- usable hashbang for UNIX

- I think java has strings in switch now, don't they? Do they have expressions?

WAIT, does Java STILL force you to write getter/setters?

marginalia_nu
3 replies
15h56m

But Java has all those features...?

AtlasBarfed
2 replies
12h12m

Oops, sorry those are features java "stole" from groovy.

Java has the nullsafe operator now and the elvis too, doesn't it?

I don't use the spaceship operator much, implicit sorting works pretty well.

Groovy's closures have a lot less GOTCHAs. They simply work as expected, at least to me. Half the time I use java closures and I get complaints in compilation that I don't get in Groovy, but maybe they've improved closures more.

Groovy's GPars library is the bomb for concurrency/parallelism. I don't know if I could function in normal java constructs.

The .with keyword is a sneaky useful technique where you can declare a piece of data like:

"some cli command" .with { it.execute} .with { /* parse output */ }

It allows chained calls that flow naturally. Groovy generally allows pretty compact flowed calls which makes scripts a lot easier.

Groovy scripting with implicit vars is a lot easier than any java scripting, even with the "simplification" described.

The shorthand access/navigation of nested lists and maps, and the map / list literals (also taken by java at some point I think) are really nice to have. Also a + operator for lists and maps I use a lot

Groovy's ability to generically call methods without mucking through 10 lines of reflection is sometimes nice.

The auto-gen of getter/setters is a must have, I think Kotlin has those too?

CompileStatic lets me selectively use full java speed without groovy overhead.

In general, I like Groovy because it is typing-optional. Python and Javascript suck because they don't really have optional type enforcement. Java sometimes asks for too much typing. Groovy lets me select as needed.

The actual sane = for string assignment and == for sane string comparison is nice.

But honestly, Java with the listed features is a lot better. I'll probably still use groovy for doing what would normally done with bash (UGH) since I have a big CLI/scripting library base that handles argument parsing, json, encode/decode, encrypt/decrypt, zip/unzip, in nice compact syntax.

Groovy is basically a dead language now anyway. The world is overrun by JavaScript and Python, and AI looms to replace us all with horrid AI python or javascript glue code.

marginalia_nu
0 replies
1h58m

Oops, sorry those are features java "stole" from groovy.

Well, yeah? Java's explicit strategy for the last few decades is to let other languages experiment, then implement the ideas that worked out once the dust has settled.

astral303
0 replies
7h29m

You can be really productive, expressive and performant in Groovy. So much of the language still works well with @CompileStatic and doesn’t require dynamic typing. Writing clear code that has decent refactoring support in IntelliJ.

Don’t forget traits! When are we getting traits in Java? Probably never.

Optional semicolons and parentheses to cut the line noise and enable internal DSLs.

Though Java has improved implicit typing with `var` and now we have reasonable lambdas, Java is still not a high-level language, but maybe it is now medium-high.

neonsunset
0 replies
18h35m

Hashbang aside this is a solid description of a base feature set of C# :D

mbfg
0 replies
19h47m

features that make strings easier to use are bad in my opinion. the number one problem in java is people circumventing the type system with strings.

switch on strings is there, as are switch expressions.

records now removes the need for getters in immutable contexts.

jimbokun
0 replies
18h8m

A form of string interpolation is in this release.

bheadmaster
6 replies
22h57m

Groovy itself is a bad Groovy.

AtlasBarfed
5 replies
20h41m

bad opinion is bad

I get gradle is a disaster (but that's more of a poorly managed and evolved DSL problem)

But ... does anyone use Spock and think "groovy sucks"? Yeah, I doubt it.

svieira
3 replies
16h9m

I hate to be "that guy" but ... raises hand.

Spock is also a DSL disaster that's trying to be ScalaTest (https://www.scalatest.org/user_guide/property_based_testing) but in a dynamic language. Every time I use it I have to re-learn the syntax. (I have the same issue with Gradle, so maybe it's just-me?)

bombcar
2 replies
14h51m

My problem with gradle is I never use it enough to get familiar with it, once the problem is solved I promptly forget everything.

AtlasBarfed
1 replies
12h31m

It's the perfect example of a bad DSL.

A "DSL" like SQL that you use hundreds of times a year you'll learn the model of.

A DSL like groovy that you use once for project setup (and for that you'll one-off it likely and stackoverflow the rest of the question) is not. And it isn't really natural, it's a bunch of arcane steps that at the end might superficially look a bit consistent, but still really isn't.

Groovy really needs an autocompleter or a generator. Or, well, as you say, you stackoverflow for everything outside the very vanilla basics of it.

But good luck getting the right version match to the syntax you need. Christ.

ackfoobar
0 replies
8h53m

Having types in Gradle by using the Kotlin DSL, with IntelliJ auto-complete, solves ~80% of that pain.

adl
0 replies
2h5m

Raises hand Here! I have to work with Spock on a Java codebase and I think groovy sucks ;-)

sireat
6 replies
22h37m

Actually a nice feature.

This solves the public static void main string args issue.

Still if I need JVM then Scala or Kotlin are still preferable over Java.

Obligatory Java for the Haters in 100 Seconds: https://www.youtube.com/watch?v=m4-HM_sCvtQ

willsmith72
2 replies
20h49m

I've never seen a java codebase I thought couldn't be better in kotlin

mdaniel
1 replies
18h42m

For reading it, I believe that. For authoring it, yikes it is slow. I'd guess due to all the implicit and implied and coercion and ... and ... and. Now I'm cognizant that I'm running my mouth without trying it on 1.9.x and a similarly recent IJ so maybe it got infinitely better, but my life experience with languages is that they only get more fancy swooshings not QoL improvements due to Moore's Law and yearly refresh cycles

I was/am always glad to pay that tax because non-null-by-default and the vastly superior val/var keyword pairs are totally worth it but it for sure is not a drop-in replacement in team environments. I am already constantly battling the vscoders (to say nothing of vimers) whining that "IJ is too slow for my eeee-leeeet typin'"

Nashooo
0 replies
8h21m

Definitely also for writing it.

blackoil
2 replies
15h52m

Still if I need JVM then Scala or Kotlin are still preferable over Java.

That's so 2010. I would avoid Scala like plague. It is a soup of all features imagined and some more. Java is difficult for novice. With Scala even experienced senior devs can look into a snippet and be befuddled. It is designed by academicians who thought clever looking choice is better.

pregnenolone
0 replies
9h53m

It is designed by academicians who thought clever looking choice is better.

That's just not true. That's the typelevel ecosystem. The official Scala toolkit mostly includes haoyi libraries which is pretty much Python like Scala.

ezst
0 replies
6h23m

About a decade ago, some Scala library authors thinking that "everything is better as a DSL" gave Scala a reputation for being a hieroglyphics soup, but that cannot be farther from the truth today. It's a really nice language to learn and to use, and the only one in my experience that I would want to take with me to scale from a quick dozen-liner script bash-style to a highly concurrent, highly available server application, from native to jvm to JS.

And the foothold in academics has some practical perks, too, like a sound type system (DOT calculus), compatibility guarantees at a theoretical level (TASTy), and what's cooking in the area of capture checking might be a general solution to many of the industry's biggest challenges (e.g. colorless asynchronous programming, safe errors, safe resource management, ... Think of Rust's borrow checker as a special case of this, and the consequences for scala-native as a systems programming platform).

masfoobar
4 replies
8h4m

I really disliked this the first time I saw it. I was like "WTF is this?"

I can only think the reason why they did this was to compete with python, as our scripting languages that do not require a main/Main entry point.

Personally, it just feels wrong for compiled-based languages.

I think they could improve on C# with their namespace. Rather, for example, a typical C# file looking like:-

  using EFG;
  namespace ABC
  {
    public class XYZ
    {
     
    }
  }
They could just :-

  using EFG;
  using namespace ABC;
  public class XYZ
  {
    
  }
Pretty much taken from the C++ way.. but it saves on space availability.

sfn42
1 replies
7h55m

Namespace declarations have been a thing in C# for a while

masfoobar
0 replies
7h46m

Yep. Point is it should have been added since Framework 4.

neonsunset
1 replies
7h52m

The second option is what C# defaults to since a few versions ago.

masfoobar
0 replies
7h47m

Correct -- was added since .net 6, I believe.

aembleton
4 replies
22h19m

Maybe in another ten years they'll remove System.out.println and allow for a simple println to be used.

Or maybe we'll all move to Kotlin by then.

chopin
1 replies
21h27m

You can statically import System.out if you are so inclined.

aembleton
0 replies
20h0m

You can but for a new user that is even more of a barrier than writing out System.out.println

pjmlp
0 replies
10h41m

And create the Kotlin Virtual Machine, with a Kotlin based ecosystem?

lotsoweiners
2 replies
23h10m

That sounds a lot like Top-level Statements in the .Net world. Personally I don’t use that feature because I’m old and get confused if things are magic but can certainly see the benefit for the newer devs.

starik36
0 replies
23h5m

Yeah, no doubt inspired by the .NET feature. I use it all the time for throwaway console apps.

jonathanlydall
0 replies
4h55m

I’m also a somewhat old school C# dev and the main reason I don’t use top level statements is that they only work in a single file of an application, so that single file is different from every other file in your solution.

It’s okay if you’re only writing a single file, and it really seems intended for beginners or micro applications, but for those of us writing anything besides the most trivial, it’s merely “cute” and just adds inconsistency.

int_19h
2 replies
22h52m

They almost caught up with C#, which ditched requisite class declarations years ago. Although C# went one step further and allowed top-level code outside of methods, so that hello world is now:

   Console.WriteLine("Hello, world!")

johnyzee
0 replies
22h32m

You can write write code outside of methods in a Java class, called an initializer block:

  class MyClass {
    {
      System.out.println("Hello World!");
    }
  }
This will run when an object of the class is instantiated. So not useful for the case in question (you could get rid of the class declaration but would presumably still need a main method).

(It's also pretty poor style, but occasionally useful in a pinch, like when instantiating an anonymous inner class, which has no constructors that take arguments)

TillE
0 replies
22h48m

It has been a few years, but top-level statements in C# are still a fairly recent thing (C# 9 in 2020).

okeuro49
1 replies
7h26m

I really dislike this feature.

It's better to just say "we will come to this concept later", rather than make a fake syntax that does this (taken from the JEP) behind the scenes:

new Object() { // the implicit class's body }.main();

It adds more confusion, as you are left explaining that you could not really run an instance method without instantiating the class -- it was just something fake for beginners.

Shakahs
0 replies
6h54m

I agree. Coming from NodeJS I appreciate how explicit Java is. The complexity is there either way, but in Java it's right up front where I can see it, not hidden away under layers of abstraction for a supposedly better DX.

coldpie
1 replies
23h25m

I 1000% agree. Though, a favorite early programming memory of mine was when static methods finally clicked and I went back and looked at all that boilerplate that meant nothing to me and it all became crystal clear what it meant and why it had to be like that.

eddd-ddde
0 replies
14h45m

This reminds me of when I finally understood why returning 0 from a function named main made sense.

bitwize
1 replies
21h33m

This is exactly what I've been calling the "public static void main problem" for years (and an illustration of why I thought something like BASIC or Python should be everyone's first programming language). Neat to see the Java team come up with a solution for it. But "public static void main" runs deeper, and has to do with immediacy: shortening the time between the programmer giving instructions to the computer and seeing the results of those instructions being executed. It makes the smallest possible Java program greatly simpler and absent unusual comments that beginning programmers might struggle with; but there's the issue of the compilation step as well! If they make Java REPL-driven they might well have a winner!

craigacp
0 replies
17h17m

Java has had the ability to run a single code file directly by running `java <path-to-file.java>` since Java 11 - https://openjdk.org/jeps/330. And it's had a Java REPL since Java 9.

bheadmaster
1 replies
22h55m

Good that they got rid of the class/public static void/string[] Args boilerplate, but if they just went one step forward and declared implicit main function as top-level scope of a file, we could've got to a Python level of tersity. Just imagine!

    System.out.println("Hello world!");

aidos
0 replies
22h40m

To be that guy, not quite a python level of tersity!

Almondsetat
1 replies
23h9m

My first Java programming course went over in detail about that piece of code and in a couple of hours taught me a lot of important Java concepts right away. Consider me not enthused about it.

whitehexagon
0 replies
21h55m

Simple code like that kept pulling me back to the JSL 1.0 spec time and time again as my understanding deepened, much like the old singleton pattern debates of old.

kyawzazaw
0 replies
23h45m

love this!

jonahbenton
0 replies
2h38m

With respect, not hostile to beginners but adding complexity to the build to support this kind of implicit sugar, when beginners are 100% going to be using AI to write code and answer questions- seems like not the right tradeoff in 2024.

dajt
0 replies
16h10m

I really doubt that. Java is complicated enough that it's not beginner friendly even if you don't have to write the class to put main into.

Given these are still methods of classes this JEP seems pointless to me. Not having to write class x {} isn't a great time saver.

cryptos
0 replies
10h14m

This is nice for beginners, but the confusion is only postponed, because then you'd have to learn why you need to write a class as a container for static methods and that these methods must be static. So, the Java developers created another special case in the language.

Compare that with Kotlin where you have top-level functions, so that `main` is just like any other function.

preommr
26 replies
23h1m

It's kind of startling to see how many places still use Java 8, estimated at ~1/3 of projects according to a survey i just googled. And something like half that still use java 11.

Nullabillity
8 replies
21h20m

In practice, Java is the language of legacy and Android.

Java 8 keeps working, while "modern" Java keeps chasing mistakes like green threads. If anything, I'm more baffled by 9+ having a non-neglegible market share at all.

citrin_ru
6 replies
21h1m

Java keeps chasing mistakes like green threads

If by green threads you mean virtual threads in JDK 21 could you please elaborate why they are a mistake? I'm not a Java developer but from what I see new concurrency model allows to write much more efficient network software - OS threads are expensive (in terms of RAM/CPU) and to handle many thousands of network connections (C10k problem) you have to either throw a lot of hardware or use NIO (New/Non-blocking I/O) which is hard to code.

One of reasons why Go become popular - gorutines look like normal threads (relatively easy to code) but more efficient.

Nullabillity
5 replies
18h28m

There were already "user-mode" implementations of asynchronicity on the JVM for years (like Monix, cats-effect, Pekko (fka Akka), etc).

Loom has a worse API, is hidden from the user (what's preemptible and what will cause OS thread starvation? who knows!), and effectively ends up infecting the whole JVM with its complexity.

Go shares most of those downsides, but as a greenfield project (..heh) there's at least the expectation that all libraries play nice with their scheduler. They also try to hide FFI starvation by effectively running each FFI call in a dedicated OS thread[0].

There's also gevent/greenlet, which tries to bolt "colourless" M:N scheduling onto Python. It hasn't exactly taken the Python world by storm either, despite being far older than their native asyncio support.

Overall, I'd consider all three implementations of the approach to be dead on arrival.

[0]: See https://stackoverflow.com/a/28356944, it's a bit obfuscated but the overall effect is the same

jen20
1 replies
17h21m

If you consider Go to be "dead on arrival", I don't know what world you're living in.

vips7L
0 replies
12h41m

And the rationale for it being dead is… ffi? Something that 99% of all apps don’t use.

zbentley
0 replies
4h44m

Go shares most of those downsides

Does it? Preemptability is pretty robustly solved in Go. While it's sometimes less efficient than I'd like, it's a far cry from the initial draft of virtual threads in java where a misplaced "synchronized" could sneakily starve entire executors. Even with CGo pinning (which, as you indicate, is rare due to the bulk of pure-Go libraries) I'm having trouble thinking of reasonable situations where full starvation or deadlock occurs rather than (admittedly unpleasant!) latency and queueing.

That said, Loom is quite new and deliberately iterative in approach, and the Java core folks are quite skilled, so I do expect to see substantial improvements in behavior and issue-detection tooling here over the coming years.

I'd consider all three implementations of the approach to be dead on arrival

I'd argue that eventlet/greenlet failed for different reasons than the concurrency model or starvation risk (the monkeypatching approach just can't sustainably work in an ecosystem as big and native-code-dependent as Python's), hence Python's falling back to traditional async/await cooperative concurrency.

The Rust folks are struggling with the same choices here as well, further constrained by their requirements of a GC-less runtime with near-zero-overhead C FFI, which precludes them from using Go's approach. There was some great discussion of that here: https://news.ycombinator.com/item?id=39242962

temporarely
0 replies
15h32m

Kilim was the first for Java iirc.

Interesting point regarding scheduler and the interruptibility of FFI calls. Just thinking about it I don't see how this can be addressed. So definitely interested in learning here: what is the remedy to your criticism here beyond "document behavior"?

kaba0
0 replies
10h4m

User-mode implementations are very easy to get wrong (you might accidentally call a blocking operation where you shouldn’t), and have indecipherable stack traces. How is Loom’s API bad? It literally reuses basically everything you know about Threads, seamlessly.

Also, Java has the luxury that almost no code makes use of FFI, so their impact is minimal.

MichaelMoser123
0 replies
15h59m

you didn't like java generics? why?

fngjdflmdflg
6 replies
21h22m

Wasn't the whole point of Java never releasing a 2.0 that there would never be breaking changes? Seems like something went very very wrong with Java if the state they are in is that the language refuses to make breaking changes and the developers refuse to take up the supposedly non breaking updates due to breaking changes based on the comments I'm seeing here. So the language never improves as much as it can and the developers never update anyway making the whole point of non-breaking changes moot.

chungy
4 replies
21h2m

Java 8 allows access to unsafe methods, which despite being meant for internal JDK use only, have been widely used in external projects. Newer Java versions do not permit the use of unsafe except for the JDK itself.

It wasn't ever part of the public API that's promised to never break, and JDK developers were annoyed that it being used meant Java got perceived as unstable, and it's gone in more recent versions.

cempaka
2 replies
17h51m

I thought the issue was not Unsafe methods (which are only just now starting to be marked for removal) but rather various bytecode weaving libraries like javassist. As the JDKs progressively enforce bytecode verification more strictly these libraries sometimes run afoul of the new restrictions. (I speak from a little experience here, managed a somewhat involved upgrade path from 7 to 8 way back in the day which had this issue.)

vips7L
0 replies
13h38m

I haven’t ever seen this mentioned. The real culprit was libraries that go into jdk internals when they shouldn’t have so end user applications couldn’t upgrade until those libraries upgraded.

chungy
0 replies
16h44m

That's probably another factor, and these two aren't the only ones.

marginalia_nu
0 replies
15h54m

Huh, but I'm using Unsafe in JDK 21?

kaba0
0 replies
10h22m

There are barely any breaking changes, I could still run a graphical application written by a prof in early 2000s, served on his website as a jar. No other language comes remotely as close to this level of stability.

As for the changes in 8->9, there was a stagnation period in the last year of Sun, and many people overfitted their libs to 8, by e.g. making use of internal APIs made accessible through reflection. This was never a good idea, and all that is happening now is that you have to explicitly state at invocation what kinds of non-future-proof modules you make use of, so that you are made aware of what could potentially change, plus it disincentivizes libraries from accessing these non-public APIs.

MBCook
6 replies
22h42m

8 reached EOL in the last year or two. I think 11 is still under LTS.

Part of the problem is the changes made between 8 and 17 could be incredibly disruptive depending on your libraries.

If they had stuck to not using sun.* stuff you were pretty safe, but a few very popular things did.

Then somewhere in there a lot of the common server stuff moved from javax.* over to jakarta.*.

Both were needed and very good, but could turn into dependency nightmares. So depending on your app/stack it wasn’t an easy transition.

17 is fantastic though, especially coming from 8. I’m excited about what’s already in 21 (latest LTS) and coming in the next LTS after that.

agurk
5 replies
22h8m

8 reached EOL in the last year or two

Java 8 is still under Extended Support until 2030 (and indefinite sustaining support). Java 11 left Premier Support September 2023.

"Java SE 8 has gone through the End of Public Updates process for legacy releases. Oracle will continue to provide free public updates and auto updates of Java SE 8 indefinitely for Personal, Development and other Users via java.com".

https://www.oracle.com/java/technologies/java-se-support-roa...

MBCook
3 replies
19h29m

Oh that’s right. My company didn’t want to pay the insane Oracle fees to keep getting support. I think it wasn’t even a discussion once the saw the number, but that’s basically a rumor.

So we have to stick to OpenJDK which means 8 doesn’t receive security updates and is untenable.

kaba0
2 replies
10h39m

Seems like willful incompetence on the company’s part.

Just for note, JDK 8 came from the same time as Windows XP. Sure, the attack surface is different, but if they have no plans on moving forward and doesn’t even want to pay for support, then frankly fck them. Then they just surprise pikachu when a bunch of their user data leaks.

Nullabillity
0 replies
9h37m

Err, what? Windows XP was EOLed a month before JDK 8 was released.

MBCook
0 replies
4h12m

That seems oddly hostile.

We moved to the latest LTS. Continuing to use an old version with no security updates would be moronic. Of course we didn’t do that.

All I was saying was sticking with 8 wasn’t tenable for financial reasons.

Nullabillity
0 replies
21h18m

Oracle JDK support is not the same as OpenJDK support (for both better and worse).

elric
0 replies
22h3m

Wait until you hear about COBOL still being used.

Snark aside, the problem with Java in the enterprise is that Oracle provides support for mind-bogglingly ancient versions (if you're willing to pay them). This disincentivizes companies from upgrading, ends up frustrating their developers, and has probably contributed to the negative reputation that Java has in some corner of the net.

I get that tracking the current version isn't feasible for most companies, especially if software isn't their core business. The Java folks do their best to make upgrades painless, but the longer you wait, the more painful it gets.

adra
0 replies
22h15m

I'm dragging my new company's codebases from 8 to 17 from soup to nuts. It's not always just about the language update, but all the old legacy crust that accumulated since java 8 that prevented anyone else to do it. My PRs are terrible and necessary.

BroomOfSYS
0 replies
22h48m

Unbelievable! It is a strong signal that people don’t care and technical leadership is bad. Always the nonsense excuses of having to work on a “legacy” codebase for more than ten years with a team of 3 developers and 4 analysts.

oaiey
24 replies
1d2h

Foreign Function Interface is one of the key advantages what C# had over Java (e.g. against huge APIs like Android or macOS). I am really curious how this JEP turns out.

soulbadguy
10 replies
1d2h

The FFI is also an artifact of CLR type system and the ability of have proper stack value based types.

grishka
4 replies
1d1h

They will eventually bring value types to Java with Project Valhalla.

layer8
2 replies
1d

I wonder how long it will take. We’ve been waiting for ten years already.

kaba0
0 replies
1d

One design iteration already has a working, implemented branch available, it’s just one of the hardest designs to get right, to remain backwards compatible, to have it work nice with generics and all the other features, etc.

So once they actually settle on a design (which they seem to have closed on quite a lot in the last couple of years), it might not take that long to happen.

ivan_gammel
0 replies
22h53m

Looks like we may see a first preview in Java 23, i.e. already this year.

soulbadguy
0 replies
19h16m

Noting that Valhalla value types are about guaranteeing object value identity with memory layout and/or flattening supposedly deriving from that. Modeling unmanaged sequence of bytes within the type system (like receiving a typed buffer from un managed code) might still be challenging

int_19h
3 replies
22h44m

Not just value types, but also:

1. Pointers to the same (and not just references to objects).

2. Unions (via explicit-layout structs)

3. Function pointers.

4. C-style varargs.

To be fair, not all of these have been exposed in C# historically even though CLR had them all along. Most notably, unmanaged function pointers took over 20 years. And since most people look at CLR through the prism of C#, they aren't necessarily aware of these features.

Still, one way or the other, we're at the point where pretty much any C program can be transpiled to C# in a one-to-one mapping of almost every construct (setjmp/longjmp has to be emulated with exceptions), and a very similar performance profile of the resulting code.

soulbadguy
1 replies
19h12m

Indeed. The CLR from its inception implemented a lot of features for helping native inter-op. I would guess that msft did make the effort simply because of their large legacy c/c++/win32 code base.

It's a shame really that msft stewardship of the .net/clr was so lacking. Of all the modern virtual machine clr us pretty much up there

pjmlp
0 replies
10h35m

Because it was yet another all-in, where all future Microsoft software was going to be .NET based, but WinDev/Office never played ball.

We just have to go back in time and see all those Visual Studio.NET shows on surviving documents, or how Ext-VOS (what became .NET) was being done at MSR.

We could have had something like Android, Inferno/Limbo in terms of .NET usage across the Windows layers, but it always bumps into the love for COM and C++, which incendently is how many Longhorn ideas were remade in Vista and continues to this day, using COM instead of .NET.

neonsunset
0 replies
22h14m

Honorable but important mentions:

5. Stackalloc (C alloca), fixed buffers in structs and inline arrays

6. ref T and Span<T>, which act just like &mut T and &mut [T] in Rust (with the same syntax). They are used in both advanced and most basic APIs alike to provide zero-cost wrapping and/or slicing of arbitrary memory (managed heap, stack, NativeMemory.Alloc'd)

e.g. You can receive byte* and length from FFI and construct a (ReadOnly)Span<byte> from them. That span then can be passed to almost every method that used to work with arrays only during .NET Framework days.

merb
0 replies
22h33m

Sadly records are not value types, maybe Java will do this better, but I doubt it. Valhalla is probably years away.

neonsunset
5 replies
1d2h

Small correction: FFI in Android land is abysmal, to get decent performance when accessing all kinds of system APIs you almost always end up having to write helpers in Java, to try to alleviate the pain of JNI as much as possible (it is still significant).

Interop with iOS OTOH is a breeze, some of the APIs may require newer Swift Library Evolution ABI (direct calls to Swift exprots, without going through C/objC) but .NET is getting it in .NET 9 (the first and only platform to have it at the moment of release).

pron
4 replies
1d2h

Calling Android "Java" has always been a stretch. Not only has Android never been compatible with any version of Java, the divergence between Android and Java is only growing. JDK 22 is Java; Android is Android.

neonsunset
2 replies
1d2h

That is true, for all intents and purposes however the glue code to (insufficiently) reduce marshalling and FFI overhead is written in Java the language, even if it does not use OpenJDK.

pron
1 replies
1d1h

Okay, but we're not talking about OpenJDK but about Java, a specification -- not an implementation like the OpenJDK JDK -- that Android has never conformed to and from which it is only growing further apart. I.e. the OpenJDK JDK is an implementation of Java; Android is not (there certainly may be some Java code that happens to behave the same way on Android, but it is not, and has never been, the case for Java code generally). The relationship between Java and Android is similar to that between Linux and Unix -- lots of intended similarities, but there shouldn't be an expectation that a new Linux feature appears in, say, AIX or vice-versa.

pjmlp
0 replies
1d1h

At least they were forced to accept how much Android ecosystem depends on Java and now Java 17 LTS is the latest supported version, minus the stuff they never supported like Swing and Java 2D.

cxr
0 replies
23h39m

Calling Android Java is certainly a stretch, but aside from Sun/Oracle folks, I don't ever see anyone do that. Android is Android, Java is Java, and Android is written in Java.

If the language of the non-standard, deliberately ES262-incompatible NodeJS programming system (and GraalJS, for that matter) is called "JS" without anyone batting an eye—which it does—it's pretty silly to insist the language of Android isn't Java.

adra
3 replies
1d2h

I started to tinker with this new API last week. I definitely think it's a lot better than needing to self compile a lot of the bindings yourself which will certainly bring more from the community into the feature than were here before.

That said, you really need to write a bunch of boiler-plate to implement useful things in java-like paradigms in the library today. Just as an example, I wrote up a sane windows _getcwd() stub and it's like 30 lines to implement correctly (properly freeing the buffer when I'm down with it)

My pet project is to see if I can write automatic stubs around calls based on published API info and sources, so that at least some of that platform binding lift isn't just for those with non-trivial knowledge of C. Well, that's the hope anyways.

schoenobates
1 replies
1d1h

I've been quite keen on the new FFI too - apologies if this is old news, but have you tried the [0] jextract stuff for some of the boilerplate gubbins?

[0]: https://github.com/openjdk/jextract

adra
0 replies
22h23m

No! Thanks for the callout! That would certainly help on my path. My main goal was to insulate calls to avoid overly complicated reference counting when integrating large native surfaces into as Java program, but certainly an important aspect is getting the function signatures to target in the first place. I threw something bad together to work sort of like this (testing using proton), but I'm more than happy to bin it for something that just-works.

ptx
0 replies
18h55m

Have you looked at Microsoft's Win32 API metadata package [0]? They're using it to generate C# and Rust bindings, and other people have targeted other languages.

[0] https://github.com/microsoft/win32metadata

zbentley
0 replies
4h53m

It's definitely exciting and a big step forward from JNI/JNA.

However, I am a little concerned about the heavy emphasis on library unloading in the JEP. Unloading is famously fraught and unsafe for wide swaths of common libraries ... or maybe I'm overfitting due to recent trauma[1] and everything will be fine.

1. https://gist.github.com/thomcc/8c4a8003cf1a282949a539e899cb4...

ackfoobar
0 replies
1d

It worked great for me. I had long wanted to rewrite a Python lib in Kotlin, since the Python part of the lib is slow, and it does not support multi-threading.

But the ugliness of JNI stopped me. Then I tried FFI in Java 21, with jextract it was amazing.

I wasn't aware of FFI at first, but the finalized version of virtual threads made me check the Java release notes.

MaxBarraclough
0 replies
21h26m

For anyone reading, here's a link to the page with detail on this project: https://openjdk.org/jeps/454

melling
10 replies
1d3h

“Vector API (Seventh Incubator)”

Seven iterations? What is going on with vectors in Java?

GreenToad
2 replies
1d3h

"Vector API" is universal api for SIMD. It will probably remain in incubator until valhalla delivers value types.

packetlost
1 replies
1d2h

Is there a timeline on Valhalla? I only loosely follow the Java ecosystem these days, but Valhalla is of particular interest to my performance-oriented mind.

e3bc54b2
0 replies
1d1h

I follow up on valhalla every now and then. It looks few more releases away, probably not before next LTS.

That being said, the amount of rigor with which the JDK devs test their experiments is really something to witness. Its equivalent to old school MS with painstaking maintenance at backwards compatibility, all the while moving the wheel of progress.

Every single change so far has been planned with a decade of advanced planning because that's just how this ecosystem roles.

exidex
1 replies
1d3h

They said it is waiting for some feature from project Valhalla. Not sure which one though

pron
0 replies
1d2h

There are ad-hoc hacks in the JDK to avoid allocation for vectors; once we get some Valhalla features, vectors could be represented as plain value objects.

MrBuddyCasino
1 replies
1d3h

The Foreign Memory API is in the works since 2014. They are just very diligent and careful.

kaladin_1
0 replies
1d2h

Yeah, given the amount of legacy infra built on Java. They don't have the luxury to move fast and break things.

voidfunc
0 replies
1d3h

My understanding is it depends on Valhalla (value classes) and they basically keep updating it as that project changes.

neonsunset
0 replies
23h27m

If you're interested, there already is a somewhat similar language that offers first-class support for these.

geodel
0 replies
1d3h

It will go on until 'value classes' are incorporated in Java

ecshafer
9 replies
1d1h

It isn't a "Sexy" PL change, but a full foreign function interface will be a huge change. In my experience, relying on the old java JNI based libraries seems to be one of the biggest things that break in upgrades. So I am hoping this will reduce the maintenance burden of Java.

DarkNova6
8 replies
22h53m

Boring changes like these are what keeps Java interesting.

New and shiny syntax sugar becomes stale real quick.

owlstuffing
7 replies
22h20m

As a modern language Java is still quite feature deficient. But you can use compiler plugins like the manifold project[1] to level up.

1. https://github.com/manifold-systems/manifold

wmfiv
4 replies
21h24m

I see Manifold as a huge leap past previous tools Immutables or Lombok. I understand there's a use case where you want to add these language features to an existing code base. But for the most part if you want the language features on the JVM, you should probably just use Scala. That gives you a set of established patterns, best practices, libraries, and a community of users.

If you want type safe SQL in particular, you can pry JOOQ out of my cold dead hands.

owlstuffing
3 replies
19h16m

just use Scala

Scala is a dying language, anyone boarding that ship is making a mistake. Anyhow, I prefer Java supplemented with powerful features Scala doesn't have, such as type-safe SQL.

If you want type safe SQL in particular, you can pry JOOQ out of my cold dead hands.

Jooq isn't bad, but it's not SQL, it's Java trying to be SQL. Manifold lets you write type-safe, native _SQL_ of any complexity directly in your code.

pregnenolone
0 replies
9h50m

powerful features Scala doesn't have, such as type-safe SQL.

What? This site is getting worse by the day.

kaba0
0 replies
10h43m

I have never seen anyone use manifold. Are you saying that I should use something like that in a serious production environment over Scala, that is a huge language with people that actually know it?

Especially that you call it a dying language, when it just got reborn, and better than ever with Scala 3.

946789987649
0 replies
3h19m

Jooq isn't bad, but it's not SQL, it's Java trying to be SQL.

Can you elaborate on this? I have been using JOOQ for years (with Kotlin), and I have never had any issues with it "trying to be SQL".

vips7L
0 replies
18h54m

Manifold isn't Java.

DarkNova6
0 replies
4h14m

I'm not 100% sold. I like some of it's features (e.g. the mentioned typed SQL safety) but adding all of it seems super heavy-weight. Lombok took a good time to become widely accepted and I don't think this will ever appeal to more than just a niche audience.

At the very least, I prefer not to have any surprises in my codebase because it looks like Java but isn't quite so really.

jsnelgro
6 replies
20h54m

Why would I use Java 22 over Kotlin?

pjmlp
2 replies
10h33m

Kotlin is a guest language, doesn't have nothing to call their own as platform.

jsnelgro
1 replies
1h47m

Android?

pjmlp
0 replies
1h33m

Android OS layer has zero Kotlin, and Google had to backtrack on their decision to let Java languish, as the Android ecosystem started to lose out on Java ecosystem, thus ART is now updatable via Play Store since Android 12, and Java 17 LTS is the latest supported version.

Kotlin is only used on Jetpack Compose and a couple of AndroidX libraries, that you have to ship alongside the application. And as alternative to Groovy on Gradle build scripts.

I expect this year's GDC to announce Java 21 LTS support.

jsnelgro
0 replies
1h47m

The downvotes are unfortunate. To clarify I wasn't trying to start a flame war.

I was hoping someone would answer with concrete technical tradeoffs and comparisons e.g. compile times, null safety, common footguns, personal experiences, etc.

I was recently asked for a comparison between Kotlin and modern Java by a team that's considering a migration of their legacy Java service. I haven't kept up with Java's changes, so didn't have an offhand unbiased comparison to share.

I've worked on backend Kotlin and Java codebases for the last five years and have introduced Kotlin to dozens of teams across my company. Nobody I've introduced Kotlin to has ever ended up preferring Java or switching back to it. There's been initial skepticism at first (reasonable), but after working in Kotlin for a week or two, I've seen even the staunchest Java devs proclaim they're never going back.

To the point on personal preference, I think it's a factor but I don't think it's _the answer_. It's a blanket statement that ignores important details. Languages have different affordances, features, paradigms, and patterns that lead you to develop and think in different ways. Some differences like null safe types are obvious improvements for a large codebase with many contributors. The feature catches real bugs and makes the system easier to build and maintain.

I think there's a lot of warranted skepticism of JVM languages that aren't Java, but something about Kotlin feels very different. For comparison, I've worked with Scala (Spark) and played around with Clojure in my free time.

I'm not sure what feels so much better compared to other JVM languages, but if I had to guess I'd say it's an emergent quality from a few things JetBrains has done really well. In particular:

- The 100% Java interop claim is real. I've only had minor hiccups with Lombok - The ability to incrementally adopt Kotlin in an existing Java codebase - The IDE support in IntelliJ IDEA is unbelievable. The suggested refactorings subtly teach you the language - Null safety lets you focus on domain modeling and business logic instead of error handling and validation - Kotlin's backwards compatibility. New versions never seem to break anything. And they even provide refactoring actions in IntelliJ to automatically update deprecated usages - Very few significant paradigm shifts. Kotlin doesn't force you to totally change your Java code to fit a functional style or anything like that. It just tries to make safer code easier to write - The political stability and longevity gained from Android's blessing as a first-class language makes Kotlin feel like more than just another JVM language. There's Kotlin running on billions of devices. That's a pretty big ship to turn around, sink, or replace

To summarize, Kotlin just feels like the elephant in the room. Aside from low-level changes like new FFI possibilities and GC improvements, it's not clear to me what value Java upgrades add in comparison to Kotlin—especially in regards to new language features and syntax.

Anyways, hopefully this followup post starts a more fruitful discussion. I asked this question in earnest based on my personal experiences and observations. If you haven't tried Kotlin yet, I'd suggest cracking open an IntelliJ scratch file and test driving it yourself.

cupofjoakim
0 replies
19h35m

To me the question "Why would I use X over Y?" in programming space is a bit redundant. Why would I use Kotlin over Closure? Why would I use Groovy over Scala?

Even only considering JVM languages you run in to way too many options for the question in itself to be worth your time as a serious discussion.

IMO - use whatever you and your team like best and that suits your needs. Java is great for hiring new devs and is arguably the most well established in an enterprise settings.

If you want an actual answer: Personal preference.

bitcharmer
0 replies
3h12m

You still need the JVM to run Kotlin. Also performance.

pkphilip
5 replies
1d3h

Interesting to see the developments on the String Templates API using the STR and fmt template processors.

bberrry
2 replies
1d2h

I'm really happy they are reconsidering the syntax. Thanks for the link

ptx
1 replies
18h37m

It sound like they're only reconsidering the prefix, not the backslashes, or am I misreading it?

So we're not getting "hello $name" but rather than STR."hello \{name}" they're now considering $"hello \{name}".

vips7L
0 replies
12h39m

I like the backslashes. It’s one character to do escaping

JackFr
0 replies
1d1h

concrete syntax TBB (to be bikeshod)

TIL the past participle of 'bikeshed' is 'bikeshod'. Tremendous.

thisislife2
2 replies
6h47m

Now this may seem like a silly question, but if I only want to run Java apps on macOS, what should I install from MacPorts? Searching for "JRE" gives no results. Searching for OpenJDK gives various options including:

- OpenJDK21: https://ports.macports.org/port/openjdk21/details/ , - openjdk21-zulu: https://ports.macports.org/port/openjdk21-zulu/details/ - openjdk21-oracle: https://ports.macports.org/port/openjdk21-oracle/details/

each of them having so many variants (see the links). What variant needs to be installed to just run a Java app?

mike_hearn
1 replies
5h12m

Usually Java apps come with Java these days, like how there's no independent way to run Electron apps, it just comes with the download of the app itself. There are tools that make it easy like jpackage and (toots my own horn) https://www.hydraulic.dev

If you want to just quickly run a fat jar then any will work. "openjdk21" is fine. The Zulu variant comes with JavaFX which simplifies things if your app needs that.

thisislife2
0 replies
2h48m

For sure, Java developers need to use a tool like yours to distribute their app. My experience with some Java applications was that running it triggered an attempt to download (I assume) the JRE, which I cancelled as I didn't know the source of download and didn't want it to download some PUA or malware. (I remember JRE for windows used to bundle some browser toolbar on windows). Hence my attemt to install it myself beforehand. But, since Oracle has stopped distributing latest JRE through Java.com for macOS, I looked for it in MacPorts. And it is really confusing - for example, if you look at the OpenJDK-Zulu port that you recommended - https://ports.macports.org/port/openjdk21-zulu/details/ - it has 4 variants:

1. Applets ( Advertise the JVM capability "Applets".)

2.BundledApp ( Advertise the JVM capability "BundledApp". This is required by some java-based app bundles to recognize and use the JVM.)

3. JNI ( Advertise the JVM capability "JNI". This is required by some java-based app bundles to recognize and use the JVM.)

4. WebStart ( Advertise the JVM capability "WebStart".)

- what the heck? I think I am better off without Java. :)

cryptos
1 replies
10h12m

This is indeed nice. However, static extension methods would have made this feature simpler (and more generic).

krzyk
0 replies
3h31m

And would also make code harder to read. I was always reluctant to use those in Scala because of this.

cryptos
1 replies
9h50m

Although I like Kotlin better, I'm really impressed how Oracle continues to improve Java. Some developers think Java is an old, cumbersome language, but it is indeed such a productive language and ecosystem with outstanding quality! Java has quite good support for functional programming, concise and immutable structs (called "records"), pattern matching, string templating, virtual threads, structured concurrency (preview for now), a vast ecosystem with outstanding quality, world class documentation, a fast and robust runtime and so on.

Even after nearly 30 years, Java is still a good choice to start something new (e.g. a startup).

munksbeer
0 replies
9h8m

It is very trendy to hate java. Which is actually a good thing, because it means I get to continue to enjoy working with java alongside sensible professional developers, who quitely get on with writing excellent code and creating industry leading systems with java. Less competition for the roles and I don't have to work with fanboy types.

kaba0
0 replies
23h18m

I doubt Oracle would fix it, as this is definitely a kernel bug that breaks userspace. It is part of the POSIX spec what the JVM relies on, and MacOS is supposedly POSIX-compliant. So it should be Apple that fixed their bug.

grumpydude
0 replies
1d2h

Unrelated to Java, but it’s so refreshing to see a simple HTML page for once

didip
0 replies
1d2h

Sweet, G1 keeps getting better for free. Time to cut a new build tag for this.