Can I tell you about live debugging of an app server and hot reloads? Pretty wonderful stuff really.
I can't believe how much knowledge, tooling and experience was thrown in the dumpster when Java was abandoned en masse by the younger generation of devs due to the rise of node.js. And if it weren't for Typescript the tooling would still likely suck.
I haven't used it for a long time, but it's still alive: https://www.gwtproject.org/
I feel like there's an adjacent universe where the JVM lives in every browser and JS was a weird failed experiment. But it turned out that the browser was the universal UI everyone had waited for, and Java didn't connect to it while JS entrenched itself there.
GWT was a glimpse of trying to send us to that universe, via a twisty back door. But it was never gonna happen.
but yeah js is a strange creature
NB: I was very distantly part of the Swing team. I did early reviews of its design documents.
I wish us devs would have access to that intermediate representation.
And that's the exact reason I'm done with it.
Typescript is somehow becoming a laguage that supports writing extremely performant high throughput and very scalable server code? That seems unlikely. So no worries, it can't become Java.
Java, as a language is fine I guess, but the culture around it sucks.
Culture is what you want it to be.
There are indeed some ridiculous subcultures within the world of developers who use Java. Like J2EE-anything or any of the baroque frameworks.
It is important to realize none of that is part of Java and none of that is required unless you really want to.
You can use Java simply as a memory safe language with reasonably good type safety that can create wicked fast code and has huge library and tooling support. On all those checkboxes, there are few-to-none options that are so good across all those aspects at once.
Unfortunately so many people just complain about writing TaskStubConsumerWatcherVisitorServiceContainerListIdentifier classes, without realizing nobody is forcing you to do that. So don't.
do you mean rmi/javabeans or something else ?
beside that, I left java long ago, and believed in simpler REST stuff but now I realize that it's indeed rediscovering stuff people dealt with long ago
As for rmi, when Java was in its heyday the most popular protocol for remote api handling was SOAP. But when RESTful era arrived Java tooling adapted very quickly and it made little difference what you were using to call outside the app server.
@Validated
public interface PetOperations {
@Post
@SingleResult
Publisher<Pet> save(@NotBlank String name, @Min(1L) int age);
}
then you inject @Client("https://example.com/pets") @Inject PetOperations pets;
and call its methods. It will use the annotations to validate the call client side before sending it, and you can implement the same interface on the server: @Controller("/pets")
public class PetController implements PetOperations {
@Override
@SingleResult
public Publisher<Pet> save(String name, int age) {
Pet pet = new Pet();
pet.setName(name);
pet.setAge(age);
// save to database or something
return Mono.just(pet);
}
}
where the same validations will occur before the call is accepted.But yeah, I built business apps with just Tomcat and no J2EE components and it was fine.
It’s easy to say “because they’re hipsters following trends” but I dipped my toe in the Java world years ago and found it immensely frustrating. Eclipse was awful compared to the lightweight editors I was using at the time. The language got in my way more often than it helped me.
I’m sure that’s not the case these days (indeed I’ve done a little Android-adjacent stuff and found it to be fine) but the idea that there were no downsides to Java at the time strikes me as unlikely.
Since Java was developed the world has shifted to accommodate a lot more rapid development and code you throw away rather than maintain. But experienced developers also know how often "prototypes" are still around decades later.
Java is also not perfect, and a lot of new languages are conscious of its faults. But the reason it's still around is that it's core principles are oriented to code that sticks around.
You could equally say this of COBOL.
> They haven't yet looked back at code they wrote and said, "ugh, what the hell was I thinking?"
Ironically, "what they hell were they thinking" is exactly the reaction I have to even Greenfield code written using Spring Boot or any of the other annotation driven nonsense.
The idea that programs written in Java are more maintainable than programs written in (say) Go, where you can read what the program does end-to-end instead of having to guess at what garbage has been generated by Lombok or overridden by some random JAR on the class path is bizarre. Let's not even talk about Gradle.
A lot of external Java framework is about inversion of control. It looks good on PowerPoint slides, but I think it's horrific to maintain (as well has hard to write). Inversion of control means you have no control, and the most common error case is "why didn't my code run?" But you can't use a debugger to tell you what didn't happen. Any breakpoints have to be set inside the framework code, which is open source but is not intended for your eyes.
Yep no magic...
Have you ever read Kubernetes source code?
Kubernetes is not a good example of idiomatic Go in any sense. Perhaps Spring Boot and friends are also not good examples of idiomatic Java, but they are absolutely the common case of what is found in the wild.
Kubernetes is a single (bad) Go project. Every piece of Java I ever see is AbstractFactoryProxyBean nonsense with annotations all over the show.
I don’t know of a Go project where I can’t start at main (for a given program) and work out how it works without a bunch of ecosystem context. I can’t think of a single Java program where I can.
My problems with Java are startup time and memory consumption (and NPEs).
If that's not your problem - fine. But writing web apps in the Java ecosystem has been terrible for many of the most important years (let's say 2005 to 2015) and that's where all the "young people" forsake it for... PHP, Rails, node.js.
(You can already guess that I'm not even counting myself as part of the younger generation here. I'd used used Java and the JVM intermittently between 2000 and 2020 but it has never been my favourite stack).
Yet it blames "hipsters" for throwing "it all in the garbage," implying that there was no rational reason for people to switch away from Java. Naturally, people respond by sharing their reasons.
And talk not to me about lightweight. I'm currently on Day 4 of setting up a Python environment in VsCode that doesn't suck. I'm nearly there though it's still a bit inferior to a 20 year old JBuilder install for Java but I guess it needs a few more years to get there. Oh and as I said, I'm on a long quest here to pave the road for my devs but it looks like this hodgepodge of extensions still won't deliver the experience I had decades ago.
I'm also not saying there's a better option for you and your team, either, my friend.
As a python programmer using bare-bones vim (on purpose), having abandoned all fancy IDEs, I really wouldn't know where the state of the art is, anyway, but I doubt the MS leopard has changed its spots.
Embrace & extend complete ;-)
This time it looks like 'integrate' will be the third step.
Thanks for the great info.
Python is pretty close to a 'Microsoft language' these days. They've hired several Python core developers to make sure windows is first class citizen for python and the developing python on windows and with VSCode is as good an experience as possible. They also develop the official VS Code Python extension and language server as well as many other python tools and extensions.
I'd say the current state-of-the-art is either VSCode with the Microsoft python extensions or Jetbrain's PyCharm. Personally I slightly prefer PyCharm Pro, but it's pretty much a toss up.
As a newcommer to javascript, I was able to learn faster and produce same quality faster then non-IDE developers. Not because I would be smarter or more talented, but because I had no emotional need to prove myself by not using ide.
It's probably unavoidable that people's memories will differ, but personally, as someone who worked with Java 10–15 years ago and then ran away as fast as he could, these are the things I remember most: the IDEs being awfully slow and unstable (though quite powerful for their time) and the language/ecosystem being painfully verbose and full of boilerplate and layers of indirection. I remember how, after switching away from Java, I felt elated by how easy and maintainable things could be when I was allowed to use simple, fast tools and write straightforward code that just did what it was supposed to do.
> there were not real licensing issues
Oh yes there were. Even in 2024 the “which JDK are you running on” debate still goes on. There are notable differences between corretto and openjdk, and openjdk and Oracle JDK. Here [0] is a stack overflow question that notes it was asked 10 years ago that talks about the various JDKs and the license change where oracle started charging for JDK access.
As for your point about IDE’s vs non-IDE’s that’s a straw man. I said that you were forced to used an IDE for Java (which is of course not technically true but compared to rails which took of at that time it is), but also that the IDE du jour (eclipse) was pretty monstrous.
I’ve said this on here before but the minute maven gets introduced into a project build times are measured in minutes. My current work project is c# and I can run my entire test suite faster than the jvm got itself up and running on my last kotlin project. Even IntelliJ and co suffer from these limitations - manually bumping the memory limits for IntelliJ and friends in 2024 is practically a requirement, and the startup times are very Java inspired.
[0] https://stackoverflow.com/questions/22358071/differences-bet...
Java and Eclipse are waaay better then C# and visual studio. Kotlin is a pure pleasure against C#.
Also, I see people using different JDKa on the same project. That there is competition is a good thing, it is not like you was locked in one.
Except, unlike Kotlin, C# has a rich selection of what to use for development across a variety of platforms and is not constrained to JVM's type system limitations, allowing the syntax differences to have meaningful impact on the code execution.
It also has excellent, comparable to Go and Rust, CLI tooling to further streamline the process of quickly managing, building, testing, running and deploying projects, something JVM ecosystem is yet to provide an alternative for.
I disagree. dotnet has it's quirks, but so does every mature ecosystem. I wouldn't use "piece of crap" to describe it (or java) and I get that it's an opinion, but I think your opinion is more misguided than what yo're accusing other people of believing.
> Kotlin is a pure pleasure against C#.
My last project was a kotlin backend powering a C+ desktop app. The kotlin backend took longer to compile than the C++ did. Kotlin is the kitchen sink bolted onto Java. It's definitely a nice environment to work in, but it's certainly not a more streamlined java.
> That there is competition is a good thing, it is not like you was locked in one.
If by competition you mean OpenJDK forks with minor differences then yes there's competition. To me that's not competition, that's fragmentation.
3-10 crashes per day were common.
Lots or coffee breaks, or at least switching back to emacs to just finish editing whatever classes you were touching.
The second thing however is that fronted is better off in non-java languages, you can afford to do small backend in typescript and what not. And larger enterprise projects were done in java the whole time.
I wasn't fond of JavaScript (In particular, I never liked dynamic typing), but when I had the opportunity to work in node.js instead of Java I took it immediately, just to avoid the pain and suffering that the Java toolchain inflicted on me.
I started my career in Java, and worked in it for 20 years before I really started using Javascript in anger. I didn't (and don't) like Javascript, but the freedom for prototyping was a revelation. When Typescript appeared, I fell in love.
I'm of the opinion that the world was a better place with Ant and when we had third party dependencies manually, deliberately adn deliberatively managed by hand in /jars/thirdparty
As someone that was writing Ant scripts when CruiseControl was modern, and there was no Ivy in sight, not sure if it was such a better place.
I hated Maven at the beggining, exactly because we got some hipster company pushing for it during Maven early days, it was still hot out of the oven.
20 years later, I don't see a reason to use anything else other than Maven.
I've looked at it also. The problem is incentives. Will developers pay for a better build system? Probably not. Then, what people use is whatever happened to be given away for free first.
Another problem with shifting Gradle is that lots of libraries now come with build system plugins too, so you'd need to replicate all that logic into whatever new build system you create. And it's actually not easy to get everyone to agree on what they don't like about Gradle. Say "imperative not declarative" and half of devs will agree and the other half will say, no, you need programmatic configuration because build systems are genuinely complex. Etc.
https://gradle.github.io/declarative-gradle/
Fingers crossed.
The biggest problem with Gradle is not Kotlin or even Groovy syntax. Kotlin isn't a bad language to use even for writing configuration. It's that the entire thing is designed in extremely confusing ways from back to front, and has a lot of awkward design choices and bugs that result in a hyper-complex user model.
What the JVM world needs is a totally new tool that has the same feature set as Gradle but with a drastically simpler mental model behind it. The only real contender right now is Bazel, I think.
Android started being devleoped mostly by C++ refugees, that is why originally all framework code is full of m_ prefixes.
Then the whole standard library fragmentation that persists to this day.
Despite the whole excuse why Dalvik was created, Nokia and Sony-Ericson had quite good JVM implentations for Symbian.
When Kotlin was introduced they stiffled Java on purpose, left it on Java 8, using Java 8 examples to promote Kotlin, and have since Android 12, started to finally update ART to more modern versions, because as it turns out, even with Kotlin, loosing compatibility with the Maven Central ecossytem isn't that great.
Still, it is mostly Java 17, and all the ongoing improvement in Java land across all JVM vendors, will most likely never land on Android.
Android is not Java, even though it relies heavily on the ecosystem for its tooling.
Android is basically Google's .NET, and Kotlin plays the same role as C# in relation to Microsoft's J++, that lead to Sun's lawsuit.
Java today looks like a fine platform, though.
I've grown up a bit since then, and so has Java. These days I work in Java for my day job, and it's perfectly fine. I don't even mind all the boilerplate, I can look at a page of code and just see blonde, brunette, redhead.
But I still love Common Lisp and Scheme much more.
Got in the way how? By insisting that things have types and one cannot blindly add an object to an array [] + {} and expect it to behave? Never mind that in Javascript adding an array to an object {} + [] gives a different result.
ETA: for bonus points, what does {} + {} return?
I hear Java has gotten a lot better. But then again there is C#, which is pretty much just better Java. Still too enterprisy for the tastes of most HN types though
I thought JS was bad at the time, but node.js was a breath of fresh air for API development, and client side JS has been fine for like 10 years (assuming you care about UI development).
I'd never go back to Java except for maybe some backend service away from the UI.
.NET has also had all these features for just as long, and is less prone (though definitely not immune) to AbstractFactoryProxyBean nonsense.
Last I checked If I change a signature or something in Java, I am not guaranteed the whole thing "checks". If I add a new exception to a function, how do I know what else is effected?
I give it five years until Typescript and peers adds checked exceptions.
[0] https://www.artima.com/articles/the-trouble-with-checked-exc...
We tried. Java was fine, JBuilder was fine. When they instead started pushing J2EE, EJB and all the other acronyms I've forgotten, this 'youngster' realised he'd never be smart enough to be a Java developer and bailed back to C, Perl and Python.
Had they focused on Java and making Java a great language in its own right, it no doubt would have gone a lot better. But all the 'hype' and marketing around Java was focused entirely on these huge frameworks and enterprise 'solution' architectures which most 'youngsters' just didn't understand and didn't see the need for.
If someone makes it clear their product isn't for you and that they don't care about solving your problems, is it strange they abandon you?
I like to say that the main value of GraphQL was never really in the dynamic queries (in many ways an anti-feature) but rather in having a nice typed spec that lets you generate typed clients.
https://oxide-and-friends.transistor.fm/episodes/the-fronten...
Only extra step is running a tool to download the swagger and produce auto-generated typescript definitions, otherwise the workflow is the same as shared code (Some projects are typescript on both ends but C# gives a ton of other benefits for backends).
Like mentioned, our regular pipe is C# producer (server) and TS consumer (client). Consuming services authored in Java,etc is usually not a problem either but the TS system definetly has a bunch of more cases that aren't easily mapped.
Alternatively you could go the openAPI route and declare your API as a spec with types for a client to consume and the endpoint to return. This works cross-language and gives you docs first. (Start from the docs, convert that to types, then implement).
I also thing that the tooling hasn’t kept the same pace as it has with graphql, where it’s easy to document your schema and the inspector makes it super easy to play with.
I have found that the tooling tends to have the problem of not knowing how to catch edge cases like webhooks, websockets, complex auth and additional logic beyond just an HTTP request. Many tools add layers of configuration and extension to work around these, but i feel it misses the mark.
I'm building Borea.dev to solve this pain by keeping the source of truth in your OpenAPI doc and allowing for custom code implementations. We support Python rn, are building out generators for multiple other languages and we're open source :P hope it helps
While I haven't gone too deep down this particular rabbit hole, if you build a Rust backend you can use function signatures and annotations to automatically build an OpenAPI specification for it. You can then consume that specification to automatically build a typescript client library, giving you an automatically updating Typescript interface to your Rust backend.
Similarly, there are multiple projects to automatically provide python type hints for your Rust python extensions. None of them really production-ready yet, but this is something people are actively working on for quite a while
There are tons of generators that can create a client with types from an OpenAPI spec. Not only to/from TS but also tons of other languages.
Have you ever seen Scala.js? Same language on the frontend and backend, in a way that actually feels first-class and real. Type system that's as powerful as Typescript but also sound. Full IDE functionality if you need it.
I have worked at 2 of those named companies where people made conscious decisions of moving away from TS backend because JS is an awful language to be used for system critical things.
I've been writing backend TypeScript for 8 years and it's more than fine.
It's not my favorite language but it's a great compromise, and I would never choose a Lisp, Haskell, Java or C over it (the other languages I know).
We built some stuff with Go and then went with full .Net. Its like fresh air after years of Js.
- Proper multithreading and performance story. Performance itself is not the most important thing when your app mostly waits on IO. However you still get to use thread pooled async in .net or parallel goroutines in go etc and they sometimes make a difference.
- ASP.NET Core is fully feature packed and easy to work with. .net has a more cohesive ecosystem where tools, libraries, and frameworks are designed to work together seamlessly. In js runtimes, you often need to piece together different approaches and deal with compatibility issues.
- Proper standard library. Both node.js stdlib and the js globals are really weak compared to what Go or .NET or Java etc provides you out of the box. I hate dealing with npm dependencies with a passion at this point and you can have minimal dependencies when the standard library is decent. There is also the fact that upgrading an npm package is a dice roll as you need to trust the semver or check update logs etc. At least with a static typed language you get to catch public api changes on your dependencies during compile time, not in runtime.
- Linq is good, Linq expressions are great. I don't really love ORMs but I tend to use Entity Framework Core on top of low level SQL access in .NET. Makes life easier.
I don't hate TypeScript though. I still use it on the frontend obviously and I'm fine with it but given the choices on backend, it does not make much sense for me anymore.
It was originally designed for writing throwaway frontend code, but people liked it so much that they started using it to build their system architecture—only to realize it doesn’t work well for anything beyond glorified RPC backends.
The type system is wishy-washy, and TypeScript needs a massive type space to compensate for it. Python is also dynamically typed, but it has a strongly typed system that saves you from runtime blowups. JavaScript doesn’t even properly blow up at runtime—you just get [object Object] or some random undefined error. TypeScript is a fantastic piece of engineering from the C# guy, but even they couldn’t fix all of JavaScript’s language-level blunders.
Few people want to build mission-critical backends on a weakly typed language.
The ecosystem is a mess, and things randomly break after a few days. My Python and Go apps from 2018 still work exactly as they did on day one. Go’s gorm and Python’s SQLAlchemy are the default ORMs that pretty much everyone uses. And how many ORMs does the JS ecosystem have?
And let’s not even start with frontend frameworks—no one loves them two days later.
The Next.js project I built yesterday is already showing 69 vulnerabilities. This sorry excuse of a language, coupled with terrible design and an indecisively childish community, makes it difficult to take seriously.
By the way you can be extremely strict and safe in typescript, it's really up to the team using it, but you can encode virtually everything and have it fully type safe.
Also, there's great tools like effect-ts if you're more functionally leaning.
It's fine to not know about the goods in the TypeScript ecosystem.
Again, I recommend you checking libraries like effect-ts or effect/schema or even better trying them.
Sure, JS has some quirks that language design gurus complain about, but nothing that actually matters on the job. Like, == operator is weird, oh well.
Python is rightfully king for certain things like data science, but parallelism and package management are two big messes in it. ||ism is trying to be fixed with asyncio, but it's kinda too late. You know packaging is broken because every Python repo has a Dockerfile, not something you see in JS where npm is solid.
Golang is more for different use cases. Looks good but really should have done error handling like Rust, or used exceptions.
sure it is
My NodeJS apps from 2014 still work exactly as they did on day one as well, what's your fucking point?
It seems like in almost all cases, you want to evolve in a forward compatible manner, with a very slow deprecation process.