Tales from the jar side: Mockito Answers, Android, Kotlin, and Gradle Oh My, The Notes disaster, A new (part time) job, and Tweets and Toots
What do you call a starving hippopotamus in Budapest? A hungry Hungary hippo. (rimshot)
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of April 9 - 16, 2023. This week I taught week 2 of my Android Developer Bootcamp and my two-day Getting Started with Spring and Spring Boot course on the O’Reilly Learning Platform.
Regular readers of (and listeners to, and now video viewers of) this newsletter are affectionately known as jarheads, and are far more intelligent, sophisticated, and attractive than the average newsletter reader (or listener, or viewer). If you wish to become a jarhead, please subscribe using this button:
As a reminder, when this message is truncated in email, click on the title to open it in a browser tab formatted properly for both the web and mobile.
Mockito Answers
This week’s technical content (feel free to skip if not interested) is about a new video I posted on the Tales from the jar side YouTube channel:
The title is “The Argument is The Answer: Custom answers from Mockito mocks,” and is about how to make the response from a mock depend on its input arguments. That turns out to be a straightforward implementation of the Answer
interface in Mockito, which I demonstrated first as an anonymous inner class, then as a lambda expression, and finally using something I recently stumbled upon: the AdditionalAnswers
class. It turns out AdditionalAnswers
is a utility class with useful factory methods, one of which is returnsFirstArgument
.
After publishing the video, I also took the time to write up a new blog post on Medium covering the details, which will eventually appear as part of the Pragmatic Publishers publication over there.
I have to say that I’m a bit disappointed with the low number of views so far, but it is a very specific problem useful to a small audience. It’s also not going to go out of date any time soon, so hopefully the numbers will grow with time.
All the code, as usual, is in the GitHub repository for the Mockito Made Clear book.
Android and Kotlin and Gradle, Oh My!
Frequent readers of this newsletter know I have a kind of “like/hate” relationship with Android development (it never reaches the level of “love,” and the “hate” side is more of a “sadly shaking my head in disgust,” but I digress). Over the past couple of weeks I’ve been teaching a course on Android development on the O’Reilly Learning Platform, and that meant it was time to update my tools again, including Android Studio.
Making that even more imperative is that this week was also KotlinConf 2023, the first live version since before the pandemic of the biggest Kotlin conference in the world. The conference was held in Amsterdam. I’m trying, rather unsuccessfully I must admit, to limit my travel these days, so since I wasn’t speaking at the conference I decided not to go. I did keep track of developments, however.
The conference demonstrated once again the determination of the Kotlin team to get people to use Kotlin for multi-platform development. Personally, I think that’s a serious mistake. I have nothing against the technology, and I do know a handful of people who have used it successfully, but the history of cross-platform toolkits is riddled with failures. It’s not easy to convince Android people to use Kotlin on iOS, and they’re disappointed when it’s not a one-click code generator, but it’s really tough to convince iOS people to use Kotlin instead of Swift.
As a Kotlin person (see my Kotlin Cookbook book), I occasionally get calls about teaching Kotlin classes, mostly for Android developers but occasionally more generally. Not once has anyone asked about multi-platform development. Maybe that will change in the future, but I’m not optimistic. Personally, I think JetBrains (the company behind Kotlin) would be much better served pushing Kotlin as a good language for Spring development, especially showing how it incorporates coroutines for asynchronous coding, but that always seems to be an afterthought at these conferences. Since Java 21 is going to include virtual threads, the multi-year time advantage Kotlin had over Java is rapidly coming to a close. I honestly see this as a blown opportunity, but we’ll see. I’ve been wrong before, but I think they’ve just about missed their chance to break out of the Android niche.
Coming back to Android, one of the big announcements at KotlinConf was that the next version of Android Studio (code named Giraffe) will generate Gradle build files using the Kotlin DSL rather than the Groovy DSL. That’s been a long time coming, especially given that virtually all Android development is done in Kotlin these days. I can only assume that performance issues in Kotlin have been holding up the move, but I don’t really know.
Whenever I see a move by Gradle to push their Kotlin DSL rather than Groovy, I’m reminded of this scene in The Sting where the con men are discussing their mark, the gangster Doyle Lonnegan:
Eddie Niles: But my guess is he's just trying to build himself a respectable image. He came out of Five Points, but he's been telling everybody he was born in Forest Hills.
Gradle keeps acting like that. The entire project came out of the Groovy programming language ecosystem, but with every change they distance themselves from it. They’d rather people think they came from Java, or even Kotlin, and never acknowledge Groovy. To be frank, I have no idea why. Admittedly, I don’t know Five Points from Forest Hills from Piscataway, NJ, but somebody at Gradle does, and for some strange reason it matters to them. I don’t get it. The Groovy community is still the best developer community I’ve ever encountered, and I’m always honored to be associated with them in any way at all.
(Mostly through my book Making Java Groovy, which in my royalties report for 4th Quarter 2022 earned me $18.62. Not a lot, but hey, the book came out in 2013, which is an eternity ago for software books. Lunch that day was on me, as long as you were okay with a 6" sandwich at Subway and were willing to get your own soda.)
Getting back to the present, this week right after my class on Wednesday night, I got a prompt that Android Studio was ready to update to the just-released Flamingo version.
(In case you hadn’t noticed, recent versions of Android Studio are alphabetical and named after animals. I upgraded from Electric Eel.)
Each upgrade breaks something, but I encountered a surprise right away. Whenever I make a new app in the IDE, I start with an Empty Activity. Here’s the new screen for that in Flamingo:
If you’ve used Android Studio before, you might wonder why the Empty Activity icon looks a bit different. That’s because this isn’t your predecessor’s Empty Activity — it’s now what they used to call an Empty Compose Activity. The previous Empty Activity is actually the icon below that one, called Empty Views Activity. Surprise! In other words, if you don’t actively try to stop it, Android Studio now forces you to use Jetpack Compose.
Jetpack Compose is Google’s alternative GUI toolkit, which creates the user interface using a series of Kotlin functions rather than XML. It was released to great fanfare back in July of 2021, which is a bit over 20 months ago, or just under two years. That’s a long time in this space, where things change all the time.
During the keynote address at KotlinConf (recording available here), Google announced that nearly 23% of the top apps in the Google Play Store use Jetpack Compose. I’m sure that’s a much lower number than Google wanted, and I’m frankly surprised they admitted to it. I mean, it’s been almost two years, and less than a quarter of the top apps use it? That’s not a good sign, given the amount of marketing dollars Google has been pushing at it since long before that 1.0 release date.
I can only assume that somebody at Google decided to force the issue, and now if you’re not careful, you’re using Jetpack Compose in your new app whether you want to or not. Here’s a snippet buried about half-way down in the What’s New in Flamingo page inside Android Studio, which shows up when you first upgrade:
Nice combination of “by default, templates use Compose Material 3” and “We recommend using the Compose Material 3 templates (for example Empty Activity) as the best practice for creating an Android app,” [emphasis added] though they don’t say why that’s a best practice. It just is, so stop resisting the march of progress.
Google does provide a decent tutorial on Android Basics with Jetpack Compose, linked right on the Android home page, which was updated about two weeks ago. Believe it or not, it already contains screenshots and recommendations that are out of date — welcome to life in the Android community.
Look, I have nothing against Jetpack Compose. I’m not overly fond of designing user interfaces in Kotlin code, but using XML was no picnic either. As an instructor, I figured it’s now time to dig into it, especially because I promised the students this week I’d show them a demo. Naturally, I ran into problems immediately:
Every time I create a new project, Gradle inside Android Studio is set up to run on Java 8 for some reason, and the latest Compose compiler requires Java 17 (whoa), even though I don’t think Java 17 has more than 20% market share either. I have to go into the settings and update the Gradle JDK to use my current Java 17 version. I’ve looked for some way to do that for all new projects, but haven’t found anything yet. Please send me a note if you know how to fix that.
Then the IDE tells me I can update to the latest AGP (Android Gradle Plugin), version 8, which I do, but then I get a whole series of “duplicate library” errors, because the project itself assumes Kotlin 1.7 rather than 1.8, and I wind up somehow with both. Incidentally, that’s not supposed to happen with Gradle, but so be it.
I finally figured out how to fix that by going into the root
build.gradle
file and switching theorg.jetbrains.kotlin.android
plugin version to 1.8.20, matching my Kotlin version. That causes a different error, because now thekotlinCompilerExtensionVersion
listed in the app’sbuild.gradle
file has the wrong setting, which I have to change to 1.4.5.
After all that, I have a running application and environment, and can follow some (but not all) the steps, because again some of it is already out of date.
I know, I know. If it was easy, anybody could do it. But I hate to think of the hours I’ve lost to silly issues like this. What makes it all worse are the little videos Google embeds into their tutorials, featuring relentlessly (and I mean relentlessly) cheerful people who are so thrilled that you’re learning from them, but who all have accents so thick that it’s very hard to follow what they’re saying. I’m glad Google is featuring a diverse workforce. I really am. But is it too much to ask that (1) the people on videos speak clear English, and (2) they lay off the caffeine for a while before recording?
Sigh. I’m really trying to avoid curmudgeon mode, but sometimes it’s hard. Now get off my lawn.
The Substack Notes Fiasco
Last week I talked about the chaos that ensued over at Twitter when Substack announced their upcoming Notes product. In case you missed it, this article in the Verge summarized everything nicely (or see the section entitled Elon Throws a Tantrum, Again, in last week’s newsletter).
I honestly didn’t intend to pay much attention to Notes. I already had too many social media feeds to keep up with, and I couldn’t see how this one was going to matter. The whole mess with Man-baby Elon, however, made me pay attention, which is a textbook example of the Streisand Effect:
(from the Wikipedia page linked above) The Streisand effect is the way in which attempts to hide, remove, or censor information can lead to the unintended consequence of increasing awareness of that information.
This week Substack launched Notes, probably earlier than they intended. I posted this:
Apparently I got two likes out of it, but no replies. My only other Note was about the video I published, described at the start of this newsletter.
I was thinking of doing more when disaster struck, best described in this article by Mike Masnick in TechDirt. The title is “Substack CEO Chris Best Doesn’t Realize He’s Just Become The Nazi Bar,” which I should explain.
The Nazi Bar story began as a series of posts on Twitter, which I’m not going to link to because who knows how long they will survive. Instead, here’s an article that summarizes it.
Basically, the story is about a guy who goes into a sketchy bar with a curmudgeonly bartender. Another guy comes in and sits down, and the bartender immediately says no and tells him to leave. He even brings out a rifle and puts it on the counter to make sure.
After he goes, the narrator asks why the bartender did that. He says the guy was wearing Nazi paraphernalia, and you can’t let that stand. They act all nice at first, but then start bringing a friend, and another, and another, and before you know it, the bar is a Nazi Bar. Then it’s too late to kick them out or there will be trouble. The moral of the story is that you can’t give hateful people an inch of space or they’ll take over the whole place.
Masnick’s article talked about how Chris Best, CEO of Twitter, went on a podcast to announce his new Notes product, and this was the result:
Nilay asked about content moderation, and Best dodged the question, as he always does when Substack is involved. As you may or may not be aware, there are a LOT of Substack newsletters produced by, shall we say, morally questionable individuals, and Substack doesn’t care about that at all as long as people are reading and subscribing. Nilay bluntly asked what Best would do if someone posted a Note saying that “all brown people are animals and shouldn’t be allowed in America,” and Best had no answer for that. It was a complete fiasco, because he couldn’t just admit they do not and will not do any content moderation on this platform.
It’s one thing when it’s a newsletter. Part of the reason I’m so open with my thoughts and opinions here is that anyone reading my newsletter is doing so on purpose. While my archive is open, most people who read my newsletter actually subscribe, so they’re willing to be here, at least until they’re not. Sure it’s still public in the sense that I’m not charging anything, but it doesn’t feel as public. You’re only here if you want to be.
Notes is different, however. You don’t just see Notes from people you subscribe to. The feed also has an algorithmic component that includes Notes from people it thinks you might like. It’s entirely possible the algorithm will guess wrong, and you’ll see posts that are potentially downright offensive. What then?
Best has no answer to that, and like most Tech Bros, he thinks “free speech” is great if it earns him clicks, and therefore money.
The bottom line is that I’m going to keep an eye on Notes and see how it plays out. I may post a note from time to time, letting people know when I post a newsletter or a video, and see what happens. If it turns into a Nazi Bar, however, I’m out.
New (Part-Time) Job
Before we get to this week’s Tweets and Toots, I have an announcement. This Fall I’ll be a Visiting Assistant Professor of Computer Science at Trinity College in Hartford, CT. I’m teaching a single course, called Software Design, which is essentially a course in Object-Oriented Programming in Java. I plan to make sure the students learn the functional parts of the language, too, at least as much as I can.
Right now it’s only one class a semester, but it might grow later. I’m thinking it might be a good thing to do as I get closer to retirement. I know at least one jarhead reader who has done that (Hi Bill!). The funny part is that I taught there once before, way back in 1997, when I taught a sophomore Dynamics course for engineering students before I changed careers to IT. I guess I should teach a university course at least once every 25 years, just to stay in practice.
As with most transitions, there’s a story here, but we have some time before it happens and this newsletter is already way too long.
World Championship Update
Last week I talked about the chess World Championship match going on between Ian Nepomniachtchi and Ding Liren in Kazakhstan. So far the scores have gone:
That’s draw, win for Nepo, draw, win for Ding, win for Nepo, win for Ding. Four decisive games out of six, and both the draws were hard fought. It’s a really good, really even match so far. First player to 7 1/2 points wins, and this thing could go the distance.
Tweets and Toots
Spider Dad Joke
Sounds like something Peter Parker would say.
I Can Stop Any Time
Oof, that hit really too close to home.
Coffee, Tea, or …
So true, and about coffee snobs as well. I sometimes admit that when I was younger, I used to brew one pot of coffee on Monday and then each day after that I’d heat up another cup in the microwave. Shudder. Truth is, in the mornings I’d be happy to take my caffeine intravenously if possible.
Nuclear Propulsion Explained
A couple weeks ago in this newsletter I talked about my summer jobs working in a nuclear power plant. I really wish I’d had this figure at the time. It explains so much.
Nice Guys
I’m sure every woman knows nice guys like that.
Now There’s A Thought
What could go wrong?
Far, Far Away
There’s a decent cross-over gag in there somewhere. This isn’t quite it, but maybe it will inspire one of you to find a good one.
Dungeons and Dragons
And, Finally, A Proofreading Gag
Sad but treu.
Have a great week everybody!
The video version of this newsletter will be on the Tales from the jar side YouTube channel tomorrow.
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:
Week 2 of Android Development Bootcamp, on the O’Reilly Learning Platform
Getting Started with Spring and Spring Boot, same
This week:
Reactive Spring and Spring Boot, on the O’Reilly Learning Platform
Week 3 of Android Development Bootcamp, on the O’Reilly Learning Platform
Deep Dive: Spring and Spring Boot, an NFJS Virtual Workshop
Thanks for the shout out.