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.
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.
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.
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
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!
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.
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.
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.
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.
> 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.
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.
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.
> 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.
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.
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.
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.
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.
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#.
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.
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.
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.
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.
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).
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.
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.
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).
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."
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.
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.)
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.
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:
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?
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.
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
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...
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.
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.
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.
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.
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.
"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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
> 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?
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:
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!
>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.
>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!
>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.
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!
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.
I gave a presentation on bytecode and class loaders if you’re interested. The deck is at speaker deck and there’s a link from there to a recording I did for the LJC if you prefer me narrating it:
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?
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.
I interviewed Mike Milinkovic who led that team and who became Eclipse's executive director back in 2013, if you're interested in a trip down memory lane:
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.
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 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.
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>).
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.
268 comments
[ 3.7 ms ] story [ 233 ms ] threadhttps://github.com/gjvc/strongtalk-2020
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 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.
https://www.oracle.com/java/technologies/java-archive-downlo...
Everything I tested works flawlessly.
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.
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.
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!
What good is this when roughly half of the java programs I had to ever use required the official sun / oracle jvm to work
There are ISVs using Java that only certify the Oracle one for support reasons, but this is generally not for technical reasons.
As of Java 11, completely the exact same code as Oracle JDK. The only difference is licensing.
Amazon, SAP, Alibaba, IBM and Microsoft are more than comfortable with it.
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.
I only heard about Python much later.
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.
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.
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.
If I remember correctly the first usable one was actually 1.0.1.
Also remember some bugs as it was possible to combine accessors together something like having public private.
https://github.com/barismeral/Java-JDK-1.0-src
How much time (and money) do they invest? Do you have numbers comparable to java? :)
I hope their generics turn out nice because there are lots of interesting decisions to make in their design.
Let's hope it doesn't end the same way as error did
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
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]:
[1]: http://pizzacompiler.sourceforge.net/index.html[2]: https://www.artima.com/scalazine/articles/origins_of_scala.h...
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.
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 don't know, if today Eclipse fares better, beacuse like many people I switched to IntelliJ never looked back.
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.
Now they’re invading Golang. I’m happy they’re taking their time.
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.
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.
[1]: http://immersivemath.com/ila/index.html
I do not miss that codebase.
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.
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
J# was Java for .NET, a C# sibling.
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.
Happy birthday Duke!
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.
Meet Project Lombok. Problem solved and forgotten.
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.
Whats next? Dependency to check if a value is null?
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.
I do use package private fields liberally, though. Just not non-static public fields.
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.
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).
https://martinfowler.com/bliki/UniformAccessPrinciple.html
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.
- Ctrl + shift + T => search for types
- Ctrl + O => search for methods
- Ctrl + T => switch between classes
- Filters, https://help.eclipse.org/2020-12/index.jsp?topic=%2Forg.ecli...
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.
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.)
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...
#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:
“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:
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.
But for some dumbass reason it's not "the Java way".
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.
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.
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?
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.
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
But nobody actually does it.
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.
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.
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.
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 :-)
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.
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.
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.
It's the standard Java build tool at this point. I don't know of anything better.
I really don't see it anywhere else to make it standard, besides it depends on Maven Central.
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.
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.
"Why are we doing a Factory for Singleton Factory design pattern here?"
"Because this design pattern is made for this scenario"
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.
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.
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.
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.
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.
Java has many warts but the bytecode stability is an admirable achievement.
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/
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.
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.
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.
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.
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.
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!
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.
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.
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
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.
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.
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 ...
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)
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.
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.
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.
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.
https://speakerdeck.com/alblue/bite-sized-bytecode-and-class...
(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. :)
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.
https://en.wikipedia.org/wiki/Visual_Caf%C3%A9
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.
https://www.infoq.com/interviews/Milinkovich-past-present-fu...
These alone would have cut down so many boilerplate codes.
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.
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.
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.
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.
C++ also does not rely on type erasure.
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 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.