Tales from the jar side: Java 18, the new NFJS season, and funny tweets
Me: Why did you marry me? Wife: You make me laugh. Me: I thought it was because I'm so good in bed. Wife: See? You're hilarious!
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of March 20 - March 27, 2022. This week I taught my Spring Data course and my Functional Programming in Java course on the O’Reilly Learning Platform, and my Gradle Concepts and Practices course as an NFJS Virtual Workshop.
Regular readers of this newsletter are affectionately known as jarheads, and are far more intelligent, sophisticated, and attractive than the average newsletter reader. If you wish to become a jarhead, please subscribe using this button:
Java 18 Released
Since version 9, Java has been on a six-month release schedule for new major versions, with a new one appearing every March and every September. Last week (March 22, to be precise) saw the release of Java 18. This is a major version, but not a Long Term Support version, meaning it has an intended lifespan of only six months. In other words, as far as Oracle is concerned, when Java 19 comes out in September, Java 18 might as well no longer exist.
Most companies aren’t interested in upgrading their Java Virtual Machines every six months, however, so that’s why there are Long Term Support (LTS) versions exist. The idea with LTS versions is that for them, Oracle guarantees bug fixes and security patches for a minimum of three years.
Note that this may be changing. Last year a discussion on the mailing list suggested that they will soon be moving to a two-year cadence for LTS versions. This is because pretty much everybody has been ignoring all but the LTS releases, and the Java team isn’t happy about that. They’re hoping that by moving to every two years, companies will increase their upgrade frequency. The response was positive, but that was mostly from people who would have upgraded anyway. We’ll see if they actually adopt the two-year cycle, and if any companies respond by upgrading. I don’t know if it will happen, but we’ll see.
Bringing this back to Java 18, if you take a look at the OpenJDK site for it, you’ll see that there’s not much to it. Pattern matching for switch is now in its second preview, and I want that one to be finished because it combines nicely with sealed classes and interfaces, but apparently that won’t be a formal release until at least Java 19. I’m glad strings are now following UTF-8 format by default, but that’s more an acknowledgement of reality than a real change. Finalization is now deprecated, but we’ve been warned away from that for years.
I suppose the only changes that may actually affect me are either the code snippets in JavaDoc documentation (though the JavaDocs for Java 18 look the same to me), and maybe the simple web server.
The idea behind the simple web server is that now you can just type jwebserver, and all the files and folders in that directory will then be available for HTTP GET or HEAD requests. It looks like this:
You can change the default port (normally 8000) and the directory to serve files from, but that’s about it. It doesn’t handle https (i.e., no secure sockets) or any other kind of HTTP request (a POST request returns a 405: Not Allowed, for instance), so it really is just a simple file server.
According to the spec, you can create more powerful servers programmatically using the classes in the com.sun.net.httpserver package, but I don’t know that anybody will do that.
Again, not exactly life changing. I also discovered that while IntelliJ IDEA will download it for you, the IDE doesn’t really understand it yet. I expect that will change soon, but I don’t know if that will happen before the NFJS season starts in St. Louis next week.
I did update my Latest Features In Java talk in anticipation, but until IDEA is upgraded I can’t add anything from Java 18 to the code in my Java Latest GitHub repository (again, not that there’s much to add anyway).
I have started using Java 17 as my default Java version, though, and I really do like a lot of the recent additions (records, sealed interfaces, pattern matching, the enhanced switch statement, a few other small changes). We’ll see how that goes in my upcoming classes.
New No Fluff Just Stuff Season
The NFJS conference tour is managed on an annual basis. With some exceptions (like UberConf or some of the other major shows), the speakers are brought in for an annual schedule, and new talks are prepared each year. It’s true that some speakers add new talks halfway through, typically for UberConf, but in general most speakers come up with a few new talks at the beginning of the season and go with those for the rest of the year.
Of course, it’s not like all the speakers become experts in completely new areas every year. That’s hard, and true expertise takes more time and experience than that. But hopefully you can branch out from areas you already know and develop new ideas from there. For me, a natural branch like that has been to go from JUnit testing with version 4 to all the major changes in version 5, which led me to associated libraries like the Hamcrest Matchers or AssertJ or even Mockito (more about that one soon). This year I’m also adding PBT (property-based testing, though I still can’t help seeing that as peanut butter testing) and the testcontainers project.
Sometimes, though, you want to add something completely different. For me, this year I’m adding a talk called Genetic Algorithms for Evolutionary Computing, which is a topic I know something about but am hardly an expert. Back in the 90s I was in an Artificial Intelligence group at my job at the time, and my boss like genetic algorithms, so I got to know the basics.
The basic idea is that you’re trying to optimize some function (meaning you want the maximum or minimum value), and genetic algorithms are a way of finding an optimum without getting stuck on some local minimum. A classic example is the Knapsack Problem:
Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible.
The idea is you have a fixed-size knapsack, and you want to fill it with as many valuable items as possible.
You could in principle just try out all the combinations, but as the number of items gets bigger, the number of combinations goes up exponentially.
Each item has a size and a value. In the 0-1 knapsack problem, you maximize the sum of the values with the constraint that the sum of the weights must stay below a particular value.
You start by encoding the knapsack as a sequence of 1s and 0s, where 1 means include a particular item and 0 means do not. Each item is a gene, and a collection of them is a chromosome. Then you make a population of chromosomes, and then:
Evaluate each item’s fitness
Decide which ones are the best and let them reproduce, creating more items
Throw in a mutation that flips some bits at random. That’s the key to avoiding local minima — the random flip attempts to move far away in the search space to see if you’re missing something
Keep only the ones that satisfy some minimum fitness
Repeat until the total value is stable
A really good summary of how this is done is shown on this Medium post by Vijini Mallawaarachchi. She shows the creation of the initial population, selection by evaluating the fitness function, reproduction by crossover and mutation, and even some code to try it all out.
I decided that rather than write my own engine, I would go for a solid, open source implementation called Jenetics. I still can’t decide if that was a good idea or not. It’s really powerful, and even uses all the latest features in Java 17 (!), but figuring out what all the pieces mean has been a major struggle that I’m still fighting. Sigh.
It includes the Knapsack problem as one of its examples, but I’m still trying to figure out how to decode the output into a list of included items. Hopefully I can figure it all out before I have to head to St. Louis.
I’m scheduled to give a lot of talks at the conference. My other new one is called Property-Based Testing: Concepts and Examples, and for that I’m using the jqwik library. Property-based testing is really interesting, because instead of coming up with individual test cases, you decide on some features that all examples must satisfy, and the framework generates a bunch of test cases for you. A trivial example would be addition, and properties would be “sum of small positive numbers is always positive,” or “adding zero to any number gives back the number”.
The good part is that jqwik will generate a lot of samples, including edge cases you might overlook. Here’s a sample from the manual that illustrates how it catches failures in logic:
The first test fails because the minimum integer in Java is -2,147,483,648 and the maximum is only 2,147,483,647 (one less), so taking the absolute value of the minimum overflows the integer type. Easy to miss.
The second one fails because if one of the two strings is the empty string, the length of the concatenated string is equal to the length of the other string, not greater. The framework catches both of those problems right away.
Anyway, it’s going to be a busy week as I finish updating all my slides for the conference, and figure out how to interpret Jenetics results.
Mockito Book
I haven’t talked about it much, though I’ve alluded to it in these newsletters several times, but I’m working on a short book about creating mocks, stubs, and spies with the Mockito framework. The book will be part of the Pragmatic Answers series, which means it should only be about 50 pages long, and it will only be available as a ebook.
You’d think that would be easy, or, more to the point, I foolishly thought that would be easy, but not so much. There comes a time in every writing project when you can see the destination, but the more you do, the further away it recedes. I’m in that stage now. Every time I think I have a draft ready to go to readers, I realize it needs more work.
This week I also have a goal to get that draft ready before I head for the NFJS conference. We’ll see if that works, too.
On the plus side, I’ve learned a lot about Mockito during the process, and there are parts of the book I’m really happy with. Unfortunately, as I dwell on the rest of it, I start to realize I can’t write at all and have no business converting poor, defenseless phosphors on a screen into meaningless drivel. Somehow I manage to forget that I go through this stage on every single writing project.
It’s easy to forget pain, which I suppose is more of a feature than a bug, or no woman would ever have a second child.
Random Tweets
This is a fun thread, so be sure to click on this one in order to see the rest:
Speaking of cool images, check this out:
As it says, those are shadows. You have to zoom in to see the zebras.
Good idea, but there was no follow up to say whether that worked or not. I hope it did.
Finally, I try to keep politics out of this newsletter, but this was just too clever:
Gives a whole new meaning to parental controls. I love it.
As a reminder, you can see all my upcoming training courses on the O’Reilly Learning Platform here and all the upcoming NFJS Virtual Workshops here.
Last week:
Spring Data Fundamentals, on the O’Reilly Learning Platform
Gradle Concepts and Best Practices, an NFJS Virtual Workshop
Functional Programming in Java, on the O’Reilly Learning Platform
This week:
Deep Dive Into Spring, an NFJS Virtual Workshop
The Gateway Software Symposium, the first live NFJS event of the year, in St. Louis, MO