We like to give Oracle stick (and rightly so) but this is rolling/LTS done right: you break stuff in the release right after the LTS one, to give people time to adapt.
It was just a coincidence. They do it right: ship when it is ready. LTS is not an openjdk term it is something that vendors might offer for any jdk version.
LTS was proposed by Mark Reinhold [1] who leads the JDK Project in the OpenJDK community in 2017. There was a lot of discussion [2] that resulted in many vendors supporting and adopting the LTS model.
It's a thriving ecosystem (which is great!) but yes, Oracle does contribute a significant portion [3].
Worth noting that if you can, don’t stay on LTS. It adds cost which many modern teams can avoid[1].
It doesn’t mean enabling Java 18 on Production on day 1, but certainly it means adding a Java 18 compiler to your CI, running tests using Java 18, etc.
Yes, newer JDKs should ideally be rolled into at least DEV and perhaps QA just so breakage can be found early and fixed early. STG/PRD of course is something else.
Even if you don't use any of the new features, there may be deprecation warnings and such that one should be aware of sooner rather than later. Tweaking early to ensure compatibility with current-LTS and future-LTS versions is worth some cycles: if you don't, you'll pay for it eventually when old(er)-LTS is inevitably retired.
This discussion immediately brings to mind all of the iOS apps that become completely unusable the day a major iOS update is released, and then take a week to fix.
I get that not everyone has spare time and energy, but it doesn't take that long to grab a beta, put it on a device (or load up the simulator) and find out. Leaving it until the last minute just forces you into a panic, and seems irresponsible when you had months to just test your product.
That was not the experience when MySql switched in v4.1, at least for existing apps. Probably for net new ones it was great. Maybe things are different now?
Windows default went over to UTF-8 from UTF-16 a few years back so its probably alignment with them especially with MS now rolling their own linux and java.
To the best of my knowledge, Windows still uses UTF-16 internally. They now support opting for UTF-8 as the charset in the 'A' APIs, but that doesn't mean Windows natively uses UTF-8.
Python should really have done this for 3.x. The breakage thanks to using the system default locale is hard to overstate - PYTHONIOENCODING winds up being a bit of a PITA for writing cross-platform code.
I don't know, they may be broken in terms of approach and design. But when the charset changes, new and never-seen-before things will start arriving downstream.
Internally strings will either be UTF-16, or if a string can be represented in LATIN-1 it may use a more compact representation.
JEP400 is about I/O, previous to this change when you create something like a FileWriter without specifying the charset the platform default would be used. For a long time this has been recognized as a common foot gun, hence this change to a default that is more likely to be what the developer actually wants.
UTF-16 represents a fairly reasonable compromise, not sure what your disgust is for.
UTF-32 (with no BMP concept) doubles the memory usage of most international text and quadruples the memory usage of ASCII text (which is the most common), yet characters outside the BMP are barely used outside of emoji.
Native UTF-8 in memory makes character indexing a non-constant time operation, which would bite people badly in cases where they've written a loop over the indexes. This is of course the point at which you say, ah but what is a character exactly. If you go down this route you end up with Swift and Emoji Flag Calculus classes. The string APIs become incredibly convoluted or inefficient for the common cases. It hardly seems worth any kind of backwards compatibility break for this.
So Java does the pragmatic thing: String can switch between 8 or 16 bits per "character" and this is basically always good enough. If you care about woring with emoji or Egyptian hieroglyphs in memory, then you either have to deal with combining characters or just bite the bullet and decode to UTF-32.
> Native UTF-8 in memory makes character indexing a non-constant time operation
The only reason that Java's UTF-16 has constant time indexing is because they use a braindead definition of character which is "UTF-16 codepoint".
If you want constant time character indexing you need to go UTF-32. But obviously the downsides are too great for most users. So in practice everyone uses UTF-8 because it is usually the most memory efficient.
Plus it turns out that character indexing isn't actually that common of an operation, so it is really the right move for almost every application.
But in practice the Java definition of a character basically always works, because characters that aren't in the BMP are vanishingly rare in real software outside of emoji, and of course, Java long pre-dates emoji.
Yes, that won't change anything internal. However:
> ...JVM's internal string representation is UTF-16
Hasn't been try for a while. They switched to using a byte array internally for storage, plus an encoding. Currently that's either UTF-16 or Latin 1, unless compact strings are disabled in which case it's all UTF-16.
You're talking about implementation details of java.lang.String. The interface it exposes is still UTF-16.
Latin 1 has the special property that each of its fixed-width code units maps onto a single UTF-16 code unit. It is for that reason alone that CharSequence implementors can use it as an alternative to UTF-16. Imagine trying to implement `char charAt(int index)` if you're backed by a UTF-8 byte array (or UTF-32, for that matter)!
From a programmer's perspective, Java is pretty much as UTF-16 as ever.
Is there a reason to use Oracle's closed-source Java implementation instead of the opensource implementations? Asking as someone who's ignorant about Java.
edit: per comments below, Oracle's Java is open-source too these days.
In this case it means GPL+Classpath Exception. The link goes to the Oracle provided OpenJDK builds.
Oracle also has their own build of the JDK which is not GPL. That is free to use in commercial software as well, under their "No-Fee Terms and Conditions"
There used to be really prominent banners telling you about it. I don't see them now, but I'm also not sure they switched back. Here's an article I found explaining the switch to requiring paid usage.
The 2021 license change reverted this somewhat, by giving you one year of security fixes for free in the long term support versions (I’m sure I’m missing some detail, if not completely misinterpreting things, here)
Mainly if you want long term support from Oracle. Many enterprise systems are very slow to update. So they can't manage to upgrade before the LTS version goes out of support. So instead of paying to developers to continuously update the code base they pay Oracle to keep supporting the "out-of-free-support" versions of the JVM.
That wasn't the only reason why I left one job but their Oracle buy-in was a big factor. Things like paying 7 figures a year for support, and then having the Oracle support manager ask if they could redistribute the hot-patch I made to other customers.
My first boss wrote the TCP stack for a long defunct mainframe, which was distributed via a “shared source” program that his employer paid for and eventually was licensed to his employer at significant expense.
Indeed. The primary reason I was so annoyed by that is that this was when (IIRC) IE8 was released, and day one we noticed that their sloppy JavaScript caused an exception which broke the entire UI. That happens but when I contacted enterprise support, I got a surprisingly snotty “we don't beta test Microsoft's software for them” message closing the ticket. They re-opened it when I pointed out that it was the release version and rolling out enterprise-wide to our Windows desktops for security reasons but I was not expecting a fix for a while based on the blow-off (this proved accurate), much less the call from a support manager a couple days later who'd seen in the case notes that I'd mentioned having patched it on our cluster (this was literally one line of code — trivial for any decent web developer).
I completely understand, in the same situation myself atm after several years of lean and agile work, somehow ended up having to manage this EBS crap on a new contract (it was only part of the spec). It's a nightmare.
Depends. Many companies want to rely on long-term supported versions with security/stability updates directly from the folks that wrote a majority of the code in the JDK itself. Also as noted above, Oracle offers the Oracle JDK under a free-in-production license with overlap with the next LTS giving users time to upgrade.
I personally haven't had a reason to use Oracle's because I like having the latest version and any actively maintained LTS versions available for development and would prefer to use one vendor for all of them. Eclipse Temurin and Azul Zulu are the two I've personally used, but I'm not aware of any technical differences. They should all work the same since they're built from the same code.
Most of the big vendors are running the TCK tests to certify compatibility as well.
The Oracle JDK ships with capabilities not found in OpenJDK. Oracle ships webkit for instance--to parse/render HTML. OpenJDK does not. There also used to be a JavaScript engine, which I believe was deprecated unfortunately, and does not ship with OpenJDK.
That's a separate issue. There are lots of licensed OpenJDK builds, and even for Android the case is no longer relevant as Google now licenses the API from Oracle.
Probably not for the most of the tech companies nowadays, but there are still large companies who still uses Oracle products, so they might pay Oracle Java support as a package deal most likely.
I think it'll be very atypical for a companies who doesn't use any of the Oracle product to use proprietary Oracle Java and pay for the support
I don't get that sentiment, at all. Why would you be complaining about Oracle sponsoring JDK development (the resources they put into it are tremendous), which you can benefit from absolutely for free, 100%, no strings attached whatsoever? Can you help me to understand the reasoning here, because it just doesn't make sense to me.
It doesn't mean to me either, I was only making a point for the typical Oracle bashers that still haven't got the memo that OpenJDK is anyway mostly done by Oracle employees, while using the same style from the parent post.
You can get a paid commercial support license for Oracle's JDK to get an extended maintenance window. But Oracle's publicly available builds don't require a paid license. However,they only provide public builds of the current Java version. If you want LTS, you have to pay them or use another vendors builds.
That's changed a bit. As of JDK 17, Oracle offers Oracle JDK builds under the NFTC license [1], free for use in production with updates overlapping the next LTS version.
This is tangential and possibly too open ended to be productive but worth a shot anyway. Why is Java so popular? I know of a major Silicon Valley company that's migrating their backend to it. Why Java over other languages? Or maybe there's not really other viable options?
I'm speaking as someone who spent the last 6 years focused on frontend web technology.
To echo others: relatively good performance, incredible tooling/deployment infra (really best-in-class), intercompatibility with tons of other languages built on top of the JVM such that it can be functional/do actors/whatever your other weird approach is, relatively high productivity due to a large library base (not just the standard library but also a huge amount of stuff written to support android apps), and ease of hiring/replacement.
But to throw another onto the pile, Java being statically compiled makes it a lot easier to comprehend a larger codebase that you didn't necessarily write yourself. The history of dynamically-typed languages is basically getting to a certain critical size and realizing there's some merit to a well-defined, compiler-checkable code interface and then retconning it in - this happened with Facebook (Hack-lang), with Typescript/CoffeeScript (Google), and I think there's one for Python now too.
So yeah, basically people like Java because it's fast and versatile, because it's got a Pythonesque amount of stuff already written for it, and because it's got features that are oriented towards bigger teams with more turnover/etc that make it practical for business reasons.
Javascript in V8 is more performant than Java on a lot of tasks, and almost always 'sooner'. V8 is focused on 'getting going quickly' and it does, very fast. Java takes some time to optimize for most tasks.
Also, 'performance' isn't really an issue once you are past 'good enough'.
I don't think most devs are worried about Java/Node/Python/Golang performance on the backend for most apps. Obviously not always the case, but in most instances, it's not a primary concern.
Frankly, these days, when I think about 'performance' I think about 'developer performance!'. Java downsides in that its bureaucratic by convention, but at least it's super solid and reliable. I really, really wish it were a bight lighter however.
> Javascript in V8 is more performant than Java on a lot of tasks,
Source? I constantly see companies switching from the likes of python and javascript to compiled languages after they reach a certain scale.
I find Java to be extremely developer friendly, especially nowadays with features like pattern matching, records, switch expressions, and the upcoming project Loom
Modern frameworks like quarkus.io are also a step in that direction. You might also want to check out https://jodd.org/.
I've built V8 instances and run some tests, but you don't need to do that.
Just write some roughly equivalent code and run it in Chrome vs. JVM and see for yourself. It's not nuance or controversial, it will really 'stick out'.
In basically all cases, V8 will 'get fast very quickly', it reaches a high level of performance on the second or 3rd iteration of a bit of code, whereas Java takes thousands of iterations.
That's a very, very broad and crude generalisation, but you'll see it very clearly if you just try it yourself.
It actually does make a difference depending on what you are doing as well - if you're running as server that uses the same code paths all day long, and executes them 1K times per minute, well then Java is fine. But for things like UI I particular where yo need the code to react it's a problem.
'Developer friendly' and 'modern frameworks' are a another question.
Javascript is much closer to java than to python in terms of performance. And due to the variability of the JIT compilers, it can sometimes be faster than java, but generally the latter wins out.
But the parent poster is right that the two teams did choose a different workload to optimize for, V8 being fast faster while java taking more time to JIT compile a region, but that is mostly due to the difference between their most-common uses, running websites’ code as soon as they load vs mostly running on huge—ass servers with sometimes terabytes of RAM.
Go ahead and run some code on V8 and the equivalent Java.
You'll notice V8 is 'extremely fast' at getting up and running, while Java takes quite some time - often thousands of iterations of a specific bit of code before it optimises.
Oi Vei, I literally said 'fast at getting up and going' and 'over time Java is more optimised'.
Those tests ultimately measure 'peak performance'.
Java takes much longer to reach that level than V8.
Given the fact that a lot of software does not run for a long period of time, and especially UI/Web code (and possibly serverless), the net result is that V8 is basically faster. It gets too near 100% performance after 1 or 2 iterations. Java takes 1000's of iterations.
For many applications, the 'advantage of being fast soon' considerably outweighs any kind of incremental performance benefit that Java might offer over time.
This is mostly true for UI software.
V8 'is fairly quick, and right away'.
Java is 'sticky and slow for a bit, and then a bit faster over time but it's not noticeable'.
V8 is a regular car: stops and starts as needed. Java is a race-track stock car - accelerates up to a high speed and stays there. You don't need a race-track car to do food delivery, because the added peak performance is pointless.
"If you exclude the well performing languages java performs excellently."
But that is what I think OP means. It isn't top tier performance, but it is in the second tier which I wouldn't argue for qualifying for "relatively good".
FWIW I find that languages tend to fall into a couple rough performance groups:
- Native at about x1 performance: C, C++, Rust, Fortran
- Compiled GC at about 2x performance: Java, Go, Haskell, Lisp
- Dynamic at 20-50x native performance: Python, Ruby...
JS is a weird one that varies a lot depending on your workload and can sometimes look similar to compiled GC performance.
Yeah, I'd agree (with the sibling as well). Obviously native code is faster but Java is about as fast as it gets for a managed language. It's massively fast (these days) in comparison to, say, Ruby. Python manages to do relatively OK by throwing away any sense of threading and the synchronization of internals that might entail but it's still significantly slower than Java.
Speaking of which that's another advantage of Java. Threading works basically as expected, and now it's even got modern promise/future APIs. Python's "just clone all your memory and do everything through IPC" is super clunky in comparison.
In many cases, that's also inherited by other JVM languages, and interop is really cool there too. You can use Java libraries in your Scala/Kotlin/etc, or call those routines from your Java code. It's not just one language, it's all the languages on one engine, and they all run decently fast for what they are.
C#/DotNet is really fast too (I would say faster than Java if anything) and it's pretty similar to Java in most ways. Bytecode, JITed, static typing, etc. They also got the second-mover advantage, to see all the things Java did wrong and fix them - like checked exceptions, or the clone() interface. On the other hand, at least as of 10 years or so ago, the tooling was absolutely primitive compared to what's out there for JVM stuff (and at the time it was all tied to Windows). Maybe that's changed with Roslyn but they're coming from behind, and Java has been around for a long time and it's tough to overcome that inertia.
C#/.NET are cool. Ironically enough, Java is getting the second-mover advantage when it comes to green threads by means of Project Loom. Forgoing async/await for a much better experience.
1. GC is an enormous productivity improvement for applications whose performance characteristics can afford it. Seriously, I can't think of a single programming language feature/concept/technology that makes a bigger difference in developer velocity than memory safety and GC.
2. Static types are also a large productivity improvement for developers comfortable using them and the kinds of projects that benefit from them (large, multi-dev, multi-year).
3. Imperative and object-oriented. Java is imperative in the small, which is familiar to most developers and seems to strike a balance of letting developers write correct code with good performance. Java is OOP in the large and for many classes of applications, that's been a wildly successful way of organizing code and lowering the cognitive overhead.
4. Path dependence. The past largely determines the present. We don't reset all of our technology choices and start from scratch at the beginning of each fiscal quarter, so the languages that were widely used tend to stay the languages widely used.
Java was the first heavily engineering and marketed language that featured GC, static types, and OOP, so it got big and continues to stay big.
I also think it's a pretty decent language. The things people don't criticize about Java are mostly complaints about a certain style of programming in the 90s and less the language itself.
> I also think it's a pretty decent language. The things people don't criticize about Java are mostly complaints about a certain style of programming in the 90s and less the language itself.
(assuming that's a typo there, the things people don't like/the things people criticize?)
I disagree on that point, I think the language itself was a problem. Java 6 and prior were very very verbose and very very slow. I think that really changed with JDK 7/8, but the java we know today isn't the java of the 90s.
Even then, to some extent that problem hasn't gone away, it's just been papered over with frameworks and library code. Like honestly even as a java dev, I couldn't tell you off the top of my head the exact code to open a file, read each of the lines, and then close everything, or the right way to open a JNP connection to RabbitMQ or something. Anything touching files or sockets is still an absolute nightmare of boilerplate code, inputstreams, filestreams, printwriters, try/catch, and mother. fucking. IOException. thrown everywhere. But you don't care, because you just call Apache commons-io or Spring RestTemplate.
And that has contributed to some criticism of its own. Spring tends to turn into architecture-astronaut crap, like everyone's favorite AbstractSingletonProxyFactoryBean.
> Java was the first heavily engineering and marketed language that featured GC, static types, and OOP, so it got big and continues to stay big.
The other quiet boost that people don't talk about is Android. Tons of libraries get written with the intent of being used in some android app somewhere, but you can use that equally much on desktop/server. It really really helps the rapid-prototyping aspect of Java that ~half the smartphones in the world are running Android.
> (assuming that's a typo there, the things people don't like/the things people criticize?)
Oops, yes, sorry.
> Java 6 and prior were very very verbose and very very slow.
It's kind of verbose, when looking at it from today's perspective, but at the time I didn't think it was that bad. I think they deliberately tried to be less cryptic and more wordy than C/C++ (which can often be impenatrable). I think they overcorrected for that, but I don't think the language is interolerably verbose.
Performance was definitely bad until Lars Bak and company showed up and wrote HotSpot. But almost every managed language at the time had poor performance. It was certainly painfully slow compared to C and C++ but... what wasn't?
> I couldn't tell you off the top of my head the exact code to open a file, read each of the lines, and then close everything, or the right way to open a JNP connection to RabbitMQ or something.
I mean, I couldn't tell you how to do that off the top of my head in just about any language. Except C. But, of course, the code I would write for C off the top of my head is simple and wrong because it doesn't handle all of the various ways IO can fail.
Networking and file systems are honestly just kind of grungy. You can paper over it with simple APIs but what you end up with is code that looks pretty but can fail in obscure ways.
> try/catch, and mother. fucking. IOException. thrown everywhere.
Yeah, checked exceptions were simply a mistake. I don't fault them for trying to fit exceptions into the static type system. It was a cool, ambitious idea. At the time, no one really had a sense of how the ecosystem would settle around using exceptions. In practice, it ended up being more trouble than it's worth.
> The other quiet boost that people don't talk about is Android.
Android is definitely keeping it popular these days, but Java was huge because of server development before Android came along.
Depends on which implementations you're talking about.
But even fast Smalltalks weren't very fast relative to C, just relative to most other dynamic languages. And, of course, the people who made Smalltalk fast ended up making Java even faster.
Were there fast managed object-oriented languages? Yes, Self and a Smalltalk or two.
Were there fast managed statically typed languages? Yes, SML and Haskell.
Where there fast, managed, statically typed, and object-oriented languages? Not many. Maybe Eiffel, but that was shackled by DbC dogmatism and probably some amount of Eurocentricity. I don't think Ada had GC back then and if your complaint is that Java is too verbose, you sure as heck aren't gonna like Ada.
Java values backwards compatibility very highly, so if something runs today, it's likely to keep running without modification on future JVMs. (Though the 8->9 transition was pretty rough for some.) Compiled Java artifacts are usually portable across OSes and CPU architectures, so your build pipeline can be pretty simple even if your infrastructure is not.
JVM performance is generally fine, and the language prevents you from introducing whole classes of memory safety bugs. You can still shoot yourself in the foot with native (JNI) extensions, but the decent performance of the JVM makes developers use JNI far less frequently than, say, Python or Ruby devs reach for compiled libraries.
JVM byte code decompilation is fairly trivial, so tools for the security scanning of artifacts are cheaper and more fully featured than similar tools for scanning machine code.
> Java values backwards compatibility very highly, so if something runs today, it's likely to keep running without modification on future JVMs.
this has been the case in the past, but Java is gritting its teeth and making some breaking changes in the JDK11/16/18 era.
libraries that mess with the unsafe/internal namespaces are the most prominent example - there are a ton of legacy libraries that are going to break from that change unless updated - but there's also a big push for modules and for classes to encapsulate themselves more strongly.
Which is essential for the longevity of a platform. You can’t further develop the JVM if you are bogged down by code depending on the internals. Encapsulation by modules is hugely important, and if we are honest, anything that depended on internals were prone to bugs anyways. Sure it sucks, but they will update sooner or later
JavaFX isn't guaranteed to be in a JVM. You run into "deprecated" APIs that were removed. JVM options change, and that breaks how things are deployed. If the JVM were a stable target a site like http://whichjdk.com/ wouldn't be necessary.
This is just how things are. It's Java fanfiction to say this isn't the case, and necessitates having multiple JVMs installed.
http://whichjdk.net seems to be a site that tells me not to use the Oracle JDK without a license? There's a listing of which releases were the first to include certain language features, but it seems to mainly be giving advice around JDK vendors, not JDK versions.
There are two kinds of backwards compatibility at play: BC for compiled artifacts (let's call this Java ABI compatibility) and BC for language APIs (Java API compatibility). I have run into issues trying to compile an application with one JDK version and then run it on another (specifically, I believe JVMs will generally not run artifacts compiled with a later JDK version), but API backwards incompatibility is really rare in Java.
I do recall having to do a bit of cleanup when a previous project moved from Java 8 to Java 11, since a ton of deprecated APIs were pruned in Java 9, but those APIs were published by the JDK authors as standalone JARs, so I could remediate by adding a maven dependency. JVM backwards compatibility isn't perfect, but it's a much more stable target than other languages I've worked in.
an odd one for me is JNLP - I have a motherboard with IPMI and they chose to do that through JNLP, which makes it an absolute pain in the ass to use the interface.
There are occasionally breaking changes but most old jars out there will run fine in the latest runtime, so the answer to your question is going to depend on how squirrely your use case is.
The JVM is great. It's easy(-ish) to deploy and there is a library for anything you can possibly think of, probably more than one, on Maven. It handles large throughput and big memory usage very well and is extremely tunable.
Using the JVM doesn't mean you're limited to Java anymore, and hasn't for a long time. I have built software for the JVM for the past 6+ years nearly exclusively in Clojure with only a few moments where I needed to dip down into Java proper.
Can confirm. Been learning Clojure lately (after using Python for a long time) and it's great. That being said, the JVM is a bit chunky in terms of disk usage and when you get into really high performance things, tuning heap space and whatnot is a pain (I'm looking at you ElasticSearch), but it really is a fantastic piece of engineering.
The language is simple. Reasonable performance, lots of opportunities to tune that performance without changing code. Great error handling. Works across all platforms in most cases. The tooling has a long standing reputation for being incredible, given what Eclipse and Jetbrains have done for the community. It integrates nicely with native code, and is easy enough to interface with (compared to e.g. Node.js and python, which have hellish bindings). Strictly typed, which has a lot of benefits. Lots of long-standing libraries that have been battle tested and still work even today. Great ability to mock, inject, and invert dependencies.
No language is perfect of course, the point isn't to start a war. I don't personally use Java for my own projects anymore but I can see why it's very attractive.
Great error handling? What does that mean? Checked exceptions seem cool at first, but are really just nonsense… as your only real way of dealing with this is:
1. Catch, log and rethrow, or
2. Wrap as a runtime exception (so you don’t have to change every method signature up to main())
Sure, there’s option 3: catch and handle… but this is used 1/50 times, and the ergonomics of (2) overwhelm the utility of this.
BTW, vavr is nice. Just, “run it all” and optimize for the golden path. If there’s an error account for it locally.
Anyone not seriously considering option 3 as the default, with options 1 and 2 being the exception that one must have good reason to take, automatically disqualifies himself as ignorant of proper error handling.
Of course you catch and handle errors. Or at the very least you must think about whether it makes sense to handle an error on the current abstraction level that you are on, which means you must always consider option 3. Only if you decide that it's not possible or doesn't make sense to handle it ("I am too lazy" is not a reason to not handle it!) you decide whether you need to throw it one level up the stack. And if doing that is the sensible thing, you think about whether you want to make the exception part of the API of whatever you currently write or not. If you want to, you throw the exception without doing anything (most of the time you don't even log it, because you understand that the receiver at the end, the one who finally handles it, is responsible of logging it, otherwise you get multiple logs of the same exception written out just because someone sprinkled logging into several abstraction layers). If you want to hide the exception type somehow, you wrap it in a more fitting exception that's explicitly or implicitly part of the API of whatever you're writing, and throw that one. That can, but doesn't have to be, a runtime exception.
I really don't get what's so hard about exception handling. Java's exceptions are a pretty good analog to how one must model proper error handling in multi-layered software applications anyway, regardless of the programming model used to implement it.
By your opinion 90%+ of Java ecosystem is ignorant of proper error handling, which in itself is a statement on how poorly this method of error handling is looked at.
I have seen quite a bit of code in the Java ecosystem over more than 15 years, but far less than 90% of it. And even in the small slice that I've seen, I'd say the quota of ignorant error handling is way lower than 90%. Especially the higher-quality Java libraries that people reuse over and over usually behave okay with regard to exception handling nowadays.
sure. consider me ignorant of proper error handling.
looks like the "true scotsman problem", though. i'm using state of the art packages like jgrapht which throw runtime exceptions, and i'm manually catching those runtime exceptions, pattern matching on the exception messages, and trying to handle.
when the community doesn't use the API, it's a tragedy of the commons problem. there's a lot of grey area between what constitutes a runtime exception vs. a checked exception. it's all very subjective!
This is not as useless as it sounds. You can analyse the logs and find out why these exceptions are occurring. A lot of times these lead you to subtle bugs which you might not have noticed otherwise.
Was referring more to structured stack traces. You're able to shoot yourself in the foot in any language's error handling system - quite trivially at that.
That's not the real problem with checked exceptions in Java.
You actually have the same problem with any result type in a language with static types and mandatory explicit types in function signatures - you change one type and you have to adjust the callers, sometimes many levels above. This is just life ;)
One of biggest troubles with checked exceptions is that in Java it is impossible to generify them the same way you can do with argument and return types. You can't write a generic filter or map function that throws the same checked exceptions as the lambda (or any other interface object) that gets passed as an argument. This makes it impossible to use code that throws checked exceptions in some contexts and forces developers to wrap them in RuntimeException.
And because those situations are extremely common these days, especially after some FP techniques influenced how Java code is being written, almost noone uses checked exceptions and you typically get runtime exceptions flying around the whole codebase. Which are even worse - they turn very quickly into an unmaintainable mess - because now any function can throw just anything at any time, and that's not even explicitly visible.
And here we get to the next big problem with exceptions (not just checked exceptions): they add a high number of alternative control flows you need to analyze in addition to the main "happy path" of the program. An exception can happen anywhere and it might leave the data in incorrect, partially updated state. In reality many devs simply pretend the problem doesn't exist, and they check the happy path only. In languages with no exceptions, a function can exit only by an explicit return - and that is way more readable and easier to analyze.
And the last thing which seems to be more a cultural problem, rather than a Java problem, is that somehow most Java programs communicate typical, expected problems with ugly and mostly useless exception stacktraces. Can't connect to a host? I get a stacktrace. File not found? Two screens of stacktraces... That's IMHO a terrible approach to error handling. As a user I am totally uninterested in what code was being executed when something failed (that should be reported only for bugs so the developers can fix). I'm interested in getting a human-readable message with context helping me understand what went wrong and how to fix it.
It isn't? You have a function red that doesn't throws anything you use a function blue that throws checked exceptions you handle the exception and it's all. The red functions doesn't become blue.
if the "red" function isn't successful, than you're mapping that error to what? a RuntimeException? great – you've now escaped the indirection with the original solution – just use RuntimeExceptions.
map it to another checked exception and you now have a "blue" function. and, you also have another layer of abstraction in your errors.
if you can't actually handle the error, skip the circus and just let the exception propagate to a general error boundary (alongside all those RuntimeExceptions you're unaware of).
It's a deep ocean, your defense mechanism of guarding against Checked Exceptions is a small fraction of all exceptions.
To be fair, I did really like the idea of checked functions when I first started using Java. But in practice, it's just too hard to tell what operations should be Checked / Unchecked (sometimes).
No one really uses checked exceptions. But I agree they suck, IOException is the bane of my existence. It's the #1 reason why I don't like Rust or Go. Checking errors is dreadful.
That's true, but that doesn't mean we should pretend the problem does not exist.
Using unchecked exceptions is sweeping things under the carpet. Generally unchecked exceptions should be used only for bugs (array index out of bounds) or unrecoverable situations (JVM crash, no memory). I/O does not belong there.
Because Java is stable and mature, has well-understood performance, is statically-typed, has a proven track record when it comes to backwards compatibility, is reasonably fast and has lots of library and tooling support. Additionally lots of people know it.
Some complain about verbosity. It's really a non-issue particularly in a modern IDE and not worth making a language decision over.
Definitely an issue in 8. My hack is to call everything an `int`, write the statement, and go back and let IntelliJ handle the proper name, adding the import, etc.
I understand though, that in more recent versions of Java this is taken care of for you.
Java is easy to understand and it's hard to shoot yourself in the foot with (no raw memory access, unless you use JNI/JNA). Garbage collector makes memory management a non-issue. Exceptions make error handling easy. OOP is a simple concept and many real-world programming tasks can be laid out as a nice class hierarchy. Java's changes are few (as opposed to some other languages), feel logical (to me at least), and solve real problems. Most of "syntactic sugar" features don't make the code using them less readable.
Java also supposedly runs on everything. And, you could as well write Android apps in it.
If you actually understand Java, you'll understand why this is wrong. Only newbies have confusion about this, most of which dissipates when you actually learn the language you're working with. Tired of this 20+ year old "flaw" being used as cannon fodder.
In practice, how often are you interested in it? C# has `Object.referenceEquals()` because you _may_ want this sometimes. But to have reference equality be the default for something like `==` is a design flaw. Not one that can be fixed now, of course, but it will continue to cause bugs for years to come.
Dunno, I do a fair bit of low level java work, happens every once in a while.
Curiously, I don't do a lot of value-comparisons. Based on grepping in the repo for my search engine, I appear to do one every 1000 lines of code. May just be how I write code though. Some people seem to do that a lot more.
Python uses the `is` operator, which is semantically much more explicit (and arguably correct, though C#'s use of the `is` operator is probably more correct).
Look, languages are moving away from permitting constructs like "if (x = 1)" because it's difficult to distinguish from "if (x == 1)". Adding "if (x === 1)" into the mix is arguably a step backwards in terms of clarity.
This is like saying that null references are a non-issue because it have been there since the 1970s and that "true" $LANGUAGE developers never collide head-first into invalid dereferences. If something is ridiculous and un-ergonomic, it stays ridiculous and un-ergonomic no matter what. Reference comparison by default is ridiculous and un-ergonomic.
Null references exist in every language with the concept of null. It has nothing to do with Java specifically, and Java gives you a lot of information to debug them.
For what it’s worth any decent IDE will warn you about that. But as a Java developer you know it’s wrong, Strings are objects and that’s not how you compare objects.
The tricky one is numbers.
Integer == int // fine
int == int // fine
numVarOne == numVarTwo // Uh-oh
In that third example you better make sure they aren’t both boxed objects or BigDecimals.
I’ve almost never seen the string one for some reason. It’s always boxed numbers.
Yep. I’ve been bitten by that myself. It’s sneaky because it may pass all your unit tests because you’re using small numbers. Then it gets to prod with record number 2718 and kablooie.
Only if you skip all the tutorials and don't use an editor that warns you about it. Which is another selling point for Java; it has the best editor support and quality assurance tools out there. It took years for e.g. Javascript to catch up and it's still a far cry from a proper typed language with tooling.
I mean by that same logic, Javascript will confuse you as well because `{} != {}`, or C++ because of pointer mechanisms and custom operators.
It's really says a lot that you have to compare with JS or Cpp so that Java comes out on top. Those are 2 extremely flawed languages that are the butts of cliché jokes well-known across every programming circle, their history alone has "HACK" written all over it.
Still, coming from other languages, it is all too easy to write this and this silently fails without any warning.
This is consistent with the rest of the language, but I'd bet one rarely wants referential equality when comparing strings.
People commenting "yeah but that's because you are a newbie / you are comparing references and you should know better" miss the point I think. I can easily see myself making this mistake while fully understanding what's going on.
Basically the tooling around Java is very evolved and Java static type system helps the IDEs a lot. One of the main reason enterprises prefer Java. Also majority of the tools and IDEs is free for commercial use.
I learned this 25 years ago when I got started with the language. It tripped me up once, I learned about how references work in Java, and that was that.
I learnt C years before Java, it's also the first language I properly learnt. And a little bit of C++ too, so I've known the concepts of pointers and references way before learning Java. In C, you also either do pointer equality or explicit value equality (with strcmp) for string equality tests. I never had any issue understanding how things work in Java. It's not about learning anything. It's about doing mistakes. And I won't take "you should know better" as a counter argument to a mention of some rough edge in an API or a programming language. It's like Javascript: you might know the differences between == and === in Javascript full well, but still happen to write == by mistake because you just wrote some C/Java/Python code just before. I'll probably not forget about .equals(...) in Java most of the time but the fact that == would be silently accepted and not do what is wanted is still a bit concerning (and .equals(...) is ugly, too).
A linter will do indeed and that's a fair point. I'd argue that linters are there to work around rough edges of programming languages, but that's fair enough too, every programming language has its gotchas and I'll accept considering a programming language + its linter(s) instead of a programming language alone. However, that's still not ideal because you might have to work on non linted code and deal with these gotchas without any safety net.
I hadn't thought about number comparisons (mentioned in other comments) but that's even worse indeed.
It's no wonder Kotlin and Groovy both chose value comparison for ==.
For me the choice is really about the JVM, rather than going with Microsoft and .NET. I work mostly in Clojure, which runs on the JVM. But I have the whole universe of Java libraries available to me. Whatever flavor of language you are into, you will find something that runs on the JVM.
The competition includes languages like Rust, Go, Haskell or Erlang. Most of these lack the languages that you'll find on the JVM, so it really is a question of what you are trying to do. Go is certainly interesting in some places, especially if you want a binary that is entirely self sufficient. Each of these languages is interesting, though of course one has to wonder about hiring, whereas finding developers who've worked on the JVM is easy enough.
I think it has a relative speed performance over languages that are interpreted (runtime).
It also has an ecosystem of tooling to monitor and profile built both into the JDKs and by teams across Silicon Valley (eg first class bazel support).
I’m in one of these companies now, and while I’m certainly productive using Java, it’s also got huge downside in the community which these companies don’t really care about.
Never have I seen so much cargo cult practice. The ecosystem isn’t great, with hard to google docs and everything pointing you to a poorly written baeldung article.
Java gets no one excited. And, it gets no one fired.
Actually, i like it for basic desktop apps, because it just works, and i stay clear of the last 12 years of front-end dumpster fires, where nothing that is over 18 months old, can build, compile or get support anymore. In my day job, I inherit "fun" tasks as 'get this thing someone glued together with webpack4 and frontend-du-jour to work with webpack5 in 2022. Java thank you, any day of the week.
It's a combination of JavaFX, a custom controls library that implements Material Design and GraalVM native image. Whether you want a non-native UI toolkit on iOS is a separate matter, but it can be done technically.
In fact, you can ship JavaFX apps to the web too. It doesn't compile to megabytes of JS either - instead, the JavaFX app runs on the server and the UI is projected to divs and SVG elements on the fly. The browser provides native scrolling and text selection. If you have low latency to the server (e.g. same continent) it can work remarkably well. Check out https://www.jpro.one/ - the entire website is a JavaFX app.
I feel like those crying cargo-cult or enterprise never stopped to look at the alternatives they use. Like Django or Rails. It's in many ways worse than java when it comes to conventions, abstractions doing magic, and weird rules for structuring code.
i've got tons of open source packages on my github with interpreted languages :p
But yeah, I guess i first started using Django ~2008 if I recall correctly, and switched over to Pyramid in 2010. Since then, I've used many other frameworks – in Python, Ruby, JS, C#, Java, and Go. Regardless of the language, I always try and go closer to the metal when I can.
I think your assessment about the others being potentially worse is fair: they're all bad in their own ways. I think it just takes time (and experience across many different teams) to develop good taste.
* It's very fault tolerant. In almost every case C++ would mushroom cloud, Java can walk it off. It's easy to write code that cleans itself up on error. try-with-resources is great.
* Modern JVM JIT and GC are pretty damn good, and the tooling is great.
* It's very boring and stable. I see this as the killer feature. Cool is a conserved quantity. It's extremely hard to write cool software in a cool language, as that attracts cool developers too busy getting cool jobs to maintain their cool framework you depended on. There's a lot of mature high quality libraries available. APIs are stable, stuff very seldom breaks. You can often use code that's 10-15 years old just fine. This has changed a bit lately, but it's still extremely reliable.
There are drawbacks as well, primarily memory mapping files is difficult, some of the aforementioned libraries are a bit bloated as well and overall the language sort of encourages large complicated solutions to simple problems.
Language with a fast runtime minus startup (although maybe they've fixed the startup since I last looked) that is incredibly tunable to fit your specific needs for good performance profile, while not needing to manage raw memory the way c or c++ would.
Personally I prefer c#, but a lot of places already were using Java in significant ways before c# became good (IMO 2.0ish) and saw no reason to change.
Java’s startup only slows down when a ton of classes have to be loaded, e.g. that’s why Clojure’s repl takes quite some time as you are loading two standard libs.
But noone cares about hello world. You're not building hello-worlds in real life.
Slow startup time is a problem in automated testing of big codebases - when you aim to test the whole codebase, but each test alone does not stress any code path hard enough for the hotspot compiler to kick in. So basically most of your Java code in testing runs in interpreted mode, which is like 20x-100x slower than properly compiled and optimized C/C++/Rust.
If no code path gets run enough times, then frankly, it simply doesn’t matter, they could have been written in bash and still be “fast enough”.
Like, I can’t fathom a program that doesn’t have loops where the actually important part happens. You simply can’t write enough “linear” code to make a modern CPU sweat even just a little. And if you do have said loop, than it will be JIT compiled.
But it's not just interpreting linear code. It is also classloading which involves a non-trivial amount of work before any code in a class can even run. Also I never said the testing code doesn't have any loops. There often are loops but they need to run for a really long time until hotspot kicks in. So if you lose a few tens of millisecond here and there in a single test, you will get minutes or hours in total in a codebase that has hundreds of thousands tests. And it gets terribly worse if many of your tests are end-to-end tests that e.g. launch new JVMs.
It's a stable and well proven technology that still has a lot of developer activity. Businesses are trying to make money, not explore technology, so a lot of them don't want to bother risking deliverables on something they may not have experience with.
Java had so many marketing crazes that it's crazy. I still remember the "Java mobile game" fad from a dozen of years ago - Java this, Java that, Java for phone, Java for toaster...
At some point, the public mind starts to associate "programming" with Java. Since there were (and probably always will be, unless we evolve into utopia) hordes of job-desperate people who would do anything to feed themselves and their families, a lot of them hear about Java, start programming in Java and develop their whole world around Java. Java helps them with this by providing this huge, Java-centric ecosystem which gives you everything you ever need to do whatever you want to do.
Of course, there is also the fact that Java is a managed environment and makes it a lot harder for programmers to write broken code, which makes large-scale programming possible even if all you have is a horde of mediocre programmers. But then again, that property is not unique to Java.
I see this post is getting some downvotes; I'm not sure I agree with all of it myself. But I would ask those, who reject the premise here outright, to think back really hard to how things were in the 1990s. The Java brand was everywhere. It was a truly massive endeavour and one of the first languages to really go "viral" as the Solution For Everything.
People laugh at the cute "Java runs on four billion devices!" tagline but back in 1995 if you weren't doing Java, you were a last-century coder. It was so pervasive Brendan Eich even renamed his strange scheme-smalltalk mashup "JavaScript".
No, but I think it's a big contributor to the network effect advantage Java has.
I'm not bashing the language - it certainly has its defenders. Some people regard simplicity as a virtue (although I'd question how simple Java is nowadays). But I think even ardent Java fans will concede, Java has some deficiencies as a language. The main reason people use Java, is that people know Java. And the main reason they know Java, is because it is used.
I mean, Java is not a liked language by any metrics, so I guess fans (myself included) are more than used to bashing. That’s why I don’t think that marketing helped the language become as great as it is. Sure, it had a part, but if something would have been substantially better it could have taken over a long time since java is not hypes at all anymore.
What else would you use? Java is the shark that ate everyone else's lunch. At this point all you have as alternatives in the category of "easy to use for backend type stuff" is C#, and go. Both of which have their pros and cons but on the whole aren't bad choices. I guess like bellbottoms, Java is making a fashionable comeback.
Kotlin is actually the natural upgrade from Java if you want something that feels more modern than Java. Very easy to switch to from Java: a conversion tool is actually built into intellij.
For most traditional Java frameworks (like Spring or Quarkus), Kotlin has long been a first class citizen (support, documentation, custom Kotlin extension functions, etc.) and probably the easier language to use when you are starting out with those frameworks. And of course on Android, it has long replaced Java as the default language.
On the server server-side, Spring has done so much work on integrating with Kotlin in the last five years that you are probably not doing yourself any favors if you choose not to use that. Kotlin DSL support is just a killer feature here. Spring has really embraced that and they've added nice Kotlin DSLs for pretty much everything that matters. No more builders. No more endless function chaining. No more annotation magic (or at least a lot less of it).
I'd been eagerly following Kotlin since it was announced in the early 2010s, and could hardly contain myself when I finally got to try it out in real life about a year ago. But... honestly, in 2021, it was underwhelming.
- Compiler performance, especially of mixed Java/Kotlin compilation, is spotty.
- Support and tooling maturity is way behind Java. I'm trying to use it with Bazel, but the support lags far behind the Java equivalents.
- Interop with Java libraries that use annotations or interfaces is maddening.
- Perhaps a matter of taste, but the `var` keyword is a blight, even in Java.
- for all the complaints about "== vs .equals" and that sort of thing, these are by now incredibly well understood pitfalls that are generally checked by static analysis, sometimes even at compile time now by e.g. ErrorProne
In the early days, when it seemed like Java development might stall because of legal hell, Kotlin was a breath of fresh air. But today now, Java is clearly on a path to cannibalize Kotlin's most valuable features. Record classes and pattern matching obviate the biggest draws of Kotlin, while maintaining the buttoned-up, no-fun-but-extremely-pragmatic rigor of the Java language.
Once the glow started to fade, I was left with a very boring, familiar question: what am I really gaining by using this new tool? Is it worth the cost? and on my list of problems I deal with daily as a Java developer, the problems addressed by Kotlin are now so far down on the list that it's not worth dealing with even the tooling friction imo. For me, anyways.
But Kotlin will never be first class citizen on the JVM itself. Also, I feel like kotlin is falling in-between all the platforms it try to handle (android, native, js), which might not be a good thing to do.
Those statistics are a bit misleading because there is a lot of legacy Java code out there.
You can see that in the statistics for Java 8 in the link you provided. 37% is still stuck on Java 8. That's quite old. We're talking about projects that have not updated anything in close to ten years. And some even use older versions than that apparently.
That's not because those versions were that good but because some people just are that conservative. Java was always popular with conservative companies like banks. Companies like that are likely not using anything released in the last six years. According to Jrebel, that's about half of the survey. You can read into that what you want. But it's kind of meaningless for new projects.
Kotlin had their 1.0 release only six years ago. Spring boot 2.0 followed two years later and that was the first version to incorporate a lot of Kotlin and add explicit support for it.
It would be more interesting to get some statistics for Spring Boot 2 projects and Kotlin usage. Or even break them down by point release (2.7 is coming out soon) and there should be a version 3 by november as well. I'd expect a jump in Kotlin users with each of those point releases. JDK 17 / Kotlin 1.6 are going to be the minimum supported version for v3.
So, the percentage of users of anything over java 12 vs kotlin users is kind of suggestive: 12% vs 8%. Modern Java seems to be not that much more popular than Kotlin. And of course there's a difference between people that have upgraded their JVM and those that are actually actively using the new language features in Java.
Kotlin can target Java 8 JVMs, yet hardly anyone adopts it in a meaningful way without papa Google forcing it.
It would also be interesting to compare those Spring Kotlin numbers against the versions back when Spring was equally motivated to support Scala and Groovy a decade ago.
In any case it hardly matters when the platform only supports Java out of the box on the JDK, without extra tooling, and anything besides InteliJ is a second class experience.
It isn't what Android devs say, always complaining about compilation times, IDE freeze ups with.
InteliJ is partially written in Kotlin, unless they decided to port everything on top of Kotlin/Native.
As for why Kotlin exists at all,
> And while the development tools for Kotlin itself are going to be free and open-source, the support for the enterprise development frameworks and tools will remain part of IntelliJ IDEA Ultimate, the commercial version of the IDE. And of course the framework support will be fully integrated with Kotlin.
Java developers are cheap and easy to find. There are libraries for everything that you would need - AWS SDK, Redis, etc. Performance is tolerable and can be improved with things like Micronaut and native ahead of time compilation (GraalVM).
Good <insert any language> coders are generally amongst the best paid ones, but let's be honest an average Java developer is lost if they can't find an annotation to solve their problem. It was the "default mid-tier university language" for a while, and it really shows in quality of people who apply.
it's really bimodal imo, there's a tier of sweatshop contractor job that pays $50-70k (or did before salaries got nuts the last few years) and then senior jobs pay $140k ish average now. Senior getting paid more isn't new but it seems like maybe a 2x ratio is higher than elsewhere.
As opposed to what developers that aren't cheap? Node.js? PHP? C#? Python? I have no idea what developer you're talking about here. Do you think JEE developers are cheap?
Because Java is engineered. You can imagine the amount of work going into it. You have multiple companies have whole teams working just on different garbage collection algorithms. No other dev stack has this kind of focus. The JVM is a small wonder. And Java is evolving quite nicely too.
JVM echo system / tools / libraries / performance is awesome. Frameworks like Spring/Spring Boot have made JVM the default choice for many big tech. It is a no brainer and it works. No one will ever get fired for choosing Spring Boot for a new project :)
Its popular because it was popular. C#/Go/Rust/Scala/Kotlin have some advantages over Java but aren't worth switching because Java works fine. Java has been around a long time and lots of people know it.
Great tooling. Good performance. The JVM is very tunable. Huge ecosystem of libraries. Language wise modern Java is fine, but if not, there are other languages on the JVM that interop.
With Java comes the whole JVM which is equal parts blessing and curse. You no longer need to know a bunch of OS details, but you pay in overhead.
From a business standpoint, there are lots and lots of Java programmers out there. Of course that doesn't reflect anything about the average skill of those programmers..
For a typical business app, I really don’t think there is all that much overhead. Java is very fast, virtual calls are basically free due to the JIT, and these apps usually don’t need that much cache coherency for issuing an SQL query for a request. It’s not decoding video.
If you think 512mb of base memory usage is "nothing" and you're ok with slow program start times, that's probably fine.
If you're like me and you sort of get sad when your program uses more than 64mb when idle because it feels wasteful, then yeah that overhead is pretty gnarly.
"But we have servers with hundreds of gigs of ram!" you might respond - and sure, we do, but having resources doesn't mean you have to use them. It is better to write small fast efficient programs than extravagant enterprise stuff.
What about the fact that Java is the most energy efficient managed language? Not constantly crunching through memory to choose which memory should be freed is efficiency, not laziness/bloat.
Sure, there are use cases where it is not a reasonable tradeoff, but for CRUD business apps, it is perfectly fine. Especially given that not all cores can be used uniformly.
Tooling is quite good with IntelliJ and Gradle, Kotlin is neat. It's pretty fast, allows for high level'ish programming and is verrrry widely used (many like to claim this helps for finding devs, seen by many others as the super scarcest thing producing software, but i beg to differ).
First comer advantage. Initial Java was a robust, yet simple, sane build tools, relatively safe, typed language when most everything else was c or c++ and not as "safe" (modern c++ is actually very safe language if you stick to its guidelines however). Over time Java has become almost as complicated as Modern C++ but people picked it up over time mostly. It's still used because it's still a robust general purpose language, tons of libraries, huge corps don't like to rewrite things, and there are lots of Java programmers out there. Don't let the webstack blind you, there is a whole other world out there of backend, embedded, finance, and legacy stuff that hackernews audience is just a small part of.
One thing that is not mentioned is security. There are java libraries for almost everything. And when something is implemented in Java it is much harder to exploit.
Python and node are both great but mostly just wrap C libraries, so If openssl or your database driver has a bug your fancy interpreted/sandboxed language does not help.
Java has existed a long time and developers have had time to reimplement many popular protocols and libraries. This can sometimes cause few % points of performance, but you get stability and the excellent monitoring&debugging.
For example, if I need to accept images from the internet I would use Java since there are pure java image libraries that cannot be exploited with unexpected data. At most it fails and everything is cleaned up.
This is an interesting question. Not because of Java (that is answered) but because of the alternatives. Kotlin/Scala/C#/F# are the same stack types, C/C++/Rust are lower level, leaving it realistically (job market) to Python, JavaScript and Go. Python and JavaScript are quickly sorted out as non static typed and Go is still not in the league of Java or .NET despite all it's amaziness.
So it boils down to: do the people like static typing or not.
1) network effects, around runtime and core library especially. IMO, for enterprise, runtime is especially sticky.
2) of the JVM languages, Java will (always?) be the easiest to hire for
Java (and .NET) have vast ecosystems with lots of developer experience, a massive standard library, a big selection of 3rd-party packages, vendors and services, solid backwards compatibility and deployment stability, and tons of research/development constantly making everything better.
Contrary to the Silicon Valley popular opinion, these languages are incredibly productive and run much of the world, with code running in all of the Fortune 500 companies down to small businesses and even your phones.
It's popular for the same reason C++ and JS are popular, hype trains and lock-in. There's no good reason to use it in a new project, people saying "Performance" and "Tooling" need to take a good long fresh look at the language landscape, we're not in 2005.
A trivially easy replacement would be Kotlin, it compiles to the same VM (and additionally webassembly), it is designed and implemented by one of the leading IDE vendors, it can trivially call and be called from Java, it has tons of zero-cost syntactic sugar that covers the inhumane verbosity that Java buries you under till your eyes bleed and your hands scream. A well-designed language, what should have been all along.
not op, but in my company: all the people who wrote the systems left decades ago for better paying gigs. Broken CI/CD culture, DevOperations people are afraid to write (or unwilling to learn) IaC for deployments, must manage things by GUI (made at the time when JDK 1.8 was released). Developers are not engaged nor motivated to learn new tooling/best practices nor interested in migrating off JDK 8, since it just 'works' so why change it. Mgmt does not know much about tech so does not know that 'severe' technical rot is happening
I think for most people it's the introduction of the module system. If it causes code to break in libraries you're using and there's no direct replacement for those libraries, it's a big hill to get over.
I think it's a mix of complacency, the change to a LTS model, internal governance, and lack of awareness. The company will only get off their ass once 1.8 no longer receives any updates. Looking at some of the older tickets in the system, this was the case when java 7 was no longer supported (massive influx of migration tickets in '15).
A Spring Boot project with a good number of dependencies, the bleeding edge Spring Boot supports newer Java, but then you need to worry about Hibernate's compatibility with the latest Spring Boot, etc.
I think at least some of my dependencies still rely on reflection features that are limited by Java 9.
In my case: infrastructure group declines to support different Java versions for different use cases. We have a lot of Spark 2.x code, like thousands of different jobs. Spark 2.x only supports Java 8.
Wow, that's a really well-established feature to remove. But reading "JEP 421: Deprecate Finalization for Removal" [1] did convince me it's a good idea to deprecate it. I'm suspicious they'll never ever actually be able to remove them, given the reality of maintaining backwards compatibility.
They removed much bigger things, and broke backwards compatibility in much bigger ways. Finalizers aren't really used much in Java except for safety checks ("you forgot to close this object"), which can go missing without breaking things.
If you are leaking file descriptors in a production service it will absolutely break things. Generally most servers that aren't pushing the FD limit can get away with delayed reclamation of FDs but if you never claim them you will run into problems.
Plus most code probably handles this poorly. I suspect it will often result in exceptions opening new files or connection which are just caught and retried forever, resulting in your server locking up after some period of time. If you are lucky it just crashes and restarts. (The ultimate garbage collection.)
Java has the Cleaner API as a possible solution for this. (Also, try-with-resources is really great generally)
But I agree with you, it is anecdotically a problem for me right now as well: intellij under osx can’t index/import a bigger work project due to getting too many files IO exceptions all around, even though I tried increasing both the system limit, the java vm flag, everything..
Backwards compatibility. Forwards compatibility isn't well supported by Java, or any other platform. The best you can do is catch exceptions and route around them, or use reflection for that.
Examples of things that have been or are being removed more important than finalizers:
- As noted, SecurityManager deprecation
- JavaFX. It was bundled in Java 8, lots of apps were written on that assumption, then it was removed. They all had to be re-packaged.
- Web Start.
- Removal of access to JDK internals in general, which lots of stuff depended on.
- Removal of various Oracle Java specific stuff, e.g. the resource management/control API.
- Java EE stuff. Annoying because a lot of stuff used it only for a few utilities, and because it actually got renamespaced so you couldn't even just add in the packages from elsewhere.
And there were lots of other backwards compatibility breaks, e.g. when they changed the format of the version number a lot of stuff broke.Probably more that I've forgotten.
Java is a great platform and I use it all the time, but Java's backwards compatibility is highly overrated. They don't care about real apps at all, probably because they hardly use any. Their backwards compatibility is defined relative to their own specification, not working software, so important apps have broken repeatedly over time.
The simple HTTP server is a nice addition. I end up using python's SimpleHTTPServer for all sorts of things so it will be nice to have an alternative right in the JDK.
Ever since Java 11 enabled running single Java files directly without compiling them I've been using my own trivial single file web server for this purpose: https://github.com/ianopolous/simple-http-server
Still waiting for JNullType to be deleted or made illegal to inhabit all reference types.
"I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. In recent years, a number of program analysers like PREfix and PREfast in Microsoft have been used to check references, and give warnings if there is a risk they may be non-null. More recent programming languages like Spec# have introduced declarations for non-null references. This is the solution, which I rejected in 1965." -- Tony Hoare
Let's give credit to C# and Dart for fixing this, and bring shame to Java and Go for not doing so.
I gotta say, I'm impressed with what they put together for the FFM. Previous iterations were terrible, in the way only Oracle can. In particular the ability to upcall and to manage mostly-safe handles off-heap with a declarative API is pretty nice. However, if I understand this correctly, FFI calls are going to be limited to modules explicitly authorized on the command line, which blows and defeats the purpose of having all this safe stuff being required instead of manipulating pointers directly. I assume there's some kind of reason for this but it seems like it's just going to be extra noise limiting time-to-hello-world without benefit. It still remains the most relevant part of P/Invoke that it's so performant and clean that the standard library makes all its syscalls with it, rather than getting magic backdoors from the runtime.
JavaFX by far. The API is probably the nicest I ever used of any toolkit, it's got a lot of features, is maintained by multiple companies, is mature, has a well integrated WebKit control, good multimedia support, can do 3D effects, uses CSS, has a UI designer, is stable, runs on embedded, mobile, desktop and can be "projected" to web browsers using JPro, and most releases are just bug fixes these days.
Currently fully FRP UI is quite popular (Jetpack Compose, ReactJS etc) but frankly whenever I've read such codebases I've been somewhat unimpressed. You can make JavaFX work that way with a bit of extra utility code, and there are places where that approach makes sense, but fundamentally a well engineered OOP UI toolkit is in its element. The functional reactive approach seems to create quite a few problems. Whether it creates as many as it solves, I reserve judgement as I haven't had a chance to write a large GUI app since they came out. Still, I've written a lot of them in the past and would definitely be tempted to stick with JavaFX despite having worked through the Jetpack Compose tutorials.
Effective Java [0] is the Java book. It covers up to Java 9, and I expect the author will release another edition for Java 17 at some point.
Java 9-17 adds some major language features, but they're not so major that you'd really need a whole book. You could look up the individual JDK release notes and see what each release changed.
Most likely never, given Google's agenda to push Kotlin.
Android 13 is surprisingly adopting more Java 11 features, most likely because they need compatibility with Java libraries that have moved beyond the Android Java subset.
It's legitimately fascinating to see the rise of pattern matching, to the point that even Java will have it [1]! Combined with lambdas, this is a different language than the Java 1.5 that I first learned. If you would have told me that this would be valid Java code:
static void testStringOrNull(Object o) {
switch (o) {
case null, String s -> System.out.println("String: " + s);
}
}
I would never have believed you. And while it's not Elixir-level pattern matching, it's not toothless either. This is valid pattern matching code too:
static void testTriangle(Shape s) {
switch (s) {
case Triangle t && (t.calculateArea() > 100) ->
System.out.println("Large triangle");
default ->
System.out.println("A shape, possibly a small triangle");
}
}
Everything since Java 7 has been a pleasure. The language is so much more mature now. The only problem is enterprise companies giving it a bad name, but I guess that's the price you pay for its broad usage.
Do you think Enterprises will ever give up the mountain of "design patterns" that (IMHO) make Java less desirable to work in? The Enterprise FizzBuzz is funny because of how true it is [1].
2022.1 is coming shortly. In any case, one can easily specify jdk18 as the platform to use for a project. The IDE might not recognize some syntax, but the code will compile and run just fine.
I don't think they ever supported a JDK on the day of release, they don't seem to have any sort of inside-track that would allow them to fix bugs before then.