Java 1.0 Turns 25
infoq.com
infoq.com
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.
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:
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 discussed them and he sent me this:
Don: Hi Jens! I'm catching up with all the work you've done since the Snap 5 release! You've made excellent progress!
The problems you had and optimizations you made for Chrome sound interesting! Is there a summary or design document or discussion thread about it that I can read to catch up with it?
Watching your Snap!Con20 keynote on Hyperblocks. Your delight in programming is so contagious even with social distancing and teleconferencing!
Jens: Thanks, Don! The architectural changes were kinda profound, and I wasn't too eager about them had it not been for Chrome's suckiness. Now I'm really glad that all the work paid off, and Snap! has become much better, more stable and faster on all browsers, especially also on mobile ones.
I don't really have a document aside from the short "migration guide" in the Github repo, but that doesn't discuss the architecture. That was a discussion between moi, John Maloney and some others.
Don: Was there a Buddha Nature of the changes, or did everything change?
Jens: Not everything changed.
Don: I find architectural evolutionary stuff fascinating, like watching people solve the trolley problem for sport!
Jens: I basically reverted to a Squeak model of display refreshing, instead of pre-rendering and caching every morph in advance. So the changes were mostly "surgical" and only affected parts of the whole thing.
Don: Bert's paper about SqueakJS was a delightful mind-blower! His solution to the GC problem!
Jens: Now that I mention is, I do have some slides that I drew for SAP management in April that talk about architecture - even though they didn't understand any of it. Let me see whether I still have them...
Don: I loved reading the original Self papers back in 91 or so. I was visiting Amsterdam for the first time and had printed them out, and was reading them in a coffeeshop smoking weed. MIND=BLOWN!
Jens: https://drive.google.com/file/d/1QD-tqtTL3ldtmtqmViNm-C7TW0n...
Don: Thank you!
I'd heard so much about Morphic and wanted to know what that was about, and why people liked it so much. Didn't that come from Self?
Jens: Oh, yes the SELF papers were all wonderful, and Bert's / Vanessa's SqueakJS is the most awesome piece of software.
Yep, Morphic came all from SELF, that's right
Of course, I first saw it in Squeak, and hated it at first, haha.
Don: The self papers just kept piling on layer after layer of amazing stuff: clean model. efficient implementation. jit compiler. but actually debuggable, with dynamic deoptimization! And they made it clear in those papers that those ideas could be applied to other languages, not just Self. They meant Smalltalk but didn't realize that Java would be the main beneficiary soon (then JavaScript).
When I was working for Kaleida and evangelizing ScriptX (like CLOS-y object oriented scheme, kinda like dylan, with a multimedia library), the Python people really annoyed me because they were so smug and happy with their language, and I had a kind of envy for them, clinging to my sinking language.
Then I became one of them and it was ok.
I still do Python, but it's not my focus now, and I'd start new stuff in JavaScript now.
Jens: Yeah, it's somewhat ironic that V8 turned out to be the main beneficiary of Lars Bak's work, not a Smalltalk system, isn't it?
Don: Yes, and sadly ironic that David Ungar stayed loyally at Sun while the other guys forked off their own company that got bought by Sun for lots of money, and poor Dave didn't cash in on the reward he deserved.
Well maybe ironic is the wrong word, just too bad Sun didn't treat Dave better, for all his work. But leaving a company, doing something cool, then selling it back to the company is a great "we told you so" move!
All those ideas from Self were portable, and migrated out of Self to Java then to JavaScript, and lots of other places too, like LuaJIT! But they called in in the original papers, it was not language specific.
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. :)
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.
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.
I remember being distinctly annoyed that the Java 1.1 broke the model introduced in Java 1.0, in which a JVM which had no Windows showing or Threads running would terminate automatically. When Java 1.1 was created, the event dispatcher thread was created (incorrectly, in my opinion) as a non-daemon thread, which meant as soon as you loaded the toolkit the JVM would never close until you hit System.exit. Here's the bug I proposed a fix with in November 1998:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4030718
The shutdown hook never got fixed; these days there's convenience methods to add a shutdown hook to the (J)Frame so that on close it would call System.exit for you.
I've written a bit more about my history here if you're interested:
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)
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.
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).
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:
obj.instance_eval{ @foo }
“Objection! #instance_eval can be overridden! DRb proxy-objects do it!”Well, okay, let’s get creative, and start breaking through the seemingly pure-OOP semantics of Ruby, revealing the more functional-language underpinnings:
inst_eval_fn = Object.instance_method(:instance_eval)
inst_eval_fn.bind(obj).call{ @foo }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?
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.
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.
public record SomeViewModel(String name, int age) { }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 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.
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.
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.
I do not miss that codebase.
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.
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.
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.
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]
True. Also, Odersky and Wadler's Pizza language [1] was available as early as 1996 and the language designers at Sun were well aware of it and keen on adding it to Java. Odersky mentions this here[2]:
Bill Venners: How did Scala come about? What is its history?
Martin Odersky: Towards the end of my stay in Zurich, around 1988/89,
I became very fond of functional programming. So I stayed in research
and eventually became a university professor in Karlsruhe, Germany.
I initially worked on the more theoretical side of programming, on
things like call-by-need lambda calculus. That work was done together
with Phil Wadler, who at the time was at the University of Glasgow.
One day, Phil told me that a wired-in assistant in his group had heard
that there was a new language coming out, still in alpha stage, called
Java. This assistant told Phil: "Look at this Java thing. It's portable.
It has bytecode. It runs on the web. It has garbage collection. This
thing is going to bury you. What are you going to do about it?" Phil
said, well, maybe he's got a point there.
The answer was that Phil Wadler and I decided take some of the ideas from
functional programming and move them into the Java space. That effort became
a language called Pizza, which had three features from functional programming:
generics, higher-order functions, and pattern matching. Pizza's initial
distribution was in 1996, a year after Java came out. It was moderately
successful in that it showed that one could implement functional language
features on the JVM platform.
Then we got in contact with Gilad Bracha and David Stoutamire from the Sun
core developer team. They said, "We're really interested in the generics stuff
you've been doing; let's do a new project that does just that." And that became
GJ (Generic Java). So we developed GJ in 1997/98, and six years later it became
the generics in Java 5, with some additions that we didn't do at the time. In
particular, the wildcards in Java generics were developed later independently
by Gilad Bracha and people at Aarhus university.
Although our generics extensions were put on hold for six years, Sun developed a
much keener interest in the compiler I had written for GJ. It proved to be more
stable and maintainable than their first Java compiler. So they decided to make
the GJ compiler the standard javac compiler from their 1.3 release on, which came
out in 2000.
[1]: http://pizzacompiler.sourceforge.net/index.html[2]: https://www.artima.com/scalazine/articles/origins_of_scala.h...
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 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.
Is there a way to drive performance to the JVM, or shed light to what might be the cause? Thoughts to why a much older pc with less memory, worst memory card, seems to perform flawlessly.
Here to look for any other solutions I could try. I love to be working on the mac, but like to have the performance I find when running the java app (with ui elements) on a pc. Something that comes to mind at the moment is maybe trying here a remote desktop to a windows machine to see if performance is better than running natively on the mac.
Sorry in advanced for the slight vagueness on the specific app running and lack of specs provided.
Memory: As far as I see, there is a built-in profiler within the app showing the memory usage. It has a high limit to 1gb and I see it rise quickly to about third of the way and repeated (quickly, about every 2 seconds) garbage collect down to 200mb. So it appears memory consumed very fast and than it garbage collects. Then repeats.
Right-click the binary and select “Show package contents” to peek inside. Chances are you’ll find a code signature, an icon, various support files, one or more jars and an executable that launches the main jar.
Figuring out what the main jar is typically is easy. You may have to experiment to find out what the current directory has to be when launching it.
Thought I share where I am at:
I think I'm in the right direction now. There are log files associated with previous crashes due to out of mem errors. The app here also includes a java vm_param file so I can maybe experiment with a few settings here and hoping here by decreasing the GC recycling time maybe things improve. Also, I will be looking whether the app may have somehow embedded a jvm (possible?) rather than using the one I have provided.
Happy birthday Duke!
I immediately concluded that no-one will ever use it and that's it's just a fad. (Just like I predicted there's no way to make money from a search engine :) ).
Things changed a lot with Java 1.3, which, for the first time, came with JIT compiler.
And with modern escape analysis, lock elision, new GCs, etc, I no longer (OK very rarely) look to C/C++ for performance anymore.
I still miss real pointers (better unsafe, et al), native types collections (there are external ones) and more control over what gets put on the stack vs. on the heap (escape analysis is not good enough, yet.) sometimes.
(Edit) Oh, and discovering that AWT was useless for just about anything.
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.
- simple
- object-oriented
- distributed
- robust
- secure
- architecture-neutral
- portable
- interpreted
- high performance
- multithreaded
- dynamic
Quite a list! See the original paper here:
https://tech-insider.org/java/research/acrobat/9503.pdf
I was one of the first students to do a project in Java (which I suggested myself).
Yes, at that time, Java was cool technology.
https://www.oracle.com/java/technologies/java-archive-downlo...
Everything I tested works flawlessly.
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.
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.
The Self language had all the tech, they had a full compiler team, a high performance implementation and could reasonably do everything Java could. So much that the same people ow did Self eventually end up working on the JVM as well.
And Java Script, end-up up itself being basically like Self in many ways.
Maybe the Self team focused to much on research and the Java team focused more on getting it out there.
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.