7 ms·
> Although Java has evolved over the years, the core of the JVM has maintained stability – to the point where applications compiled with Java 1.0 can still be r
by sradman 6y ago
> Although Java has evolved over the years, the core of the JVM has maintained stability – to the point where applications compiled with Java 1.0 can still be run on modern JVMs, albeit much faster. The bytecode format has (largely) remained unchanged;
Java has many warts but the bytecode stability is an admirable achievement.
- walkingolof 6y agoThat stability comes with a huge cost, for example, Value types, desperately needed, has been going on FOREVER (7 years and counting) with no end in sight ..
- wilsonthewhale 6y agoIf you've been following the development progress, they've gotten the VM side largely ironed out and under testing. Nothing on the language side has been polished yet though. As an honest estimate, I'd give about 2-4 more years. But it's definitely further along than I thought it would be. See: https://cr.openjdk.java.net/~briangoetz/valhalla/sov/ https://cr.openjdk.java.net/~briangoetz/valhalla/sov/
- victor106 6y agoValue types and Loom (lightweight threads) are two things that will shape Java in profound ways for years to come. 2-4 years for value types seems quite long but the changes to the spec to accommodate value type is much more broader in scope so that’s understandable.
- DaiPlusPlus 6y agoLoom question: I gather that it basically has implicit awaits, so how do you “force no-await” so you can run operations concurrently?
- victor106 6y agoGood question. Something that @pron can answer better
- marwis 6y agoSpawn virtual threads
- pron 6y agoSpawn new threads (and then join them).
- DaiPlusPlus 6y agoIs than an OS thread or a Loom-thread though? If it’s an OS thread, then that won’t scale and defeats the point of using Loom (though it does still reduce the overall system load). If it’s a Loom-thread then doing `.join()` is the same thing as doing an `await` - in which case it’s silly to not just have a `.dontJoinJustYet()` method that’s available for every Loom promise.
- pron 6y agoYou pick the thread implementation, but clearly a virtual thread would be more appropriate. And yes, join is semantically the same as await, but it fits with the design of the platform. And also yes, there are convenience methods for spawning threads and joining them, such as ExecutorService.invokeAll/invokeAny.
- benjiweber 6y agoThere has been significant progress though. Especially since the 6 month release cycle. Lots you can do with Records now https://benjiweber.co.uk/blog/2020/09/19/fun-with-java-records/ https://benjiweber.co.uk/blog/2020/09/19/fun-with-java-recor...
- JoeAltmaier 6y agoAnd also a sad failure. Bytecodes lose most of the semantics of code - value scope and lifetime; code structure etc. So jit compilers have to reverse engineer all that. They'd have been better served to simply have the source code. I remember being intensely disappointed when I learned Java produced bytecode (Java 1.0). Even back then I knew better, that losing semantics would be a huge hurdle to be overcome.
- dehrmann 6y agoJava bytecode looks a lot like Java, and except for local variable names, Java disassemblers do a pretty good job. Maven also solved this by very strongly encouraging the distribution of source jars. It's very rare that I have issues with missing source code when I use a standard IntelliJ setup.
- JoeAltmaier 6y agoAgain, why disassemblers? Why not put semantic info only into that java file? Why on earth go through the ritual of creating bytecodes, then un-creating them? Clearly bytecodes are not what anybody wants.
- alblue 6y agoJava bytecode allows for Debug attributes, which are produced by default in most build engines, and say which field maps to which item on the stack and for how long. Even if that information is removed, the fact that you have the return value of an invokedynamic called `object.getName` means that you can often have a much better chance of redeeming the information than in other compiled languages. The key difference is that fields and methods maintain all their names in the bytecode; in C, non-public symbols are usually stripped leaving only the calls to libraries present.
- pradn 6y agoYou do bring up an important point. Have there been successful cases of taking several levels of the code at the same time? Is there a JIT that uses both the bytecode and the AST together? Some things are easier using some data, for sure.
- cesarb 6y agoThe bytecode stability is only half of it. The other half the stability of the standard library, before Java 9 it was very rare to remove anything from it. I recall things like a RCS or SCCS revision tag which was accidentally put in a public static field, and it was kept frozen (with the same value) as a public static field just in case someone was using it for some bizarre reason. Starting with Java 9 things changed, many things were removed (starting with all of J2EE) and other things are going to be removed soon. This is one of the reasons why it takes so long for projects to migrate from Java 8 to Java 9 and beyond.
- pjmlp 6y agoBack in 2018 I had a client with Java 1.4 in production, some never migrate, even if there aren't hurdles.
- Quekid5 6y ago> This is one of the reasons why it takes so long for projects to migrate from Java 8 to Java 9 and beyond. EDIT: Oh, just realized... it's probably a misunderstanding on my part. "Java 8 to (Java 9 and beyond)" is the intended reading, probably. My bad. ----------- DO NOT READ BEYOND THIS POINT ---------- Maybe it's just a phrasing issue, but... The Java 8 -> Java 9 (or 11, in practice) transition was special in a few ways (modules, mainly), but I don't see why any future transition should be quite as disruptive? Do you have anything concrete in mind, because if you do, I'd like to know about it!
- alblue 6y agoNo, it's likely that it won't be quite as disruptive in the future. There were a few backward incompatible changes with modularisation (in order to break module cycles) but the bigger disruptive changes were moves away from sun.misc.* packages which should never have been used by production code (but which often were, because speed). Fortunately Java took a middle-of-the-road approach; it didn't quite get rid of as many things as it could (Unsafe stayed around in a few ways). Had it all been killed off then the transition would have been more problematic. With Java 17 being the next LTS I don't think there's appetite to break things before then but it's quite possible that Java 18 will really put the hammer down and remove Unsafe for good. That, I think, will be one of the last disruptive things Java does.
- alblue 6y agoI gave a presentation on bytecode and class loaders if you’re interested. The deck is at speaker deck and there’s a link from there to a recording I did for the LJC if you prefer me narrating it: https://speakerdeck.com/alblue/bite-sized-bytecode-and-classloaders https://speakerdeck.com/alblue/bite-sized-bytecode-and-class...
- neilv 6y agoAnd the JVM was seen as cool from the start, even though there had been various noteworthy bytecode/p-code/etc. virtual machines before it. There were already a few books on JVM coming out. And while the JVM spec was still in draft, Jonathan Meyer had already released an assembler for the it, call Jasmin, and I wrote an Emacs mode for it: https://www.neilvandyke.org/jasmin-emacs/ https://www.neilvandyke.org/jasmin-emacs/ (I'd been doing some early desktop GUI application development in Java (writing my own widgets, since AWT was too minimal), and I wanted to get into the JVM, to play with implementing some higher-level language features that couldn't necessarily be implemented well in Java. So, of course, the first thing a person needs, before it is possible to start using a language, is an editor mode for it. :)