Even on the client where Java has lost to Javascript, I'm finding it more enjoyable to add features to my 15-year-old SWT app [0] rather than dealing with the multiple layers of abstractions that is Javascript+CSS+DOM (+ maybe Electron). Personally I think it's a shame Sun dropped the ball with client Java - if they had chosen SWT over Swing and provided a minimal JVM then maybe Java Web Start would have beaten Javascript web apps. It's also a shame Sun sold Java to Oracle - Google would have been a better steward, and probably would have been willing to pay more for the Java parts of Sun.
I'm now trying Dart to develop a few Flutter apps. It's no doubt a better language, but not that much better - I think Flutter would have been more successful if it was built on Java.
The flip side of Java's stability is stagnation. On the server-side, customers use mostly Spring/Spring Boot these days to make Java's overengineered stack usable, using even more over-engineering and metaprogramming. Same with maven/gradle, which turns what should be a developer-focussed build system into an enterprise XML mess.
SWT? I'm glad it works for you. Last I heard, IBM had pulled out of developing Eclipse and SWT/RCP over ten years ago. In the one project where we used it, the app looked like an IDE, and customers hated, then cancelled it. Designed as wrappers for OS-native GUI controls, it has even less of a place in a browser than Swing had. Last I looked, of the Java rich-client frameworks, only Swing has been updated with HIDPI support, whereas JavaFX and SWT haven't. None is using any of those (with the exception of experimental JFX apps) for new apps in this decade.
Whereas in the modern JS world, you start out with a lean project and then add small libraries from NPM that all work slightly different for every feature you need, in the Spring world where the framework has matured for 10+ years most of the things you will need are in the box or are available as external libraries that all work on the same defined interfaces.
Spring Boot with Java 11 or Kotlin are still my preferred backend stack for that reason. It’s solid, has aged well and makes me super productive.
Even stuff in “core” dependencies like webpack/yarn/npm/npx/nvm/babel changes a few times a year.
Right now doing a react native app and a browser extension. While javascript/typescript is fun to write, the time you have to spend fixing the tools is just horrible. Whiping cache, rebooting, switching package versions.. It makes the overall experience cumbersome.
I would not call something stable if it manages to work 2 whole years.
There was definitely an era of that, but over the past decade or so it's been acknowledged as a problem, and there's been a lot of effort put into making things simpler and more vanilla. Modern Spring is much much closer to plain old code. (Of course it's still possible to write in the XML/setter injection/afterPropertiesSet style, and always will be - that's backward compatibility for you - but it's very possible to migrate existing applications to a better style in place, which very few platforms manage).
> Same with maven/gradle, which turns what should be a developer-focussed build system into an enterprise XML mess.
Maven is pretty close to the perfect build system, it's just taken a while for knowledge and practices to catch up with it. All the stuff people love and praise Cargo for, Maven has been doing for 15+ years.
Despite Spring being Enterprise it still scales down to simpler apps pretty well due to its modularity.
These can be build into a single jar app that is easy to build and deploy, and combined with a database migration library, maintain their own database schemas. Very, very usable.
Yes, I probably would not use Java on the frontend unless it was for a technical audience.
People complain about the verbosity of Java, but how much time do you spend learning a new framework and all of the gotchas? At the end of the day it seems easier to just write the boilerplate. All of that verbose code means you got exactly what you asked for.
JVM projects never surprise me. When there is a problem debugging is a dream.
Could you elaborate on the overengineering part? There are many modern frameworks that are much lighterweight than Spring/Spring Boot, and with the introduction of lambdas in Java, things are even more straightforward.
Also, gradle doesn't use XML.
All our customers doing Java Web projects are either on JEE, or a CMS platform running on top of servlets and JEE related JSRs, like Liferay and AM.
I also do a good bit of frontend and holy crap it's exhausting. That's the main reason I push hard for Java backend. Backends tend to stick around about a decade longer than you would like, while front end code is due for a rewrite every 3 years
They didn't and Google didn't want a pay a single dollar to Sun on Java. As James Gosling has mentioned multiple times. I don't understand why people are still painting Google as Saint after all these years.
currently they recreated the java apis by pulling in apache harmony and they tought that they are in the right or at least in a fair use position (they still think they do). but I agree, I'm not sure if the direction of java would've been better when google would have the stewardship.
java is a stable api but it also doesn't evolve. The tradeoff is you get a program guaranteed to work no matter the upgrade vs being able to build better toolage.
React changes every year or 2. It is exhausting. But you get way better patterns and some things that drastically improve productivity.
Also keep in mind that React is a library, not a language. If you want to compare things, compare Javascript to Java, or the Java stdlibs to React. Maybe that's what you meant when you said Java.
IMO, Java and its libraries are nicer to work with solely due to its static nature and OO design. It is worlds apart from a scripting language when you need to refactor, or even just understand, legacy code. And if you can't even run tests on that legacy code anymore, like a React project over a year or two old?
What are the better patterns and productivity boosts you get from React vs. a Java ecosystem?
That and a few page reloads never killed anyone.
You have probably missed the last 5 years. From streams, to closures, to default methods, to functional interfaces, to local type inference, to new Process APIs, to modules, to unsigned arithmetic, to new date/time APIs, http client, 2 new GCs, shell REPL, etc... with more to come, and new releases every 3 months...
It consists of the main Flutter app and a Dart library for communicating with Nissan's API.
Maven and spring are the worst parts, for me, when dealing with Java. I don't mind the language at all.
Worse: Oracle bought Sun.
"Add a new garbage collection (GC) algorithm named Shenandoah which reduces GC pause times by doing evacuation work concurrently with the running Java threads. Pause times with Shenandoah are independent of heap size, meaning you will have the same consistent pause times whether your heap is 200 MB or 200 GB."
The original algorithm was published in 2016 [2]. It consists of 4 phases: initial marking, concurrent marking, final marking, and concurrent compaction.
GC use can be optimized in high level languages with support for value types (which are still missing in Java, though) and it is not like every game needs to be the next Fortnight.
There is such a thing as reference counting :)
(This is why I'm excited for ARC / Swift on the server...)
The performance increase is from a different algorithm + full multithreading. Not from collecting garbage less often as is a common tactic to reduce time spent in GC
"35C3 - Safe and Secure Drivers in High-Level Languages"
Each JVM implementation (Azul, IBM, OpenJDK, PTC, Aicas,...) has their own collection of GC algorithms.
And their behaviour depends pretty much on the application as well.
Well, one could build and run Shenandoah GC with JDK8 and JDK11. Ref: https://wiki.openjdk.java.net/display/shenandoah/Main#Main-B...
Here's a presentation on Shenandoah by one of the principal developers (focuses on the how): https://youtube.com/watch?v=4d9-FQZZoVA
Slides: https://christineflood.files.wordpress.com/2014/10/shenandoa...
Another presentation (focuses on the how, why, and when) at devoxx: https://www.youtube.com/watch?v=VCeHkcwfF9Q
Slides: https://shipilev.net/talks/devoxx-Nov2017-shenandoah.pdf
---
Tangent: Go GC (generational, non-copying, concurrent mark and concurrent sweep) and the improvements it saw from 1.5 -> 1.8 https://blog.golang.org/ismmkeynote
The mutator/pacer scheme, the tri-color mark scheme, using rw-barriers during the sweep phase are interesting to contrast between the two GCs.
If you want an order of magnitude jump in performance need to see if the IBM work on Scala Native version of Spark manifests.
The GC time is lower and multi-threaded but most importantly the "pause time" is low and nearly constant (based on root set size)
The old GC's all scaled pause time roughly linearly with heap size. Apps that created a lot of garbage would have all their threads yielded for large amounts of time.
Now, essentially, it doesn't matter how much garbage you create. This is awesome because you used to carefully watch how many allocations you made to avoid bad GC times. Now it doesn't matter. Make as much trash as you want and the GC will deal with it
I expect this needs to be taken with a chunk of salt, since a smaller heap can only require so much GC...
Pause times. Not GC times. Shenandoah pauses to scan the root set only. The size of the root set doesn't grow with the size of the heap.
You can have a large root set and a tiny heap, or a tiny root set and a massive heap. They're entirely independent.
But (in my naive opinion) double dispatch seems a more elegant and java-ry solution, i.e. polymorphism on argument classes, so different methods are invoked for different object runtime classes (instead of using the compiletime type of the variable).
The switching could be optimised, as ordinary polymorphism is in the JVM.
Sure, you'd wreck legacy code if you just introduced it, but there's surely a backcompatible way to do it that isn't too awkward.
BONUS: goodbye visitor pattern!
Sure, you could match on types, but you wouldn’t be able to extend that to destructuring patterns, or regsxps as patterns on strings, or so many other ways patterns may be extended in future releases.
Their initial motivating examples was bare instanceof, but I now see they extend it.
How would destructuring fit this model ?!
From what I understand, graal has made a lot of headway with language interop, as well as a handful of specific memory optimizations and native compilation, but overall is lagging in pure throughput/latency performance behind hotspot. It would be really cool if we could get the best of both worlds.
As for GraalVM, I don't think it's meant to be mixed in with those 2 at all. From their website (https://www.graalvm.org/), it sounds to me as if it's a completely different project that shares none of the goals the other 2 JDKs have:
> GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Kotlin, Clojure, and LLVM-based languages such as C and C++.
> GraalVM removes the isolation between programming languages and enables interoperability in a shared runtime. It can run either standalone or in the context of OpenJDK, Node.js, Oracle Database, or MySQL.
Twitter use Graal in production - I think it's about 13% faster for them on their real workloads. If you send a Tweet it's going through Graal.
GraalVM is... complicated. There are a few parts to it:
1) An advanced JIT compiler, written in Java, and distributed as ordinary maven/jar packages, etc. You can use it yourself if you want. Interestingly, this compiler package ("graal") can be used for the JVM itself, and it will be used to compile the Java code that is run by the JVM. The "JVMCI" feature allows you to plug third party compilers into the JVM and replace HotSpot, and Graal (the library) is such a replacement. You can use this compiler on ordinary OpenJDK 10+ with a special startup invocation.
2) Truffle, which is another library for writing programming language interpreters. It does a lot of magic to make them fast. It uses the graal JIT compiler to do this, so it depends on the previous library.
3) A bunch of programming language implementations under umbrella: Python, JS, etc. These are implemented using Truffle. By using Truffle, these language implementations magically share an object model (so they can interoperate), and they get a JIT compiler, based on Graal, for "free". This means the languages can interoperate and JIT together cleanly (the compiler can inline JavaScript into Ruby!)
4) If you use Graal as the JVMCI compiler (i.e. for your host Java code), and you use Truffle-based languages -- Graal can extend benefit #3 to the host Java code itself. This effectively means the JIT compiler can inline and optimize code across every language boundary.
5) SubstrateVM, which is is a tool to turn Java programs into native exe binaries. The intent is you use SVM on the programming language interpreters, to produce interpreter binaries that look "normal" to the user. These binaries are run on custom, non-JDK/HotSpot runtime. The Java code is not JITed, but interpreted code -- Ruby, Python, JS, etc -- is. (This means you have benefit #3, but not #4). SubstrateVM uses a custom generational garbage collector (written in Java!)
6) The "GraalVM distribution", from graalvm.org. This is a combination of all the above pieces together as a sanctioned package. This package uses JDK8 as the base virtual machine.
7) The GraalVM distribution comes in both a "community" and "commercial" edition, which do have technical/feature differences.
Here's the thing: you can use everything from 1-4 with an "ordinary" OpenJDK today if you know what you're doing, and you don't need a special JDK build. SubstrateVM might also be workable, but I don't know.
Points 6-7 actually mean that there is generally a difference between "GraalVM the platform" and "Graal the compiler". Notably, while OpenJDK no longer has feature gaps vs the commercial OracleJDK, GraalVM does, which I find a very weird choice on Oracle's behalf and unfortunate, but maybe it will change one day.
If you want to use one of the new low-latency garbage collectors (ZGC/Shenandoah) with Graal, I don't think that's possible as of right now: garbage collectors need to interface with the JIT compiler, but ZGC does not support the JVMCI interface (it will explode on startup), and Shenandoah doesn't either, I believe (but maybe this changed). This will almost certainly be fixed in the future, of course.
Rest assured progress is being made.
https://jdk.java.net/valhalla/
The engineering problem is that they want to keep old jars running on a world of value types.
I suspect I won't ever use value types in my code though unless it's drop in to refactor from AnyVal=>AnyRef (or w/e the java equiv is).
* Does accepting a value type parameter accept it by value or by ref? * How does this play with GC? Can I get dangling ref with value type? * How does value types play with inheritance e.g. will it be like c# and struct and they will be boxed any time treated as ref? * How safe will it be to convert a class from being value type based to Object (w/e AnyRef equiv is). Will I need to inspect all methods that deal it now?
This can probably just be resolved with a style guide like c++ can be mostly sane if you're starting a new project today with an aggressive style guide, but I just appreciated not think about this and just count on escape analysis + gc + hotspot tricks like monomorphize code paths with some counters to be good enough.
For example: https://rcoh.me/posts/cache-oblivious-datastructures/
Something like
@FunctionalInterface
interface Function<T, R, E extends Throwable> {
R apply(T t) throws E;
}During compilation, type parameters are erased. "T" becomes "Object"; "T extends Something" becomes "Something"; assignment becomes type conversion. But at the end it works correctly. If you try to make something that wouldn't survive the type parameter erasure -- such as having two methods with the same name, one of which accepts "List<String>" and another accepts "List<Integer>" as their input -- it will be a compile-time error, because you can't have two methods with the same name and the same parameter "List".
But imagine that you have a type "MyException" extending RuntimeException, and your code has "catch (MyException)". After compilation, this would become "catch (RuntimeException)", which is wrong, because it would also catch other RuntimeExceptions, and it is not supposed to. But if you make this construction a compile-time error, then... the whole thing becomes useless, because what's the point of having an exception type you cannot catch.
Makes HashMap computeIfAbsent much less useful than it should be. It's impossible to use a function in there that throws a checked exception (all I want is for the exception to propagate out of computeIfAbsent for the parent method to deal with).
Best option I've found is to wrap it in an unchecked exception, then unwrap it in the parent method, which is just .... yuck.
public static void main(String[] args) {
try {
sneakyThrow(new IOException("io"));
Test.<IOException>emulateThrows();
} catch (IOException e) {
e.printStackTrace();
}
}
static void sneakyThrow(Throwable e) {
Test.<RuntimeException>sneakyThrow2(e);
}
private static <E extends Throwable> void sneakyThrow2(Throwable e) throws E {
@SuppressWarnings("unchecked") E e1 = (E) e;
throw e1;
}
static <E extends Exception> void emulateThrows() throws E {
}[1]https://www.artima.com/intv/handcuffs.html [2]https://lrytz.github.io/pubsTalks/ the link to his thesis doesn't work anymore. I cherry pick some of it in my talk for a Scala meetup in Utrecht https://www.slideshare.net/yoozd/effect-systems-in-scala-bey...
But my favorite is abusing the language using Lombok SneakyThrows. It just feels dirty using it. In a good way.
Sometimes I wish Java had one too to complement Optional. I wonder what the argument against that is? Too much confusion with the existing Exception system?
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
} System.out.println(switch(day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
}); int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};Actually, looking at the version history, I guess it's not weird that I thought 8 was pretty recent, as until 1.5 years ago (Sept '17) it was actually the latest and it is still supported until 2020 (unlike 9 and 10).
v6 2006
2007
2008
2009
2010
v7 2011
2012
2013
v8 2014
2015
2016
v9 2017
v10 2018
v11 2018 again
v12 2019Funny enough, Java 11 will be end of life the following year. It's not even worth migrating to, better jump to java 15 then.
If they wanted to decouple, they first should have created a cross-platform jpackager-like tool that generates native executables for major platforms.
I remember JavaFX was launched with great fanfare as a modern replacement, which it certainly might have been - a modern, efficient platform. I am afraid it will slowly decay and dissolve into oblivion to be replaced by gigabyte-size electron apps.
Why? Besides being owned by Oracle, which is enough of a reason to never use Java ever again, it's also lost the niches that brought it into existence. Java no longer runs everywhere. Java on the web is dead, and you can now write ubiquitous apps in basically every language. There's no reason to deal with the JVM and it's domain knowledge when you can write a nimble Go app for your backend and a Javascript app that will run on mobile, web, or desktop. A VM language? You mean v8 sandboxing and web workers; WASM which lets me write C, C++, and Rust all of which can talk to Javascript APIs. All of my services are stateless and ephemeral. Crashing is expected, and I can use host monitoring tools instead of introspecting the JDK. On the cloud it gets even worse for Java. Why use a meaty framework like Spring when I want to just spin up a bunch of micro services, or have an API gateway kickoff a bunch of lambda jobs.
Java also took OO in so many terrible directions. OO defined by it's creator looks nothing like the enterprise OO that big business sold to commoditize programming, which now only exists as a ball and chain on legacy systems.
One day Java will be like Cobol. There's probably a lot of money for Java developers for many more decades, but god I do not envy anyone that has to do it.
More importantly, the JVM ecosystem is much bigger than Java itself. The JVM is a highly-optimized, cross-platform, garbage-collected environment on which people have built much more progressive languages that lack the syntactic baggage of Java: Scala, Groovy, Clojure, Kotlin. Clojure is one of the most popular and performant Lisps we currently have, and Scala is one of the closest things we'll get any time soon to a practical version of Haskell. Both of these projects got to avoid building their own garbage collectors, which is an enormous lowering of the effort barrier. And to top it all off, all of these languages' binaries are interoperable, which not only allows you to use different ones for different parts of the same system, but makes it much easier to gradually migrate your legacy codebase to a newer, better language.
I don't know if I'd start a new project in Java-the-language, but it's far from a Cobol situation.
Apache Groovy has inherited all of the syntax of Java. When Jeremy Rayner built the Antlr 2 based syntax for Groovy back in 2005, he began with the syntax for Java, then added the Groovy-specific grammar to it. The latest version of Groovy still uses that syntax, so if Java has syntactic baggage, then Groovy has it too.
I'm picking Groovy will still have that baggage-laden syntax for a while yet. 2 yrs ago, Daniel Sun built an Antlr 4 based replacement grammar, but the Groovy project managers at Apache are taking their sweet time in rolling it along. They even had its optional preview removed from the version 2.6 beta of Groovy.
A lot of my reasoning was criticizing the JVM itself, not Java. VM languages add unnecessary complexity in the post container world where ephemerality and kernel APIs (containers) can give the same advantages, although I think Kotlin and Clojure and remarkably good languages.
Java is old, it's crufty. Yes.
But it's extremely fast compared to anything but Go, C#, and "low level" languages nobody wants to touch for web stuff.
The JVM is also extremely reliable. I've seen apps run for years straight.
And the tooling is better than basically anything. Profiling, debugging, realtime code generation and modification. Libraries for anything you can imagine. ~4 solid IDE's.
Java's OO is fine, and all the nightmare patterns died years ago. You only see them because Java has been around for so long. Modern frameworks like Vert.X or DropWizard are fairly nice to work with. Even Spring Boot isn't too bad.
But Spring is dated and not often used for new projects.
The JVM has extremely powerful built in monitoring API's that put any other language I know of to shame.
WebWorkers are trash compared to Java's nice threading model. It even supports CPU optimized Atomics.
There's nothing unusual about writing microservices in Java. V8/Node is just as "big" a virtual machine as the JVM except JS runs ~5x slower and takes 5x more ram.
You can also write Lamda in Java.
There's many valid critisicms of Java but yours are largely invalid
Yes there are.
...but the parent assertion that Java will one day be like cobol; no longer taught in intro to CS course (where now we see python), considered bloated and legacy, and not picked for new projects (where we see the rise of languages like kotlin eating into what was once the primary growth for the language with mobile apps) and encumbered by problematic licensing issues...
Seems quite valid.
You have to live in a bubble right now not to get the feeling Java is stumbling, and there’s no indication to me that the overall direction of the language is positive right now.
...I’m sure there are still years ahead for earning a good living as a java developer, don’t get me wrong, but that’s a different issue.
> But Spring is dated and not often used for new projects.
Spring Initialzr (https://start.spring.io) is used millions of times per year.
Fast is a poor word to talk about benchmarks between languages. Memory, throughput, latency are the things we should be talking about. There’s also trade offs where predictable scaling of latency under massive load is important (Erlang, Elxir), or spending less memory and starting up quickly in order to scale horizontally is important (Golang), or speed of development is important (PHP, Python), or correctness is important (Haskell, Rust). Java is rarely the winner in any area in favor of being well rounded, but as we should be using tools that meet at least the broad requirements it is always possible to make a better choice than Java.
> I’ve seen apps run for years straight.
This is why Java is dated. I am an Erlang developer, which is known for being hot reloadable and running forever. It turns out this model is actually juxitposed to Kubernetes and severless, which both presuppose letting processed crash at the host level and starting and stopping quickly. This also gets into the tooling argument because profiling in Java would rather the VM be long lived.
> The tooling.
I too have an operating system with great tooling, it’s called Linux. My knowledge of tooling is more broadly applicable, I can introspect any binary and attach probes to the kernel with bpf. Profiling for a VM is table stakes because you’re on your own. Not only do you have to figure out what’s going on in the JVM you also need to duplicate your effort to figure out how the JVM is running on the host.
> Java OO is fine.
OO in general is not fine.
- fast enough for most things without a lot of pitfalls/gotchas
- easy enough to read for most developers
- easy enough for most developers to pick up if they've never used it, even if they aren't exactly enthused by the idea of doing so
- supported enough that you'll never be the only person who is debugging something
- widely used enough to never be alone when you are trying to use it in unsupported ways
- has commercial support from multiple companies
Basically all the things that a lot of "enterprise" companies love.
Edit: formatting
Yes.
There is no need to engage the GP - let him rant about Go and JS. Java is still huge, for both legacy and new projects.
For context - I started as a C/Kernel dev. I also spent 2 years with Java on mission critical backend code. Both have their uses.
Applets, JavaBeans, and CORBA. What a loss.
> Besides being owned by Oracle, which is enough of a reason to never use Java ever again,
That stopped being an issue years ago. OpenJDK is a thing, you know?
> Java on the web is dead,
I don't think you have any idea about the hundreds of millions of lines of Java that power the web as you know it today.
The rest of your post is filled with equally uninformed claims but I'm going to stop here.
>> I don't think you have any idea about the hundreds of millions of lines of Java that power the web as you know it today.
Presumably they meant Java in the client, not the server.
Well, that's seeing the glass half full.
OpenJDK was complete garbage in the java 6-7 era, less than 5 years ago. Pretty much every major java software was requiring to install the Oracle JDK. Nobody would accept a bug or a support issue if it happened with the OpenJDK, which was the first question to be asked. And that wasn't fear mongering, java applications that worked perfectly fine just didn't work on the OpenJDK.
It is better now. I personally haven't seen an OpenJDK JVM crash in a while.
If Oracle's ridiculous interpretation of API copyrights holds up, they have a kill switch for OpenJDK.
Yes, Oracle, the company that sues people for breathing the same air owning Java is an issue.
Maybe I am uninformed, but you haven't made a good case that there's any truth to that.
The only reasonable alternative is C#. But it has to go a long way to reach Java's level of stability and trust on non-Windows servers.
> JavaScript itself is a terrible language (along with other dynamic languages like PHP, Python, Perl, Ruby)
You know, I used to think that languages had a single axis of Good. And each language sat at a certain point in that one dimension.
After several years each of experience writing large web applications using C++, Java, C#, JS, Python, Ruby and Go, that mental model of languages being good, bad or terrible seems incredibly naive now.
But overall, if someone were to ask me to write a web app today, I would probably use Python server-side and break it down into microservices. Client-side, probably just pure js + HTML5 APIs.
Why? Because I don't have the time to argue about languages being better or worse. I am too busy writing code that does useful things.
In a high-skill rockstar team, dev time is by far the most expensive resource. In a startup environment, using your dev time wisely is the difference between a unicorn and a failed business. Nobody gives a fuck if your route handler executes in 1ms or 20ms. I'll gladly pay the 20x hosting costs if that will get my feature out to customers a week earlier.
i don't know why this comment was downvoted so much. i fully agree with every point that LASR makes. if you disagree, i'd like to see your counterpoints please.
For browser or Node.js, TypeScript is the way to go IMHO. Node.js and it's ecosystem have it's issues, but TypeScript is quite nice and a considerable improvement over JavaScript, while being close enough to JS where it fits nicely into the ecosystem. Only downside is that it adds a compile step that can potentially grow to be time-consuming.
I feel bad for people trying to write in other languages and manually re-inventing dozens of features the JVM ecosystem just gives you for free. In many ways, the whole container-push has been essentially people trying to achieve what the JVM already gave you (isolation, cross platform, etc etc). I still don't see anything equivalent that doesn't impose huge burdens of complexity (which java does have but it's a known quantity with two decades of maturity).
Google did containers in Borg many years ago, and many of its servers are written in Java.
When I stopped caring about POSIX.
It is true that for smaller, less demanding software, there are many alternatives, but except for a very short period (~2000-2005) Java never dominated that kind of software. Early on people used VB, FoxPro and Delphi for that stuff, and later PHP, Python and Node.
Even with Rust, Go, and .Net core out there it's really hard to beat Java's battletested libraries/frameworks and excellent tooling. Java is still very relevent today and will probably still be for a very long time.
Also, funcitonal programming is a style of programming, not a collection of features. Just because you have a map and sort method and a hacked in lambda syntax doesn't make Java anything less than OO. Multi-Paradigm usually means one paradigm with a bunch of extra crap in there to make bike shedding easier.
Part of the reason big businesses were able to abuse enterprises with their abominable Java server stacks is because corporations were slow to trust open source. But developers persisted and open source became too compelling to ignore, creating the upward pressure to embrace it and break the bloated and overpriced enterprise app server's stranglehold. This likely prevented the demise of Java that you suggest has happened.
In fact, when it comes to enterprise these days, you're pretty much either a Java or a .NET shop.
You'd rather use wasm to write c to talk to javascript apis? Your case against Java might be more compelling if it wasn't so gross itself.
I still use Java a lot for application servers[1] and enjoy it.
I've also used Go, but I wouldn't want to try and implement, say a non trivial REST server with it.
I don't have the time to code everything from scratch, or to use an immature Go library or framework for example, when there are perfectly good ones in the Java world.[2]
Perhaps it might be best to just see languages as tools, and that each language has a purpose.
Java is old, so what? Lots of people derive value from it, and it's very stable.
You might be glad that banks use it, instead of immediately jumping on whatever languages you mentioned above. At least it manages to do boring things like keep you accounts relatively safe from hackers.
[1] https://www.dropwizard.io/1.3.9/docs/
[2] And yes, for that kind of application, unchecked exceptions are way more convenient than thousands of lines of if err != nil all over the place. And annotations in Go are an afterthought and it shows.
I'd suggest updating your misconceptions regarding Java before posting Yet Another Tirade about it.
E.g. the Javascript module/npm ecosystem is an absolute mess compared to any sane package/project description system, yet few people would disqualify JS for it.
Yeah, those poor devs with a rock solid, best of class, platform to write code on, with tons of libraries and tooling.
>Java no longer runs everywhere
It still runs everywhere where it matters. Nobody really cared if it could run on crappy smart tvs and other such BS SUN tried to push it. 99% of Java use has been for server work and enterprise development, and it remains there.
And on mobile, well, Android uses basically Java with a name-change.
>Java on the web is dead
Java on the web (Applets) was DOA, and has been dead for over 15 years. It's not gonna make any difference now.
>and you can now write ubiquitous apps in basically every language
Which again is neither here, nor there. People have been using Java as a very strong language for backend systems, application server side work, and enterprise stuff. And those deploy on at most one OS 99% of the time.
They don't use Java like e.g. Electron or QT. The only Java apps that are like that and are mainstream are basically IDEs.
>There's no reason to deal with the JVM and it's domain knowledge when you can write a nimble Go app for your backend and a Javascript app that will run on mobile, web, or desktop
Whatever.
>A VM language? You mean v8 sandboxing and web workers; WASM which lets me write C, C++, and Rust all of which can talk to Javascript APIs
How hipster. Meanwhile others do real work on Java, with finetuned GCs, mature libraries, and so on. I'm not sure where you've seen all this "WASM and Rust", as both are not even blips in production compared to Java adoption -- and wont be for a while, if ever.
>All of my services are stateless and ephemeral
Mine don't care much for the latest fads, so there's that.
>On the cloud it gets even worse for Java. Why use a meaty framework like Swing when I want to just spin up a bunch of micro services, or have an API gateway kickoff a bunch of lambda jobs.
I'm not ever sure what Swing has to do with a Cloud java deployment. Perhaps you meant Spring, but even so, it doesn't make sense.
And of course with Java you can always use something like Vert.x, which tops the performance charts for microservice work -- so much so, that the others are not even on the radar.
>Java also took OO in so many terrible directions.
2010 called, they want their arguments back.
Also, not sure if you've noticed, but Java is still in the top 3 of most in demand languages (along with JS and Python).
Perhaps your ideas about its death are premature, if not deluded?
And from this it seems to me you are somehow biased against the java ecosystem without hands-on experience to base your opinions on.
Java basically copied (and cleaned up a bit) C++ OOP of the time. Don't blame Java for any bad direction, it was following rather than leading.
There are also thousands of companies which are focused on Java, Java, and more Java. Many schools are also geared towards churning out more Java engineers, and people who don't yet know Java want to learn it because there are still so many Java jobs around.
That's a lot of inertia to overcome.
It's still true, though, but it's a compliment. Most languages have no hope of ever becoming the next COBOL. For Java, it is practically a certainty, even if Oracle were to pull the plug on it this very moment. It's too big and too important to die.
However I really dont see what benefits Spring brings. Spring Boot is great for prototyping and trivial apps, but for big systems you really want to break it apart. DI is better done with ServiceLocators. Some of the smaller libraries like Spring Shell, Spring Mobile are junk. And I still see lots of XML config that you dont know if they'll fail until you try to run them.