I'm starting to think the biggest selling point for Java and dotNET platforms is, not platform-independence, but code obfuscation.
In mid-1990s closed source was big, and Java provided a platform to obfuscate the code before shipment, while retaining the advantages of hardware-specific code-gen (final phase of a compiler), to make it harder for the user to copy the ideas.
These days open source is king, no need to obfuscate, and a reason C is making a comeback of sorts.
> I'm starting to think the biggest selling point for Java and dotNET platforms is, not platform-independence, but code obfuscation.
I wouldn't agree for that in the case of .NET Framework.
On one hand, the safety of both languages does make it easier for obfuscators to pull certain tricks i.e. swapping out direct calls for Delegates (memory safe pointers for those unfamiliar with .NET terms) or throwing a bunch of indirect method calls, etc etc because in most cases object lifetime is something you don't think about in LOB .NET.
On the other hand, the problem is that almost any IL can be pulled back into a representation that may not be -fully- comprehensible, but again there are tools to even help with that b/c the C# language spec is well defined enough you know what you need to strip that isn't truly needed for a decompile.
Java/C# got big because of (1) hype, (2) somewhat-filled promises of xplat, (3) somewhat filled promises of better productivity because you don't have to think about most object lifetimes.
We're seeing a shift back to Go/C/Rust/Etc because people are realizing as data grows that a lot of their C#/Java code suddenly isn't so great at huge scale when a GC is churning all the time.
Both C# and Java are working on this in their own way of course; Java is doing a lot of work on their GC, .NET is doing a lot of work to make sure that their IO pipelines for things like sockets are better handled; after that it's up to the dev to decide if they want to go struct-happy.
Java and .NET have mature decompilers. Obfuscators or minifiers replace meaningful symbol names with gibberish. Meanwhile in natively compiled applications that information never existed in the first place unless it was explicitly added into the symbol table and not removed.
If you want to obfuscate your codebase then write your software in Delphi. The native code it outputs will drive any reverse engineer insane even though there was no attempt at obfuscation...
- C is "write once, compile everywhere, run everywhere"
- Java is "write once, compile once, run everywhere"