Java Is Underhyped
jackson.sh
jackson.sh
- not high level enough to compete with Python/Ruby/JS/PHP, etc
- not low level enough to compete with Rust/D/Nim/Zig
- not specialized enough to compete with Erlang/R/Go/Julia
- not opinionated enough to compete with Lisp/Haskell
So why use Java ? It's good, it's fast, it's productive, it's well supported, battle tested and documented for decades with a huge pool of devs. And many companies already use it and the tooling is excellent.
But those are not sufficient reasons for me.
Python is older than Java, well supported, battle tested, documented with a huge pool of devs. But it's way better for high level stuff, data mangling, scripting, gluing, and for most web dev stuff.
If I want a distributed system or something with a lot of I/O, Erlang and Go will always be better than Java. Sure, they are less widespread, with all the stuff it implies, but for such a nice need, I will pay the price hapily: my goal is optimization for the use case. Same for stuff that needs to go fast or have a small footprint, I'm not going Java if I can go Rust.
If I want to have fun, Java is out of the loop. Better sharpen my inner weirdness by fighting with some exotic lisp. Why try productive ? I wanna enjoy myself, not run a business.
So Java is not a bad choice. It's an excellent tech. I just don't have a use case for it.
IMHO, YMMV etc.
If I don't need performance, Python is ok.
If I do, I won't go Java, I will choose something that is built for performance. Python is good enough for 99% of my performances need. The last 1%, jumping to java is not a big difference, I'll use rust or go.
I won't use go for the ecosystem, but it's unique characteristics: easy concurrency, dead simple binary production. Java can't beat that. IF I need an huge ecosystem, I'll go Python.
For the need for Java, I would need this very specific sweet spot where I need just enough speed, and just a rich ecosystem enough to justify it, and nothing that is a killer feature in alternatives. And a situation where compromise over this is not possible.
It never happens to me, that's all.
That's where you're wrong, kiddo.
But that's not the point. The point is that, for the 99%, staying on a slower language is ok. For the last 1%, I'll skip Java and go to Rust/Go. If I have to do a rewrite for perf sake, I'm not going to go half way.
And for IO, you will get faster perf in Go more easily. Sure, you can finely tune your Java code to get there, but it's a lot harder.
It in both cases it will eat up way more memory.
There is a reason Google, that did use heavily Java internally, is now moving to Go, a language they custom designed for concurrency.
Basically every language is more expressive there (even Java), GC is much much better - in benchmarks it is not as obvious only because Go avoids creating garbage most of the time, but it can’t always be avoided; and the platform is incomparably richer on the JVM side.
And Go is better if you do I/O.
That's my points. Compromises.
I'm not saying "Java is bad". I'm saying, "I have no use case where I, personally, would use Java over something else."
I do know other people have use cases for it.
I just don't, because those compromises don't make sense for me.
Java does have android right now, although it has to share with ReactNative, Xamarin and flutter. Again, for different compromises.
Java also has the IDE ecosystem between Netbeans, Eclipse and all JetBrains offerings, with exception of Apple and Microsoft offerings.
You are trying to move the debate toward the quality of java, which is was never my point.
> If I do, I won't go Java, I will choose something that is built for performance. Python is good enough for 99% of my performances need. The last 1%, jumping to java is not a big difference, I'll use rust or go.
So given that, I am curious where are those GUI alternatives with the required perfomance in Go and Rust.
- you need a GUI
- you need perf beyond what Python is capable and you identified it clearly in advance
- you can't use numpy / multiprocessing / cython, pypy or they won't give you the perf you need
- you can't find a main hotpath you can optimize with a 5 lines c or rust extension and write 99.99% of your app in python. Or you don't want to bother.
If you ever find yourself in this very use case, then yes, use Java.
But I never found myself in this very precise use case.
Please.... That's literally the worst option for python on this planet. For all "just do multiprocessing" the tooling is horrible garbage. Then we get to Twisted and Gunicorn the Spring Framework of Python world.
Its only saving grace is that all other cross-platform GUI systems also suck, and if you're doing everything else in Java it might be the path of least resistance.
(Though I haven’t tried its mobile “backend”)
"Filthy Rich Clients" by the nowadays Android UI architects
"Swing Hacks: Tips and Tools for Killer GUIs" by Joshua Marinacci, well know in the UI research community
https://www.amazon.de/dp/0596009070
And then commercial libraries like
import random
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
def hello(seconds):
print(f"Starting hello in {seconds}s")
time.sleep(seconds)
print(f"End of hello in {seconds}s")
return seconds
# At the end of this blocks, it automatically join() and clean
with ThreadPoolExecutor(max_workers=2) as executor: # 2 tasks in parallel max
# this send jobs to threads via safe queues
a = executor.submit(hello, random.randint(0, 5))
b = executor.submit(hello, random.randint(0, 5))
# this collect results from queues in order of completion
# sync is automatic
for future in as_completed((a, b)):
print(future.result())
And if about network I/O only, you can get even more perfs using asyncio.Threads in Python are only inferior to Java threads when it's about using several CPU.
I do enjoy in python that it is quite easy to utilise multiple processes in a code-light fashion, but some things are more natural as threads.
It's hard to separate the absolute performance of Java the language from Java the culture where inefficient patterns or attempts to implement dynamic behaviors in some framework code defeat the JIT (not to mention the benefits of type-checking). If you have a team which cares, it should be faster but the average business app I see does not have that team and will, if lucky, perform within the same order of magnitude as Python.
Speed doesn’t matter always, but when it does it Java feels snappy. Our programs our command line based so our framework use is limited. Also the built in data structures are nice. I still find getting Java’s set up painful, which is a huge impediment for us using it more.
(yeah I know it has type hints now)
Whilst I roughly agree, that's still a bit too simplistic.
In particular, we might prefer something like Rust to write a performance-critical algorithm, but that forces us to make a decision:
- Do we stick with Rust for everything else (networking, data plumbing, etc.)? This forces us to confront the ecosystem problem.
- Do we wrap our algorithm as a library for other languages (like Python)? This forces us to confront interoperability (ABIs, FFIs, cross-language dependency management, etc.).
There's lots of room in between these extremes for other pareto-optima, like Java.
Also, we often need to consider latency and throughput separately, rather than just "performance". Java is a pretty stark example, since it's pretty slow to start but reasonably fast when left running (compared to native binaries like Rust, which are low latency and high throughput, or scripting languages like Python which are high latency and low throughput).
I got into Go for a while, but if I'm honest, it's a kludgey language. Half the reason it has taken off as it has is simply down to the fact that it's backed by google.
* performance is not really an issue for most software ("97% of the time, premature optimization is evil"). A well designed software doesn't suffer from performance issues with current computer performance, unless you do AI or bleeding edge graphics or science simulation.
* there are ways to speed up performance sensitive parts with something else than java, for example by using C/C++, would it be with a python module or cython. Not ideal, but generally you gain performance by adapting your design, not by changing languages. A garbage collector is rarely predictable, hence java is not a good fit for performance.
* I remember playing minecraft with friends, and the server was regularly crashing because it was out of memory, or something like that.
> I remember playing minecraft with friends, and the server was regularly crashing because it was out of memory, or something like that.
I've seen this, but I don't think you can really use one server program running out of RAM as indicative of much. I do still find the pre-setting of max memory on the command line a little bit odd though.
A lot of graduates think that compsci jobs involve optimizing algorithms or some shit coz they did that type of thing as undergrads, so they port that attitude across.
It's also the reason why pypy was massively hyped for a while and then not really used all that much. It was solving the performance problems python never really had.
I have noticed some younger engineers on C++ projects doing some kooky things "because it's more optimal", and have taken time to explain to them that the micro-optimisations they're using impact readability, are going to be done by the compiler anyway if they're at all useful, and are likely to be several orders of magnitude less relevant than some lock somewhere, or a bit of IO, or whatever.
Handling process memory usage pre-docker wasn't so easy.
Could be a problem with the logic/design of the server rather than a problem with Java? Despite memory being GC'd, you can still run out of it if you just keep allocating stuff. The important thing about Java is that it doesn't suffer from the usual C or C++ memory exploits.
> well designed software
Ah, there's my problem. Maybe at some point I'll get a chance to work on one of those.
- Python: 1991
Furthermore Python and Java set out to solve very different problems, which is reflected in their design decisions.
We are talking about Java as a language, not the JVM as a platform.
You can also run Python on the JVM.
Although, some Java compromises are definitely linked to the JVM.
Jython is stuck on 2.7 and unmaintained.
They cannot fully embrace the JVM while targeting ART, JS and native at the same time.
That 3D graphics library using SIMD and value types from JVM on ART or JS?
Good luck achieving the same perfomance and memory semantics.
Kotlin/Native has already been rebooted as its memory model was incompatbile with JVM libraries.
From the app side you just don’t use classes that you can’t use?
It will be interesting to see how things like Valhalla and Loom will pan out.
The main company behind Scala changed its name and now also offers Java consulting.
Unless the project requires Spark, there is little reason to even care Scala exists.
Then there is the version 3.0 where they started having brain damaged ideas like changing the whole syntax.
Scala today is Kotlin in 10 years.
One benefit of being old in this industry is having survived multiple fashion waves of guest languages on each platform, then watching how those guest languages fade while the platform languages adopt some of their features.
Or even how whole platforms become irrelevant making it a complete moot point regarding whose languages are on the platform.
There has been a consistent increase in Scala jobs in the last 12 months according to Indeed.com
Java is like you say not the greatest at anything but it is also not the worst at anything. Its great for projects where the you don't know what you should optimize for or don't care.
If java is to boring maybe kotlin is the way to go. I really like kotlin and in my personal experience the only downside is that the IDEs is not as good as the java counterparts yet.
You know the joke: a dev has a problem, uses Java, and now has a ProblemFactory :)
Not to say Java is not a great language for big projects, it certainly is well equipped for that, especially because it has superb tooling available on the market.
But I've done plenty of big projects in Python, some ended badly, some ended great. Not to mentions dropbox, youtube and instagram are testaments to Python can be used in large projects.
So I don't think Python is unsuitable for big sized projects. You certainly do have to worry about different problems than in Java, especially for projects that started without type hints. In my experience though, you reach less architecture dead ends with Python because the language is so flexible that a bad decision early on can easily be transformed or worked around even very late in the project without much fuzz.
So I don't use "size of the project" in my consideration to not user Python/Go/Rust/etc over Java.
I think this joke is probably about as dated as the versions of java it was made about.
Singleton is still a design pattern used in the wild.
Why bother setting things up explicitly in the way you want when you can declare things as injected, other things as singletons, and then have no real idea why it all went horribly wrong?
Inertia is huge in our industry, and the HN bubble doesn't gives a good picture of it.
Behind corporate firewalls I now see things done the way they were 10 years ago: packaging, string handling, concurrency...
I assume it's the curse of being popular and old.
And java has been popular for longer than Python, so inertia is even stronger. It doesn't matter if it has lambda since V8 if people still believe the best practice is to pass fat objects around.
(Poe's Law disclaimer: yes, that was light sarcasm.)
I LOL’d at this joke (again) because it’s true, but if we’re honest, it’s also unfair. ProblemFactory is a bad idiom, rather than anything to do with Java The Language. You could (and IMO, probably should) just use a new Problem().
Java The Language was very stable for a very long time, so IMO the hype and fads got built on top. First we have a constructor - no, now we need a factory, but how to construct a factory? I know, let’s use another factory! All in the same unmodified language.
Likewise, how do we configure an object? First we have methods, but languages are cooler, so let’s build a DSL, no wait let’s use a fluent API so it just looks like a DSL!
I one had a dev replace a constructor call with a fluent builder, so now in the single use case where the object was ever created, we got five LOC where previously we had one.
His code was idiomatic, it was bad engineering, but it wasn’t Java the language.
Java is a pretty great language, but some of the crap people stuck on top of it was (and still is) a nightmare for readability and reusability. I use Go these days, and prefer their more basic approach to engineering, but there is much I miss from Java-the-language.
Stuff like "everything is a class".
Java also had the unfortunate destiny of becoming popular at the time where "OOP all the thing" was a mantra in tech circles. Also design pattern were all the rage.
Those things have a huge inertia, and while Java is not a much more flexible language, the image stuck, to the point that new comers still implement singletons in the wild.
It was very much a marketed language and a language designed to be sold to top heavy corporations. This fueled a lot of the crappy design decisions, the hype and the culture.
“OOP all the things” predated (and led to) Java, it wasn’t a product of Java (C++, Objective-C, Object Pascal and, well, a bunch of other things from the late 1980s and early 1990s were where it got started.) Java was about a decade into it.
I know not everyone will agree with me, and that’s fine, but I always found Java to be far more pragmatic than, for example, C++, which well and truely predated Java.
Java was a product of “OOP all the things”, it wouldn’t have existed without it.
I know the excuse that they are just meant to be used to wrap the return value of a function that might be null, rather than as a guard against NPEs, but that just means we’ve got a crappy, verbose Optional class ... and NPEs.
It was the most half assed attempt to fix the billion dollar mistake [0] anyone could have come up with. It needed syntax and compiler support, not a stupid wrapper class.
I don’t really get your other arguments. I think the problem has been solved better in other languages including Swift, Kotlin and Rust, and Java could have learned from them, but didn’t. I can’t see why direct language support couldn’t have been added to solve this “billion dollar problem”. Even the Elvis operator would have helped.
I'm absolutely convinced that's true for some of them. I was never 100% convinced it was true for all of them.
Same goes for Python. Reading the hacky code of a geographer for his SIG system is rarely a fun day.
The Factory pattern’s pervasive use in Java was in large part a fairly direct consequence of JavaBeans requiring nullary constructors, so that the normal constructor work for a Bean had to be done elsewhere, i.e., by a Factory. Now, Beans was just a core part of the first-party enterprise framework that was central to the ecosystem and not strictly part of the language, but its not completely unrelated, either.
But my memory is that pervasive use of Factories came along many years later, and seemed to be driven by the perceived needs of TDD, for example to provide instances of mock classes in unit tests. And I thought the factory pattern itself came from the GoF, but I might be misremembering.
That said, I’m not trying to contradict you. It’s likely that there was more than one driver for the pervasive adoption of factories. In any case it was a bit of a nightmare for a while, hopefully things are improving there now.
It did, and GoF certainly influenced OOP outside of Java, too. But EJB created a need into which the Factory pattern was really the only solution. (GoF precedes EJB and even Java.)
But certainly its not the only thing; Java hit popularity right around the time GoF was most influential; OOP languages whose ecosystems developed earlier (e.g., C++) or later (e.g., C#, though GoF-heavy code isn’t unheard of there) wouldn’t be as influenced by it, all things being equal. Java just had the perfect combination of language features, early specs like JEE (which included Beans), and timing to be naturally inclined for maximum naive GoFism.
I think that applies to literally every language. Bad programmers write bad code, regardless of whether it's Go, Java, Python, Bash, or Assembly.
It's a funny joke, but it maligns a harmless pattern identical in FP to a function returning a function.
While FP coders would brag about how awesome high-order functions are, we just keep mocking our own style for some reason. Factories are very powerful when used right.
But my main complaint about Python is trying to use someone else's software. Then it degenerates into a maze of twisty little passages of trying to install the correct set of dependencies, not knowing where those files are installed (which makes it difficult on a cluster, as you may need to do the install on every node separately). Then you try using pip and it fails because some element of what it is trying to install isn't compatible with your operating system for reason 1. So you try anaconda instead, and that fails in a different way, like it runs a C compiler on some file (!?) which fails because $REASON. I have numerous examples of Python software where I have followed the (detailed, precise) installation instructions, and it doesn't work.
Whereas with Java, you just dump the necessary jars into a directory, include them in the classpath, and it works.
Don't get me started on R.
The reason packaging is still a problem in Python are linked to the language:
- to get perfs, you need compiled extensions, which java doesn't need. So a Jar can be fast and portable, while in Python it's an "or" proposition. Wheels help, but they still are OS dependent, so you need a build per OS.
- PYZ arrived very late in Python, while WAR were a very early thing in Java. Few people even know you can distribute a whole Python program in a single zip file with dependencies using something like shiv (shiv.readthedocs.io). So few people do it, and it's a shame. We do it for 0bin though: https://github.com/Tygs/0bin/releases. And it doesn't solve the wheel problem, although nuitka does but it a higher prices to pay.
- packaging tooling have been a mess for 2 decades. Setuptools/distutils/setuptools2, easy_install/pip, and setup.cfg/setup.py/pyproject.toml. We failed as a community on this one. It's getting better, but it's a slow process.
- the Python community is at least half composed of amateurs. It's a good thing for the dynamism of the community, but it also means the software are not very polished. Hard packaging + amateurs = packages that are releases when they reach "just good enough" stage, not one inch more. It also means you'll get things like leaking stack traces, config files in src and the likes.
So yeah, compared to Java, Python packaging and distribution sucks.
But compared to rust all packaging and distribution for all languages do, so there is that.
There are two main exceptions to this rule. One is when an actual software engineer ends up working as a scientist and having to write papers (like me). Then, the paper is more likely to be about the software itself, and the citations of the paper are from people who have also used the same software. This creates an incentive to make the software high quality, in order to get those citations. The other exception is when an institute decides that the world needs a decent piece of software to fulfil a vital role, and actually funds its development.
Oh, I should probably mention - I just helped out with a programming course for undergraduate medical science students. Most of the time I was tearing my hair out about the terrible programming practices being taught by the module leader, who admittedly had absolutely no computer science qualifications whatsoever (and in fact didn't know the difference between a forward slash and a backslash).
I think a solution to this is to recognise software quality as a common benefit, and divert funding towards it, allowing real software engineers to have an actual meaningful career in university. Universities are usually all over common benefit stuff, so you would have thought this would be easy enough. The Research Software Engineer programme in the UK is a start.
Pyinstaller builds bundle the python binary with the project. It works without a Python installed on the system, is not portable and the resulting binary is fat. It also can fail in numerous way and be slow, but end users will find it the easier to use when they work.
Pyz files just contains python code. Shiv produce them by bundling your code and the dependencies, but you still need a Python installed on the system to run that. You pay the cost of zipping only on the first run though, after that, it's unzipped. And their are portable if you use no binary wheel. It's light and easy to get right.
In that sense, they look more like War files in Java.
Pyinstaller, like cx_freeze and nuikta are for end users.
Pyz are for devs.
or, even worse, scientists.
The previous crowd with love for monkeypatching everything and hate for abstraction other than dictionaries wasn't too pleasant, too.
Code style! Hah. First day on the job I asked about that and was told nobody cared and everybody had their own preferences.
... I'm very bitter today. I'm working on it.
Everything is jupyter notebooks, to the point where example documentation is delivered as notebooks and services run notebooks as it’s apparently easier to do that than to get people to write their code properly. “Oh but data exploration” they say, which is fine, but you shouldn’t be doing data exploration in your prod ML pipeline anyway, and you’re writing code, it’s really not that hard to follow some even rudimentary practices.
I'm forced to use Python at work, because data scientists demand it, and I can rant about your "good for data" language for at least 24 hours straight.
Python isn't great at anything specifically, but it's crap in a few specific places. No multithreading? Fine! But then Python core libraries are crap at IPC, when multiprocess is the preferred way of parallel computing!
I don't know where you read either of your propositions in any of my comment.
You've listed things that rely on full stack of libraries and deployment options.(except scripting) As someone who has the pleasure to work with Python - Python is horrible at a lot of these things, in spite of the beauty of the language itself.
Python is the best language in the world for small tools under 500 lines to solve glue and data munging problems.
Like you mentioned, wheel files are not nearly as customizable as JARs. You can easily pick & choose the dependencies to include in JARs (fat JARs) and change namespaces of dependencies via shading to prevent collisions.
I've generally found it easier to add JARs to Spark clusters compared to attaching wheel files to PySpark clusters.
> with Java, you just dump the necessary jars into a directory, include them in the classpath, and it works.
Ant, maven, or gradle, and then some jars, somewhere? What's the classpath and whats $JAVA_HOME for this project?
Oh and now I have to make it work in the IDE too, click through a billion menus and dialogs, sync the build system, sync the dependencies, configure runtimes and classpaths, try to rebuild for the 10th time, pray.
> Oh and now I have to make it work in the IDE too, click through a billion menus and dialogs,
You click "Project from existing sources" in IntellIJ and it will recognize both Maven and Gradle projects and just work?
Sync the dependencies? configure runtimes and classpaths? What? With Maven and Gradle? Your talking Ant here.
- Install and set the right java version system-wide
- Copy some config files for the project system-wide (granted, this is not java specific, but still)
- Click in some IDE menu to enable some build settings
- Click in some IDE menu to install some "Lombok" plugin
- Click in some IDE menu to select the right jdk
- Click in some IDE menu to edit the run configuration:
- select main class
- paste program args
- paste env vars
- select right “Use classpath of module:” option
- Click in some IDE menu to fiddle with "Spring Loader path": modules, dependencies, reorder the dependencies (!)
- Click in some IDE menu to configure getting the actual logs
- Click maven-sync, rebuild-project multiple times, restart IDE until it suddenly works
The first guy who got it to work had to write a guide with screenshots!I know you will say, this is all fault of whoever made this crap project, or my fault for not fixing it. However this was my experience, and it has been similar every time in my life that I had to touch some java project (although this last one is the worst).
The project could have been set up instead with the "Maven wrapper"(1) which provides "mvn.cmd/sh" scripts at the top level of the project to fetch and run the proper Maven. So after cloning the project, all you have to do is set a proper JAVA_HOME if it's not already set, and then do "./mvn clean package" at the top of the project to do a complete build. The IDE's will then set themselves up properly if you import the project as a Maven project, and will sync with changes to the Maven pom.xml whenever it changes (Intellij does at least). That's really hard to beat.
(1) https://github.com/takari/maven-wrapper (Being integrated into Maven itself soon).
We occasionally do remote debugging at work. It’s just a matter of copy/pasting the correct JVM incantation into the IDE.
It is. There's really no excuse for that. If it's been similar every time then you've worked on crap every time.
Building a java project should be (and is on projects I work on) as easy as installing a jvm and running either maven or gradle to build it. End of story.
"Install some lombok plugin" is only necessary if you want the IDE to understand lombok, IntelliJ will just pop up a box saying "Want this?" and you click "Yes". I don't see what's so onerous about that.
The rest you describe is really down to poor developers.
So "no offense", but shove it.
In my experience (sample size of hundreds of projects), Maven projects are <<by far>>, on average, easier to build and manage than most other languages. The repo structure is standardized, the build cycle is standardized, the built packages are always in the same place, etc.
The Java installation is a 1-time think. It's also a quick google away. I see this complaint a lot, I never understand it. It's plain and simple bikeshedding: someone complaining about a 1-time task that takes 5 minutes in total.
The rest of the stuff is IDE specific and I have no idea why you'd have to configure "getting the actual logs"?
Treating the IDE like a separate problem is not realistic with java.
With e.g. Rust, I can use vim, vscode, whatever floats your boat.
> no idea why you'd have to configure "getting the actual logs"?
Some genius java logging library, I can only guess.
True, but with IntelliJ 99% of what you wrote is auto-configured.
Eclipse needs a bit of hand-holding, but almost everything you described is due to project configuration.
> Some genius java logging library, I can only guess.
That's your problem, you're assuming that Java is dumb and its libraries are dumb. They're not. I'm reasonably sure that <<all>> mainstream Java logging libraries log to console by default.
The previous engineer must have been a marvel of a developer to manage to screw even that up.
What I'd say is: Java, especially older enterprise code, had a ton of over-engineered patterns. These are slowly fading away, except for Spring, and even Spring's simpler these days. Java also tends to have some low quality and a ton of average but unmotivated working devs on Java projects. So yeah, there's that ecosystem problem.
But for example, if you'd start a new project and you approach Java with an open mind, it's one of the most powerful and flexible techs available. And it's much more modern than the stereotypes imply.
It is not, that's what I'm saying. And I don't understand why, if IntelliJ is the de-facto IDE. I'm sure that a fresh project is a one-click import, but an average project that isn't fresh anymore, always have similar IDE-setup-magic problems. At least in my experience over the years.
I know plenty of people who don't use a formal IDE. This "I don't use an IDE" is a stupid flex.
It's not a flex, simply a matter of preference: I find using the mouse too irritating, others prefer it because it's simpler.
But that's not my gripe, my gripe is that setting up IntelliJ, the one defacto standard IDE to actually work is some voodoo ritual of a dozen steps and restarts and so on.
With Rust you code in VIM because there's nothing better. Improving Rust IDE's has been one of the teams big focuses for years. Everyone codes in random text editors because there's no amazing IDE.
You don't need to constantly "extract method", move to class, generate all these mountains of classes by rightclick. This says a lot about the language.
But the main point is that with rust it actually just works: there is one way to set global toolchain and per project/dir. You're not required to also click through a million menus and dialogs and copypaste stuff and sync and rebuild and restart to get the editor barely working.
In Rust, macros generate code on build. In Java, Annotations Processors do. I don't see a big difference between these approaches, besides Java's mechanism being older and crustier. Rust macros generate tons of code.
> if you have rust-analyze you get inline errors, code completion, jump to definition, autoimport, autoformat...
Last time I checked, Rust analyzer was in alpha/beta. Java has all this and it's battle-tested. Including language server for VScode and other lightweight editors, and several options for build plugins that auto format.
> You don't need to constantly "extract method", move to class, generate all these mountains of classes by rightclick.
Lombok, or one of the popular Builder libraries, gets rid of all this boilerplate. I don't generate anything using IDE. In my experience, most Java user don't. There's many mature libraries for geting around class ceremony.
> there is one way to set global toolchain and per project/dir. You're not required to also click through a million menus and dialogs and copypaste stuff and sync and rebuild and restart to get the editor barely working.
You are right. Rusts build system is simpler and better integrated. But Java has amazing build tools, maybe the best out there. A properly configured maven project will compile, test, and run with one command. And it will import into your IDE with a simple "import project, yes"
I have worked on a ton of Java projects over the years and never had to deal with most of what your describe.
However I'd expect Lombok users to outnumber Lombok devs 100k to 1 :-)
I frequently find that the particular constellation of build tooling and libraries particular projects have requires a particular version of the jvm and all the environment variables set up correctly. In some other languages there is widely used tooling to manage the install and use of the appropriate platform version for the project.
If you're working with a variety of projects, fiddling with the installed jvm and java_home and friends is not a one time thing.
Yeah that’s a crap project. My experience was always that mvn install / ./gradlew run will just work. On all three OSs. And if I happen upon a decade old random jar file, and run java -jar something.jar, it will just work in the great majority of time. I think no other platform has it this smooth.
Even if your project is so messy, then you should be able to just to version a working setup (maybe needing to figure out how to make the correct JDK version be used across different machines) and after that it'd become a question of just having to check out the project from the version control system and click a green button in IntelliJ.
This most likely wouldn't solve all of your issues, but at least would help make onboarding slightly less painful and slow.
The run configuration can be automatically created by Intellij by attempting to execute a runnable class. You only need to set program args and env vars if needed - and that would be true for ANY language or program.
The spring loader path appears to be specific for this project.
The run logs are independent of Java. Thats just getting program logs.
There is no need to maven-sync and rebuild-project multiple times, unless you are explicitly refactoring the project module/build structure. Once you have imported a maven project, you can simply click build.
Create new Java project in IDE Add no dependencies Use the built in IDE tooling to create a runnable JAR and tick the box to export the Ant build to a build.xml file.
Why would I want to complicate things by adding Maven/Gradle to the mix?
And I will also give you the secret trick of superninja senior developpers: be the one who manages the build process, so you will never EVER be fired.
My point is there are a wide variety of application types out there, not everything is a web application, not everything needs to use a complex build and dependency management system.
So just use Maven and save anyone coming after you a bunch of trouble when they have to extend your project ;-)
Non-networked applications don't tend to need to be so paranoid about keeping up to date with the latest versions of dependencies.
That is not my experience at all. I dont have to rebuild work project many times. Creating new scratch project for playing in is easy and fast. Dependencies are managed by maven and I rarely have to deal with that beyond added dependency tag.
All needed is having the correct version of Java, and maybe give maven a password so it can access private libraries. It's dead simple.
And more importantly: it's the same everywhere.
I haven't used Maven in a bunch of years.
But source code goes in src/main/java. Test code goes in src/test/java, resources (images, files, whatever) go in src/main/resources, test resources go in src/test/resources. There is a pom.xml file that contains dependencies, and if it doesn't, it points to a parent which <<does>> contain them.
There might be submodules and they all are folders containing another pom.xml. That pom.xml generally points to the main pom.xml.
Etc. There's a bit of tedium in there, but <<it's always the same>>!
The level of consistency is something most ecosystems dream about.
And you know what? That means that you can use your spare brain cells for actual creativity or hard work.
Dependency management is a mess in the Python world and my number 1 complaint. You have pip, pipenv, poetry, anaconda, to manage your 3rd parties. And if you want to avoid conflicts and have consistent runtime you need to create a virtual environment to install these libraries and redownload everything.
Otherwise libraries are installed user or system wide, in a directory that depends on the Python version that you use but they are not versioned there.
With Maven you don´t have the issue. Your 3rd parties are downloaded in a global cache directory (the Maven repo) and are all versioned. For the delivery you can either provide them all and have the runner set the CLASSPATH or have them packaged into a single jar.
I am not saying Python's packaging is any good, it sucks. But you can't realistically ignore Java's IDE shitshow.
Maven can build a nice fat executable jar, with just one XML block added to the pom.
I've opened a 5year unmaintained project with IntelliJ yesterday - click package and got a working executable.
I opened another project built with SBT... and guess what? No errors!
Let's try that with a Python project (LOL!)
As a Java/Python/Go developer I can say that packaging is a solved problem as of 2021.
I like to point out Airflow as an example. It's still a complete nightmare to deal with and it has many steps for just packaging the application.
https://github.com/apache/airflow
I have less trouble packaging and running a 3 year unmaintained Maven Java application, than actively maintained Airflow. And let's not forget that I can target Java 8, without having to install Java 8 on my machine. (Which only adds to Python's complexity)
That's an interesting take; my experience has been (at least the community) is quite proudly dogmatic on the One Right Way To Do It, for all values of "It".
I also don't like Python, but I think for different reasons and perhaps a bit less than you.
Never used R, but I understand it to be quite fiddly.
This hasn't been true lately. Python is growing ever more complex.
But, for people still working in "computer science-y" domains, I haven't seen the historical dogmatism lessen; in many cases people are digging in.
In other words R is wrong tool to use for building the software just from maintainability standpoint.
I've seen very complex R packages that have been around for 30+ years. They are actively maintained. Applying good design principles, unit testing, modularity - all that is very much doable in R.
And you will want to write software in R, especially if the purpose is to support the very activity of working with R packages and to expose the R statistical environment over HTTP. Case in point, the software I link to, in my comment above.
Java is far worse on this front. Let's take a look at JEE or Spring - The entire experience is akin to summoning a demon with waving reciting correct incantations in correct places while having no idea about what even goes on in the background. There are MessageChannels, MessageProducers, ClientFactories that interact in mysterious ways and initiated in also very mysterious ways. And then there's EJB's and their containers which are just blackboxes of automagic.
Or how about Hibernate?
It now has 2 dependencies. It is a 1000 times easier to use than hibernate, despite being one of the worse ORM in Python.
That the problem with old Java libs like Swing or Hibernate: they have been designed for the 90' and don't leverage the potential of what a modern Java version can do.
There are many modern java libraries that are very lean and mean out there and package into small-sized redistributable assemblies.
It's my guess that you are using a lot of Python libraries that are wrappers around C or C++ libraries which have dodgy cross-platform support, because I can't see another way this is happening. If so, it's hardly fair to blame Python for that...
Fwiw, I’m normally on a beefy desktop so I might just be brute forcing this issue.
I think the main problem is that Gradle doesn't have the same support as Java for ABI compatible changes, so invalidation of modules are more common.
https://blog.jetbrains.com/kotlin/2020/09/the-dark-secrets-o...
I think you're right - ABI compatible changes are likely the culprit.
How do you mean? What IDEs are you referring to? Kotlin is fully (and very well) supported in IntelliJ Idea - unsurprisingly so, given that it's JetBrains own invention...
Mypy is excellent. It has two-way type inference like Haskell. Good usage means catching almost all type errors before running.
So is PyCharm, which is IntelliJ for Python.
And me too.
Scaling a Python project complexity is not harder than scaling Java, the things you have to be careful about are just different.
In comparison one of my personal projects is in Rust and while that’s currently maybe only a thousand lines it’s already significantly easier to deal with.
- you can integrate code from hundreds of developers fairly safely (knowing that no one has changed the default behaviour fo builtins and different dependencies won't clash).
- the syntax, although not the most succinct is fairly easily readable and maintainable by other developers.
But even for Python (which syntactically speaking is probably the easiest to read of all the list), if your team scale, you just scale the tooling with it.
The Python ecosystem is very rich in tooling for enforcing best practices. Poetry will manage dependencies cleanly. pylint will let you check that builtins are not overriden. Mypy will check for types.
So of course, it's not as good as Java, but again, the post is about compromises the language make, which are not the proper ones for me, personally.
I dislike that people conflate simple languages with easy to read code.
Low level verbose abstractions make code harder to read - going through the layers of IFactoryRepositoryLocatorBullshit because the language abstractions suck doesn't make it easier to read code.
It makes the code more accessible, in the sense that you can probably find some 20$/hour devs to read through that and spend a day solving something that should take a couple of hours most.
Good high level code express the problem domain without boilerplate and let's you focus at problem at hand - Java is terrible at that.
What specifically is Java terrible at? I find Java to be as expressive as most mainstream languages. Certainly no less expressive than, say, Python or JavaScript.
Java can't even have a free standing function without 6 lines of boilerplate minimum and 2 levels of indentation to start.
Nominal static typing with weak generics and no almost no compile time programming support - you end up mucking with reflection or code generation if you want to do anything metaprogramming related or non trivial higher order functions - JavaScript and Python just deal with it at runtime, and if you need to type it out - you can still generate types that convey to the user what the result will be (the underlying code doesn't have to be typed)
Function<String, String> fn = parameter -> parameter + " from lambda";
Using annotations and cglib, you can do all the meta-programming you want.
Annotations and CGLib -> reflection nonsense and boilerplate - if you tried that and compare it to something like a dynamic language with open types (eg. JS/TS) you are just being dishonest if you're saying the two are anywhere close to comparable.
I remember doing a node ORM extension where I just injected standard revision management primitives into the entity as a part of repository. That would take an insane ammount of work in Java in comparison to get the same API functionality (namely it was mostly transaparent to the consumer)
Just like anything else. Put it in a package and just static import it from where-ever you need it.
Umm, cglib https://github.com/cglib/cglib is not reflection - its bytecode enhancement. You can inject, create types dynamically, modify types dynamically - all of it is possible. What you just stated is quite straightforward in Java actually and can be fully transparent to the consumer. It's by no means an "insane amount of work".
Now, if you bring up hot language features - sum types, etc - I agree that Java falls behind. But the stuff you offered as criticisms, Java actually excels.
It's exceedingly rare for this to be untrue of Python — it's technically possible to hack builtins but there's intense community pressure against doing that.
> - the syntax, although not the most succinct is fairly easily readable and maintainable by other developers.
This is sort of true but it misses the aspect which makes Java hard to maintain: the language being less capable means that you end up with more boilerplate syntax which has to be understood when reading it and the patterns that produces tend to be the long-term maintenance issue instead.
The boilerplate syntax you talk about comes from like java 1.4.
Modern Java is quite expressive with streams and lambdas. If one does employ the Java Beans convention than yeah, he/she has to autogenerate a few getters setters, but those don’t occlude the actual logic.
And frankly, empirically, Java is anything but hard to maintain. You would be hard pressed to find many languages that continue to manage at the scale Java apps routinely handle.
Yeah, it’s (typical business monstrosity) hard to understand, probably has many thousands hours of technical debt, but it just works, and more things can be added to it (and occasionally with much more work, removed as well).
I was thinking about things I've recently seen in new Java 15 code, so no. There are lots of old APIs in the Java language and popular libraries, and while things like streams are quite powerful, they're far from universal. I still see developers cranking out code which has to do what is built-in in other languages.
As a simple example, not having multiple return means that you end up with worse APIs in some cases or small classes which exist to wrap a couple of things — not necessarily terrible but it means that you've just taken on maintenance work for something which would be trivial in other languages. That extra code isn't exactly a huge lift but when you add things like that up regularly it's not hard to understand why all of the good Java developers I know are keenly following things like Kotlin which give more expressiveness without giving up all of their familiar tools.
But I do agree that there is space for improvements here.
For example: imports inside functions instead of at the top of the file (because the import does work, but the configuration hasn't been set up yet).
An example of this is an internal package at my workplace which makes a external service request at import time.
The reason Java does compete so successfully is that it is high level and yet provides a virtually unmatched combination of performance, maintainability and observability (including always on, low-overhead deep profiling). None of the alternatives you mentioned come close. This is why it continues to be a top choice at Amazon, Apple, Netflix, Google, Alibaba, Uber, Soundclous, and almost all Fortune 500 companies. Saying it is "out of the loop" is either wishful thinking or delusional, depending on your perspective. It's just not the reality.
I'm just saying, "to me, that's why I never end up using java".
Java is good enough for the vast majority of things. But so is Python.
And for specialized things, there are better choices available to me.
I'm not a Fortune 500 though.
For a very different definition of "good enough," i.e. unless you're working on a large codebase maintained by a large team for years, need high performance, or need deep low-overhead observability. So Java is "good enough" for a much wider selection of "serious" (large/mission-critical/long-lived/ high-performance) software.
> And for specialized things, there are better choices available to me.
That's OK, but in reality Java does very successfully compete with almost all the languages you've mentioned; it is they that, in practice, find it very hard to compete with Java.
But even when the language became the bottleneck, they went the road of rust and go, not the road of java.
Again, not to say Java is not used by those companies with great success.
Trending does have an impact.
But by experience, having a killer feature, and a good adoption story usually does much more.
E.G:
- PHP: easy to make web page in 2001
- JS: monopoly on the client side web
- Go: simple concurrency and binary production
- Rust: borrow checker
- Python: "yes, you can do that too. Also in 2 lines"
Etc.
https://excel.uservoice.com/forums/304921-excel-for-windows-...
Any long time developer on MS stack knows that actually means "thank you very much but no".
So, I would not be so sure.
As for Dex,
> Research language for array processing in the Haskell/ML family
> This is an early-stage research project, not an official Google product.
Where is Python?
But it’s also a google side project, so previous experience dictates that it’ll be dead somewhere between arrival and 5 years time.
Plus all the boilerplate coming not from the language but the OOP design patterns.
Performance critical, lower-level servers are typically written in C++ at Google - think things like Spanner or GCS. Google only allows a very restrictive C++ subset.
Application servers are typically written in Java or Go. Which is preferred depends on the organization.
Google of course makes extensive use of Guava and Guice, and Bazel, which itself is written in Java.
The language itself isn’t great though. Java solutions tend to be bloated and make it hard to decipher the underlying domain logic.
I certainly wouldn’t pick Java for a small team of experienced developers.
Now, from a project success perspective, I think it's not. I've seen a lot of Java projects fail, over engineered, full of spaghetti code, riddle with inscrutable abstraction, stuck in a glue of badly designed architecture that has been fossilized by the type system.
I'd say from a project risk perspective, it's a pretty average language, it has pros and cons, but they balance each other.
these are properties of a poorly designed project, and isn't due to it being java.
You may be able to causally link the failure to the people on the project being "incompetent" - but that's not really the fault of java!
i say java is a pretty good language, if you have large teams, with varying levels of competency amongst the members. As long as you have somebody good to do the overarching design and direct the project, it would do relatively OK.
if you have a small, elite team, then it may not be the right choice (depending on the team).
> I've seen a lot of Java projects fail, over engineered, full of spaghetti code, riddle with inscrutable abstraction, stuck in a glue of badly designed architecture that has been fossilized by the type system.
Sure, but do you really think the same organization would have produced perfect simple elegant error-free code is Haskell or Smalltalk (or whatever "better" language you are comparing to) under otherwise same requirements, deadlines, resources and management?
I'm not saying languages doesn't matter. A better/more appropriate language is like having a bigger screen or a better chair. All else being equal, it will increase productivity and make developers happy. But it will not make or break a project. The things that will break the project: Bad/unclear specifications, bad management of change requests, lack of testing, unrealistic scheduling, lack of customer feedback, bad communication or conflicts among developers.
Choosing a less popular platform (like say Clojure or CoffeeScript or whatever) might very well increase productivity compared to the conservative choice. But slightly increased productivity will not save a project, while the additional risks involved could very well sink the whole project. Which is why most businesses seek to reduce risk rather than maximize productivity when it comes to development platforms.
Many languages haven't been popular long enough to have a nice pool of experienced engineers to pick from. Java has that advantage, which not many languages have.
"So weak"? You do realize that this is basically where every language was less than a decade ago?
We're in 2021, not decade ago.
Though it seems java in general attracts a culture of slow moving bureaucrats which doesn't necessarily translate into higher quality (in fact, I'd argue it translates into worse quality).
You are conflating to different layers. Not being able chase a competitor's big feature can be the death knell to your company, yes. But this does not mean that building your business software on stable and proven foundations is a high risk. On the contrary you want to be fast moving with your business features not with keeping up with quicksand under your feet. I.e. a stable well understood basis, is IMHO a prerequisite to moving fast above of it.
In addition to my arguments above, one still has to consider whether a tool matches the problem. Writing an Excel plugin in Java is probably a very bad idea (I really don't know, I just assume that anything based on .NET would be a better fit), although both Excel and Java value long term compatibility. If you want to follow the latest trends in AI without really understanding what is going on, it is probably best to follow all the tutorial about AI and use Python. But if you plan to hire people that understand the details of AI libraries, you might come to the conclusion that the AI libraries on the JVM also provide the basic blocks you need, the higher levels are customized to your application anyways.
To come back to the original point, a technology or programming language is not good if it moves fast, it is good when it fits your problem, doesn't create too many new problems, is well understood by you and your team and is maintained.
In practice, I've barely ever seen this assumption truly come to fruition. I see java codebases degrade, become undecipherable messes filled with reflection, inflate themselves to become incredibly hard to understand or work with, at similar rates. I still see JSPs throwing garbled stacktraces that barely help understand what's wrong. Still see business shoot itself in the foot because it said "this should never happen", so the code is made under the assumption it doesn't happen, because null is still available and no one uses optionals, and 2 months later you have clients show you another NPE after going through 15 layers of business-modifying logic and people spend a week uncovering how the situation can take place (or worse, it is retroactively sealed up and the actual bug is still there). If there's some magic spell that helps java become less messy than other static languages or even some dynamic languages, I have yet to see it.
At that point, one has to question: what are we losing the sprint for? Are we truly increasing the odds of us winning the marathon? Not even its most espoused benefits, libraries, write once work everywhere, etc., seem to be remotely unique anymore. The only two answers I see, are legacy, and the number of java devs available. Lose a java dev, no problem, just pop in another. Want to rewrite the app in a different language, or even in less verbose, modern java? Good luck convincing management firmly believing that a rewrite of one month is more costly than pushing out features at 1/10th the speed post-refactor for another 2 years.
Java isn't the problem. People lacking a broader view are.
But Erlang was just such a good fit for this project. I wasn’t so huge on the Java version of Akka. I also briefly looked at Scala, but I avoid Scala for similar reasons to C++ and Haskell. The nativess of a lot of the features I wanted to Erlang just looked better and it will be a cool homage to the language’s roots.
Also this is probably more my fault, but I don’t really understand how distribution works anymore. Supposedly Oracle JDK is no longer supported and you’re supposed to package a JVM with your application, but all the big Java apps still require me to have a system wide JVM to run them? OpenJDK seems to work fine for now.
Also after toying with a LAPB implementation, I’m so mad other languages don’t have a good type for dealing bit level data. Bitstrings are a godsend.
So you can just install OpenJDK from a package manager, use the jlink tool and create your own small “JRE” that you want to bundle. Jpackage can create a platform native executable from that, that is either an installable exe, .deb, rpm or MacOS’s format (I forgot it’s name)
"Running Java" requires detailed system engineering / ops expertise specific to how the JVM works and can be tuned, and all too often, how specific frameworks internally pile their abstractions on top of each other. Problem is, a modern "Java app" is a pile of large frameworks and libraries.
As a system engineer, I HATE Java applications written by clueless programmers. They are difficult to handle and I often have to dig in and fix bad usage of framework features that somehow passed code review by equally clueless "senior" developers. I then get to spend a day to find out why this or that connection pool in there managed by this or that library does not handle its connections correctly, just to find the magic framework level variable that tunes that specific screw. Stuff of nightmares.
Every Java project is also __severely__ underdocumented. That's because even if you write documentation for YOUR code, the framework has books of documentation on ITS specifics, and includes high-level libraries which THEMSELVES have heaps of specific documentation. Climbing the tree until one arrives at actual standard library calls is like climbing into clouds and hoping to see the sun some day.
> almost completely disregard how that code works on the JVM
As an occasional clueless programmer, I've had occasion to touch systems written in Java. Could you point me at some resources?
Reality is complex, and for non-trivial programs complexity is going to be somewhere.
Endless abstraction, loading giant things into RAM, looping over every item in huge arrays. Blocking server threads for minutes at a time. In most languages you would be punished severely with awful performance or OOM. Java chugs along until things get horrifically bad.
This weaknes stems from Java being OO. On larger projects you start to have abstractions which tend to be insucfficiently documented or the documentation not being updated with changes. Throw in some helper classes here and there, from a certain point of complexity of the project from an outside perspective the whole thing looks like being obfuscated.
The language is underwhelming, the JVM is great.
I haven't seen any benchmarks, but I doubt a Scala app written idiomatic style would be any slower than the Java version written in idiomatic style.
Also, what is this C spirit we are trying to stay close to? I'm certainly not interested in any "C spirit"
What I love about Java is, that I can update the runtime without being afraid to break something. I also love the mature eco system. What's also great is that the compiler catches most code issues before you try running your code.
What I don't like is the module support introduced with Java 9, which is vastly inferior to OSGi.
Java is typically used in larger or long-lived organizations. It is rare to start new projects from scratch. Most development is maintenance and extension of existing systems. Even if you start a greenfield project, it would be most prudent to chose the same platform and language which is already used in the organization. An alternative language would not only have to be better, it would have to be very significantly better to make up for the overhead and headache in maintaining code in multiple languages - never mind the increased difficulty in hiring and training developers.
Geeks tend to evaluate language based on how appropriate they would be for a greenfield project with no organizational baggage. But this is an extremely rare use case for most business.
HN often has reports about startups rewriting everything from scratch every four months, when a new language or platform becomes fashionable. But this is not the world where most developers live.
Anecdotally, I see a trend of greenfield projects moving from Java to NodeJS. I can't think of too many organizations that have zero web presence, and basically any modern web presence requires the use of JS, so there's almost always some JS expertise built into the organization.
That is usually part of the front-end team that don't do the backend SQL work. Tho team that would get assigned the work for a backend greenfield would be versed in Java.
That’s an outgrowth of most projects being quite small. Paying a team or 20+ people to work on one thing is freaking expensive to the point where it needs major benefit or huge company to be worth it. On the other hand maintaining lots of little projects that all automated something can easily pay for a single developer at even fairly small companies. Across tends of thousands of small and midsized companies you get a lot of such teams which grow and shrink, split off and merge over time.
THIS. The product is blended and so must the teams be. Among all the full-stack developers I've worked with, the "frontend" or "backend" designators tended to describe preference or strength, rather than limitation.
I think you underestimate the number of huge companies that see major benefit from large teams working large development efforts.
1,829,875 companies with 5-9 employees 779,922 companies with 10-19 employees 467,634 companies with 20 - 49 employees 170,749 companies with 50 - 99 employees
Of that a few are pure software companies, but it’s far more common to want to automate something. Which often means outsourcing it, but then they simply can’t afford these kinds of large projects.
At the other end only 23,553 companies have 1,000+ employees. Yet even at that scale it’s not guaranteed to have large development teams in house, a single hospital can have 1000+ employees and use mostly 3rd party software with a few generalists to stitch everything together.
Starting from the other end, the Stackoverflow survey has 50% of devs identifying as full-stack. Most surveys have Java as the #2 programming language, where it’s been for the last 20 years. That says nothing about how those devs are organized among teams, but I don’t think it points to such arrangements being “rare”.
I always took that kind of a breakdown to mean most website developers where full stack with embedded etc being their own categories. With majority full stack teams including various specialists as needed, which fits my experience over the last 20 years.
However, Android is Java and is frequently used as a front end. As things grow I normally see teams split by system, so I can see mobile being split off as their own team becoming more common even if it’s the still the minority. That said, it’s teams managing the backend teams which would be considering Java vs NodeJS and based on that 55% I think most teams are familiar with JavaScript.
In contrast, our Java upgrades remain painless. Many of our JS services have been merged back into older Java back ends
It's orthogonal to my point though.
Startup times are not an issue on servers as processes are typically long-lived anyway. It is a bit of an issue on serverless (lambda etc.) but that’s a relatively new thing. High memory usage is generally poor tuning - if you give the JVM 1gb it will use it and avoid GC until it needs to. Sometimes it’s poor coding too, I’ve seen web APIs accepting files as base64 encoded json strings which is horrific server side.
look at this graph: https://alvinalexander.com/sites/default/files/inline-images...
from: https://alvinalexander.com/scala/graalvm-native-executables-...
Obviously I don't have their dataset, so it's not exactly the same test.
edit: In fact the numbers in the blog are so far off mine they may accidently have been testing /usr/bin/find.
There was just not much interest in it, because performance gets worth, and startup time is seldom interesting. (Pretty much only command line tools would require faster startup, and recent serverless)
And memory usage is a tradeoff. Though most of the time java could run with almost half of the currently used memory, it is unnecessary work to GC if memory is available.
I learned Java on gcj (gcc support for Java), and it generated executables. I've no idea why they killed it. Maybe someone more in the know can explain.
WELL SUPPORTED???? Have you ever coded a real thing in python?
I'm getting "Warning, no longer supported" console messages in all my basic well established tools and libraries written in python because a guy that lives in a world of academics and theory and not in a world of business and delivery dates decided that python3 was not going to have backwards compatibility with python2 because they made a massive irreparable disaster when they designed python2.
That is not a professional tool for multi-million dollar companies, that is a toy for spoiled nerds. Exactly the same that Visual Basic 5-6 were when I was starting. Extremely easy to use and extremely fast, at the price of been garbage for anything larger than a toy app.
And because all the kids learned that at uni and went to create the next thing in it like PyTorch and TensorFlow, now you have to do all the real code in C / C++ to handle what python can't in terms of speed an reliability, doubling you code base, your Dev teams, and the needed skill set.
I have been programing in java in large multinationals for 10 years and I used python every single day for the past 3 years for what its useful: small hacky scripts to increase productivity. The real sh*t that manages you cellphone towers, you home-banking, you online shopping, your logistic chain and your android cellphone apps, all things that I have worked on, gets done in Java.
I myself have coded a streaming platform getting half a million user every day in Python. Baring the CDN to store the content, it runs on 2 servers, one for the DB.
So real things get done in Python pretty well.
_But as the company grew, new engineers who joined couldn’t understand the code. Clever code is usually short and cryptic, written by and for the individual who came up with it, but is hard for anyone else to understand—and nearly impossible to maintain. Guido called this “cowboy coding culture”. He recognized its value in our early stages of trying to implement things quickly, but knew it wouldn’t be sustainable over time, so he decided to speak up in his own quiet way._
And now they'll have to rewrite everything in programming languages where maintenance is not a burden.
[0] https://blog.dropbox.com/topics/company/thank-you--guido
Here you go:
https://dropbox.tech/infrastructure/rewriting-the-heart-of-o...
No one dreams about garbage trucks or puts one in a car show but they’re there and ready to go right back to work when you are.
- cryptography: It has a wide range support of symmetric/asymmetric algorithms from legacy to modern ones.
- XML and SOAP with Web Service Security in particular.
- Modeling large business concepts because of static typing, Objects inheritance and polymorphism, no memory management while still being performant. I would not use Python for that but other languages can compete C#, Scala, Kotlin, maybe Typescript.
The cryptography module in Python is awesome. lxml and sud deals with XML and Soap in a blink.
Modeling large business concept is a joy with dataclasses, and the language will never be the perf bottleneck.
Now I understand that if you are experienced with Java, it would solve all those problems perfectly.
But again, I would not, personally, gain anything by using it for this.
It's way easier than C++ and will get you 80 percent of the way there in terms of performance
Interesting - you seem to be saying that Lisp is very opinionated. If that was your intent, may I ask why? Your experience doesn't jibe with my experience as a Common Lisp user, which is that Lisp isn't opinionated enough, and gives you too much flexibility (in some cases).
I think the opinion you're trying to convey is "not untyped enough".
If I needed to waste more time on hacking a setuptools script, to get a file placed into /usr/local/lib/shared... I'd rather use Go or Rust.
Scala has a "tunable" level of PL feature usage; you can write very Java-esque Scala at the beginning and slowly incorporate more advanced features.
The key thing about these features are that once you understand what they do, it allows you to write fewer lines of code overall. Fewer lines typically means fewer bugs, and it communicates intent with more clarity (at least to developers who are familiar with the patterns).
This makes it easy to onboard new devs who may not know a lot of Scala and let them be productive from day 1 (writing Java-style Scala) while advancing their skills towards more fancy idioms.
I have stayed away from JVM-land after taking a different tack in my career trajectory, but I worked at Twitter about a decade ago when they were transitioning to a JVM-based stack and were early adopters of Scala. It was really a joy to be able to simultaneously get my work done while uncovering all of the new cool language features!
Based on what?
I think if Java's new features are an attempt to woo new developers, Java comes off pretty tragically, like the old guy in the club, trying stay relevant by showing off how it just got up to date with ideas that hit the mainstream ten years ago. Whoa, check out these record classes! Fresh stuff over here! I don't think there's any significant audience for this (a few "ignorant computer science undergrads" aside,) and I doubt that's what Oracle is shooting for.
I think what Java is really doing is reassuring people who committed to it long ago that it will take care of them. Java is not the old guy in the club; it is the middle-aged guy dressing up and taking his wife out for a night (or half an hour, depending on her arthritis) of dancing at a jazz bar. It's doing its honorable best to show the people who committed their lives to it that it understands they still need a little bit of excitement now and then, and they don't have to sacrifice their dignity to some cad at the bar at the country club to get it.
They don't really want to leave Java. Java understands things about them that nobody else ever will. All Java needs to do to keep them is love them enough to keep doing its best.
It might not be what you choose for a new company, but it may not be fashionable here but it is very common and quality of life improvements are welcome.
My guess is that they're not trying to win over people from other languages with these features, but rather to not give Java people a reason to move to other languages. Why move (legacy and lock-in aside), when Java has the features you're considering moving elsewhere to get?
I'm sure that Java developers have a vision which they're moving to. They're trying to convert old language into a new one with immutable classes, pattern-matching, green threads, modular JVM, all that stuff. May be I'll like that new language, but so far I'm a little bit unsatisfied. And, as it seems, young people are not that impressed either.
Kotlin will survive because it was picked for Android to avoid copyright issues. But the difference between the two languages is vanishing small.
Kotlin was Google's backup if the suit went Oracle's way.
[0] https://en.wikipedia.org/wiki/Google_LLC_v._Oracle_America,_....
And I'm definitely happy that Java does not feature implicit injection, which looks so cool but is so painful to work with in Scala.
When I need HKTs, I can pick a perfectly good Haskell :) I'm afraid Java or even Kotlin will never achieve this level of FP-ness; for that, a language should be designed differently. Rust, OTOH, likely will.
But why would they bake in a misfeature? Yeah it is popular, but was never a good idea to begin with. Records and new language features try to slowly shift the focus to a more immutable, FP-oriented style of OOP, which is imo a good decision. Of course it doesn’t make imperative code legacy, the two worlds can coexist perfectly.
> Modules are weird thing that nobody asked for
This is the feature that allows the JDK team to do their work. You either expose the internals and freeze it, effectively killing the platform, or encapsulate it. It is/was a great decision, and it didn’t broke too many things.
> They throw out Java EE instead of improving it
Giving EE to the Eclipse foundation and transitioning it to Jakarta EE is about improving it. It allows the Eclipse foundation to move faster without having to go through the JDK standardization process.
I agree that it's underhyped. You can pick a lot of other languages, but no other language is as broad as Java.
Python reads like a dream but has useless perf and threading.
Javascript (Node et al) has the I/O concurrency but no clear solution to threading, and is bad at number crunching.
C++ has good perf but is overly complicated, compiles take forever, no good module management, etc.
Rust is great but super-hard to learn.
Golang lacks tooling and perhaps some libs, albeit being a really good contender.
Naturally there are other languages to bring up, but I personally think that Java strikes a good balance. The language itself doesn't really have any clear weak points anymore. With lambdas and streams, even FP is succinct in it.
The only thing really speaking against Java right now is the culture of overly complicated frameworks with too much meta-programming and magic. And the fact that the market of lightweight alternatives is too fragmented.
I agree with this, but I think these qualities are shared by a lot of languages that run on the JVM, and Java the language is no longer a worthy flagship language for the JVM.
> With lambdas and streams, even FP is succinct in it.
I have the opposite reaction to lambdas and streams. I think Oracle could have gone two ways with the evolution of Java:
- Be conservative about what features were adopted into Java, but be willing to change the syntax and feel of the language to do it in the best possible way. Only add features that both made sense for Java and had proven themselves after years of experience with the languages that pioneered them, but give Java the most elegant and polished version of them, so that Java would be a kind of "best in class" language that trailed the leading edge but always reflected it in an excellent way -- at any moment, the best version of Java that could be built with the industry's combined experience.
- Or, keep Java feeling as familiar as possible, while adding any features that are embarrassing to lack. It's okay if new features feel bolted on or don't feel as elegant as they do in newer languages; it's more important that longtime Java programmers don't feel like the fundamentals of the language are changing underneath them.
Streams are what convinced me that Oracle were committed to the latter route. They came out with an implementation that looked and felt clunky compared to what people were used to in other languages, but it felt very Java-y, and existing Java developers were pretty immediately comfortable with it.
Something I underappreciated until I delved deeper into other languages is how much observability the JVM gives you into how an application is running. Something like VisualVM makes it incredibly easy to see what threads are running, in what state, etc.
There's a class of things where the overhead of a VM (like the JVM, not VMWare) doesn't make sense (kernels, drivers), and startup time can be an issue, but for code where pretty good performance is enough, running in a VM is an asset to me.
Guys, c'mon, get your head in the game. Before we tech out how under hyped JAVA is we still never sorted out just how awesome VI is and how VI is way better than EMACS, Code Lion, and whatever other crazy complex IDEs are out there. Once we figure that out, only then can we afford to resolve the lesser pressing problems.
I’ve kinda started to like Kotlin from syntax perspective & Go’s nature of compiled and low overhead prospective. I wish somebody can combine those together (don’t tell me GraalVM).
Yes, it's one of the few mainstream titles where Java has been successfully applied, but I believe Minecraft's success was specifically because it was written in Java.
With no JVM, there would have been no Minecraft mods at the level of flexibility that Forge provides, and the game would probably have stagnated in comparison with the sheer amount of community content from the past ten years that's available. Being able to use libraries like ASM that allow you to transform the compiled bytecode in radical ways were possible only because Minecraft targeted a virtual machine. The incredible thing was that this was in spite of the obfuscation Mojang applied to the compiled source. If it was possible to create a flexible mod system at all thanks to the JVM, people were just too motivated for any deterrence to stop them.
For the people who say that Minecraft should have been written in C++ or something from the start, because Java is a mediocre programming language, there's Bedrock Edition. Nobody I know cares about it enough to play it. For all its bloat and performance issues, the benefits of the JVM were simply too convincing.
Been playing for just under ten years, everyone I know plays Bedrock these days. I built and manage a very popular tool / Minecraft community and while I don’t have actual numbers, my general sense is the majority of players run either console or mobile Minecraft - all of which are Bedrock at this point.
If you don’t care about modding or particularly complex redstone, I don’t know why you wouldn’t run Bedrock. It’s far more stable, reliable and performant. My laptops fans rarely come on in Bedrock but never shut off in Java.
In my eyes Java is the public prototype / feature target and Bedrock the actual product.
Because not everybody runs Windows? I don't consider mobile and console platforms as gaming, but that's just my biases.
Most PC gamers use Windows, consoles or devices. The non-Windows gaming market is very small.
While I prefer Java edition, my kid much prefers Bedrock, because it has the main killer feature of being able to share a world directly with friends. Anyone that's an XBox Live friend can see when they're playing on-line, and join the world. No need to set up a realm, run my own server online somewhere, or punch a hole through the firewall to the minecraft server at home etc.
- https://mcpelauncher.readthedocs.io/en/latest/ - it’s out of date but they link a fork that works.
Gatekeep much? You know that you just excluded probably 90% of all gamers right there?
Mobile I was used to, but consoles as well is next level gatekeeping.
There's an additional problem: when Notch first wrote it, he had some experience of doing games on the JVM and wrote the code in a performance sensitive style. But it wasn't a fully OOP style that people associate with clean, well designed codebases, so when Notch moved on, they immediately went and introduced tons of tiny classes for things like points or vectors where the prior code simply passed the components as parameters. That trashed performance. Again, newer JVMs are better at gobbling this stuff up, but it didn't help. Valhalla will eventually remove this tradeoff.
At any rate, Minecraft is a very good example of why more people should target the JVM for video games: modding is real, it can create communities that propel your game further than ever. It's not a great example of how to get the best possible game performance from the JVM. At all.
I'd bet this has more to do with the fact that the Java version started out as a one-man project (that wasn't even expected to take off), whereas Bedrock started as a multimillion-dollar project by Microsoft who a) knew the project scope ahead of time, and b) could hire a (presumably) world-class team to design and implement it
Personally I've never had real performance issues with either
* some very used redstone features on java are clearly bugs and rightly so are not on bedrock, but even those have a very specific and exploitable use
Java is a language with mandatory GC, tiny objects scattered around the heap (poor locality), and no value types or low-level memory access.
This makes it very poor for games (you know, other very basic ones).
But they're rapidly addressing these concerns.
i dont think you need value types at all, and you can simulate it by using byte buffers with an abstraction on top of it. After all, what's the difference between value types and a byte array?
As for things like low level memory access - you also don't need that in most cases. Graphics libraries will give you enough access. And for any other case, you can always JNI into native code, or call any existing system calls or libraries. Interop between java and native is not that bad (cumbersome for sure, but still possible).
The only reason java gets poor performance is the coder doing java is too used to producing garbage (or is too inexperienced to write high performance java code). you can easily avoid most performance problems in memory by pre-allocating and reusing memory by pooling. These techniques are already commonly employed in C.
for the parts that don't need high performance. And for leveraging existing libraries, if any are suitable.
The difference is a bit like coding in Java vs coding in assembler (more below in an example).
> The only reason java gets poor performance is the coder doing java is too used to producing garbage (or is too inexperienced to write high performance java code).
Read about Entity Component Systems, the leading architecture of high-performance game engines these days.
To do this in Java, with the implied memory locality, would basically mean storing your entire game state in bytebuffers, and constantly unpacking and packing them to do any operation on them. And when you unpack them if you unpack them to a random object in heap, you negate the entire purpose of the locality of a bytebuffer. So you somehow need to do the job raw, reading everything inline and putting it back inline, so you can stay on the stack.
I also doubt that the get/put calls you'd need to do to get/set every number would be free. So performance would probably end up quite terrible.
> you can easily avoid most performance problems in memory by pre-allocating and reusing memory by pooling.
If you make an object pool in Java you'll save on memory alloc/dealloc. You won't achieve memory locality, so your code will be much slower than languages where you can do that.
Also significant game state is not only represented by renderable content.
Also there are classes of games for which the latency introduced by a GC may not be that much relevant (e.g. strategy or simulation games).
Really? https://www.google.com/search?q=JavaScript+is+the+worst+lang...
If it exists, some people hate it. If it's popular, most people hate it. It's a universal law. /s
Anyway, you never hear "JS is not suitable for high-end games" because with JS that's kind of self-evident. While with Java, some people don't know enough to realize that.
> Also there are classes of games for which the latency introduced by a GC may not be that much relevant (e.g. strategy or simulation games).
Strategy/simulation games can get quite big/complex. Keep in mind you're not just modeling the units, but also the terrain the various particle effects and so on. You can definitely pull off something like StarCraft 1. But people want games to match the capabilities of their hardware, not that of a Pentium from the 90s.
And performance remains crucial on mobile. I.e. you may get the game going, but it'll suck your battery empty in record time.
Expand?
https://medium.com/@youngty1997/jdk-14-foreign-memory-access...
Project Valhalla (Inline Classes aka Value Types):
https://dzone.com/articles/project-valhalla-fast-and-furious...
The links I picked are a bit random but they'll get you going with the basics.
Especially now with ZGC, not even tiny freezes should happen.
I think this is because of the way it handles memory. It's like the clunkiness of C++ without the power to optimize. Also, compared to python it is fast, but not compared to C or Rust.
That said, for 99% of applications the Java garbage collector is safe and tends to produce reliable code. The article is right in that Java is an extremely useful language with good tools. Games are an edge case.
It is comparably fast. Much more close to them than to python.
Regarding modding, I think if the game is successful, then there will be at least a small handful of people that write a modding interface for others.
It's the version used on all handhelds and consoles.
The GC is constantly overworked because Java has to allocate immutable vector and matrix classes on the heap.
In other languages (like C# for example) you'd make that a struct and enjoy value type semantics and stack allocation (in most cases).
Java has a branding problem. Java (and Oracle) missed the wave of the last 15 years when tech became "cool." If you were new to tech/programming and wanted to pick up a language, which of these three would you pick, based on the website?
- Java: https://www.java.com/en/
- Kotlin: https://kotlinlang.org/
- Scala: https://www.scala-lang.org/
Java just doesn't have the cool factor that other languages have. A little rebranding could go a long way to reinvigorating the language in the eyes of newcomers. And I say that because the author of this blog post is a newcomer. Experiened developers know that, despite the ugly Oracle branding, Java is a good language with a sophisticated ecosystem of tools surrounding it. He seems to be mostly enamored with the developer experience of IntelliJ + Java + Maven. And while it is great, that experience is possible with most programming languages.
Disclaimer: I haven't used Java since my early University classes 10+ years ago.
Don’t pool it all together with this Java website - which sucks but not because it was from 2010.
I abhor and loathe modern web design.
I just remember the Java.com homepage from visiting it in computer lab in 2011 so I could play Minecraft.
The Java download button looks clickable without me having to hover over it. The Kotlin "get-started" link doesn't look clickable, because it's next to a different link that has a different style (both actually are clickable). The Scala one has a download link that also doesn't look clickable.
Rubbing salt into the wound, if you click on the second link for Kotlin ("learn more"), the back button doesn't work.
Summary
Java website: made as obvious as possible, prominent download and search interface on main page; type in your search and press enter.
Kotlin: Links differ in appearance from each other, back button broken for some links, which don't even look like links. Cannot type in a search term until after visually finding and clicking a search icon. Then you type in your search term (two-step process).
Scala: download link looks like neither a link nor a button. Never found a search button. At least "Back" works.
I have to say, the Java landing page works best. That your personal preference is for less obvious and less simple user interfaces doesn't make the simple and easy to use interface a bad choice.
What is really going on here is that there isn't a "the Java website". There is no single organisation or project behind Java which could put such up a website. Similarly, where is the C++ website? The C website?
java.com was originally the website aimed at end-users who need to install Java to use desktop applications written in Java. It looks like it's from 2010 because that's when the last of those went extinct.
C website: http://www.open-std.org/jtc1/sc22/wg14/
- https://www.oracle.com/java/technologies/javase-downloads.ht...
If I go onto my GitHub and try to get any of my old projects running I am extremely confident that the non-Android Java ones will still work. All of the other ones will probably have "rotted" over the years and send me down a day-long rabbit hole looking for old dependencies or build systems.
There's something to be said for that amazing stability. I can't think of another language where you can find some .edu page from 2001 with a link to a library (.jar) that does what you need and you can actually use it in a modern application.
Doesn't mean we don't touch old code (change idioms, generic safe, build process etc). It means we do it when there is value to us for updating it. Not because we are forced to due to an infra change.
At the same time code that ran on a PA-RISC machine now happily runs on a mac arm (even then it was great because the same code ran on PA-RISC, powerpc, x86 and X86-64).
If that code was written in python it would have likely gone through two breaking cycles at least. C sure that would have worked but the cost of having it working such a variety of systems would have been humongous for a small group like us. What real alternatives have this claim? C++ chances that I can compile code from 2000 without issues is minuscule.
Sure I had my EJB "fun", and when I look at some of the micro-services being deployed I see the same problems. Because they are reflections of organizations. (i.e. sometimes have the feeling that changing language in an org is like switching your in-office communication to Italian, because it so fast and romantic.).
Just because there was "bad" code written in the past doesn't mean new code is done that way. Yes it exists, yes it needs to be poked once in a while, but that is a lot cheaper than rewriting in a modern style.
Really? I have code from the late 90ies and it compiles just fine. Do you perhaps mean dependencies? Because the issue there is the completeness of the framework and libraries around Java rather than the language itself.
So you need to get them but they are not available anymore and may depend on code that doesn't compile anymore. Due to e.g. 32bit assumptions, changes in what a 'long long' means and small hiccups like that.
Or the fact that C++ code was "almost" C++ code and not actually C++ code. Just a variant that was supported by an "almost" C++ compiler.
Not really the case for smaller utilities but larger projects originating on what is now rare equipment suffered from this.
So maybe not "miniscule" but not rare in my experience either.
But again, that's a problem with the OS, not a problem with C++. POSIX compliant code still compiles just fine on POSIX-compliant platforms and 32-bit code compiles just fine with 32-bit compilers as well - nothing changed in that regard. It's a similar story with other APIs such as Win32.
> Due to e.g. 32bit assumptions, changes in what a 'long long' means and small hiccups like that.
If you try to compile 32-bit code as 64-bit code you're porting, not recompiling. You can also just specify -std=c++98 (with g++) or just use an old compiler.
In my experience the problems with Java code are just as annoying, but those problems don't come from within the language itself either.
Things that weren't natively available had to be added via external scripts, application servers, native libraries, etc. And getting a fragile jumbled mess to work that relied on a specific Tomcat server version, command line scripts, external libraries or - god forbid! - certificates, was a major PITA as well.
Even today trying to get something as simple as SSL certificates working with Java can be frustrating. Why? Because for some reason Java insists on keeping its own keystore because it's the JDK that decides which authorities are to be trusted - not the user, not the OS, only the JDK.
Well, one of the installed versions, which gets to be real fun if you're working with containers, but I digress...
I would definitely not say that java is perfect, but the java ecosystem does have some very practical advantages that more than compensate for some of its very real disadvantages.
I LMAO when Python changed (or broke...depending how you look at it) the basic print functionality between version 2 and 3. Meanwhile I can use the latest and greatest JDK to compile old java code.
Don't get me wrong, I think Python is awesome for what I needed to do (data manipulation) and would likely be my language of choice for such tasks in the future.
Also, the best way to get a highly commented article on HN is to write one on why you love, or hate Java.
I once wrote an application in 2005 that kept running with unmodified source code up until 2017 in production across multiple operating system upgrades, database upgrades, and a transition from 32-bit to 64-bit runtimes.
I'm almost expecting a few years down the road, Microsoft will go back on 4.8 being end-of-the-line for .NET 4 and start releasing new minor versions of it because of all the customer code that can't be ported to .NET 5. Or maybe it will just end up like VB6. Stuff written in it still works, and will continue to work, but it's considered a dead language.
"Initially" would be somewhat closer to the truth than "always".
What the hell? I don't think we have the same definition for any of these words.
I know Java has changed quite a bit since Java 8 (Java 9 being the last version I used professionally before switching completely to Go), but I just can't write Java again, it's physical. When I want to try a new Java feature and think about writing the scaffolding code, my stomach actually hurts.
Not to mention the pain point that it still is to install and configure a JDK, and make it work properly with Intellij, why is it still so complicated?
Then there's Maven and Gradle that are just... bad, I have no other phrasing. I hear a lot of people saying Maven already solves all the problems we have with today's tools but that's just not true, even the entire Maven stupid lifecycle should be thrown away!
Where’s the pain?
Honestly I haven't had to deal with the issues you talk about in the last five years (which is as long as I've been writing java commercially, before that I was mostly a C developer).
Having had recent experience with Go and Javascript/Node, I can't say either struck me as especially easier or more intuitive to get started with.
Maybe things have got much better in the last handful of years, I don't know. My experience of getting started with a java project in that time has been no worse (and not really any better either) than in other languages.
Java tooling can be painful but to me it's VERY squarely middle of the road.
My problem is that Java is one of the (probably) 3 biggest languages in use, both investment and dev time wise, and it's overall just not that great.
I generally agree with "not that great" - Java the language I actually find fine, and to me it scratches a lot of the pragmatism that Go tries to get, with different warts in each. I try to avoid the Java framework ecosystem so I don't have to deal with beans and annotations and piles of codegen, not because I don't like the language. And Android has done much damage to the community's impression of Java.
I don't have to setup a $GOPATH, downloading dependencies doesn't kick off a million scripts that end up running native compilers, like in the node/ruby/python/php ecosystem. I can build and run a Java project on almost any system, without making substantial changes to my environment and without giving up and using docker for my dev environment.
I have been in situations where I had to compile some projects from other people and it has been painful every time. Especially as I might be in an environment where there are no IDEs that wrap things up for you.
Everyone has different experiences and requirements for their projects and not everything is same as it is for you. Don't take it personally and try to passively insult other people's intelligence.
tar -xzvf <jdk archive>
<set JAVA_HOME env var to point to dir>
<add to PATH $JAVA_HOME/bin>
So complicated.
IDEA can download and configure one of multiple JDK distributions in a single command:
I used to work for a company that had about 100 different Java web applications running, each with their own JDK. It was _trivial_ to set up and maintain. Was it wasteful? Sure. I shipped a JDK with each application. Was it hard to automate? No. Basic deployment automation made it trivial. The JDK was just an application artifact alongside the JAR file, and the application starting script set JAVA_HOME pointing to it for that process.
IntelliJ makes it trivial to maintain a project specific JDK. You just add the location of your JDKs to it (IIRC it can even auto-populate the list), and then choose the JDK from a simple menu within the IDE.
Other languages have other pains, for example I have physical revulsion against the version management hacks for python or ruby (rbenv and stuff like that - somehow hacking environment variables on the fly to manage multiple installations of the language).
Two years ago I wrote a small web app in Python and I found hosting very complicated, compared to Java. PaaS exist but are very expensive.
You can put it another way and say it doesn't feel good to write Java without JetBrains.
I used to be a C++ wizard. I did things with that language that were just unspeakable. I used features so obscure that I don't even know if they have an official name.
Then after I dunno... the five hundredth nonsensical linker error, something in me just snapped and I just can't ever go back there.
As for amounts of scaffolding, IntelliJ product writes it for you. And modern Java forces you to write only a half of it anyway.
Like, if you're out of work for a couple of months and the only way to feed your kids is to take a Java job, I don't think you'd pass it up. I wouldn't pass it up either even though I don't like Java. The whole language feels like it's designed to meet some minimum lines of code requirement.
If you're working on a team, strongly typed languages like Java and C sharp are a must. Otherwise it can get extremely hard to figure out what exactly other people are doing.
Python, for example, is also strongly typed. You most likely mean static typing, which is very useful but not exactly Javas or Cs strong suit either.
Most people basically work to eat, I've taken Java jobs just because I needed the work. It can always be worse.
I would honestly consider the alternatives. I'd probably take it in the end because money is good, but I'd try to flirt with manual work instead, if Java was my only option.
Eh. 150k working on Java enterprise systems vs working at Costco for 15$ an hour. Java isn't great, but it's still much easier than C or C++ imo.
In a perfect world we could all work in Python all day, but that's not life
More seriously, IDEs exist and work, so if people are productive with them, what does "but you'd be less productive if you didn't have your IDE!" gain us? C++ is a bit less verbose, but still the wide majority of devs uses an IDE with it because it does useful things. Programmers of Lisp etc use editors that have tools to edit Lisp files better. etc. I get not liking the existing options as a matter of personal taste, but that's different.
I've never seen a Java program in my entire career that was actually fast and not a huge pain to work with. I'm working on a new one right now and the prototype/skeleton literally does just basic CRUD operations and the CI/CD pipeline takes 7 minutes.
Golang was a breath of fresh air for me.
"This cannot be understated: Java simply feels good to write"
But why?
The only explanation that follows is that "a lot of this is due to the craftsmanship JetBrains puts into IntelliJ IDEA. Everything is autocompleted, jump-to-definition is fast, find-usage works well, and refactoring is easy".
I too think that IDEA is an excellent IDE, but why should Java take the credit for it. If anything, the more it needs an excellent IDE in order to feel pleasant, the worse it says about the language itself.
It really looks to me like the "ignorant computer science undergrad" mainly worked with JavaScript (having only dabbled with C++ and a few other languages as part of his uni courses), and got excited by discovering a proper IDE and a statically typed language that happens to have a low entry threshold.
It actually does, the language itself makes those features possible. The reason javascript does not have as good IDE is that language itself stands in a way.
The large the project, the bigger the gap gets.
I really do believe that the reason we have programmer holy wars is because we approach problem solving in different ways.
The way I approach solving a problem with a computer program is almost incompatible with the Java programming language. And, no- this is not a thinly veiled way to shit on object oriented programming. I can work in an object oriented paradigm just fine. It's just Java specifically that doesn't work for me.
Here are some examples that constantly bother me when writing Java:
* Null. Enough said.
* Writing value types used to be very tedious and bug-prone before Records. I haven't written Java with Records yet, but I'm glad to know that they'll be there if/when I do Java again. Even for an object-oriented architecture, value types can be useful and I use plenty of them.
* Type erased generics are painful. Especially with interfaces.
* The number and arithmetic APIs are incredibly frustrating. No unsigned numbers, silent wrap-around on overflow, silent data truncation on casts, etc. I have zero confidence that my Java code that deals with numbers is robust at all.
I'm sure that many programmers don't even notice these things, because they way they interact with program design is just different than my way. But when I write Java (or mostly any JVM language) one or more of these issues are on the forefront of my mind with almost every single line of code I type. It's almost unbearably frustrating.
You just download the JDK, and set JAVA_HOME to point to it when you want to use it.
For IntelliJ, you set the JDK in the project settings. It has a menu where you can point it to a JDK it knows about already, a JDK on your FS, or you can select a JDK for it to download for you. Couldn't be easier.
Java build systems are mostly terrible - you're right about that. Maven has the best tooling support, and is actually very straightforward, but a bit limited. I have had a number of bad experiences with Gradle. The Blaze-family build systems (Bazel, Buck, Pants, Please, etc) are far more sane, but have low adoption.
JVM is great. I think it gets a lot of love (in comparison with .NET Core which is IMHO as good as JVM). In this one, you see JVM everywhere except desktop apps.
Then, there's Java itself. As a language, it really isn't as modern and doesn't provide much what isn't already available in C#, Scala, Kotlin, or even PHP or TypeScript. And it doesn't provide some things that other languages have. So on this scale, once you know Java, you can be productive, but I doubt you will be more productive than someone who knows C#, Scala, etc.
And then, there's Java culture. Plenty of Java devs (mainly in J2EE, Spring world) don't develop in classes, they develop in design patterns. AbstractFactoryStrategy, complete abstracting out databases, five layer data models, classes for things that should be enums. It's a matter of taste, you don't have to do it (Android devs don't do this that much even when they use Java). And I think all the coolness of modelling, UML, etc. is over.
I think, you can be productive in Java (if you use it a bit like PHP). I think JVM is fantastic. For me, I am 8 years in Clojure world and I wouldn't go back to design patterns, writing (in Java often generating) dozens of lines of code just to insert something to the database (entity, mapping, repository, business logic layer, etc.) when in Clojure, this would be three lines (defn, schema check, insert).
I actually think the core language is great. And under Suns management Java was largely what golang is today; it was the pragmatic choice and it put the focus back onto writing code and away from complicated language features.
Then IBM stepped in with JEE, and it completely transformed Java into a language for bureaucrats and over-complicators. JEEs ethos was that the programmer is stupid and that the framework saves the programmer from their own stupidity. Not the greatest of ideas if you ask me.
Sane people jumped to newer languages. I tried to stick around and argue against bureaucracy, but in the end I realized the pointlessness of it all.
Now I'm ironically back with c++, but still the community is much purer and focusing much more on actual coding than snake oil.
Still write Java on my spare time and love it for it's relative ease of use, speed, and clarity. Not the most portable, ironically, but my language of choice for prototyping.
Java still has some true high quality libraries in it. I'm yet to find a good replacement for Doug Leas concurrency libraries in other languages. And the containers are great. And despite all the flak it gets, I actually think Swing is really good for whipping up a simple UI.
- The programs are very verbose for the functionality they provide. There are countless lines of getters, setters, and trivial constructors. While IDE helps to write them, it makes reading existing programs slow and frustrating. Lombok helps, but very few programs use it.
- If you do want to use Java ecosystem, there is Scala. It also has strong type system, nice IDE support and big ecosystem of third-party libraries, but is much more expressive and easier to read and write that Java.
- Finally, if you have to run medium to large java programs, you need to constantly tune the JVM. Unfortunately, you can't "confidently trust the JVM to do what's best" -- you need to get familiar with GC algorithms, manual heap sizing, GC tracing options and so on.
Java still has plenty of uses because it has so much code written in it, but luckily, the new projects are using it less and less. I really look forward to the day when I can stop tuning -Xmx option in start.sh files!
3 month warning that they'd blow up the ecosystem. I have no idea why a company that builds products for devs would take such an aggressively anti-dev approach to shutting down a core service.
I think the biggest change for me was the redesigned collections-library, but that was rather simple migration.
That said; there are a few breaking changes with the migration to 3.0 - especially if you rely on unsupported features of the compiler, namely macros. Macros have been widely used in the past and will not be supported anymore.
Oracle owns Java.
This automatically puts Java on my list of tools I'd prefer to avoid for new serious projects. (Legacy projects; if it's working and it isn't an issue yet, maintenance.)
Never touch anything from Oracle.
Then you will be fine.
Oracle is the company that wants you to buy a license for your MariaDB(!) instance running on a small AWS instance! Yep, that happened.
Source: have worked with Java for years, three of those around Oracle products.
But OpenJDK is Oracle's. They are the primary contributors to the project, and they really made it 100% open-source.
[1] https://en.wikipedia.org/wiki/OpenJDK#Collaboration_with_IBM...
- IDE support for Scala is half as good as Java and I suspect a good reason is the language. The auotcomplete in intelliJ is almost as bad as it is for python and the IDE really struggles to understand the code; CPU usage when scala is open is MUCH higher than Java.
- On all the Java apps I've worked on, I've never tuned the JVM. Tuning the VM sounds like focusing on the wrong part of a bottlenecked system. I've never tuned Python or PHP either but they aren't as performant. Regardless, GC gets better every release.
It sounds like your negative views are more about the applications you've worked on than the language or technology.
This is not my experience. I found the IntelliJ autocompletion to work very well with Scala. There are nice code-suggestions, highlights for implicit parameters, refactoring works as a breeze. What exactly are you missing?
> CPU usage when scala is open is MUCH higher than Java.
That is true. MUCH higher.
That's true for 2005, not 2021, with var, type inference, closures, streams, and other such features. And since forever getters/setters are auto-generated by the IDE (including Emaca and Vim) and can just be ignored, and Java today has Records which don't need them.
>- If you do want to use Java ecosystem, there is Scala.
Now you have exponential problems. Scala has less support, slower builds, and features Scala-devs are eager to abuse to make the code unreadable.
>- Finally, if you have to run medium to large java programs, you need to constantly tune the JVM.
No, you really don't.
Production algorithmic trading app, 100k LOC, 8 GB heap, 258 threads, right now only using 105% CPU; Java 11, and this is the complete extent of JVM tuning we have done:
-Xmx8g -XX:+ExplicitGCInvokesConcurrent
Back in the Java 1.x days, you often did need to do careful JVM tuning. But for the past few years, you haven't. The ergonomics are enough for a very broad range of workloads.
And to add to what you wrote for those that are not familiar with those types of apps: "Production algorithmic trading apps" is among the worst case regarding to peformances / pauses / and tuning needs.
Unfortunately, the Scala compiler is quite a bit slower than javac. In practice this doesn't hurt quite so much anymore; incremental builds make working even with large code bases quite snappy. Full-rebuild; get a coffee.
The build tools for Scala have _massively_ improved in the last 5 years. IntelliJ support is superb and VS Code with metals is shaping up very nicely.
I agree that since Scala is a unopinionated language, you need to be strict in what you allow your devs to do. Code reviews and agreements on levels of abstraction and concepts used is mandatory.
I've worked with multiple teams in the last 8 years and this discipline is important when working with Scala. Doing so will give you the opportunity to write clean, maintainable and readable code in a very powerful language.
https://scala-ci.typesafe.com/grafana/dashboard/db/scala-ben...
The Scala 3 compiler has much fewer passes though.
You either haven't used Scala, or you haven't used Java.
Sure, you can find libraries using complex type-level machinery, macros and so on. But wading through complex Java libraries that overuse OO design patterns isn't particularly approachable either.
There are one or two knobs left but those are fundamental to GC technology and it's not even obvious they're bad to have. GC lets you trade off memory against CPU time in ways manual memory allocation does not. You can throw memory at your program and it'll run faster, or you can constrain it and it'll run slower, but that's not a decision the developer can always reasonably make. It's in some ways inherently an ops/deployment/end user thing.
Other GCd languages either:
1. Have knobs too (Go/.NET both have knobs), just usually not very good ones.
or
2. Are so slow (Ruby, Python) that GC tuning is really the least of your worries and they just don't expose it at all.
or
3. Are JavaScript, in which case everyone pretends that running a VM designed exclusively for laptops and mobile phones on the server isn't a giant waste of resources. V8 doesn't do GC tuning because its only real customer is web browsers where users can't do that, and heaps are small anyway.
Java ended up getting a totally unfair rap about GC because it actually was fast enough that GC performance mattered, and was interested in power users on the server where exposing knobs can make sense. Other competitors don't even try, but this doesn't make them better. After all, nothing stops you just ignoring the knobs and plenty of users do exactly that.
Scala has a whole slew of problems of it's own. IMHO, Kotlin is where all the Java refugees on the JVM continent are at.
Language development looks a lot like the startup path anymore. Claim you fill a need. Focus on growth growth growth by adopting features from as many communities as possible as fast as possible. If it's trendy, add it! Have a flashy web page. Find some venture capital by getting a big org to underwrite/champion you. Figure out how to really solve problems and fix everything once you've got critical community.
- It forces us to go through the ceremony and verbosity of static typing, yet blows away lots of the benefit by pervasive use of `null` and `Object`. Compare this to ML or Haskell, where there's less ceremony (Hindley-Milner type inference) yet more safety (no `null` or down-casting)
- Checked exceptions have a similar ceremony and verbosity problem, yet the pervasiveness of unchecked exceptions prevents us actually having much confidence that calls will succeed. Compare this to effect systems, even rudimentary ones like Haskell's (`Maybe`, `Either`, `IO`, etc.): if a function doesn't return one of these 'effect actions', we can be pretty sure that it will succeed (the only unchecked exceptions I've encountered in Haskell are pretty catastrophic things like OutOfMemory).
- It needs to be compiled ahead-of-time, which requires more tooling, makes automated testing more annoying (we have three different failure-reporting mechanisms: app compile error, test compile error, test failure), tools like REPLs are second-class afterthoughts, etc. Yet the resulting bytecode still requires an interpreter (JVM), which takes a while to spin up, and makes deployment and packaging harder (we don't have a self-contained binary).
- It pushes an OOP style, but requires that we keep subverting it; e.g. pervasive use of using structured-programming constructs like `for` (which other OO languages like Smalltalk avoid in favour of method calls), which requires we break encapsulation/implementation-hiding (e.g. if we loop with an 'Iterator', we need to know whether anything we call will use that same Iterator).
- It seemingly pushes a high-level, highly-abstracted design (methods calling other methods, classes maintaining their invariants, etc.); but then throws threading into the mix, which breaks things into such low-level pieces that even 'i++' needs to be thought of in terms of constituent parts (read, increment, write, return).
I agree that Scala's better (e.g. reducing a lot of the typing ceremony; making it easier to remain high-level/abstracted (e.g. encouraging 'map' and friends rather than effectful loops), etc.); it inherits some of Java's problems (and doesn't even flag checked exceptions!), but it's nice enough to tilt the balance in many cases.
Who is pervasively using Object? You are talking about a language that hasn't existed for a decade.
Since then I've defined a .has method which requires the argument to have the same type as the collection, which completely avoids such problems.
My `.has` method uses cats.Eq and is monkey-patched on to the Iterable interface:
implicit final class IOps[A: cats.Eq](val i: Iterable[A]) {
def has(x: A): Boolean = i.exists(_.eqv(x))
}Yet not the most important static analysis suite, which is included in the compiler, and enforced on all code: the type checker ;)
This sounds like you're not programming in the Java language, you're programming in some sort of graphical macro language which compiles down to Java (presumably built-in to an IDE of some sort?).
The fact that people resort to such things is evidence that this is a valid criticism of the Java language.
Thankfully, Java ecosystem has learnt from other languages and frameworks and with Java 8 onwards has addressed some of major pain points For e.g. lambda, streams, vars, text blocks, records etc,
On the other hand, Shopify and Dropbox that used Ruby and Python heavily had to invest in type checking to bring back some sanity and this is evidence that beyond a size of code base, static type checking is worth it.
Considering these, I find Java to be a very good option to build stable enterprise applications compared to Ruby or Python.
Which is honestly why I think Typescript with Node on the backend is an excellent choice for many enterprises.
Actually, Java has great tooling, JVM is very nice, it has great potential for high performance code generation. It has everything for debugging. But at the end of the day, language is driving people to write bloated software.
I just wonder, how come e.g Linux kernel code 100 times more readable than any project in Java? More importantly, how did we come to this point that we accept bloated/unreadable code in the name of higher/better languages?
Java became overcomplicated by frameworks and design patterns, so has always felt bloated and slow. But has worked best for business logic. Though is maybe behind COBOL thus far, and tends to hide/obscure logic. No two java designs looks the same, scales well or converge to clear consensus. The language did lower the bar for what cheap programmers could accomplish faster though.
What vendor lock-in? The whole thing is open source from the compiler to the runtime - https://github.com/dotnet
If anything Java is more locked in as the most popular and 'official' runtime/devkit (Oracle Java/JDK) is completely closed source.
Linux is highly readable because Linus imposes readability on it through sheer force of will, and because they are willing to sacrifice driver API on the altar of clean code. The result is a very efficient and readable kernel that hardly anyone uses in the environment with the most complex and heterogenous hardware i.e. desktops and mobiles. Android doesn't really use Linux these days. Since some years it has developed its own stable driver ABI that bypasses the kernel for most things.
If all Java codebases were run by a dictator-for-life who could sacrifice trifling details like adoption in order to get the most readable code possible, you'd find you'd like them a lot more too. And a few such codebases are actually like that! Look at the source code of the JDK itself sometime (not the bits by Doug Lea though), or Guava, or really quite a few open source Java projects have readable and nice code.
Ship functionality as libraries, not massive sets of "Thou shalt do it our way in our all-encompassing , over-complex, hard to debug straitjackets."
The language itself is not what it was, it's very capable.
I make a point of starting all new projects with just the JDK, and taking that as far as possible before adding dependencies.
A 40k LOC codebase i work on has these external dependencies (plus some company- and vendor-specific libraries, which we would need in any language):
1. Netty, for serving HTTP
2. Glassfish JSON, for parsing and formatting JSON
3. FastUtil, for efficient collections of primitives
4. Guava, purely to get PairedStatsAccumulator
5. SimpleFlatMapper, to parse and format CSVs
No frameworks, no criminal bloat.
For the first few years of its life, this app used the JDK's own HTTP server, which was fine. Then we wanted to add websockets, so we needed a more sophisticated server.
If there is a problem with Java here, it's that people don't realise you don't need frameworks. A lot of developers will reach for Spring, Java EE, or something else like that right at the start of a project, without questioning the need for it. But this is not a failing of the language, or a problem you have to impose on yourself.
But it's not the only way.
I think this author is going to be up for a rude awakening when it comes to the benefits of nominal typing, as this is the area that I couldn't disagree with more. I've commented about this before, but structural typing in Typescript makes it so much easier to refactor and to get one existing piece of code to confirm to another existing piece of code. Refactor projects in Java could sometimes literally take months when you had a major version upgrade from some important dependency and now you had to replace all your Foo1 objects with Foo2 objects, even though the interfaces themselves were largely the same.
I just find myself sooooo much more productive in the Node/Typescript ecosystem than I ever felt in Java.
IMO Java and C# and other compiled languages have the opposite problem with languages like python and JavaScript (I love all these languages btw). It’s easy to get up and running quickly with the latter. It’s not until your project has grown in complexity when the formers value becomes apparent. This is similar to mongodb vs say, Postgres.
Also modern Java has picked up a lot of the better ideas from Kotlin and Scala. I still prefer Kotlin but I think a lot of criticism I read is referring to older versions of Java.
No, Java is just about as hyped as it needs to be. Which is to say, it's more or less fine. Not great, not terrible. Middle of the road at best.
No true scotsman? Even if you want to argue that Java CAN be made more terse, the vast majority of Java that exists today is incredibly verbose. Even running a Java program is verbose. Java is the only language I've used where it's more common to have a shell script that starts your Java program than just running ./helloworld.
And yes, Go is less verbose than Java. Go might require some boilerplate, but it is certainly much less verbose than Java.
So, less magic is better. I will take Java codebase over Scala or Python every time, unless it is a toy script which is 100 lines
AOP sucks because it is paaaain to debug, proxies are magic. There is Dagger that solve some stuff
Who needs CPP macros when you've got reflection?
https://software-mastery.teachable.com/p/uncommon-sense
FYI: I am NOT an author of this course.
Take a look at a http server one in Java and one in C. Readability difference is crazy.
My company is in transition from Java to C, for bunch of stuff just for performance reasons. So, I debug similar projects time to time both in Java and C, http server, in memory cache, iot server etc. After seeing both, I just think although Java has great tooling, it drives developers to write unreadable code.
No, this is utter, utter nonsense. I have written plenty of both, and it's not even close.
If you are going to press this extraordinary claim, you need to supply at least some evidence for it.
Com.prout.shit.lol...
It’s just impossible to use without editor support. Nobody who cares for their sanity can type out those package names manually. I think even Gosling said as much.
CoMarshalInterThreadInterfaceInStream
D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_UNGUARDED_VALIDATION
RtlWriteDecodedUcsDataIntoSmartLBlobUcsWritingContext
Or how about: GtkColorSelectionChangePaletteWithScreenFunc
The alternative is things having names that aren't actually descriptive at all, which is not clearly better.Saying this as someone who Java after Python and other languages.
I'm used to Python (and some Go) for decades, and the verbosity of Java is a non-issue to me.
I'd rather have the speed, type safety, and refactoring tools support, over Python... (not to mention the much better packaging situation).
I'd still prefer Python for smaller programs, basically because of the startup time and quick write/try cycle. But for larger stuff, I'm not so sold, and I've been doing them (in Python) for decades...
Manual for loops? No generics?
It was simple, performed well (other than GUI and classloading sometimes took a minute) and was very portable. I even wrote some demos in it in the late nineties to show it can actually do 60 Hz realtime graphics.
Over time, the ecosystem got pretty strong. JVM improved and the performance got better. Life was good.
But something bothered me. Those crazy dependencies, how everything was overcomplicated. Perhaps JVM got too good at optimizing and monomorphizing abstractions away? You didn't have to pay performance penalty for complexity anymore!
Worse, all these layers of dependencies and abstractions made it nearly impossible to actually understand the whole system and figure out root causes for the issues other than by using arguably fairly mature and good tooling available.
All this made me puke. So I stopped coding in Java, maybe 2005 or so. Haven't looked back.
Nowadays I'm happy developing things where Java doesn't stand a chance. Kernel drivers, bare metal firmware, tricky low level stuff, vectorized high performance code. Things that just can't get bloated or they might not work at all.
I don't have strong feelings about JVM much anymore, as long as I don't have to touch it.
JVM's high power consumption bothers me though, we're wasting so many nuclear powerplants worth of power for pretty much nothing. Of course the same is true for many other high level languages.
Perhaps we should work on high level languages with low power consumption?
And frankly, you simply can’t write all the software in use in low level languages. Yeah, it is theoretically possible but not feasible
Don't ask me how to create one. But perhaps someone who sees this has some ideas that gets us started on this path. You never know.
Power consumption doesn't get enough attention from software developers.
The reason Java can be a nice language/runtime today is the sheer amount of resources available to be poured on it due to all the hype in the 90s. It was supposed to save us from all the effort porting our software to many operating systems and processor architectures (the computing world was much less homogeneous back then). It was supposed to run everywhere without modification, from the smallest smartcard to the biggest mainframe. It was supposed to not only run within our web browser, but also be the implementation language of our web browser, or even the whole operating system. It was supposed to magically be faster than even C and C++ (those who used Java back then can recall how slow it was; for instance, hanging the whole browser for a whole minute while the JVM started up was not uncommon). Everything was supposed be written in Java; it was not good enough to call a native library for whatever functionality you wanted, it had to be rewritten in pure Java.
Java was a mediocre language. All that hype led to a virtuous cycle, which allowed it to grow into what it is today.
Tbf with Android that came to pass, at least until the applet apocalypse
Heck, here were native Java CPUs, Java Smartcards and different editions like JavaME for what today is branded IoT devices.
I cannot get the "write once - run everywhere"-slogan out of my head to this day. I don't even want to imagine a world where Java Applets actually "won" the internet and we would have proprietary multimedia applets instead of <audio> and <video> tags or even just CSS...
But once you are through that painful process, there is no other ecosystem more stable than Java. Things don't move too fast and that's a good thing for production applications.
I do dislike the verbosity sometimes while doing something that would take just a few lines in python or ruby. But IntelliJ more than makes up for it.
IMO, if you want to get a descent job in a large company working on backend systems, you want to learn: Java, C/C++ or recently Go. You will be able to build pretty much anything, from a micro service to self driving car.
If you want to stick to startups, you can do well with anything else till it growth, experienced engineers are hired and rewrite it in one of those languages.
I really don’t care what language I’m using if it it doing the job. I use Java, Java Script, Go, Python, Scala when appropriate.
Java has become reasonable though I'd always reach first for Scala or Kotlin (maybe Clojure?) I'd like to work with Rust but it seems hard for an employer to cost-justify the dev work to avoid paying for G1.
The fact that you don't care does not make everyone other than you not a reasonable person.
Frankly I don't see how any reasonable person could fail to develop some preferences, but I bet you would not like it if I called you unreasonable, or perhaps just unsophisticated.
I’m talking about picking a tool that does the job according to the requirements (speed, memory, debuggability), not based on what some YouTuber said.
We are engineers and paid for results. It help with carrier to embrace it.
Here is one: there is a database written in Java and you need to implement more features. There is 10000000 lines of code in the companies source and new code should be the same. I can go on and on.
Personal advice - if you want growth, drop preferences. When FAANG interviews nobody even asking what is your preferred language as nobody cares.
Nothing is exciting about it since it's so common. I personally dislike Java since I just find it hard , you'll never want for work as a skilled Java developer
1. a lack or deficiency of something.
"Victorian houses which are in want of repair"
In this case it's a double negative, OP means you'll always be able to find work as a skilled java developer.Anyway I looked it up, seems it's a legit usage, my bad.
Akin to "for want of a horse"
Another way to think of it is simply another slightly different meaning for the word "want". Just like in "for want of a horse", or "was found wanting", you can replace the word "want" with the word "lack" in all these examples.
"You'll never lack for work", "the project stalled for lack of engineers", "the code was found lacking"
"Want" may be used as a drop-in for "lack" in each of those.
You could also just say "lack work" instead of "lack for work". But that doesn't really make the "for" redundant. Though I can't explain the reason why not.
Maybe the "for" in "lack for X" or "want for X" is like the "for" in "look for X" or "wish for X"
> You could also just say "lack work" instead of "lack for work". But that doesn't really make the "for" redundant. Though I can't explain the reason why not.
I think it's just that "want" in its original usage is a noun. "Wanting" in "found wanting" is really a gerund of "have a want," not a gerunding of "want." "Wanting" as a gerunding of the verb "want" doesn't necessarily imply a lack. "Wanting to go to the park on Wednesday" doesn't mean you lack anything.
This is nothing more than the ramblings of an inexperienced kid who thinks they know it all. He'll probably look back on this in a few years and realize how little he actually knew.
In Java, this overall approach manifests in myriad of different ways:
- Functions and data are tied together. It's difficult to create new functions (methods) that operate on existing data, you have to inherit, and even that avenue can be closed, even indirectly because you find that you cannot actually get to some internals.
- Interfaces are tied to objects. You cannot explain to the compiler that a given class actually supports a certain other interface in the way YOU define it.
- Everything is a reference, no value types. No need to worry about the intricacies of cache management, we will handle that for you.
- No need to worry about CPU optimizations or memory management either - we will do that for you, without an escape hatch.
- You cannot change the existing operators to introduce more convenient syntax, because I said so. Any kind of "macro" - code generators, compile-time checks, conditional compilation, DSLs - forbidden.
- The class and package hierarchy determines the access to its components. No way to override this from the outside, no way to expose things that are hidden. Worse, this is implicit, for example, class method accesses an object attribute, where taking a parameter would be more convenient; this hurts reusability pretty badly.
Some of these shortcoming are only now being addressed, because people actually need to do these things anyway, in certain situations, which leads to proliferation of patterns and magical code generators.
I think it’s made worse by the fact that you can program in another language, in a shitty codebase, and walk away saying “wow that language is very painful”.
When in reality, it could’ve been the codebase and not the language.
I see a lot of “but look at this successful project in language X”. Okay sure it was successful despite the language. Programmers are smart, we can make things work.
Philosophically forcing developers into having to program in an OOP style, as opposed to having it as one of many tools, is a cardinal sin in my eyes. Same for forcing reference types.
I’ll argue garbage collectors are bad too, but tbh that is more of a debatable topic.
Data classes that expose their internals are a great way for some program logic, but let’s say a database connection is very much not a simple data class. It does have some static data, but it should not be accessible to the outside, because then it is not safe to close/use/whatever.
But I think you completely missed my overall point about being patronising, meaning, the idea that the author of the language/library knows better than the user of the language/library. The reason why Java is so guilty of this is that its other competitors at the time (C++, Common Lisp, Python) at least acknowledged other paradigms than OOP, and were not so fundamentalist about it.
(Smalltalk is a notable exception, but it is not as patronising in other ways as Java is. But in general, OOP tends to be patronising because its central tenet is that the definition of the object should alone determine its properties, they shouldn't be changed/imposed from the outside. Which is a good rule of thumb, but sometimes in practice becomes an obstacle.)
Working with it as a dev, my opinion improved. A lot of the new FP inspired APIs make logic much terser, and the OOP stuff can make implementing certain architectural patterns very clean.
The other great thing about Java is that nearly every conceivable question has been answered, as far as day to day development. Not so for newer languages.
My biggest pain point with java is the type system. Like, you basically need to write or consume a library to work with tuples.
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Throwable> {
void accept(T value) throws E;
}
public static <T, E extends Throwable> void forEach(Collection<T> elements, ThrowingConsumer<T, E> consumer) throws E {
for (T element : elements) {
consumer.accept(element);
}
}
There is a significant shortcoming, which is that you can't catch exceptions using the type parameter - this does not compile: public static <T, E extends Throwable> Optional<E> forEach(Collection<T> elements, ThrowingConsumer<T, E> consumer) {
for (T element : elements) {
try {
consumer.accept(element);
} catch (E e) { // <-- not allowed!
return Optional.of(e);
}
}
return Optional.empty();
}
You can kludge your way around that in various ways, but none of them are pretty.The points listed in the article for why Java is great apply to many of the workhorse languages in the industry today.
It’s also a natural consequence of TS explicitly choosing not to expose its type system to the runtime; a choice which confuses many, but makes sense given the potentially unpredictable performance impact that could have. But there are plenty of good tools for declaring validation and getting types “for free”, allowing you to choose explicitly where you want to incur that runtime cost—typically at API/network boundaries.
This is not much different from interface/protocol/contract based typing, which often appears in a goofy way in Java: class Foo implements IFoo. But when you work in an environment where interface typing is commonplace and done well, it really helps guide good modular design.
I have spent more time than I ought to have trying to find conforming types in TypeScript and Go code through trial and error. Fortunately I get feedback pretty quickly in my editor, but it is still a frustrating exercise. I want to build mechanisms, not solve jigsaw puzzles.
In some contexts I miss this in TS, in others I find it unnecessarily limiting. Probably an even split. Though I find myself wanting nominal types more for primitives (sure email is a string, but not every string is; or is this number really an unsigned int?).
I work an an Android use case, so reading Java stacktraces, and code commits became a valuable skill.
Then, I learned the value of using Java libraries such as Appium and Selenium for end-to-end integration, performance, and reliability testing.
Then I started using Java libraries like Okhttp, Jackson to build fancier test setups.
While this was happening, I was learning the value of writing code that could be ran in containers - which Java does. Now I can create microservices that I stick in containers on Google Cloud Run or Pivotal Cloud Foundry - and pass arguments to execute tasks.
After getting these foundational skills developed, I started working on adding features to Android apps in the use case.
Since I had learned that much, I figured I should write a personal site using Spring MVC, Spring JPA, VueJS, ChartJS, and CockroachCloud (postgres). I then went and wrote a DAO microservice to write to CockroachCloud on a recurring schedule, and used Java with JDBC to learn how to access postgres without Spring.
Java has become a great skill, that I picked up almost entirely during the pandemic. Especially when paired with Javascript. On Javascript, what I find interesting is that some teams have rewrote services from Javascript to Java. IME, Java works on everything, and with everything.
Once you master one object oriented language, having to learn Objective-C or another variant of Java like Kotlin or Scala becomes that much easier.
IMO, there are 3 things are worth learning. They are SQL, a high level scripting language, and a object oriented language. They all have their uses, and the skills are transferable. For me, Java just happened to be the most valuable skill I could learn.
A few years passed and I got to program in Java in a commercial environment. It was J2EE 1.4.
It was bloated, had a really heavyweight and crappy ORM (JavaBeans? Active Beans?). As a framework it sucked. Also it was boring business applications, the cool kids used Python at that time.
Just my personal snapshot of how Java lost the hype for me - crappy "dozens of layers" framework and an unappealing niche.
In one job, i used an enterprise framework that actually predated Java EE. Several ideas in EE were copied from it. But incredibly, this framework was substantially better than early EE. I believe, because that framework was built by people who actually needed to ship products to customers to pay their bills, which limited the amount of overcomplication and obstruction they could get away with. There was no such limit on Sun's architects.
Given their insidious licensing and litigious nature, I wouldn’t touch Java with a ten meter pole.
theamk's post about
> There are a few reasons to avoid Java today.
Hard agree, and had the same thought BECAUSE Oracle.
I work on a codebase with hundreds of thousands of lines that haven't been touched in 15 years. We're on Java 11 with plans to update to 17 later this year. Our 8->11 upgrade took me 3 days on a million+ line codebase. And when we released there were zero bugs related to the upgrade.
Java has the stability keep projects maintainable over decades. The only mainstream language with comparable backwards compatibility is C.
C# is much smaller community.
Microsoft isn't as good about avoiding breaking changes.
Java has more quality tooling options.
The CLR GC is way worse. Shenandoah and ZGC, and even G1 on new versions blow away CLR GC.
Also heard the JIT compiler isn't as good from an Oracle dev a while back. C# performs better in synthetic benchmarks because it exposes more low level primitives.
C# is far ahead in syntactical niceness and exposing lower level primitives. It also has reified generics and true primitive types. The "language" itself is definitely better than Java, there's no question. It's everything built around Java and the capabilities of the JVM that make it better than C#.
However, it's the culture around Java that I hate, and that's the reason I avoid Java. The amount of low quality Java code out there is staggering. The culture around Java is one of extreme levels of abstraction and encapsulation, and it makes reasoning about Java code really painful some times. If you have worked in a Java shop, check out the Enterprise edition of FizzBuzz: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
I've had to work with Java professionally for a number of projects over the years, and honestly the only use for it I've actually agreed with as "good" is on Android -- and as we know, Google tweaked it, battles ensued, yadda yadda ...and even they are moving away from it.
The shitshow that owns it is good enough to avoid it, let alone the language itself.
We will never see its like. There's no money in programming languages anymore, no one would drop the kind of cash on pushing their pet language that Sun did back in the day.
What I'm saying is: Java have had its hype and should settle in for a dignified middle age rather than try to hang with the cool kids.
- debugging environment
- memory and CPU profilers
- compilation and linting time of 100k+ codebases
- IDE support for 100k+ codebases
- static analysis & software architecture metric tooling (complexity, dependency analysis etc.)
- inherent scalability of the language, maturity of patterns & practices of scalability
"Dependency heavy workloads and industry trends"
The author complains about JS having small packages about trivial things (and for some reason when people talk about this they always mention lpad, apparently lpad is the only small package in NPM /s).
And about the fact Java has a type system. Many languages have a type system. In fact JS also has a type system through TypeScript.
"Nominal typing"
TypeScript typeguards are compared with the lack of Java typeguards.
- Java has typeguards and they're even being extended: https://openjdk.java.net/jeps/394
- Type guards have nothing to do with nominal vs. structural typing. They're rather used to disambiguate unions. If you have no unions you need no type guards.
- Interfaces in TS are structural, but classes are nominal. Typeguards can be either.
"Removal of responsibility for optimization"
The author believes Java frees them from memory management and multithreading race conditions, and the need to optimize (like think about underlying data structures, algorithms etc.).
Java reduces memory management concern relative to C++, but you still have reference leaks, you still need to free resources like file handles, connections etc. Also Java is no different than JS, C#, Python, etc. in that regard.
Java DOES NOT prevent race conditions.
Java DOES NOT mean you don't have to optimize.
-------------
All in all this reads a bit like a JS developer who just discovered Java and is excited. That's good, but my conclusion is Java isn't underhyped. Or overhyped. It's hyped just about as much as it needs to be.
Is this true? I might be missing something, but this snippet to me suggests otherwise[0].
[0]: https://www.typescriptlang.org/play?#code/MYGwhgzhAECyCeBhcV...
You can think about the structural type as a hash check on a type. If the hash matches, chances are it's the type you want. Collisions are possible, but highly unlikely, hence why in practice it works great (and we still have instanceof and tagged types).
I would just recommend learning another programming language :)
>by crystallizing type definitions and guaranteeing type guards by default.
Not so crystallizing if you know.. if you've ever used a Java List, Set or a Map. i.e., List<icouldbeanythinginhere>. such guarantee. wow.
Honestly, I'd prefer TS with strict mode over Java any day because nullability is explicit, don't have to watch out for the dreaded NullPointerExceptions left and right.
Iterator ghostI = hashtableNPCs.entrySet().iterator();
while (ghostI.hasNext()) {
ExpiringEntityPlayer expiringEntityPlayer = (ExpiringEntityPlayer) ((Map.Entry) ghostI.next()).getValue();
}
Apparently this is the only way to do it, and the Map.Entry type absolutely nukes any semblance of type safety. Iterator<Map.Entry<UUID, ExpiringEntityPlayer>> ghostI = hashtableNPCs.entrySet().iterator();
while (ghostI.hasNext()) {
ExpiringEntityPlayer expiringEntityPlayer = ghostI.next().getValue();
}
However, it's a sham. The generic types are stripped at runtime. The compiler will prevent you from putting values in the map that are not an ExpiringEntityPlayer, as long as you are diligent in using generics everywhere, and don't fall in the few traps where the wrong type can slip by without a warning, but you can still be hit by a ClassCastException at runtime if you're not careful.While it is true the generics are more or less syntactic sugar, I have never seen a ClassCastException due to this in all my years.
hashtableNPCs.values().forEach(ExpiringEntityPlayer::something);(I'm not affiliated - just someone coming back to Java after 20+ years of C++ and Python).
Recent stuff includes:
* Vector API
* Record classes
* JDK Flightrecorder
* Java 16
Having 100% is just as not enough because you can arrive at a line of code from exponentially many states. Mutation testing is a good way to show whether the tests are actually worth anything.
Code coverage is just a control tool.
Also, congrats on graduating from CU! Just graduated last semester.
Newcomers get no real guidance on what to do. What do you install? It can be any of a number of different vendors. How do you deploy? The official documentation hasn't been updated since Java 8: https://docs.oracle.com/javase/tutorial/deployment/index.htm.... It still mentions applets! (Which are going to be removed soon.) IMO, all projects should be using jlink and shipping a slim runtime they've used to test against (https://docs.oracle.com/en/java/javase/11/tools/jlink.html). There's basically zero documentation on how to use this for non-modular applications, and you have to find and apply non-official plugins to get that work done. I continue to see most deployments using the entire JDK which, honestly, has been unnecessary for three years.
Nobody really knows what they mean with "OpenJDK". They might be talking about some distribution based on the source code. Or, they might be talking about a download from jdk.java.net. Or they might be talking about installations from Azul, Microsoft, AWS, or any number of ad-hoc vendors because the name is unlicensed. This is a big deal, because I've had team matest install "OpenJDK" and actually end up with ad-hoc builds that weren't tested, and had random bugs.
Professionally, I've ended up having to deal with fixing landmines because Java devs tend to not learn the intricacies of their frameworks as well.
The technology is still going strong, and is moving faster since the modularization. Loom (https://blogs.oracle.com/javamagazine/going-inside-javas-pro...) will be a big deal... but I wonder, will most devs practically understand how to take advantage of it?
I'm actually old enough that Java was my main language during CS. No Python...
Before that when I during my teenage years I got to lecture by some senior in IBM that showed how amazing is Java and it's the future. (That was 10! Years before I've attended)
And that's that's the thing... Hype is all about "new" things. And after a while it dusts off.
HN had a lot of posts about good developers. usually it sums up as problem solving and human relationship. Never I saw a good developer of language N.
Is java considered old or outdated for today in CS? I'm learning Java in my AP computer science class to this day.
It even did deliver at the beginning, but then it stagnated.
Now, it's just bloated. The syntax, the programming model, the package manager, the runtime. If you look at systems like Eclipse and Jenkins, even the software developed with it seems to go that way.
Kotlin should have called itself Java++ imho, that would help adoption in enterprise where managers might not know difference with Java
I feel like the takeaway the author should have arrived at is that hype comes and goes, and doesn't really correlate with whether a piece of technology is valuable or not.
It's following the hype that steered him wrong in the first place.
Over time, I've found myself more interested in tech that sticks around. There's usually something to learn from it.
I totally agree that Java is not bad (also chatted with some friends about IntelliJ etc.), but as many have pointed out, it simply has a lot of weird tradeoffs that are already baked into the language. I always say that maybe in a few years I'd just say screw it and go write Java for a big corp. But for now I'd still like to enjoy writing Elixir with similar-minded folks as much as I can. Nothing compares to it in terms of developer experience yet. Maybe it's a form of meaningless stubbornness/resistance idk.
There's Kotlin (better than Java but not by a big margin), Typescript, anything else?
And I've heard good things about Dlang but I've never used it myself, I'll have to check it out some more.
Java is the most in-demand technology in my home country, Estonia. Java also has around 800 open positions at any given time where I live now (Buenos Aires, Argentina). In fact, pretty much everywhere I've looked, Java is consistently one of the best ways to get a job simply because it has the most jobs available.
HN favourites like Go and Rust? I haven't yet found a city in Europe that would have more than 10 job offerings for either of them.
However, the sausage is still made Java. Amazon, Google, and Apple are, as far as a I know, primarily Java shops. It's just no one ever starts a blog with "Here's something cool I did in Java".
Outside of USA, a little digging I did via Glassdoor:
Buenos Aires, Argentina: - Rust: ~5 jobs - Go: ~3 jobs - Java: ~800 jobs
Lisbon, Portugal: - Rust: ~6 jobs - Go: ~30 jobs - Java: ~278 jobs
Barcelona, Spain: - Rust: ~1 job - Go: ~50 jobs - Java: ~751 jobs
These are just places I've lived at and while I can see Go slowly becoming a thing, Rust is still half a decade away from anything tangible for the real world I would say. So if anyone asks me what should they become an expert in for the next 10 years, I would not hesitate to say Java.
Additionally, pretty much all the distributed data processing tools run on the JVM, which is a big deal if that's what you do for a living.
Python, JS and C/c++ are full of idiosyncrasies.
Java allows students to quickly get up and running and focus on the 'CS'.
That said, Python might be more practical for anything applied in school.
If you extend your consideration to build systems and other tooling, it's easy to see that students have a lot to overcome with Java as an intro language.
I think purpose-built languages like the HtDP languages or Logo are better choices. Students can get started with zero faff, learn the essential concepts, and move on.
Java is a fine choice for higher level courses, with students that are already capable programmers.
Yes - 'Logo' is a good choice for the most entry-level users, maybe for high schoolers who are taking CS as a 'required' part of the curriculum, but anything beyond that Java is fine.
I think Generics, Java9++ 'Modules', jar files and class files might be the idiosyncrasies to worry about.
That said, it's weird that in 2021 we don't have a universally 'basic' programming language that is essentially the 'vanilla' of programming.
Somewhere inside JS/Python/TS/Java/Dart I think is that 'basic vanilla' imperative language I think.
I personally find the Java language cumbersome and the type system constraining. These days my preferred languages are Python, Go, and C. In my experience, Java is not a good choice for exploratory programming where adapting old code to new use takes significant repurposing effort.
- Maven
- Gradle
- Weak type systems
- 1 class per file and other dogma that leads to a million tiny pieces of spaghetti (cough GoF)
- java version hell
- garbage collection tuning (yes at scale its necessary and no I don't want to make more grafana dashboards of our application's gc and whatever open-source datastore we are using's gc since they thought it was smart to write in java)
- verbosity to the max
- people convinced none of the points are problems and that they are actually features. Its one thing to deny my pain it is another thing entirely to say its a "good" pain.
Setup jbang and install java if needed:
curl -Ls https://sh.jbang.dev | bash -s - app setup jbang
Create a java file that has dependency on picocli and just runs:
jbang init -t cli hello.java
Run it: ./hello.java
Edit it in vscodium with live fetching of dependencies(you can use your own ide too): jbang edit --open --live hello.java
Java is one of the most unpleasurable technologies to work with. It is slow to start up, full of idiosyncrasies, and all in all, a pretty awful language when it comes to brevity. Java is the epitome of "lets use this language so we can hire cheap coders." It is a vestige of what it came from, even if some new features have been added 10 years too late.
There were a lot of complications(students hadn't learned java previously), and it took some understanding of what the JVM was doing, vs c/c++ where pointers made it very clear what was happening. This was also in very early days of java, just at the beginning of JIT and hotspot.
I haven't worked on a big Java project in a few years, but I would always find myself missing stuff from C#.
Many years ago I discovered that I could use all the Java components just like that: https://speakerdeck.com/brutuscat/jruby-experiences
1. it is battle tested, stable, and its strong and weak sides have been pretty much studies and internalized by developers
2. Java devs are like sand on the beach. They can be found everywhere at a cheap price. Develop something, then slowly outsource/offshore dev to cut costs and continue milking sales contracts.
I depend on some ancient Java libs and they still work just fine. It's a huge relief when major version bumps don't break everything.
There’s no GC’ed VM that competes with it still, compatibility is taken seriously and what build systems + Docker try to solve now with a lot of moving parts was solved years ago with uberjars.
I don't use it day-to-day in my work anymore, but the principles I learnt were definitely useful!
Cross platform support used to be the trump for Java, but DotNetCore/5 works on Linux and has nearly everything ported over now.
Rider is really good, better than Visual Studio in most respects even, but it does cost about $100/year for a personal license. There are some programs JetBrains offers for free licenses though.
VS Code is also an option, albeit much less powerful.
The issue with Java is that you need an IDE for it to be usable. That's not an argument for Java itself.
And that is your opinion, not shared by many. There is nothing inherent in the language that makes it hard to write from a text editor. It’s definitely not made for scripting, but with like 4 additional lines you have to write as a main method, I wouldn’t call it infeasible.
This kid's going to the moon.
I think it really fell out of favor due to Oracle's litigious handling of it. As soon as Oracle bought it I remember people actually cancelling Java projects and changing languages.
Another problem is how complex and verbose it got. Original late-90s Java was pretty clean but eventually the ecosystem fell in love with enterprise style cruft and overengineered everything. It's less a problem with the language than the community though. Like C++, you do not have to use every pattern and language feature... but many people think you do and write ridiculously complicated verbose code.
Thanks for the info. Didn’t know this. I use AdoptOpenJDK and am grateful the free version is so fully featured.
I’d imagine back in the day Oracle Java reigned supreme and their licensing terms were a real concern.
Oracle bought Sun in 2010, things looked okay for a year or two, then it started to get scary.
The situation now is not scary: there is a community process to manage the language and library definitions, the JDK is open source, with Oracle contributing, there are other significant contributors (notably RedHat and IBM ... so now just IBM), and there are multiple freely-available high quality binary releases of the same source.
It could potentially get scary again. If Oracle stop contributing to the open source JDK, and instead work on a closed-source version of their own, then it's not clear that there is enough developer power among the remaining contributors to keep things moving at a healthy speed. But then, if that happened, maybe users would abandon Java rather than pay Oracle, so it would be a suicidal move for Oracle. Or, if that happened, other contributors could step up contributions to hoover up customers from Oracle. But it's not entirely reassuring to be depending on game theory like this.
Except that if you actually code for money, neither of those have many jobs available. Heck, in many cities I've looked _any_ jobs available. Java is still one of the most employable tools out there simply because it has a lot of jobs. Sometimes the hype-train of HN makes me think that people here are just coding for a hobby or their own start-up and entirely forget how the real world actually works.
It's not fast, not specialized, but is completely adequate for almost all use cases.
A mini-van is incredibly boring, but that's also it's best selling point.
Oh if only that was true. Sadly it's probably one of the most popular languages in undergrad courses around the world.
The API's are comprehensive, well thought through, to this day it's bizarre nobody has copied Javadoc. Python docs drive me mad.
For a script - Python. For the web Typescript. For low level C or Rust.
But Java is quite powerful for anything that stretches in between: not the fastest to write, but generally fast, the tooling is robust, the performance is quite good usually.
And I love that it's uncool.
JavaDoc-style structured documentation in comments with toolchain to generate user docs from a combination of the comments and the associated class/method/function signatures has been widely applied; Doxygen and JSDoc obviously owe a lot to it, as do Sandcastle (for .NET), Rdoc/YARD for Ruby, Sphinx/autodoc (for Python), etc.
I’d be surprised if there is a major language today for whuch there isn’t at least one JavaDoc-inspired documentation generator.
I don't know about the language itself but as an ecosystem Java failed spectacularly. Why is there a strong relationship between an application developed in Java and lack/horrible setup of documentation for this app? I just find it everytime I use something developed in Java.
java -jar application.war
Is as elegant as: v=irReminds me of a rationalization I heard once about how people pick their brand of cigarettes. They all taste like crap until you're finally addicted, then the one you happen to smoke at the time is now your brand.
Every new language / stack now gets compared to Java with IntelliJ because that's what they learned. Can't tell 'em any different.
I think my emotions are misplaced: I might just like IntelliJ.
Java is a phenomenal piece of kit, the amount of engineering that went into the JVM is insane. But people took the lessons from Java and put them into newer languages, that don't have the problems Java does that require an IDE.
My love is in the language that IDEs don't and can't really add much to, Ruby. Emacs give me all I need.
VSC has a pretty good Java experience.
Certainly the emacs mode does: https://projects.eclipse.org/projects/eclipse.jdt.ls
[1]: https://github.com/redhat-developer/vscode-java/issues/1132
Sure, java has its place and enables fine productivity in enterprise dependent workloads & scale; but that scale's complexity is often nominal, because what's unique about a traditional java-based system? Why would you use Java to be unique... the jvm is perfectly magical? nah.
Don't generalize engineering, lol, "feels good"... I think you mean "personally comfortable" which is what the oracles and jet-brains want you to feel. There is no art in java.
I'd struggle to invest so deeply or engrain myself in an enterprise setup vs whatever personal/business circumstances Id be in that situation. If you really want to be hip in that type of world go .NET
Java was designed by people who had absolutely no intention or desire to ever use it. They cribbed parts from other languages they didn't really understand, and changed details in ways that make no sense on their own, or with other things they changed for actual reasons.
Their estimation of its expected users was very low, so they made everything dull and squishy so nobody could do much harm whether by mistake or deliberately.
It got billions of dollars more hype than it deserved on merit. Its privileged place in the corporate world, like its good tooling support, are direct products of that hype. The hype it got on first release, beyond the (very large amount of) money backing it, comes from a peculiar twist of history: right then, millions of programmers were sharecropping on Microsoft's plantation, and saw Java as their 40 acres and a mule. It was a balky mule, but it promised freedom from switching to a whole new app framework literally every 2nd year.
Since then, a very large number of libraries have been made to package most common operations. It's barely adequate for making libraries, but people have put a great deal of effort in because of the big user base.
"I enjoyed programming in Java, and being relieved of the responsibility for producing a quality product.":