JavaChannel’s Interesting Links podcast, episode 13

Welcome to the thirteenth ##java podcast. It’s Tuesday, January 30, 2018. Your hosts are Joseph Ottinger (dreamreal on IRC) and Andrew Lombardi (kinabalu on IRC) from Mystic Coders. We have a guest this podcast: Cedric Beust, who’s always been very active in the Java ecosystem, being a factor in Android and author of TestNG as well as JCommander and other tools – and it’s fair to say that if you’ve used modern technology, Cedric’s actually had something to do with it. Really.
As always, this podcast is basically interesting content pulled from various sources, and funneled through the ##java IRC channel on freenode. You can find the show notes at the channel’s website, at javachannel.org; you can find all of the podcasts using the tag (or even “category”) “podcast”, and each podcast is tagged with its own identifier, too, so you can find this one by searching for the tag “podcast-13”.
A topic of discussion from ##java last week centers on code coverage: what numbers are “good”? What numbers can be expected? What’s a good metric to consider? Joseph likes (apparently) absurdly high numbers, like 90% or higher; Cedric recommends 50% code coverage as a good baseline; Andrew targets 70%. Expect a poll in the channel on this! It’s a really good discussion, but it’s not really going to be summarized here; listen to the podcast!

  1. Grizzly – an HTTP server library based on NIO – has been donated to EE4J. That’s not particularly interesting in and of itself, but there’s a question of whether all the projects being donated to EE4J imply an abandonment of Java EE as a container stack. It may not be; after all, EE4J is an umbrella just like Java EE itself is, so this may be very much what we should expect – which makes pointing it out as news rather odd. (The original item was from Reddit.)

  2. Pivotal gave us a really interesting article, called “Understanding When to use RabbitMQ or Apache Kafka.” Kafka and RabbitMQ are both sort of message-oriented, but there’s a lot of confusion about when you’d use one against the other; this article discusses both RabbitMQ’s and Kafka’s strengths and weaknesses. It would have been nicer to talk about AMQP as opposed to RabbitMQ, but the article works nonetheless. Kafka is a high-performance message streaming library; it’s not transactional in the traditional sense; it’s incredibly fast. AMQP is slower (but still really fast, make no mistake) and provides traditional pub/sub and point to point messaging models. The main point of the article, though, is that if you need something other than a traditional model, Kafka is there… but it’s going to involve some effort.

  3. Gradle 4.5 has been released. It’s supposedly faster than it was, and has improvements for C/C++ programmers. It also has better documentation among other changes; Gradle’s good, and this release is important, but it’s not earth-shattering. This discussion veered off quickly and sharply to Cedric’s homegrown build tool, kobalt – and mentioned Eclipse’ Aether library, since migrated to Apache under the maven-resolver project.

  4. More Java 9 shenanigans: Java EE modules – including CORBA, specifically – aren’t part of the unnamed module in Java 9. This comes to us courtesy of InfoQ, which pointed out CORBA specifically – CORBA being harder to reach isn’t really a big deal, I’d think, because nobody’s intentionally dealt with it who hasn’t absolutely had to. And it’s not really a Java EE module, really, so pointing out the removal along with Java EE is accurate but misleading. What does this mean? Well, if you’re using one of the nine modules removed, you’re likely to have to include flags at compilation and runtime to make these modules visible for your app. (See http://openjdk.java.net/jeps/320 for the actual Java Enhancement Proposal.)

  5. There’s a Java Enhancement Proposal for multiline strings. It’s in draft, but has Brian Goetz’ support; this is one of those features that Java doesn’t have that’s left people wondering why for a long time, I think – every other JVM language seems to include it. This doesn’t come up very often – if it was actually all that critical it would have been done a long time ago – but it’ll be nice to see it when (and if) it does make it into Java. It’s done with backticks; it does not use interpolation. Interesting, though.

  6. Baeldung has an article called “The Trie Data Structure in Java,” which, well, presents a Trie. It’s a good article, and explains the data structure really well – but doesn’t explain why you’d use a Trie as opposed to some other similar data structures. Tries represent a tradeoff between data size and speed; Tries tend to be incredibly fast while being more memory-hungry than some of their counterparts. Incidentally: there’s a question of pronunciation! “Trie” is typically pronounced the same was as “tree” is – while Joe pronounces it like “try” and struggled mightily to concede to peer pressure and say “tree.” Naturally, he was inconsistent about it; early pronunciation was in fact like “try” but, as stated, convention says “tree.” And it is a tree structure…

  7. Simon Levermann, sonOfRa on the channel, published a reference to his new pwhash project, a result of a series of discussions that seem to have gone on for a few weeks on the channel. It’s a password hashing library; it provides a unified interface to a set of hashing algorithms, like argon2 and bcrypt.

Javachannel’s interesting links podcast, episode 6

Welcome to the sixth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 30. Scary! Tomorrow’s Halloween.
This podcast covers news and interesting things from the ##java IRC channel on Freenode; if you see something interesting that’s related to Java, feel free to submit it to the channel bot, with ~submit and a URL to the interesting thing, or you can also write an article for the channel blog as well; I’m pretty sure that if it’s interesting enough to write about and post on the channel blog, it’s interesting enough to include in the podcast. (And guess what? That happened this week. See entry #4!)

  1. First up we have two articles about NoSQL from Matt Raible and Okta.com – “NoSQL Options for Java Developers” and “NoSQL Options for Java Developers, Part II.” They were published almost a month apart. In Part I, Matt mostly focuses on a very general overview of the NoSQL landscape and how he chose what NoSQL products to focus on – which ended up being MongoDB, Redis, Cassandra, Neo4J, and Postgres JSON. In Part II he encourages more of a discussion from some NoSQL luminaries about those five. They’re sharing stories and anecdotes about the databases, and it’s interesting reading, even if a little light on content – but they do have some interesting quips to throw out. One in particular stood out to me: you really should justify using something other than Postgres these days, and while I’m a big proponent of NoSQL, I totally agree. They also point out that some people see NoSQL as a magic bandaid for performance, and that’s simply not the case, at all.
  2. Up next we have “A Gentle Introduction to the Bag-of-Words Model.” The Bag-of-Words is a very common way to help trim down inputs for automated learning, or artificial intelligence; one of the things about AI is that it’s painfully easy to overwhelm systems with irrelevant input. This article introduces one of the most common ways to trim input, by providing a focus on words used most commonly in a bit of text – a corpus – or maybe the least common words in that corpus, too, really. (Which set of words you choose depends somewhat on what you’re trying to do.) Interesting article, fairly well done, I thought. Not heavy on code – in fact, painfully light on code – but bag-of-words is actually really easy to write, so that’s not a big deal.
  3. Java 9 is all the rage these days, even though I don’t know anyone who’s actually deploying it yet. Our next article is “Making JSR 305 Work On Java 9,” which focuses on using the annotations for software defect detection – JSR 305 – along with annotations from javax.annotation, which apparently doesn’t work very well in Java 9, due to the packages being split across multiple jars. Part of the problem is the implementation of the JSR 305 annotations themselves; it’s not really been a problem in the non-modular world, but Java 9 is more strict (and should be) about how modules are implemented. The article shows some workarounds and actually does enable the use of the various annotations (and has some warnings along the way) but I think the greater takeaway is that Java 9 is a sea change for Java. It’s probably one that was necessary – sure, we had OSGi and Java EE to help modularize the JVM, but there were and are crucial limits to those approaches that Java 9 is actually trying to address – but even though it’s been necessary there’s still a lot of pain and technology transfer involved.
  4. We also have some content from ##java denizen yawkat: “How (not) to extend standard collection classes.” It came from a discussion on ##java about someone needing a bounded PriorityQueue. I was being really pragmatic and short-sighted, and suggested just overriding the add() to enforce a limit, but the truth is, that is short-sighted – and yawkat wrote this article discussing why and how to actually extend such classes properly. Very well done, and it’s much appreciated.
  5. Another note about future releases of Java – I was going to say “Java 9” but apparently that numbering system is endangered. There’s a JSR – JSR 383 – for Java 18.3, the release scheduled for March 2018. The main difference I see is in local variable type inference, JEP 286. Type inference is cool – Scala and Kotlin have it and rely on it – and it’s great that Java will get it soon too, but the “Java 18.3” name is going to take some getting used to. I still don’t like it. Maybe this is part of their Halloween pranking: “Boo! It’s Java 18.3!” to which my response is, well, “booooo.”
  6. WildFly 11 Final is available. There are lots of improvements here – not many of them are earth-shattering, I think (and I’m waiting for them to go to WildFly Orange or WildFly Jet Fuel, following Oracle’s ridiculous naming practices – okay, I’ll shut up about how I don’t like “18.3” from here on out.) Anyway, WildFly is the fully open source version of JBossAS; it really is a great product. I prefer it to all of the other Java EE containers these days, even though I usually work on distributed services and not monolithic servers any more. I use a lot of the Java EE APIs without using an actual traditional Java EE container, and that’s the current trend I’m seeing – but I’m pretty sure that my data set is pretty constrained. Congratulations on the release, WildFly people.
  7. InfoQ comes in with the JUnit 5 release announcement. JUnit5 changes some annotations and introduces lambdas into the testing mechanism. It also changes the runner mechanism. It requires Java 8, but that’s okay; everyone should be on Java 8 by now anyway. I really like that JUnit is moving forward; I’m mainly a TestNG user, but TestNG has been pushing JUnit to add features, and I imagine that JUnit will likewise push TestNG to add features. Everyone wins.
  8. Up next we have “Project Loom: Fibers and Continuations for the Java Virtual Machine.” This feels really familiar, actually – there used to be a Continuations feature as part of RIFE, and that was around years ago. But here we have an official continuations and fibers suggestion; fibers are lightweight threads, and continuations allow scheduling of tasks on those lightweight threads. I’m not doing it justice here, but it looks great; it’s a long article, worth the read, notable more for its existence than its actual technical content at this point (but the technical content is a good read. Many other platforms have features like this, so it’s good that Java might get them.)
  9. The Gradle project has published “The State of Gradle Java 9 Support,” an article going over the increasingly popular build tool’s support for and integration with Java 9. Multi-release jars still rely on an external plugin, but the module system is supported by Gradle’s dependency resolution, from the looks of it. This is an excellent practice to have, on Gradle’s part – let people know what is supported, how it works, how to use it, and set the expectation that changes will be discussed and documented. It’s almost like open source; open discussion and knowledge transfer.
  10. Lastly, there’s a call for votes on the OpenJDK mailing lists for a new garbage collector, ZGC. It’s currently a skunkworks project of sorts for Oracle, and is aimed at providing low latency for multi-terabyte heaps, a phrase that gives me the willies. I’ve worked with large heaps before – but mainly through things like Azul’s Zing platform. It’s really neat that the Java ecosystem keeps changing like this, though, in that we gain new feature sets all the time and Java just gets better and better. Now if we could only maintain sane version naming and remember to work together…

Interesting Links – 22/May/2017

  • Github gets an App Store.
  • Jenetics is an advanced Genetic Algorithm, respectively an Evolutionary Algorithm, library written in modern day Java.
  • Need to run things before or after your unit test executes? Don’t forget the lifecycle annotations, for TestNG and JUnit.

Expected Exceptions from JUnit

Use JUnit’s expected exceptions sparingly, from the JOOQ blog, says not to use JUnit‘s “expected exceptions” feature. (Or, more accurately, to use it “sparingly.”) It’s good advice, but it’s also largely limited to JUnit (with one main exception).
What they’re addressing is the transition from this pattern:

@Test
public void testValueOfIntInvalid() {
  try {
    ubyte((UByte.MIN_VALUE) - 1);
    fail();
  }
  catch (NumberFormatException e) {}
}

To this pattern:

@Test(expected = NumberFormatException.class)
public void testValueOfShortInvalidCase1() {
  ubyte((short) ((UByte.MIN_VALUE) - 1));
}

They have four reasons that this doesn’t actually get you anything:

  • We’re not really gaining anything in terms of number of lines of code
  • We’ll have to refactor it back anyway
  • The single method call is not the unit
  • Annotations are always a bad choice for control flow structuring

Of these, “The single method call is not the unit” is by far the strongest point.

We’re not really gaining anything in terms of number of lines of code

It’s a matter of opinion, but we generally are gaining something in terms of the code. The refactored test has one line of actual code: ubyte((short) ((UByte.MIN_VALUE) - 1));. Everything around it is window dressing. The original test has the try/catch code, which adds a lot of noise – and discards the “error condition,” which is the actual metric for success (it fails the test if there’s no error.)
Is this a big deal? … No, it’s not. But it’s also not a point worth making.

We’ll have to refactor it back anyway

Here’s where JUnit itself messes things up. The authors actually have a really good point, if you’re locked into JUnit:

In the annotation-driven approach, all I can do is test for the exception type. I cannot make any assumptions about the exception message for instance, in case I do want to add further tests, later on. Consider this:

try {
    ubyte((UByte.MIN_VALUE) - 1);
    fail("Reason for failing");
}
catch (NumberFormatException e) {
    assertEquals("some message", e.getMessage());
    assertNull(e.getCause());
    ...
}

Ah, JUnit. JOOQ is making the assertion (see what I did there?) that they can’t examine Reason for failing or some message with the annotation.
They’re right… if you’re locked into JUnit. TestNG can, of course, look at the message and validate it. If the message doesn’t fit the regex, then the test fails, just as expected (and desired).

@Test(expectedExceptions={NumberFormatException.class},
      expectedExceptionsMessageRegExp="Reason for failing")
public void testThings() {
  ...

The single method call is not the unit

Here’s what JOOQ says:

The unit test was called testValueOfIntInvalid(). So, the semantic “unit” being tested is that of the UByte type’s valueOf() behaviour in the event of invalid input in general. Not for a single value, such as UByte.MIN_VALUE - 1.

They’re running yet again into a limitation of JUnit. The actual point they’re making is correct, but TestNG provides a @DataProvider mechanism, where you’d actually give the test a signature of testValueOfIntInvalid(int) and pass in a set of integers. That means you can test a range and corner cases, with a single appropriate test.
People have written a data-provider-like feature for JUnit (see junit-dataprovider) – which only highlights how JUnit is affecting the choices made by the JOOQ team.

Annotations are always a bad choice for control flow structuring

Hard to argue with this one: Java has excellent control flow, even if it’s verbose at times. However, the annotation is direct enough (with TestNG, at least) that you aren’t really violating control flow: you’re saying “this is a test, it has these execution rules, and this is how you measure success.” With JUnit, you don’t have the same control.

JUnit.next

According to JOOQ, the next generation of JUnit (junit-lambda) fixes things a little, by offering a lambda solution to exceptions:

Exception e = expectThrows(NumberFormatException.class, () ->
  ubyte((UByte.MIN_VALUE) - 1));
assertEquals("abc", e.getMessage());

That’s admirable, but they’re still behind TestNG by a few generations – and there’s still no data factory mechanism.

In Conclusion

Their closing statement is actually really good:

Annotations were abused for a lot of logic, mostly in the JavaEE and Spring environments, which were all too eager to move XML configuration back into Java code. This has gone the wrong way, and the example provided here clearly shows that there is almost always a better way to write out control flow logic explicitly both using object orientation or functional programming, than by using annotations.

It’s worth noting that the statement was actually driven by a lack of features in JUnit (when compared to TestNG) but the point remains.