Are .NET 4.x and JDK 8.x the "zombie" runtimes of enterprise software?
A few reasons:
- Heavy enterprise usage, especially in midcaps and MSMEs.
- Industry inertia — teams hesitate to rewrite working systems without a compelling business reason.
- In some cases, older stacks are more stable and “battle-tested”, especially for use cases like WinForms or thick-client apps.
It's kind of ironic that even today, the default .NET version baked into fresh Windows installs is 4.6 (or nearby), not the shiny new .NET 8/9. Meanwhile, Oracle still offers JDK 8 — albeit behind a paid support wall — much like Microsoft continues to patch .NET 4.x via Windows Update.
Eventually, these older branches will be sunset. But given their stability and widespread industrial use, I feel like that day might be decades away rather than years.
Curious to hear — how do you see this transition unfolding? And are there any good examples where teams actually migrated away from 4.x or 8.x successfully?
And the support lifecycle for .NET4.8 is ironically better than they are for .NET 6 (already dead) and .NET 8, because of the shipping-with-windows thing.
The odd-numbered .NET releases aren't even worth looking at from an enterprise perspective.
So yeah, there'll be a bunch of .net framework code around for a while.
That said, it's frustrating, because in some places the performance just isn't there, and there are so many nuanced differences between them there's a weird effect trying to switch between them.
You not only have to recall which APIs are available in each, but the performance differences between otherwise identical (or near identical) APIs.
Having just spend the better part of 3 months porting a lot of legacy projects, you're absolutely right, but I am not sure where MS said this would be smooth. There are some processes that are standard enough but certainly there is a lot of hands on work involved, and actually for good reason, there are performance and security issues that need to be addressed (In my brief, and hopefully final experience).
That said, porting from event .net versions (stable LTS versions) such as 6 -> 8 has so far been flawless, I think over the last year, we ran into maybe some minor semantic issues.
It's not perfect, but I have to defend MS unfortunately, they are taking things in the right direction while being tied to a LOT of legacy enterprise clients and systems.
- WCF ? (very enterprisy i know) : you are still mostly screwed
- aspx ? compulsory rewrite
- MVC ? mostly smooth (but most of the pain is in initialization so comes early and can discourage newbies)
- Console ? mostly smooth
- before .Net 6 ? it was a death march, not only many API were lacking, but third party libraries were also missing.
- .Net 6 -> .Net 8 ? very smooth
The client libraries only came separately, and much later[1] , and in typical "Fuck your migration path" fashion, doesn't have any .NET standard support.
[1]: ( https://devblogs.microsoft.com/dotnet/wcf-client-60-has-been... )
Using .NET Framework carries significant risk and opportunity cost. Updating LTS every 2 years usually comes with simply bumping up versions and rebuilding.
And also, bumping the .NET version from 8 to 9 or 9 to 10 is typically a very small effort for most. I think what the OP is describing is working for a software cost center where they don't value the software system itself.
Opportunity cost? Sure, but you can’t deny that small teams that just wanted some stuff to please a business itch were able put the shitty code in whatever Win server they had at the time and forget about it. They didn’t have to ask IT to evaluate any installs, it was right there. And today in win 10 servers, that code still runs, returning ugly aspx.
We have some equivalent 2.1 stuff laying around and no one wants to go through the trouble of updating that.
You’re probably going to say something like “well that’s what you get when you just let your code rot and no one cared to document it and maintain it”. Yes, true, but that’s not the on topic point, one of those constantly comes up in vulnerability reports and one doesn’t.
And as phillipcarter noted, increasingly more libraries drop 'netstandard2.0' target, depending on the workload the performance difference is going to be anything between 50% and multiple orders of magnitude (e.g. Regex engine has gotten tens of thousands of percents faster for some patterns).
Working with .NET Framework from non-Windows environment requires using Parallels / UTM on macOS or QEMU or any other VM env. on Linux - there's Mono but it's not a replacement, and I don't think Visual Studio will work under Wine.
There are all sorts of hidden costs that you don't plan for, that come with using .NET Framework.
However, the workplaces that adamantly refuse to upgrade also select for developers who may not be familiar with pattern matching or other features at all, and never read release notes.
Even if Microsoft puts in a huge effort to updating a migration tool to be seamless, we wouldn't use it. It'll only happen when either the larger enterprise corporation migrates, or when Microsoft forces people off 4.8.
It's close to the change when get/settwrs were made mostly redunant (but not quite).
Just so much less boiler plate that you didn't even really realize you were writing.
Most of the time boring old technology beats shiny new one.
Yes... if you do self-contained deployments or build containers, then of course you're tied to the version you've built with - but that is your choice and therefore your responsibility.
You are now blaming having that some deployment choices cannot be updated manually. It is the wrong mindset.
Close.
* The requirement is to jump every second year when a LTS version comes out. Last one was .NET 6 to .NET 8. And next, .NET 10 will come in November 2025. You can jump 1 version every year, but it's not a "requirement".
* It's just called ".NET" now, not ".NET Core". There is no ambiguity in e.g. ".NET 8" - it's the modern version formerly known as ".NET Core".
* Release is every year in November, and every second one is LTS. there's no "almost", it's every time. IDK if this will still be so in 10 years time, but it's been consistent.
* maintenance cost? Yes, you have to review project files and build pipelines in order to to update, so there's some detailed work, but the actual breaking changes and puzzling issues are few to non-existent. It typically goes very smoothly after you change some numbers.
This is basically seamless now, the framework isn't changing in backwards-incompatible ways anymore.
There is a much stronger case for enterprise apps being stuck on .NET 4.x.
There are some community projects that try to fill this void by porting entityframework classic to .net core for example though.
Not hard to argue the opposite either; as you have to upgrade every 2ish years anyway is the LTS track really that valuable compared to updating every march-ish when the latest has been proven? 6 -> 7 -> 8 -> 9 was trivial too.
Meanwhile a friend of mine still has 4.6 going strong and I’d struggle to argue a reason to migrate.
At least MS won't kill .NET Framework until they've fully transitioned Desktop Office, Visual Studio and Sharepoint, so we at least have a couple decades ahead (Much to my chagrin)
Sidenote: Whoever is in charge of Microsoft naming schemes deserves to be taken behind the barn and shot, they can't keep getting away with this
Re-released because ASP.NET Core 2.1 had a better support lifecycle than ASP.NET Core 2.2, and people "upgraded" to 2.2 not realising this.
So people got stuck on unsupported 2.2, rather than the supported 2.1.
So they re-released 2.1 as 2.3, to give people an "upgrade" path from 2.2 to 2.1.
All named after "ASP.NET Core" which, confusingly, is detached from ASP.NET on .NET Core.
( .NET Core which is now just ".NET" , of course. )
Read the whole horror-show here: https://devblogs.microsoft.com/dotnet/servicing-release-advi...
I swear .NET has had the best technology focus for the past 5 or so years, but has had absoultely the worse brand and a complete lack of developer relations / brand ambassador type work.
They need someone who can turn around and tell them to stop this madness, and focus on getting out that .NET is a fantastic ecosystem that performs damn well, and modern C# a pleasure to write in.
But instead we get stuff like "EF Core 9" that targets .NET 8, and all the 9.0.x system libraries, where isn't not clear whether you should be using them if you want to stick to the LTS and target .net 8.
I think the naming does make sense, it's just been maybe been poorly communicated, because I've seen a few people getting tripped up by it.
If I see an article about .NET, depending on the year it might be about 2 different product lines, because the shorthand was made to be the same
If I need to google how to X in Visual Studio, more than half of the results will be irrelevant, because they will be about a different product, so on and so on
If the naming was good, it wouldn't trip up people (So regularly at least), that's my point
Other ones that trip up people, Teams for personal use?, that one regularly bugs out when interacting with business users? Skype vs Skype for Business?
"We're targeting .NET (Standard)" (Which works on both Framework and used to be Core / current .NET)
"We're targeting .NET (Framework)" (Used to be shortened to .NET)
"We're targeting .NET" (Formerly .NET Core) / (6/7/8/9), current recomendation being to call this one just .NET (But not always respected, and not retroactively applied
If legacy wasn't a thing, there wouldn't be much trouble, but since many libraries and some functionality does get backported, you might be stuck with documentation doing any of them, maybe even inconsistently
* Supporting some older OSes and requiring less system base updates is key
* There's a priority to keep installation size (relatively) small
* There's a (higher-up) notion of "if it works, why change it"
On top of that, some technical issues I've encountered (since resolved) and gave up on upgrading were:
* Up until relatively recently there was no "single executable" deployment
* For some part of Core's lifetime you had this weird deployment of DLL-run-by-EXE that's a dealbreaker for the software's security boundaries & requirements
* Huge executable size, until recently where trimming unused framework code was added
There was also some period of time where the .NET party line was "WPF is legacy, we don't support it on modern .NET" and our UI is already built in WPF. We couldn't move to something like WinUI due to supporting Windows <10 and even then, WinUI 3 increases your deployment executable's size by a lot. Thankfully they added WPF support in .NET 8/9.
That's first of all brilliant if you want to ship apps that run on those systems, because you don't need to ship the runtime. But it's painful when you want to write server software. Because you don't want your deployment story to be dependent on the server having some particular system level software (or it being windows). So it's completely inevitable that 4.X will never die. Win32 won't die either.
And making the ship to a completely separate runtime that runs on Linux, and isn't an OS component (but in return requires deployment) was just natural. It's not completely unthinkable that the .NET Runtime will be shipped as part of Windows, but even that woulnd't mean that they can stop shipping the .NET Framework 4.X runtmes.
I just ported a 20 year old 200+ man year desktop app from 4.8 to 8.0 and it was pretty smooth. Even things like old binary-only proprietary winforms controls actually work, which was a huge surprise.
If you are making a web app or any kind of server side app, then the migration is usually straightforward. For client side software it's not as easy, and in some cases it's also not clear whether it's a win. If you are shipping some small Windows-only utility it's probably better to ship on the "old" runtime because your deployment will be smaller when you can use the OS runtime.
The problem: everything is tightly bound to the Microsoft ecosystem—Windows Server 2019, SSIS development in Visual Studio (which only runs on Windows), and even a proprietary VPN tunnel to access the servers. Everything. And it’s been like this for years. Needless to say, there’s no proper documentation.
I raised concerns that this probably isn’t the most sustainable way to run such a critical system. But no one ever cared. Not only is it technically outdated, but the codebase has also grown organically into a somewhat chaotic structure, with countless things hardcoded in ways that make maintenance a nightmare.
The client isn’t tech-savvy, so they never questioned any of it. And the team has always worked in isolation, with no one ever challenging their approach. Thing is: they are total experts. They know the system inside out. “Never change a running system” is the motto of the day.
Now they’re sitting on this massive, outdated, self-built system. It’s probably difficult to find developers willing or able to work within these constraints. I’m standing on the sidelines, having lost the motivation to help, wondering whether they’ll ever get out of this—or if things will just quietly fall apart in the coming years.
In all my years as a developer/engineer across several companies, this is the first time I’ve encountered such stubbornness and turf protection. (If I ever end up this stubborn, please slap me!)
MS dropped compatibility, so there really is no migration path off of .net framework, short of a full port. The resources -- time and money -- for this simply don't exist in the great majority of cases.
> might be decades away rather than years
It's never.
(Short of the decay of civilization, that is, to the point people can no longer run software generally).
People will run their .net framework software until they literally can't anymore. If MS won't/can't support it, another way will be found -- probably legacy software will run in virtual legacy environments, with security patches applied around it somehow (this approach is already in full swing, of course).
I'm not sure where the idea that everything that exists so far will conveniently disappear to make our lives simpler when something new comes out. It just doesn't work that way.
With the new .net, MS hasn't gotten away from anything. They just have yet another thing to support.
Yep, I'm sure there's at least some out there who switched to running off something like Mono on Windows to work around some unpatched .NET Framework issues.
Rewrite queries that are not yet supported on EF Core, create some new DTOs, create drop-in replacements for stuff that isn't there anymore, create plumbing to connect some old stuff to some new stuff. Figure out what's the new replacement for XYZ and use it correctly to not break anything. Replace nuget packages that are not maintained anymore or have so few downloads that they are a supply chain risk.
You need to test every endpoint, every query in your application.
And in the Microsoft World you're still pretty ok, overall, it's quite stable.
God forbid you put your money on the wrong web framework (not even talking frontend) in the Java space. There's still Tapestry/Struts/Grails/JSF/GWT/Play etc. applications serving your request out there. Saw some banking website with ".do" urls recently (indicative of Struts).
Unless we get superhuman AI that can do such migrations all on their own, those zombies might have a longer working life left than lots of developers. Many companies just can't afford to upgrade - there's so many systems built over decades that just do what they should do. Why shell out tons of money to just get the same functionality?
> Copilot agent mode can create apps from scratch, perform refactorings across multiple files, write and run tests, and migrate legacy code to modern frameworks.
https://code.visualstudio.com/blogs/2025/02/24/introducing-c...
And if Microsoft is creating synthetic data, that won’t account for the truly awful ways in which enterprise software evolves (or devolves).
Then someone like me gets called into a situation where they have ridiculous hosting costs (Windows-only, typically also MS SQL), nasty performance issues, and struggle to stay productive and find developers. The most reasonable path forward I see in those situations is a gradual migration to .NET Core and something like PostgreSQL.
And that's a major investment. Microsoft couldn't have made .NET Framework code harder to port to .NET Core if that had been their explicit goal. I find database migrations with Entity Framework similarly difficult compared to other ORMs. Startups can sometimes afford such investments, but often not.
And that's how you ironically get 2-3 year old startups stuck on a death march old school enterprise code stack. It appears to be more common than I'd like it to be.
ASP.NET is a much different beast though, but I don't see any technical reason that it would not be possible. I keep expecting one to show up. I think the ISAPI integration is the biggest hurdle there; lots of weird behaviors that would have to be addressed.
.NET (back then Core) has been going on for 9 years. Surely there was time to finally let .NET Framework choices die.
(also a common theme on HN, to complain about problems that took place ages ago and imply they are still relevant)
The one major exception was from Java 8 to Java 9. There’s some good reasons why Java 8 to Java 9 wasn’t a smooth upgrade for all. But that’s a story for another day.
For slow-moving enterprise IT departments, that would involve a major “update Java” project. Which involves budgets and people and not doing other things in the meantime.
Hence why Java 8 is still so prevalent in enterprise world.
When I joined my current team (in a big honkin' corporation with a history of layoffs and outsourcing) I inherited a dozen microservices, all on JDK8 and a couple written in Scala. So among the first things I did was an upgrade to JDK17 of every single repository. And it was mostly uneventful. More or less use a different Docker base image and bump up the Spring Boot version from 1.x to 3.4. Not running the latest LTS release is professional negligence in my book.
This is because the distribution model changed ? You would probably publish self-contained .NET app these days ? Not sure - have not built a desktop app in .NET in a decade :)
It is sad you dont often hear about any of these on HN. C#/ .Net, Java / JDK, PHP, MySQL, MSSQL, Oracle, or anything older, boring technology that is getting steady improvement, production usage, boring and never getting the upvote to get on main page for discussions. Everyone is chasing new hype and new JS front end.
A very good example of that malignant practice is this very topic which was manually de-ranked.
Those narratives are pushed by the resource owners whose wellbeing depends on disruption and hype. But stability is an enemy of disruption, and delivered functionality is the enemy of hype. So they have no choice but to de-rank the topics like that, otherwise they lose power because everybody starts to see what is hidden behind the mask.
Isn't this how it should be?
As you point out, there needs to be a compelling business reason. In our case, we are migrating to K8s as well, which is easier to make the business case for.
Security helps make the case as well. Any enterprise using Java 8 and Spring Boot is riddled with CVEs.
I think that updating from old version is prime AI work. It's not hard, usually. It's just a lot of boring, soul-sapping work, enough that if you set the famous 10x engineer to do it, they wouldn't be a 10x engineer by the end.
Then again, maybe a super-engineer would do something wild like the Minecraft 1.8 modding community did... despite being a pile of code injection hacks into a famously messy codebase, chock full of reflection and classloader shenanigans, they actually found a way to run it on a newer version of Java than the official, latest version of Minecraft can run on.
One of the values of .NET Core is that it doesn't need to be installed at all in the OS.
We are migrating away from. NET as a SaaS company. Our Monolith is in Framework and being deconstructed into .NET (current) services. It's a journey, hoping to be done in 2 years. We did successfully migrate the frontend from webforms to React, page by page. I'm sure there are other teams as well. I just interviewed a lead that was on a team doing the same thing on a Java 8 platform with a monolith.
With Windows 11, Microsoft stepped away from their normal long-term support lifecycle. Now, you get two years or so of guaranteed support per Windows 11 release, instead of the 5+5 years even Windows 10 received.
Unless you're targeting Windows server or LTSC, depending on the Windows library may not be such a great long-term solution anymore.
We know .NET Framework 4.x will still have to be supported through October 2034 to meet similar support obligations for Windows Server 2025; but Microsoft could easily let that be the end date for 4.x if they wanted, even if Windows as a whole is still supported.
JDK9 also introduced a good modularization system, which broke many Java reflection hacks. JDK17 introduced even more boundaries which JDK21 enforced.
Companies with the foresight to upgrade before the end is near have been working on fixing these issues for a while now, but with Red Hat still supporting JDK8 for another decade or so, I don't think we'll be rid of these old runtimes any day soon. Furthermore, Oracle only distributes JVM8 to consumers. If you're building desktop applications, targeting JDK8 is a lot easier than targeting anything newer, unless you precompile your application or ship your own JDK.
Java devs can use any number of OpenJDK forks with support. Companies stuck in their ways will not update their toolchains until they break, and even then they will try to find workarounds before they implement fixes.
I don't know about .NET 5+, but without WinForms, new .NET just isn't a replacement. MAUI is nice and all, but it's not as simple and easy to use as WinForms, and there's no direct translation between the two.
Futhermore, the difference between .NET 4 and .NET 5/Core is that .NET 4 ships with Windows and is guaranteed to be available. .NET 5/Core will need to have its runtime be installed.
I think both Oracle and Microsoft are considering anything newer than Java 8/.NET 4 to be "stuff for large, packaged applications, web servers, and enterprise" and the old software part of their legacy API for consumers. I don't know of any Java application that requires a newer version of Java than Java 8 (that isn't itself an SDK for developing Java applications).
All of that said: upgrading Java is worth it, just for performance reasons alone. Java may not have the latest tech and it still lacks basic modern language features such as nullable types, but JVM is still an outstanding piece of tech.
https://github.com/dotnet/winforms
They even went so far as to bring back the forms designer to Visual Studio.
https://devblogs.microsoft.com/dotnet/windows-forms-designer...
Obviously it's still a pretty sizable migration to go from .NET Framework to .NET, but at least the UI framework is available again.
You answered your own question. .NET can never ship with Windows, because it then _needs_ to be supported forever. Imagine Microsoft needing to not only support .NET Framework 4.x, but also support .NET Core 3, .NET 6, .NET 8 etc.
Java 9 was also a mess; inching slightly closer to Scala and Kotlin (but not enough to make it worth going back to Java-the-language if you had already switched to one of those), while breaking a lot of existing code (a cardinal sin for a platform whose stability was its primary claim to fame). Many people didn't bother.
Sure, at my former workplace they migrated one of the products (a document processing platform) from .NET 4.5 to .NET 8.
It's quite a lot of work to do something like that and most companies who have old products on .NET 4 don't care to update them because they still work. Many are still adding new features to old .NET 4 codebases.
Many will only upgrade if Microsoft deprecates .NET 4 and stops providing updates.
I have seen quite a few Java applications which fails at unrelated points, and every time I have been told that the thing only runs with "jre-old.very.specific.version-and.point.release". Otherwise you're out of luck.
Wasn't that like 10 years ago?
.Net Framework is the version of .Net that ships with Windows, and it's supported as long as Windows is. For Windows 11, presumably until at least 2035. It's entirely possible that Windows 12 will also ship with .Net Framework, as otherwise they'll have to convert a ton of MS apps to .Net, at which point you're safe until 2045. .Net (previously .Net Core) is the open-source cross-platform framework forked from .Net Framework. And once you move to that you're going to have to move to the latest version every 3 years, because that's how long they're going to support an LTS version for.
So if you have a bunch of apps and don't care about the new functionality, and just want to make sure you have security patches then you'll stick to the version that you've got, and you'll only move once they tell you you have to.
More about this here: https://learn.microsoft.com/en-us/previous-versions/visualst...
It is easy if we take away employment incentives, promotion oriented work.