268 comments

[ 3.7 ms ] story [ 233 ms ] thread
It’s crazy to think C++ and Java are only 10 years apart in the language timeline.
And C++ and Python only 6 years...
And many people consider python as a novel language
What's even more interesting is that C++ and Objective-C started around the same time, and while one is known about widely, the other is still used heavily in the macOS and iOS ecosystems today. Indeed, the creator of Java acknowledged that Objective-C inspired the Java runtime, in particular its late-binding and message sending capabilities, which is what Java has used to this day to allow applications to still run unchanged, even after all these years.
Oh - we share a birthday :-)
I remember buying a book at uni to learn it in 96. AHH applets
I look at the history of Java as a case study in how original intentions don't play out. Hype, disillusionment, irony.

Hype: Java "write once run anywhere" JVM was super hyped as the "Microsoft killer". In reality, the forces that reduced MS's desktop power were Apple iPhone & Google Android. MS's server software influence was reduced by Linux/MySQL and by further by Amazon AWS running that open source stack.

Java was also predicted to be the "C++ killer" because all those wasted extra cpu cycles on fat desktops could be used for GC to make "manual memory management" obsolete. Java did succeed on the server (e.g. Ebay, Amazon, Google, all run a lot of Java on backend servers) but C++ today still has the spotlight for machine learning, games, desktop apps, etc.

Irony: Java was the "serious" language for browsers and Javascript the "toy" language. In reality, Java Applets died along with Adobe Flash and MS Silverlight and Javascript evolves by bottom-up popularity to code complex browser apps.

On the desktop side, it looks like a Javascript runtime (Electron, Deno) will have more deployment than a JVM-based runtime.

If I can be bold and apply learnings from Java's history to today's landscape... I don't think Julia will achieve massive popularity for math programming even though the language was designed for it and the evangelists predict it. Instead, Python usage will always be ahead in that domain. Julia needs an influential player like NVIDIA CUDA or Google Tensorflow to adopt Julia as a first-class API to change its future trajectory and it doesn't look like that will happen.

Similar counterintuitive history with the BASIC language. The "B.A." in "BASIC" stands for "Beginner All-purpose" but it turns out that Python became the more popular beginners language.

The eventual history doesn't always agree with original design intentions of the programming language.

> Java "write once run anywhere" JVM was super hyped as the "Microsoft killer"

Java is a programming language, and you give the best example that it partially killed MS -> Android, and with Linux/MySql some of the biggest and longest running applications are written in Java and run on Linux..or whatever.

You do know that Android was originally written in Java, right?
the Android API and parts of its libraries are Java, the real engine behind that is C/C++.
I don't agree with the BASIC analogy. In the early home computer era, one of the main reasons to buy a computer was as a vehicle to run BASIC programs. Its market penetration was near 100%. It did fade (though there are many VBA holdouts in the real world), but eventually something else will overtake Python as well.
JDK 1.1 still works on windows (and on linux via wine).

https://www.oracle.com/java/technologies/java-archive-downlo...

Everything I tested works flawlessly.

Most Java 1.1 code still runs fine on Java 15 too. You'll get a bunch of warnings though
Yet in 2020 Java is still one of the most promising languages and it's VM spawned one of the most diverse and enduring ecosystems/platforms allowing a multitude of languages and frameworks to thrive.
I remember the announcement, and being thrilled as I poured over the documentation and did some Java experiments.

I didn't really get into programming it for my job until 1.1.4 though, and I remember being skeptical about the language's future when they changed the versioning a year later to Java 2, 3, etc.

I continued with Java as my main language on the job until 2017. I should note that my coding for work became a mix of Android Dalvik Java and J2EE around 2009, and then focused on Android from 2013 to about 2016, with some Elixir and occasional J2EE work (Java 8). In 2016 my main language at work became C++, with some Rust.

Revisiting Java and learning modern Java (Java 13-16) is one of my goals for 2021. That's driven by commercial necessity though. That is second to laying the groundwork for a full time Rust job though. Rust is the language that fills my heart, through and through.

I would say wait till Java 17. There's not a big difference from 11-15 and most of the new features are still in preview. Performance has been the big focus recently with new GC's, less memory use, and faster startup time
> faster startup time

Compared to Java 9, which was a big regression from Java 8 in terms of startup time. And Java 8 in turn was slower to start than Java 6.

I won't go past Java 11 because that's the last version that has an OpenJDK fork, AFAIK. I'm not a lawyer, but Oracle has changed the license for >11 that also gives me pause. I'm also very unhappy with Java's feature bloat: the JVM spec and JL spec used to be small and comprehensible, circa Java 5. Now they are both like 800+ documents. This dilutes Java's single greatest strength, which is a well-written, implementation independent specification. No other high level language has this. Python's specification, for example, is "read the CPython code".

JavaScript + DOM (especially ES6 in modern browsers) has fulfilled the WORA promise on the client, and apart from a vast library of OSS libraries, I don't think Java is particularly distinguished at server-side. Spring? Django? Rails? Express? I mean, who cares at this point? They are all just processes that bind to a port and handle HTTP requests, with more-or-less the same trade-offs and dev experience. The biggest distinction with DX is "IDE vs text editor", not language/framework.

I agree that Rust is a very exciting language, as is the general trend toward Clang/LLVM for new native languages. It seems we might finally be able to have our cake and eat it too. We'll see!

> which is a well-written, implementation independent specification

What good is this when roughly half of the java programs I had to ever use required the official sun / oracle jvm to work

WebSphere has a tendency to work only with J9.
OpenJDK is nearly the exact same code base as the Oracle VM, so this is highly unlikely.

There are ISVs using Java that only certify the Oracle one for support reasons, but this is generally not for technical reasons.

> OpenJDK is nearly the exact same code base as the Oracle VM, so this is highly unlikely.

As of Java 11, completely the exact same code as Oracle JDK. The only difference is licensing.

Does that code depend on sun.misc.Unsafe?
GPL with classpath exception is perfectly clear, everything else is the usual anti Oracle FUD.

Amazon, SAP, Alibaba, IBM and Microsoft are more than comfortable with it.

> I won't go past Java 11 because that's the last version that has an OpenJDK fork

No. (Or how come I can do `apt install openjdk-17-jdk` on my Debian machine then?)

> Oracle has changed the license for >11 that also gives me pause

Yes, except that it's only for the Oracle JDK, not for OpenJDK.

OpenJDK is not a fork, but the baseline of all Java. There are many distributions, Oracle’s is only one of them.
It’s crazy to think C++ and Java are only 10 years apart in the language timeline.
I think it is weird that it is 5 years younger than Python.

I only heard about Python much later.

Like in Aesop's fable, Python was a "tortoise" to many other languages "hare". Many languages (especially BASIC, Perl, PHP, Java, and Ruby) had moments where they had an extreme amount of attention in a short amount of time. Python never had its one defining "moment" (like Sun announcing and hyping Java), but Python steadily grew in usage nevertheless the whole time.
Well, both are far out on the fast end of the adoption rate spectrum, so subjectively those ten years have been a very long ten years.

A lot of Java had been written to pre-1.5/"java 5" standards. There is so much of that stuff that even a full ten years after falling in love with Scala (not as an early adopter, I think it was right at its popularity peak!) I happened to find myself "generifying" some ancient java code. Even kotlin is older now than pre-generics Java has ever been.

What fascinates me is that Java 1.0 is from 1996, yet it seems like there was already a large number of production systems based on it by the turn of the millennium.
I worked on one, for a large telecom: It was simple business software, which before was written either in Cobol or plain old C. The large performance penalty that Java had back then was far less important than having to mind memory leaks in C, and people already thought Cobol was a language without a big future. It was also at the time before the dominance of x86 on intel hardware, so the compile once, run anywhere idea was also quite attractive to people that knew they wanted to change hardware vendors.

It took a few more versions, and a few more JVM performance improvements, before Java was a competitive for a broader spectrum of uses, but it was competitive for business very quickly.

Java 1.0 got people excited about applets, but Java 1.1 really got people going with server side. Microsoft joined in with Visual J++ and it was also obvious that it was going to be important on the Mac. (I couldn't get it to do anything useful on my IIcx, unfortunately.) Then, with the introduction of the HotSpot VM along with Java 1.2, it got really good.

These days, we're spoiled with our wide variety of available, free languages, but at the time most software for Windows was written in Visual Basic, Pascal (Delphi), or C++, none of which was free. And Windows was almost all of the desktop PC market share. The promise of write-once-run-anywhere also made Java really interesting.

I find it weirder that both Python and Haskell are older than Java
It was a golden age. C++, Python, Java, PHP, JavaScript, C#. Every language we use today with the exception of Rust and Go came from that time.
It was (partially) because of the evolution of C++ that Java became popular. C++ was starting to gain baggage by recent additions like double inheritance. Java was seen as a clean break from that, and back to a a more solid OO model.
Where can I download Java 1.0?
It is Java 1.1.
1.0 is almost impossible to find out.

If I remember correctly the first usable one was actually 1.0.1.

1.0.2 was the most stable and lasted the longest
Might have been that one, I just remember it was exactly 1.0.

Also remember some bugs as it was possible to combine accessors together something like having public private.

Yes, prior versions were insanely buggy. 1.0.2 was pretty stable as they fixed most of the problems by then, although Java 1.1 was when companies started to really use it for stability. Problems happened with the windows fork which was pinned to 1.1.3 but it went up to 1.1.8 IIRC.
Interesting, what happened to JavaSoft? Was it a Sun subsidiary that got merged back?
I am not nostalgic for the old versions of Java. I learned on Java 3, when they designers were still saying, "yOu Don't nEEd typE paraMeterS BeCAusE yOu CAn cAsT tO Object!"
In before the Go crowd shows up; this is pretty much the stage Go is at at the moment. But they're taking their time to ensure the design is solid instead of rushed and pressured by the community.
> But they're taking their time to ensure the design is solid instead of rushed and pressured by the community.

How much time (and money) do they invest? Do you have numbers comparable to java? :)

lol, I haven't spent any time paying attention to Go, and totally forgot they're fighting this fight all over again.

I hope their generics turn out nice because there are lots of interesting decisions to make in their design.

Have you followed up on the ongoing discussion, now that the proposal has been finally done?

Let's hope it doesn't end the same way as error did

>Java 3

It was never called that way. It was 1.3... "5" was the first to start the major number 'marketerring'. Internally it was still 1.5, though.

>don't nEEd typE paraMeterS BeCAusE

This is quite false, generics RFE was top 3 in the java bug parade since 1.2.[0]

[0]: https://jcp.org/en/jsr/detail?id=14

> This is quite false, generics RFE was top 3 in the java bug parade since 1.2.

True. Also, Odersky and Wadler's Pizza language [1] was available as early as 1996 and the language designers at Sun were well aware of it and keen on adding it to Java. Odersky mentions this here[2]:

  Bill Venners: How did Scala come about? What is its history?

  Martin Odersky: Towards the end of my stay in Zurich, around 1988/89, 
  I became very fond of functional programming. So I stayed in research 
  and eventually became a university professor in Karlsruhe, Germany. 
  I initially worked on the more theoretical side of programming, on 
  things like call-by-need lambda calculus. That work was done together 
  with Phil Wadler, who at the time was at the University of Glasgow. 
  One day, Phil told me that a wired-in assistant in his group had heard 
  that there was a new language coming out, still in alpha stage, called 
  Java. This assistant told Phil: "Look at this Java thing. It's portable. 
  It has bytecode. It runs on the web. It has garbage collection. This 
  thing is going to bury you. What are you going to do about it?" Phil 
  said, well, maybe he's got a point there.

  The answer was that Phil Wadler and I decided take some of the ideas from 
  functional programming and move them into the Java space. That effort became 
  a language called Pizza, which had three features from functional programming: 
  generics, higher-order functions, and pattern matching. Pizza's initial 
  distribution was in 1996, a year after Java came out. It was moderately 
  successful in that it showed that one could implement functional language 
  features on the JVM platform.

  Then we got in contact with Gilad Bracha and David Stoutamire from the Sun 
  core developer team. They said, "We're really interested in the generics stuff 
  you've been doing; let's do a new project that does just that." And that became 
  GJ (Generic Java). So we developed GJ in 1997/98, and six years later it became 
  the generics in Java 5, with some additions that we didn't do at the time. In 
  particular, the wildcards in Java generics were developed later independently 
  by Gilad Bracha and people at Aarhus university.

  Although our generics extensions were put on hold for six years, Sun developed a 
  much keener interest in the compiler I had written for GJ. It proved to be more 
  stable and maintainable than their first Java compiler. So they decided to make 
  the GJ compiler the standard javac compiler from their 1.3 release on, which came 
  out in 2000. 
[1]: http://pizzacompiler.sourceforge.net/index.html

[2]: https://www.artima.com/scalazine/articles/origins_of_scala.h...

The ergonomics of Java kind of sucked until IntelliJ IDEA came out. Microsoft had introduced "IntelliSense" with VisualBasic and C++ earlier, and that made their stuff a lot more ergonomic despite the verbosity. The VisualAssist plug-in also was very useful.

Without having these assistants, you really understand why "Pike style" of having short API names and small variable names was popular, even if it often left you scratching your head when reading the code.

>The ergonomics of Java kind of sucked until IntelliJ IDEA came out

Not sure what's that about, JBuilder was great, so was Eclipse. I know people love IDEA but feature wise I consider it subpar to Eclipse even today.

I didn't use JBuilder, perhaps it was wonderful. Until IDEA (and Eclipse) most people I knew were using their favorite text editor, such as Emacs, vi, or Notepad++. Each one had some benefits, but I never had that ease of use I had when IDEA came out. This is all subjective, but I'm surprised people thought that the ergonomics of the language were pretty good before 2000.
At work (2001) we used JBuilder, and it was a real productivity boost for me. The GUI felt very natural and powerful. Borland knew how to make good IDEs.
For what is worth - I used it even earlier and I still remap the most used shortcuts to JBuillder's ones, e.g. ctrl+- to open classes. The shortcuts were somewhat optimized for use of both hands on the keyboard w/o mouse. I still prefer not to use mouse when I code.
Both Eclipse and NetBeans had some kind of IntelliSense, but it didn't scale very well. Scanning and re-scanning project took long time. Freshly written code either didn't appear in auto-completion lists or appeared after long delay. Huge projects lagged horribly — and that was just with basic auto-completion. Doing on-fly null-checks and displaying hints, like Idea does, was completely outside of reach.

I don't know, if today Eclipse fares better, beacuse like many people I switched to IntelliJ never looked back.

I remember things like this with VisualAge for Java and even Omnicore CodeGuide.
> The ergonomics of Java kind of sucked until IntelliJ IDEA came out.

IntelliJ was first released in 2001. Those days it was a closed-source paid product. It competed with JBuilder, Visual Age (which became Eclipse), Forte (which became Netbeans) etc.

As one of those old timers that don’t like Java’s Generics, they are what caused me to stop wanting to use Java. IMO they are terrible for code clarity. Though I prefer loose typed languages in general.

Now they’re invading Golang. I’m happy they’re taking their time.

"Generics" (a.k.a. parametric polymorphism) might be terrible for code clarity in a verbose language with subtyping and little to no type inference, but in many languages they actually improve code clarity:

map : (A -> B) -> [A] -> [B]

It's quite clear from the above type signature what this function does and does not do. It can only use the supplied A's to create B's using the supplied function. It cannot do anything else with the A's and the B's. To me, that is clarity.

This is true. But care must be taken with the feature. Iirc, Java Generics tried to take their time but refused to adopt more (at the time) exotic type inference to simplify the syntax.
without generic support, Go couldn't even provide things as simple as a Max(...) function for all kinds of numbers in their standard library.
This never bothered me as it is trivial. But clearly it bothers some people.
In those days, I had the JDK in a box of 3.5" floppies.
I was really excited about Java back in the day. My friend and I back in the 1990's started working on a STEM website that would have made use of Java applets. The idea was to present algebra concepts with graphing applets where you could modify a formula for a parabola, and then see the results on-screen in real time. Like what you could do with a graphing calculator, but with a more explanatory text surrounding it.

I just took a look at the first page of google results for "learn algebra parabola" and found plenty of learning resources... but not a single one was interactive?

With all the fancy Javascript-heavy pages these days, has noone has done this sort of thing? I also took a look at Khan Academy, and they have some interactive stuff, a lot of it is just videos.

All the frontend engineers I know are in it for the money these days. There's very little passion for building UIs that don't pull down a 6 figure income.
There’s very little passion for writing any original front-end code of any kind unless you are doing it for yourself.
Honestly what revolutionary thing are you gonna do on the web with a 2d screen? Why waste hundreds of hours of your life doing it unless you enjoy it. Just paid paid son.
(comment deleted)
I spent a few years implementing a real-time stock-charting applet with historical data, dozens of customisable indicators, drawing tools, multiple stocks at once... all using glorious Java 1.1.8 or whatever it was the MS JVM supported.

I do not miss that codebase.

Might be unknown to many how close we were to total MS dominance on the server side (in addition to the desktop which was owned by MS anyway) around 1992-6 and the push that Java and also the web got from Unix and open systems fans who weren't comfortable to surrender it all to MS.

Around 2000ish there was this push for "100% pure Java" re-implementations for common libs and stuff showing the power of a community sharing a common goal, but also the blueprint for a language-centric ecosystem (not my cup of tea) that's also present in today's Rust, Go, Python, and Node.js communities, though Node.js booted off CommonJs and older SSJS initiatives who were mostly Java drop-outs fleeing from Java's AbstractEnterpriseIntegrationPattern-ness.

Speaking of Microsoft, does anyone remember J#? I didn’t think so.
That quickly became C# though which is very good and very popular.

Edit you're right, C# and J# coexisted. I think its still the theme of MS using their own JVM then moving it to dotnet.

https://en.wikipedia.org/wiki/Visual_J_Sharp

Oh yeah, C# is superb and even offers some features Java doesn’t such as limited operating overloading. My dabble in J# was brief but interesting and served as a smooth transition to C#.
That was J++.

J# was Java for .NET, a C# sibling.

I do, even have some books and other related stuff around.
Microsoft’s attempt to “embrace, extend, extinguish” Java? Of course, though that ultimately turns into C#
Visual J# was Java as a CLR language. Visual J++ was closer to what you mean - it was the Java language and VM with some things deleted from Sun’s distribution (RMI) and some things added like WFC. They also made some breaking language extensions like delegates that later became part of C#, and were somewhat analogous to features that appeared in Sun’s Java 1.1.

Funnily enough, I learned Java in the summer of 1997 in the VJ++ IDE from MSDN tutorial videos, spent a good chunk of my early career doing Java at various places and now work for MSR where I often use Java (or the JVM) on Linux.

(comment deleted)
Still using it alongside .NET, my two favourite platforms.

Happy birthday Duke!

In principle I like Java but there are a few minor details that just make it not worth dealing with it. Getters and setters are incredibly annoying. There are lots of crazy things going on in the JEE ecosystem. The latter is a big deal when you accept an average "Java job".

If you were to give it a small facelift I wouldn't have to worry about all the tiny flaws that add up. I don't really need Kotlin, Scala or dead JVM language x. Just a slightly better Java.

>Getters and setters

Meet Project Lombok. Problem solved and forgotten.

Well, no, it is not. Lombok does not mask invocations, so it is still foo.getA().getB().getC()
I prefer Immutables for code generation. Lombok tends to interfere with Eclipse' code evaluations (last time I used it, it kept interfering with searching for a generated method's usage in your code base) and tends to confuse me when trying to figure out if something's an actual method or a method that was injected into the AST during compilation.

Immutables has its own set of problems, but at least it uses the standard Annotation processor and has a clear separation of generated code and the interface you write.

Haven't used Java's new record's yet, so don't really know anything about that.

I can't remember the exact issues, but there's enough magic going on in Lombok that it doesn't play well with Kotlin, so you're better off with Autovalue or Immutables to future-proof things. I also generally don't like how much magic Lombok uses, regardless of if you needs support for any other JVM languages.
An external dependency for generating getters and setters?

Whats next? Dependency to check if a value is null?

After spending nearly a whole day trying to get a lombok build configured and working in my IDE ... I just gave up on it. It's a nice idea but I prefer to use something like Groovy where the AST transformations happen directly in the language space rather than in a meta-build step that requires so much IDE involvement. (not to mention most of them not even needed because Groovy just does those conveniences by default).
Kotlin is slighty better Java. No more getters, setters, hashcode and toString. Kotlin is also much better Java for asynchronous programming, null-safety, and functional programming. It’s modern Java.
(comment deleted)
Without a VM to call its own, unless we start talking about ART or the failure of Kotlin/Native memory model.
Same goes for Scala and Case Classes. Alas the type astronauts went crazy with Scala, scaring some folks off.
I agree. I wish the Scala community would inherit some of the simplifying culture of the Go community.
Scala 3 introduces a number of simplifications. For example, typeclasses and other constructs are much easier with Scala 3. This said, Scala always included the idea of having a powerful type system. From this perspective, it can never be as simple as a language that doesn't have a comparatively powerful type system (or no static type system at all).
(comment deleted)
The philosophy behind Kotlin and Java really couldn't be more different. Go is much closer to a modern Java than Kotlin.

Kotlin does have some nice additions. But it is very much a kitchen sink language. I wish I could take some of those nicer additions and leave the sink.

The weird thing is you dont even need getters and setters, you can make member variables public (and final if you have to). Just its the Java culture that is so wedded to it. I like Java but its the culture that makes everything soo complicated.
getters/setters became popular with RMI. Public fields have all kind of security/code smell issues. Most classes should be immutable.
Public writeable fields are threading and encapsulation smells but public read-only fields just say, this data is part of my interface.
(comment deleted)
well, yes however fields cannot be part of an 'interface' in java. (they can but they'd be static)

I do use package private fields liberally, though. Just not non-static public fields.

Interface as used here means the broader concept of a "a class's interface is its public advertised operations" and not the specific Java thing called an interface.
I don’t fault Java programmers for their “love” of getters/setters; they’re taking something that really is a best-practice in certain situations, and which mostly doesn’t hurt otherwise (that best-practice being “making the contractual interface for an object its methods, so that the implementation can change while the interface remains stable”) and just deciding to do it all the time rather than only when it will likely have future benefits.

Which makes a lot of sense, if you look at it through the lens of cultural anthropology. Enterprises dictate approaches like this, because the alternative is leaving the choice to the individual programmer — and these same enterprises don’t hire experienced-enough programmers to trust their judgement. And so all the programmers who work for these enterprises end up absorbing this approach as a social norm, just “something you do”, rather than “independently rediscovering the need for it” in a way that would lead to them actually knowing when it’s useful. So, even when not locked into an enterprise that forces it on them, they just keep doing it, because that’s the culture that’s been inculcated on them (and how all the examples look, how all the libraries do it, etc.)

Personally, I’m not in theory against “unilateral” use of getters/setters, either. I just kind of which they worked in Java the way they work in Ruby: where referencing a field on any object other than `this` would actually just be sugar for a call to the getter/setter. Where the Java optimizer would then take special care to optimize-away the call frame for known-‘trivial’ getters/setters.

This is why Kotlin has the best of both worlds. You can access a variable through A.b and it will automatically call the getter if there's one
groovy did/does this too. any property automatically has a getter/setter in the compiled code if an explicit getter or setter doesn't exist.
Javascript can do the same, but I think it's an anti pattern, since now the caller doesn't know what side effects, or performance characteristics you get by accessing the property with an implicit getter/setter.
> now the caller doesn't know what side effects, or performance characteristics you get by accessing the property with an implicit getter/setter.

Beyond method call overhead (which may or may not be a given depending on how things are optimized in some languages), the caller doesn't know that automatically with explicit getters/setters, either; you'd have to read the source to know that just as much if they are explicit as implicit (or rely on documentation, which hopefully is complete and current).

In the programming language Eiffel this is called the uniform access principle.
The uniform access principle is that features are "available through a uniform notation, which does not betray whether they are implemented through storage or through computation"; it doesn't imply anything about what the uniform notation is. Java-style getters/setters also achieve the uniform access principle; everything is accessed only via get_X()/set_X() and never a raw field .X that would betray it was implemented through storage.
"Although it's a fundamental feature of object-oriented programming, remarkably few OO languages really follow it. (Eiffel is naturally an exception.) Most languages simulate it by convention, hence the habit of using accessors such as getAge in Java and C++ programs."

https://martinfowler.com/bliki/UniformAccessPrinciple.html

Is anyone not using Lombok these days? I haven’t written a getter or a setter in years.
I never used and never plan to. Don't need bytecode magic that my IDE can do for me.
I'm not a fan but the place where I work now uses it and it doesn't bother me as much as I thought it would. IDEs are smart enough to work with it. Although I still wouldn't use it on a project of my own.
A bean with nothing but fields and a couple annotations is much cleaner and smaller than one full of generated getter/setter code. And I can rename a field without having to fumble around with the IDE to regenerate them.
Never learned to use code navigation tools and respective IDE filters?
Those aren’t as good as just using Lombok.
Indeed, they don't provide the pleasure to dig out bugs caused by mishandling bytecodes or the verifier.
Are you referring to code folding? Stuff like that helps but it's still not as good as Lombok just generating the getters and setters for you. I'm not sure if IntelliJ can filter out some of the other stuff Lombok can generate (builders, value objects, constructors, etc.)
Lombok generates too much for its own good.
Consider the following two cases:

1. MyClass has 10 private fields, each with a trivial getter and setter.

2. YourClass has 10 private fields, of which 9 have a trivial getter and setter. The last one has a trivial getter but the setter is non-trivial.

If you use your IDE to write your getters and setters, than the two classes above will look the same at glance.

If you use Lombok, the "special" field will stick out at once.

Personally, I prefer to avoid Lombok and just use public fields. That way, the field with a nontrivial setter will also stick out, and no need for bytecode magic.

There is no magic. You have source code and when you compile you get byte code.

In the early versions of Lombok it was a bit dodgy as it used private APIs, but now the compiler has the public hooks and its all good honest compiler plugins.

Agreed Lombok is nice, but why can't they just put that in the runtime? You have to be suspicious of every extra package.
Working with java for 20 years. Have never used Lombok, and honestly don’t personally know anyone who has. (Same with Kotlin.)

It’s a big world.

(Another weird thing for the first 25 years of my career never used anything but Sybase as a relational database — across 5 different firms. Never used Oracle or SQL Server.)

Yeah, I think it's no accident that the best thing about working on the JVM is the massive ecosystem of popular libraries. Java and the Java community did a pretty good job of solving the problem of extremely large numbers of developers sharing code with little coordination over long timelines. Unfortunately, they did it because that was their vision of how enterprise software would be created: dozens if not hundreds of programmers working together on enormous monolithic applications with months-long release cycles. Your code had to be extremely defensive, so you could change the internals without fear, and also extensible and customizable, so you would be less likely to be interrupted by requests to make changes to support someone else's work. All the extra work and complexity to accomplish that became the "right" way to write Java code regardless of context.
I was thinking of ruby as you write this... it's not quite true that in ruby "referencing a field on any object... is just sugar for a call to the getter/setter."

It's actually true that ruby makes it impossible to directly access fields in objects other than `self` (ie `this`). Seriously, it's not possible ruby takes away the ability to do so, thereby making it not even a choice anymore, you have to create a getter/setter, it's the only option. There is no sugar, there is simply a prohibition on direct access to iVars in other objects, period.

What might make it look like "sugar" is that parentheses method calls are optional in ruby -- `obj.foo` is just another syntax for `obj.foo()` Whether or not it's a getter, any method at all, nothing special for getter/setter here. That's literally the only thing going on here that makes you think there is "sugar", ruby syntax having parentheses be optional in method calls.

And additionally ruby gives you a shortcut "macro" to defining the getter/setter, `attr_accessor :foo` inside a class body just automatically defines the conventional getter and setter for you. You still do need to define them though, again no "sugar".

So ruby actually comes down solidly on the side of "yes, always use getters/setters"... in some ways this is what you are complaining about, people always doing it, right?

But it turns out differently and not annoying anyone, I think, because it was planned for by the language designers in the first place, both by making it mandatory (eliminating it as a point of debate or as something a programmer will spend any time ever considering when implmeenting), and by providing devices to make it convenient.

I think the choice to make parentheses optional in method calls actually goes along with the choice to forbid direct access to fields in other objects; both because there is now no need to syntactically distinguish between the two, and because it makes it less annoying to forbid. It also causes all sorts of other complexity in writing parsers for ruby though...

I happen to know a bit about Ruby. (A lot more than I know about Java, as it happens.) Let me pick a few nits :)

#instance_variable_get / #instance_variable_set is a thing. The (default) implementations of these methods on Object are just C code that do direct IVar reads/writes. You can thus think of #instance_variable_get and #instance_variable_set as real “field access” in Ruby. It’s just that, unlike most languages, there is sugar† for the getter/setter, and there isn’t any sugar for the “direct” field access.

† (The setter’s sugar is obvious — `a.b=x` is re-written by the lexer into a call `a.send(:"b=", x)`. The getter’s sugar is less obvious — it’s seemingly just a regular method call. But think about why Ruby makes parens optional on arity-0 method calls in the first place. To sweeten getters into something field-access-looking!)

But, well, you might say, #instance_variable_get is just a method, too! I can override it as I want! Really, it’s just another kind of getter/setter — sort of a categorical one.

Well, let’s go one level deeper — you can literally “reach into” the object to take a look at its IVars as it sees them:

    obj.instance_eval{ @foo }
“Objection! #instance_eval can be overridden! DRb proxy-objects do it!”

Well, okay, let’s get creative, and start breaking through the seemingly pure-OOP semantics of Ruby, revealing the more functional-language underpinnings:

    inst_eval_fn = Object.instance_method(:instance_eval)
    inst_eval_fn.bind(obj).call{ @foo }
Java developer 6yrs here. I've worked in code bases and extended internal libraries that forgo the getters/setters model, for exposing member variables directly, and it's not better.

If you ever need to change something about that value, do additional logic before returning (I e. emit metrics), or model a data class with an interface having getter methods makes these so much easier.

I have a tendency to do "public final" variables and set them in the constructor for data objects. There's this weird hangover from Smalltalk and the idea that everything should be overridable that wants getter and setters to be functions, when basically a read-only variable in an immutable data object is much simpler and just as safe.

But for some dumbass reason it's not "the Java way".

Encouraging immutable data objects is “the Kotlin way”, though.

You have explicitly mark properties as mutable (“var” instead of “val”). I didn’t get the value of this at first, but when we started catching bugs at coding tiime that would have been runtime errors in Java, I started to understand. This was among my takeaways from working with it in production for about two years.

In general Java it's still messy because although you can make the value of a variable immutable, the innards of the object it's holding are still mutable. Such as appending to a list.

You have to go as far as Clojure does and create a whole new suite of truly immutable data containers, for full safety. I dunno if Kotlin goes this far. But yeah, it's the right way.

I blame the culture, too. It’s unreal how many programmers have internalized this idea that simple code is somehow a personal failing.

One factor I’ve thought about is how many Java programmers seem to have learned design by looking at things like the Java core libraries or a few open source frameworks, without recognizing that most people are not writing code intended to be generally reusable by millions of projects and that popularity means those projects cannot modernize their style easily, either. People write new code on new projects today as if it still needs to be compatible with the early 2000s because much of the code they learned from ossified around that time, and will claim it’s “best practice” because otherwise why would this Oracle/Apache API still use it?

Getters are necessary because Java does not have read only attributes (except final).
You will need getters/setters for some fields. So your code will look weird:

    p.x = p.getY() + p.z;
    p.setY(p.x + p.z);
It's better to use more universal approach, so your code will look unified.

Another thing why getters/setters are preferable is because when you need to replace field with computed value, you would need to replace all your code.

Proper approach would be to use properties which are available for every language but Java. They invented records, which somewhat fill that niche.

I don't like the idea of having a verb in the name of a pure function. I think it reads better to simply name the function after the result it returns.
(comment deleted)
I've used Java for over 20 years. Not once have I ever replaced an attribute with a computed value.

Also p.x = p.y + p.z is much easier read.

Another drawback of getters and setters is that you end up not looking at that code because you assume you know what it does, so you can miss when someone puts logic into a setter or getter

It was brought by Smalltalk and C++ developers, but I guess 25 years later many don't get that part of history.
I think it's a YAGNI problem, perhaps not consciously stated. The premise is if we never touch the public members, we can one day update the setters to add validation, or analytics, or include some automated formatting shim inside the getter...

But nobody actually does it.

You can make member variables public, but that means that changes to how you handle access become compatibility-breaking.

If you use getters and setters, you have more future options without breaking backward compatibility. When you are making libraries that lots of other projects might depend on, this is probably more important than when making apps, especially relatively small apps.

“Getter/setter from the start” optimizes for induced maintenance cost on dependent code.

Now, in some other languages, access via getters/setters is at least source-compatible with field access, which makes this less of (or not at all, for dynamic languages, or if it is object and not just source compatibility) an issue. But that's not the case with Java.

> When you are making _libraries_ that lots of other projects might depend on

I think that's the key part here: most developers are writing code which will rarely or never be reused but they _learn_ by looking at shared code, and shared code which is on a different development cycle by a team nobody knows, and the field doesn't hasn't had a great history of discussing how different tradeoffs are appropriate for different projects.

Or just use Java records.

    public record SomeViewModel(String name, int age) { }
Problem is lots of tooling and libraries you might integrate with assume getters and setters and literally won't work without them.
Well, getters and setters are a choice that's not predominant for the core java packages: java.lang, java.util, java.io, java.nio, etc.

Of course there were added with awt 1.1 and swing in an attempt to catch up with the visual programming jazz and for many it never disappeared. Later on there was (still is) a trend to use builders... and a general shift for immutability.

Not in the language, but Lombok makes it a non-issue
Java was (and still is) IMHO a great language, but the culture around it is why I refuse to do it professionally. Things I can't stand:

1. Multiple (often unnecessary) layers of abstraction that end up being much more complicated than the thing they were intended to simplify through abstraction. There is no concept too simple to abstract it seems

2. Verbose and hard to follow "builder" patterns

3. The extreme proliferation of design patterns. I have literally seen hundreds in various Java codebases.

4. Gradle is great but requires memorizing a non-trivial API and learning a whole new (awesome, but still) language (Groovy).

5. There's always a "Java" way of doing stuff that is different (often because of abstractions, see #1) so you have to re-learn everything that way. Example: Managing TLS certificates

5. Legacy code is everywhere, and can be really painful.

So much of it was hacked together and became critical and can never be re-written and never retired

There are more, but I weary of this discussion :-)

Gradle is only a thing in Android circles, thankfully.

Legacy code is everywhere on the world, only a selected few get to work on shiny things from scratch. Even cool startups eventually turn into legacy.

I wonder what technology used at enterprise level, doesn't suffer from those bullet points.

> Gradle is only a thing in Android circles, thankfully.

Wish that were the case, but unfortunately Gradle builds showed up in server-side, SpringBoot-heavy FinTech startup code I worked with not too recently. I guess it's due to the copy/paste nature of Spring development, like other choices in those code bases.

I don't do Spring, so I am spared from that.

That is to be expected, given how Spring is now hyping Kotlin as they did previously with Groovy, Scala and Clojure support, and Kotlin folks tend to push for Gradle due to its use on Android.

Gradle at least gave incremental builds... Even though javac is fast, practical java builds are sloooooww (maven)..
Indeed, thanks to a background daemon that needs at least 2 GB ram and an SSD to be competitive with Maven.
If I have to work with legacy code I actually prefer code written in a non-object oriented language. Badly written OOP code is often worse.
Yeah, navigating overly-architected OOP is like playing super mario brothers. The princess is always in another castle.
> Gradle is only a thing in Android circles, thankfully.

It's the standard Java build tool at this point. I don't know of anything better.

I don't know about "better" but Maven has been the standard in my company. Personally, I like it better, call me crazy.
For Android developers and ex-Ant users only.

I really don't see it anywhere else to make it standard, besides it depends on Maven Central.

Maven is the standard build tool and has been on every project I've worked on outside of play/sbt hell.
(comment deleted)
"Enterprise" is a hard term for me to use productively in software context, because it feels so synonymous with bad software.

Lots of fine pieces of software are used in small and big companies that do only one thing and do it well.

As for in house line-of-business apps, it's an elusive species because if it does what it needs to cost effectively and is not a marketing case for a fat software company like Oracle nobody often gets told about it. But I've seen and heard of LOB apps built thereupon that don't suffer from those bullet points, except for 5.

Somehow Java attracted more than its fair share -- way more -- of programmers who wanted to believe that software development had all been figured out, the right answers were known, and the only thing that remained for the profession was to be faithful to the true answers and priggish towards anyone who had doubts. That was a really weird time, especially in retrospect when we think about what the "right" answers were back then.
That’s a side effect of enterprise software development, because politically it’s all about posturing to make non-technical management more comfortable. “Wow they’re really confident they must know what they’re doing”

The same attitude existed in C++ programmers in that space that sneered at Java’s intrusion.

I see the same attitude in new teams using Golang in the enterprise.

Yes, excellent observation. I've seen that attitude a ton in the "design patterns" discussion. e.g.:

"Why are we doing a Factory for Singleton Factory design pattern here?"

"Because this design pattern is made for this scenario"

This. Exactly this. It wasn't that Java was a "different" way of doing things in business software that had pros and cons, it was that its adherents thought it was THE way of doing things in business software.
OMG! Thank you for this. I've disliked Java for years but really couldn't put into words exactly why. Reading you comment I started thinking about all the time I wasted chasing down error messages that were spread across 7 different classes. And working with TLS in Java? Nightmares abound!
1) those layers of abstractions are often the result of some smart guy in the team, reading some design patterns book and then desperately applying them whenever feeling the chance. Typical building his little cathedral story.

Its pretty horrible, but by no mean java-specific. It can be achieved in any object-oriented language, and to some extent also in others.

Patterns aren't always bad When used correctly they can greatly simplify code.
6. excessive configurabilty leads to fragility at runtime - the overuse of annotations, xml/yaml/whatever configurations and late-binding (effectively assembling the app at runtime) eliminates quite a lot of advantages of a statically typed language and brings us back to string coding: runtime-errors due to typos, jpa strings in annotations, typo in an xml file leads to non-functioning software at runtime. Classloader horrors due to deeply nested library dependencies that use different versions of libraries, fueled by the insanity called maven.
> overuse of annotations, xml/yaml/whatever configurations and late-binding (effectively assembling the app at runtime) eliminates quite a lot of advantages of a statically typed language

Just avoid Spring. That's been my motto and I've been Spring free for 7 years now. Doctors say I should live out a happy life.

I work mostly with Java and am a bit blind to other languages, at least in a professional setting. Which languages / ecosystems do it differently? I'm looking for something new.
I'd recommend Elixir as a nice introduction to functional programming while not being too arcane.
Agree, strongly. I always think it’s funny when people complain about the verbosity of Java, because most of it is self-imposed. Even more funny is that the same Java programmers will migrate to something like Groovy and then reproduce all of the same verbosity there (e.g., “Don’t use implicit ‘it’ variables! Name it theImportantThingFromTheImportantThingArray!”)
I’m really with you. The culture around it feels borderline developer-hostile. It’s exhausting and feels like I’m participating in some strange, elaborate religious ceremony.
Much of the JEE ecosystem (not all) has been replaced by Spring Boot or Quarkus. Generally they have been a delight.
I see this cited a lot, but honestly I would say the majority of jobs use Spring, and it has been that way for quite a while.
Can I suggest trying Groovy (properly, not in the form of hacking together gradle or jenkins scripts, but as an application language)?

It's basically what you want but unlike the other "dead" languages it is designed to complement Java rather than compete with it and is unlikely to ever become obsolete for that reason.

Use groovy with @CompileStatic. At least for your beans. Autogenerates the getter/setters.
I started developing Java in my first job in 1998. On that workplace, some developers before me had evaluated some kind of Java framework called "San Francisco", if I remember it right, before I joined, but decided against it. If I remember it right, it was IBM that were behind that. Is someone familiar with it? Some pre-J2EE thing..?
Yes this must have been it. Seems like something that didn't get traction...? I was wondering if it was the origin of something that came later such as servlets or EJB or something...
It wasn't on the same level of abstraction as EJB or Servlets. "San Francisco" was a business-level framework that had components for things like inventory and order management, invoicing, pricing and discounting, etc.

I guess the idea was that in-house developers would write line-of-business applications on top of it instead of customising something like SAP or Oracle Applications.

It didn't get much traction as a concept, but I wouldn't be surprised if something like it still existed in some corner of IBM's consulting business.

Okay, thanks for explaining!
I'm like not that amazing of a programmer, but Java seems pretty legit.

It's a lot of cruft to pull together and manage to make stuff work. But once it does it's fast and the codebase is fairly easy to mentally model and absorb. Yeah the boilerplate stuff is kinda annoying but whatever.

Java with Akka adds the actor and some flow/functional stuff that seems to be useful for building a distributed and complex system that would be used in the future landscape of functional computing.

> Although Java has evolved over the years, the core of the JVM has maintained stability – to the point where applications compiled with Java 1.0 can still be run on modern JVMs, albeit much faster. The bytecode format has (largely) remained unchanged;

Java has many warts but the bytecode stability is an admirable achievement.

That stability comes with a huge cost, for example, Value types, desperately needed, has been going on FOREVER (7 years and counting) with no end in sight ..
If you've been following the development progress, they've gotten the VM side largely ironed out and under testing. Nothing on the language side has been polished yet though.

As an honest estimate, I'd give about 2-4 more years. But it's definitely further along than I thought it would be.

See: https://cr.openjdk.java.net/~briangoetz/valhalla/sov/

Value types and Loom (lightweight threads) are two things that will shape Java in profound ways for years to come.

2-4 years for value types seems quite long but the changes to the spec to accommodate value type is much more broader in scope so that’s understandable.

Loom question: I gather that it basically has implicit awaits, so how do you “force no-await” so you can run operations concurrently?
Good question. Something that @pron can answer better
Spawn virtual threads
Spawn new threads (and then join them).
Is than an OS thread or a Loom-thread though?

If it’s an OS thread, then that won’t scale and defeats the point of using Loom (though it does still reduce the overall system load).

If it’s a Loom-thread then doing `.join()` is the same thing as doing an `await` - in which case it’s silly to not just have a `.dontJoinJustYet()` method that’s available for every Loom promise.

You pick the thread implementation, but clearly a virtual thread would be more appropriate. And yes, join is semantically the same as await, but it fits with the design of the platform. And also yes, there are convenience methods for spawning threads and joining them, such as ExecutorService.invokeAll/invokeAny.
How do you think Loom would impact reactive projects such as Spring Reactor, Vertx and R2DBC?
I don't know. Those who genuinely enjoy reactive frameworks will still be able to use them, but those that don't won't need to to get similar scalability benefits.
And also a sad failure. Bytecodes lose most of the semantics of code - value scope and lifetime; code structure etc. So jit compilers have to reverse engineer all that. They'd have been better served to simply have the source code.

I remember being intensely disappointed when I learned Java produced bytecode (Java 1.0). Even back then I knew better, that losing semantics would be a huge hurdle to be overcome.

Java bytecode looks a lot like Java, and except for local variable names, Java disassemblers do a pretty good job. Maven also solved this by very strongly encouraging the distribution of source jars. It's very rare that I have issues with missing source code when I use a standard IntelliJ setup.
Again, why disassemblers? Why not put semantic info only into that java file? Why on earth go through the ritual of creating bytecodes, then un-creating them? Clearly bytecodes are not what anybody wants.
Java bytecode allows for Debug attributes, which are produced by default in most build engines, and say which field maps to which item on the stack and for how long. Even if that information is removed, the fact that you have the return value of an invokedynamic called `object.getName` means that you can often have a much better chance of redeeming the information than in other compiled languages.

The key difference is that fields and methods maintain all their names in the bytecode; in C, non-public symbols are usually stripped leaving only the calls to libraries present.

You do bring up an important point. Have there been successful cases of taking several levels of the code at the same time? Is there a JIT that uses both the bytecode and the AST together? Some things are easier using some data, for sure.
GraalVM does precisely that for dynamic languages (with really really impressive speeds, graaljs’s performance can be in the same ballpark as v8 when it comes to peak performance). But as far as I know, there Java re-implementation on top of it uses byte-codes.
The bytecode stability is only half of it. The other half the stability of the standard library, before Java 9 it was very rare to remove anything from it. I recall things like a RCS or SCCS revision tag which was accidentally put in a public static field, and it was kept frozen (with the same value) as a public static field just in case someone was using it for some bizarre reason.

Starting with Java 9 things changed, many things were removed (starting with all of J2EE) and other things are going to be removed soon. This is one of the reasons why it takes so long for projects to migrate from Java 8 to Java 9 and beyond.

Back in 2018 I had a client with Java 1.4 in production, some never migrate, even if there aren't hurdles.
> This is one of the reasons why it takes so long for projects to migrate from Java 8 to Java 9 and beyond.

EDIT: Oh, just realized... it's probably a misunderstanding on my part. "Java 8 to (Java 9 and beyond)" is the intended reading, probably. My bad.

----------- DO NOT READ BEYOND THIS POINT ----------

Maybe it's just a phrasing issue, but...

The Java 8 -> Java 9 (or 11, in practice) transition was special in a few ways (modules, mainly), but I don't see why any future transition should be quite as disruptive? Do you have anything concrete in mind, because if you do, I'd like to know about it!

No, it's likely that it won't be quite as disruptive in the future. There were a few backward incompatible changes with modularisation (in order to break module cycles) but the bigger disruptive changes were moves away from sun.misc.* packages which should never have been used by production code (but which often were, because speed).

Fortunately Java took a middle-of-the-road approach; it didn't quite get rid of as many things as it could (Unsafe stayed around in a few ways). Had it all been killed off then the transition would have been more problematic.

With Java 17 being the next LTS I don't think there's appetite to break things before then but it's quite possible that Java 18 will really put the hammer down and remove Unsafe for good. That, I think, will be one of the last disruptive things Java does.

Why was J2EE removed? Not been following Java developments for some time, though I did a good amount of real life work on it earlier, and liked it at least some, back then. Also, I thought it was renamed to JEE. Or is that also outdated?
It's still available as libraries, just not with the default install
Maintenance of it has been moved to the Eclipse foundation and it was renamed to Jakarta EE.
Mainly because it was then tied to the release schedule of the JDK and for EE to compete they need to invovate faster.
Thanks for all answers.
FWIW, I had updated Java to use a capabilities model (before the "SecurityManager" cruft was so rudely shoved into the libraries) that was patterned after Joule (one of the few (if not the only) language that had passed 'red book' security certification). And part of the challenge of building it had been understanding method and class "signatures" which would inform the model. In particular, the challenge was trying to figure out what "side effects" were relevant and which were not[1]. The requirement was to throw IncompatibleClassChangeException when the class had changed and thus the capability was possibly incorrect.

We got pretty draconian and went for a "class changes can be "additive" only, so that the capabilities could be forward compatible with new classes.

Sadly, politics got in the way of shipping it so I ended up with only a couple of patents and a later Javaworld column out of it and most of work never saw the light of day.

[1] For example you might have a File class with a write() method that you wanted to be part of a write capability, but there might also be a update_metadata() method that effectively wrote something to the file so you needed that to be part of the capability, and that method might be looking at static member data of meta data flags, which were also part of the read() capability.

I'm quite intrigued to hear that Java might almost have had a sane security model – what was the political problem that killed it? Anything from your work that you'd like to see used in new languages (those patents must have expired now I assume?).
An influential member of the team didn't understand the code I was checking into the source tree so they deleted it all and added the SecurityManager instead. The manager refused to override that action because "the individual threatened to quit."
How typical was that type of thing? Although on the whole I think Java is better than its reputation, I always thought it a bit underwhelming for the brainpower around at the time; one would kinda assume in addition to yourself people like Guy Steele or Gilad Bracha might also have tried to get a forward looking thing or two in if someone had let them.

BTW, the link to your capabilities columns on your home page appears to be be broken:

http://www.mcmanis.com/chuck/java/javaworld/index.html

Interesting, Inforworld (presumably copyright owner of Javaworld) moved the article to here: https://www.infoworld.com/article/2076993/take-a-look-inside...

As to your original question, Sun was a pretty political place in general. Java was a "weird" place because it only existed because Gosling and some other folks were walking out the door and Scott McNealy asked what he could do to keep them. Their response was give them full autonomy to pursue their ideas. That gave birth to "First Person" which was an independent company wholly owned by Sun (I still have my First Person business card :-)). One of the people knew I was "loose in the socket" as they say and wanted to be sure I had an opportunity to participate and brought me over. It made the last 4 years at Sun mostly enjoyable.

As the limelight started fading from Sun and they started killing off things that couldn't make a profit, they decided to kill off First Person (couldn't make a business case for it). So the Java team negotiated with them to let us release the sources so that when we were job hunting the person could look at the source to see what we had been doing for the last 4 years. We did a stealth release in January of '95, then an "official" release in March. That put us on the front page of the Mercury News. A couple of us attended the WWW conference in Darmstadt Germany and it was all anyone wanted to talk about (much to SGI's chagrin). At which point the politics REALLY ramped up back at Sun when people figured out it would be a "good" thing to be associated with Java instead of a "loser" thing. This affected different people differently, and some, who had pretty bad case of imposter syndrome, went all out trying to claim credit for everything. It ceased to be "fun" with the hard to get along with folks becoming intolerable.

Fascinating! So basically the only reason Java is a thing today is because some manager was moved to pity by the lack of job prospects of a bunch of soon-to-be-redundant engineers (because they had unwisely spent their last few years on this dead end project without anything tangible to show for it). So they allowed a release before putting them out to pasture, only to find the dead end project suddenly had become an overnight hit?
Yeah, pretty much. At the February '95 budget meeting (which determines budget for the next fiscal year (July 1)) they agreed that FY94 was the last year First Person would be funded so by 7/1/95 it was up to us to find new jobs either inside of Sun or elsewhere.

But to be fair you are looking at it from the future backwards. At the time Sun considered "the web" to be a feature not a product (many were bemoaning that because SGI was making it so central to their identity) and a "browser plug-in" (which in itself was kind of a weird concept, originally we thought all applets would be java://applet-host) was hardly something to interest a big enterprise player like Sun. We literally went overnight from other parts of the company saying "I knew they were never going to make it." to "really this project has been ours all along it only seems fair that we should continue to direct it.", Sun Labs, SunSoft, and Sun hardware all claimed to be the reason we were even existing.

It stands today, for me, as a classic "accidental" disruption.

Sun politics, and opportunistic retroactive credit-takers, pfff! The same kind of bullshit happened with Self and HotSpot. Lars Bak developed the JIT compiler for Self at Sun, which they didn't appreciate, so he left for another company, applied his ideas to Java, and they bought his company back, and made HotSpot!

https://en.wikipedia.org/wiki/Lars_Bak_(computer_programmer)

>After participating in the design and implementation of the BETA Mjølner System, in 1991 he joined the Self group at Sun Microsystems Laboratories in Cupertino, California. During his time there, he developed a programming environment for Self and added several enhancements to the virtual machine.

>In 1994, he joined LongView Technologies LLC, where he designed and implemented high performance virtual machines for both Smalltalk and Java. After Sun Microsystems acquired LongView in 1997, Bak became engineering manager and technical lead in the HotSpot team at Sun's Java Software Division where he developed a high-performance Java virtual machine.

https://news.ycombinator.com/item?id=18691446

Java’s Forgotten Forebear (2009) (ieee.org)

https://spectrum.ieee.org/computing/software/javas-forgotten...

https://news.ycombinator.com/item?id=23800625

Call with David Ungar (2015) [video] (youtube.com)

https://www.youtube.com/watch?v=8nfrC-YLYqc&ab_channel=Herna...

https://news.ycombinator.com/item?id=20377077

>Lua's main problem is that it isn't JavaScript (i.e. in JavaScript's enviably lucky position of ubiquitous dominance).

>If I had a time machine, I'd go back and try to convince Netscape to use Lua 2.1 instead of inventing JavaScript (released December 4, 1995). And hire the Self guys (Dave Ungar, Randy Smith and the crew who eventually made the Java HotSpot compiler) away from Sun, and Mike Pall (LuaJIT) from wherever he was!

https://www.lua.org/versions.html

>Lua 2.1 was released on 07 Feb 1995. Its main new features were extensible semantics via fallbacks and support for object-oriented programming. This version was described in a journal paper. Starting with Lua 2.1, Lua became freely available for all purposes, including commercial uses.

https://news.ycombinator.com/item?id=12574290

https://channel9.msdn.com/Blogs/Charles/A-Conversation-with-...

Here's some discussion with Jens Mönig about Self's roots and Morphic's evolution, and Lars Bak on JIT compilation:

Jens Mönig (the author of Snap!) talked all about the new version of Snap! and the new HyperBlocks feature (APL like arrays) in the Snap!Con20 Keynote!

His delight in programming is so contagious even with social distancing and teleconferencing!

https://www.youtube.com/watch?v=K1qR4vTAw4w&ab_channel=JensM...

I asked him about the architectural changes, and we ...

The main thing that stood out to me is the only reason Sun could "profit" from this accidental disruption is because someone in management was a nice enough person to allow something which it sounds like they must have seen as a small net loss for the company but a big net win for the engineers involved.

I found that part much more surprising and interesting than the presence of harmful politics or people climbing over each other to claim credit for something they previously dismissed.

Of course the story would be even more uplifting had Java become profitable and not just popular...

(I mean certainly Java was worth something and the prime reason Sun got bought by Oracle, but it wasn't enough to help the company survive as an independent entity and even with hindsight it's not obvious to me what strategy would have allowed Sun to prosper)

This makes me wonder if Blaine Garst's recounting of Gosling's group drawing inspiration from what they'd seen in OpenStep as NeXT shopped it around actually makes sense.
Why would something so existentially important such as a 'security model' be blocked at the code-level, let alone 'code being checked in'?

Would that be something discussed long before anyone implements anything? It touches every part of the system and informs the very essence of the product.

You know that phrase "Reality is complicated"? Smart people tend to over estimate their understanding of complicated subjects, and it irritates them when it appears you are making something more complicated than it "should be." Even though the error is their over estimation, not the complexity of the solution.

If you combine that with their ego being unable to accept that something is more complicated than they assume, then you get the situation where they propose a solution that is simple, easy to implement, and wrong.

Add to that a measure of "hurt" from feeling like the messenger is getting the credit that you are due. And you get someone who directs their anger at the messenger not the message. Yes, it's broken, yes it's dysfunctional, but it's just business. If you are in that spot you can assuage your hurt feelings by forcing the simple/wrong solution through to "prove" to yourself that you have more power.

In all fairness I don't blame the engineer. They fully believed that their simple solution was completely adequate. I do however blame the management that put up with this. They are the ones who should have been looking out for the company/technology and not whose feelings would be hurt by doing the right thing. Several years later James apologized to me for not doing the right thing, and I appreciated that, but I also recognize that while my system was much more secure and would have not had the vulnerabilities that were later found, it was more complicated and thus harder to validate, and it could have just as easily been broken in a different way.

I appreciate the fact that the Security Model may have been 'simple' - and frankly 'simple' is usually better with these things.

However - it doesn't abnegate the fact that no matter how you slice it the 'Security Model' is an important thing unquestionably deserving of some open discussion among participants, because there existential consequences.

Especially with Security - it's not one of those things that's ever obvious. This is why we have bug bounties, certain kinds of open source - it generally benefits from 'a lot of eyes, and pondering'.

It's probably something you might try a few versions of and not even make your mind for a bit.

The evidence that 'it's a big deal' is in your own response: the solution was screwed up, and Java paid a big price.

The fact that anyone 'right or wrong' was trying to put together a solution and just 'check it in' frankly is a little frightful.

Engineers threatening to quit, and decisions made on the basis of that are comical.

If this narrative is authentic, then it seems Java Security Model - and probably a bunch of other things were just 'slammed together' by a bunch of smart guys passionately working on it, arguing, playing games' and we're lucky to have what we have today I guess.

Imagine what we would have if there was some intelligent social deliberation there.

What gave you the impression that security wasn't discussed? At the time the group was pretty small, about 12 engineers depending on how you counted. Besides Mark Miller who had done the foundational work on Joule at Agorics I also had Whit Diffie to help with the cryptographic aspects, and access to some of the top infosec people of the time.

Literally as soon as we started prototyping "Webrunner" (which later became "HotJava"), the web browser written in Java, we started talking about the risks associated with loading executable content from a server you didn't trust and running it on your computer.

Everyone agreed we had to do something but not everyone agreed with how much we should do given that Sun was going to toss the language anyway and so we would be lucky if we got half the number of users that Tcl already had.

I was nominally tasked with solving this problem and chose to solve it to the best of my ability.

To do that I created a system for signing Java code, a capabilities model that would prevent unauthorized code execution, started Sun on the path of licensing a right to use the RSA patent, added an entire crypto subsystem to the sys.* code base, negotiated with the NSA a system that would allow Sun to actually ship strong encryption in an interpreted language, and designed some structure that had to be in the JVM to support this framework.

But what you have failed to grasp is that at the time the prevailing attitude at Sun corporate was that this was a 'throw away' project and amongst some of the engineers in the team, they were more interested in showing off their language design skills rather produce something that was an actual product. After all, as these language designers reasoned, Java had removed all the things that made C and C++ unsafe right? So if the language was correct (as the reasoning went) it couldn't possibly be used to do something bad.

One of them felt all of this "security complexity" was unnecessary. They also felt that my checking into the code base this complex stuff was disruptive. But they did agree that there needed to be "something" so they wrote the SecurityManager class over the weekend and called it done. And threatened to quit when I tried to get it undone.

And the JVM was seen as cool from the start, even though there had been various noteworthy bytecode/p-code/etc. virtual machines before it. There were already a few books on JVM coming out. And while the JVM spec was still in draft, Jonathan Meyer had already released an assembler for the it, call Jasmin, and I wrote an Emacs mode for it: https://www.neilvandyke.org/jasmin-emacs/

(I'd been doing some early desktop GUI application development in Java (writing my own widgets, since AWT was too minimal), and I wanted to get into the JVM, to play with implementing some higher-level language features that couldn't necessarily be implemented well in Java. So, of course, the first thing a person needs, before it is possible to start using a language, is an editor mode for it. :)

Does anyone remember the first Java IDEs? I know there was Visual Age for Java by IBM, but Sun had something, too. Was it called "Java Workshop" or something similar?
Found it! It was actually called "Java Workshop". Here is a review of v2.0:

https://www.irt.org/software/sw017/

The UI builder was really buggy and almost impossible to use, that's why we learned using GridBagLayout manually.

I used Visual Age at work in the late 90s. The IDE itself was pretty decent but I still have nightmares about EJBs.

The micro edition of VAJ (yes, that's what we called it) was itself written entirely in Java, and the team that did that took what they learned and built Eclipse.

The only thing I wished Java had from the get-to is lexical scoping closure with a real function as first class.

These alone would have cut down so many boilerplate codes.

An Oracle marketing person reached out to me for some video clips talking about Java last Summer. One of the questions they asked is where do you see Java in 25 years? At that point in time, with a six month release cycle, the answer was Java 64. :)

I got on the Java roller coaster in the Java 1.1 days... so some 23 years since I wrote my first Applet that tied to the mainframe via RMI/CORBA. Java has really evolved. Seems there is a wide range of Java developers - those fluent with streams, lambdas and other features introduced in Java 8 - and those who don't even seem to know what Java 7 try with resources are. I suspect C++ and other languages that have been around for multiple decades see the same thing. Not sure if it is the starting education or just dated material.

I recently took some java classes and java 8 was baseline.
Be happy about it. It is no fun programming in early versions.
Ah. RMI.

It is funny. When I started with Java, one of the first real-world problems I faced, was solved using RMI.

After many years, I faced a weird situation where requests were not passing through properly and hence, security assertions were failing.I solved it by ditching the frameworks and making pure HTTP calls[1]. I thought, the wheel has come full circle :-)

[1] Disclaimer: Do not try at home, unless you know very well what you are doing. Especially when it involves security.

I remember reading the white paper back in the 90s and being so excited. It’s been a good run!
I was working in C++ when Java came out, and I remember my initial reactions:

1. Nice language, a relief after the complexity of C++, which was a complicated mess even in the early 90s.

2. GC! A great relief.

3. Completely bizarre memory model, due to the inability to physically embed one object inside another.

25 years later:

Language: My view of the language itself is lower than it used to be. This is not due to the current "objects are evil" fad, not due to the preposterous AbstractFactoryManagerFactory abstractions that are sometimes enforced, and not due getters/setters (don't use them if you don't want to, I don't).

No, I think there are two basic problems with the language itself. First, type erasure is just bad. It does simplify a number of things for implementation, but it leads to non-intuitive hacks required to get things right. Second, they got closures all wrong, basically limited to constant values so that the implementation can rely on copying. So many other languages get it right. (Have they fixed this? I haven't been an active Java user for a few years.)

GC: Still nice, but: GC performance is still an issue. This is undeniable -- Oracle is still experimenting with new GCs. Tuning is getting so arcane, that I think I might actually prefer the C model. Valgrind was not available when I was an active C++ developer. It makes C memory debugging so simple, and GC tuning is such a mess, that my preference for GC (at least in Java) has diminished.

If I had to rank memory management models, I think I'd go with 1) C + valgrind, 2) GC, and a very distant 3) Swift-style reference counting.

Memory model: The lack of physically embedded objects is still a miserable choice. I understand why they did it -- it makes object identity much more complicated. But it really does rob Java of some critical tools for improving performance. Project Valhalla (value types) seems to be perpetually several releases in the future.

C still suffers from lack of real Unicode.

One of Java's other big wins was unicode out of the box. Granted it was two-byte unicode, but still... it was aware it was a thing.

I write Groovy with @CompileStatic. I do sigh when I have to "drop back" to Java. Much like Valgrind for C, IDEs helped out with Java's rough edges.

What’s wrong with type erasure? It’s always get brought up, but other than missing overloading (it never occured to me, but it is at least an objective criticism), it is basically what every single language does, other than c#.
Type safety, overloading, doesn’t play well with arrays (T[]), and other baggage related to the lack of value types, (e.g. <Integer> is ok but not <int>).

C++ also does not rely on type erasure.

What’s up with type safety? The only escape hatch is casting (and of course co/contra/invariance, but it is a semantic issue). Overloading may be a legit issue, but I am yet to run into it, you are right about arrays and value types, but they are being worked on and hopefully project valhalla can solve these issues.

C++’s templates have different trade-offs (lack of semantic validation, though perhaps it is solved by concepts and constraints? I haven’t looked into them yet)

I learned a bit Java 1.1 in my young years, but never used it much later. I still think Java Applets, embedded Apps in websites was a great idea and much better than anything we have today. But it never happened, because they did not took security so serious and so it was dangerous and never became a thing, sadly.
Java has amazing longevity. People have been writing articles about its demise, and yet, it is still here.

I have programmed in Java for a long, long time. Getters and setters, Maven and its vagaries, abundant use of patterns - all of these make sure people have strong opinions about it.

If any new person wants to learn Java, my two cents: Master generics and lambda. Do not learn, master them. Learn to write bullet-proof code using those two concepts, including proper exception handling. You will learn about a lot of things in Java, just by mastering those two concepts.