Javachannel's interesting links podcast, episode 5

Welcome to the fifth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 23.
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.

  1. First up, we have a DZone entry; DZone‘s actually really good at picking out content that’s interesting. However, sometimes you have to be fairly selective about what you read, because they end up like a lot of such sites and go for volume and consistency in publishing as opposed to being selective for stuff that’s truly relevant. That’s why you have things like this podcast, of course, because I clearly know what’s interesting and relevant more than they do! Anyhoo, the actual reference is for Eclipse: “Fifteen Productivity Tips for Eclipse Java IDE Users,” and they’re pretty good; none of them are what I would consider the most obvious (which is: “Use IDEA instead”). The truth is, Eclipse is very popular; anything that helps people use their tools more efficiently is a good thing. Some of the tips are fairly obvious (“use the most recent version of Eclipse”) and others are just things that experienced users might know and use already, but that’s the benefit of articles like this: they make sure that everyone has a baseline of competence. Other tips: switch editors with ctrl-tab; group related projects in working sets rather than using multiple workspaces (this is one of Eclipse’ better features, and I’m glad it’s here); download the sources of libraries; conditional breakpoints and watchpoints; leverage code coverage. There are more (nine more, making a total of fifteen, as the article title promises), and none of them are awful.
  2. Next up: Java 8 updates have an end-of-life: September 2018. Along the way, new versions of Java 9 and Java 8 have been released (9.0.1+11 and 8u151/8u152) – which is good, I suppose, although expected with a new major release – but the big news here is that Java 8 is going to see no more public updates after September 2018. Progress marches on, but I have a feeling this is going to be like the Java 7 migration – which is still ongoing. We aren’t seeing as many people saying they’re still on Java 7 – or Java 6 – as we used to, which is anecdotally a good signal that people are moving to Java 8 after all. So who knows? Maybe with such a recent mass migration to Java 8 there will be momentum to allow people to move to Java 9 – especially if they don’t have to use the module system yet – and people will stay more current.
  3. More DZone: they’re on a roll (and sneak preview: they have two more links after this one). The entry this time is “Artificial Intelligence: Machine Learning and Predictive Analytics.” It’s a fairly high-level guide, and being on artificial intelligence, it’s not just Java – and shouldn’t be. It’s a good reference, though. It’s well-done. I would love to see Java be more relevant in AI; it’s certainly relevant, and is a major player in the space, but the truth is that the starting point for AI is in Python, not Java. The same goes for natural language processing; you can find tools in Java, to be sure (Stanford NLP, for example), just like you can find AI resources in Java (WEKA, among others) but they’re typically trailing the cutting edge. Most data scientists would see a preference for Java as a bit of an affectation. (And I say that because I do prefer Java, and the data scientists I know think I’m a loon for that. They’re probably right.)
  4. This is an old link, but it showed up on my feeds recently, so I’m pretending the publication date of May 16, 2017, is badly inaccurate: Java 8u131 – and yes, 131, 151 is the current build – is transparently aware of Docker memory and CPU limits. Why is this important? It’s because older builds were, well, not aware of Docker‘s machine limitations. The idea is that Docker runs a constrained virtual machine; your actual machine might have 16Gb of RAM, but your Docker image might have 2Gb available to it, and only two of your eight cores. But if you ran an older build of Java in that Docker image, it would use the actual physical machine limits to gauge heap allocation limits and CPU core usage – which could obviously cause problems (your 2Gb image would allocate heap as if it were on a 16Gb machine, which would be incorrect). So… I guess, what with this information being fairly stale, it’s good that they fixed this. And if you happen to be running an older Java, update, please. Note that you do actually need to tell the JVM to use group memory for the heap. This is via two command line options: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap.
  5. Another DZone article! This one is “Automata-Based Programming in Spring.” It really serves as a bare introduction for Spring Statemachine, which isn’t quite what the title led me to expect – I was thinking that I was going to get to read about how to apply cellular automata for problem solving, a la Wolfram Alpha, but instead it’s just a library that makes state transitions easy to manage. It’s a Finite State Machine, not Cellular Automata. This is on me for reading it wrongly, by the way; FSMs are automata, but not cellular in nature.
  6. Daniel Dietrich wrote an article called “Opinionated Database Access in Java” – because we all know that database access has no opinion involved at all, ever. In this case, he’s writing a library that provides yet another abstraction: this one leaves modeling to the database; complex queries are moved to the database; access should be simple and obvious. In other words, it’s one of the Java libraries that provides access to the database services, as opposed to backing up Java data structures with a database. It’s not mature yet (and he provides an example of the API using Scala, too, so it never will be mature.) The only thing is: the article doesn’t provide a reference to an actual project, so it’s all vaporware at this point. Plus, as the lively comment flow indicates, it’s another entry in a space that’s very crowded with possible implementations depending on what you want, from ORMs like Hibernate to JDBC layers like MyBatis and jOOQ.
  7. Java’s version numbers are likely to change. Java has generally followed a semantic versioning approach: you have a major version, a minor version, and a build number (sort of). However, there’s a proposal put together by Mark Reinhold (He Who Controlled Java 9’s Release) to go to a date-based release cycle, so the next release won’t be Java 10, but Java 18.3, meaning “released in the third month of 2018.” There are a few problems with this proposal, and I’m hardly alone in seeing them: one is that there’s not a “major release” associated with the build. With Java 8 versus Java 7, there’s a clear delineation of major versions; Java 8 is the one with streams. Java 9, likewise, has Jigsaw. But the next major feature – let’s say “value types” as an example – might be in Java 18.6 as opposed to Java 18.3, so we lose the ability to easily determine feature groups. Plus, Java applications will have a harder time determining the actual baseline versions they require; right now they can parse out the major version and say “Oh, I’m on Java 8 instead of Java 7” but now they’ll have to factor in the actual release year. Maybe it’s me being a curmudgeon, maybe it’s me resenting how Mark handled the Java 9 release, but I think semantic versioning is still better than the year/month release versioning. With Reinhold proposing it, it’s likely to be approved by fiat; I’m sure it’ll grow on me over time, like a fungus, but I still don’t have to like it. Now get off my lawn!
  8. Last week I highlighted Excelsior JET, which allows delivery of native binaries using Java 8 (so far). This week, we see Steve Perkins writing “Using Java 9 Modularization to Ship Zero-Dependency Native Apps“, using Java 17.10… yeah, the date-based versioning isn’t something I like at all yet. Anyway, it’s just a simple “Hello world” example, but it, like others, is a good start; I like seeing articles like this, because this is how we build a repository of knowledge concerning how to use these neat new features Java 9 provides.
  9. And now for the last of our links, this one also from DZone: “OpenLiberty.io: Java EE Microservices Done Right.” OpenLiberty is another microservice framework, like Spring Boot, DropWizard, or Vert.x, this one focusing fairly heavily on canonical Java EE APIs (as opposed to leveraging those APIs where appropriate as Spring Boot or DropWizard do.) It’s billed as a “deep dive into OpenLiberty,” but it’s really not; it’s really a cursory example with a single JAX-RS endpoint (although it does show live redeployment, which is neat.) The actual OpenLiberty sample application isn’t much to speak of; the redeployment is important, but the main thing the article shows is configuration of the OpenLiberty build, which is probably the most important thing it should want to show. It’s interesting; it’d be interesting to try out.

Interesting links podcast, episode 4

Welcome to the fourth ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 October 16.
This podcast covers news and interesting things from the ##java IRC channel; 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.

  1. Worth noting, not because it’s Java-related but because we’re all on the same Internet: there’s a security vulnerability with WPA2, the wireless encryption used by, well, pretty much everyone. Check your routers for security patches; if they’re not available, they should be soon, and if they’re not available soon, consider getting a good router.
  2. Effective Java is one of the recommended books from the channel regulars; it covers a lot of things that affect efficiently written Java. However, Josh Bloch is working on an update for the third edition of Effective Java. It’s available for pre-order. Highly recommended; Josh Bloch is one of the people who really knows Java, to the point where he says he can write code in Java such that he can influence how the JIT works, to make it more efficient than code mere mortals like you or I would write. So when he has a book on writing effective Java, it’s probably pretty authoritative.
  3. Facebook apparently uses their own build system, called “Buck.” It’s supposedly really fast; it apparently supports a lot of languages, which is a good thing; it does not, however, use the same build structure for source that Maven and Gradle use. That’s sort of okay; the Maven convention (which is what Gradle uses) is idiomatic in Java only because Maven itself became idiomatic, but it’s still something to consider if you’re moving to something different. My thought is that Buck might be cool but in a java-centric project, it’s probably not of sufficient interest to really move the needle. I looked; I considered; I moved on, seeing nothing really compelling in the description or tutorial that made me think “Wow!” like I did with, well, both Maven and Gradle, both of which I use regularly.
  4. Excelsior JET – who makes an ahead-of-time compiler for the JVM, so you can deploy your Java applications as native binaries – has an interesting post called “The Folder of God.” No, it’s not a religious post, although religious fervor might be involved if you hate Windows enough. Basically, there’s a way to create a folder in Windows such that Java programs running from that folder will crash, every time. (I don’t know why you’d actually do that in practice.) It’s an actual Java bug, not an Excelsior bug – but Excelsior experiences the bug nonetheless. It’s apparently been addressed in the Java sources, but your JVM might not be updated with the fix. It’s fascinating reading, even if only to make you glad you’re not using Windows.
  5. A report by realm.io suggests that “Java (on Android) is dying. There aren’t simply more Kotlin builders: they’re also switching their apps to Kotlin. In fact, 20% of apps built with Java before Google I/O are now being built in Kotlin. Kotlin may even change how Java is used on the server, too.” As a Kotlin user myself, I can say that the transition to Kotlin in dreamreal-land is progressing rather nicely… but what’s more relevant is that Kotlin on Android is increasing momentum, and that may very well drive server-side development as well, as there’s a strong tendency to be homogenous even if interoperability between languages like Kotlin and Java is quite strong. The channel recently had a discussion about Java’s checked exceptions, a feature Kotlin doesn’t share (because nobody really likes checked exceptions and the JVM itself doesn’t have them – they’re a javac thing, not a JVM thing); checked exceptions are actually a good thing in that they force you to think about your exception handling, but there’s no guarantee you’re going to actually handle your exceptions well, so they end up being an unnecessary burden in many peoples’ minds. Worth thinking about, in any event…
  6. Something that comes up fairly often in the channel is the use of the Oracle JDK vs. OpenJDK, and what the differences are between them. I always said it was in a set of closed-source libraries used in Oracle JDK, such that some features might be present in Oracle’s JVM that OpenJDK did not have. Well, while that was true at one point, it’s like all Internet knowledge: it erodes. The Adopt OpenJDK project has a page on Differences between Adopt OpenJDK binaries and Oracle JDK Binaries that actually walks through the differences, which is a really short list: font rasterizers, color management, and graphics renderers. That doesn’t compare the differences with other implementations of the JVM – Zulu and whatnot – but what it does say is that OpenJDK and Oracle’s JDK are really closely aligned right now, just as designed.
  7. The Jooq blog has an article called Benchmarking JDK String.replace() vs Apache Commons StringUtils.replace(). It walks through an optimization process and measures the effectiveness, offering a ton of apologies for what might appear to be premature optimization along the way; the upshot is that Java 9’s String.replace() works better than it used to, which might affect which implementation to use. (It turns out that Java 9’s version is slower for matches in long strings but faster for matches in short strings, which – in practice – are probably more common.) They ended up staying with Apache’s implementation for now if only because most people are still on Java 8 and thus the performance improvements are worthwhile. It’s a fascinating read.
  8. Wrapping up, we have an article from Baeldung called “Introduction to Caffeine“. Caffeine is a caching library; the article walks through its use, as one might expect. All that’s fine. What the article does not do, though, is differentiate why one might use Caffeine as opposed to one of the other caching libraries out there, like EHCache, or Guava Cache – which inspired Caffeine, actually. Channel inhabitant dudeji – which I don’t know how to pronounce – points out that Caffeine has time-to-live (as most of them do) but also automatic elimination based on unused keys; I can see some use in that, although I’d be concerned that the cache was deciding that a key was unused more aggressively than I’d have liked. I’m sure it’s tunable, though.

Interesting Links, 31 Oct 2016 (and 25 Dec 1038)

  • kumuluzEE is “A lightweight framework for developing microservices using standard Java EE technologies and migrating existing Java EE applications to microservices.” It’s not immediately clear from the web page what makes it ideal for migrating to microservices, but there it is.
  • Don’t Even use COUNT(*) For Primary Key Existence Checks” has some valuable performance advice, and considers multiple DB implementations while offering it.

Now for some Scala stuff:

  • Quo Vadis, Scala?” has some considerations of the value of Scala on the larger JVM ecosystem. Turns out that Scala has more impact than some think it does, and less impact than others think. Go figure. 🙂
  • Sbt makes me want to give up Scala” has some well-considered criticisms of the Simple Build Tool, SBT, Scala’s primary delivery mechanism. Well-written and justified; if a build tool is the primary contact point someone has with a language, and that build tool is slow and uncomfortable to use, well… that impression is going to stick with people. SBT is really powerful… and it sucks. This post walks through a lot of why.
  • From user tetero, apparently inspired by the SBT link, “Scala Collections: Why Not?” is a video presentation by Paul Phillips that feels like it’s a rant about why he’s leaving Scala: it doesn’t do things the way he wants. Sure, what he wants would be good (simplicity, accuracy, honesty, clarity) and it highlights what people see as the worst in Scala: the community’s hardheadedness about how good Scala really is. It turns out to be an anti-Scala rant, in the end, but the truth is that Scala is better than he makes it sound and just as bad as he makes it sound. Use Scala if it works for you, and don’t, if it doesn’t. (The user in question said that this video was part of what led him to Clojure. There’s nothing wrong with Clojure, but like most things, it’s not perfect and Scala’s type system oddities seem like a poor sole motivator.)

What you want to have to develop Java

Recently a user asked what they would need to know to develop a “small web application” using Java, including a database.
This is not a good question, really, but IRC user surial gave a lot of relevant information that’s worth preserving and adding to. This is not what surial said – if you’re interested in the actual content, see the channel logs – but this is a paraphrase that attempts to build on surial’s information.

What you need to develop in Java

Java

If you’re going to develop in Java, you obviously (hopefully) need Java itself. You want the JDK, not the JRE (the JDK includes the JRE.) You can use the official Oracle JDK, OpenJDK (from Red Hat, if only for more than Linux support), or Zulu – and this is not likely to be an exhaustive list by any means.
The Oracle JDK is different from OpenJDK only in some of the libraries included. Notably, the JPEG encoder is closed source, so OpenJDK’s JPEG support is not part of OpenJDK itself. Other builds may not have the same problem.
If in doubt, use Oracle’s JDK. There’s nothing wrong with OpenJDK, but when people mention the JDK, they usually mean the official JDK in terms of features and support.
One word about versions: use Java 8. Older versions have already been end-of-lifed, even though they’re still available through archives.

An Editor

Want to start a war? Make a firm recommendation for a development environment, and insult the other environments. The truth is, Java uses text as source; use what works for you.
Popular choices for development environments are IDEA (with both commercial and free versions, although people think of the commercial versions first), Eclipse (also with commercial and free versions, where people think of the free versions first), and Netbeans (with free versions and probably some commercial versions hanging out somewhere.)
All three are quite capable in their own ways. Eclipse is famous for having a perspectives-driven approach, where IDEA and Netbeans are more traditional. They all have free versions; try them out and see what works for you.
Of course, there’s nothing preventing you from using any other editor, either: Sublime Text, Atom, Brackets, vim, emacs, or anything else that can generate text.

A Build System

Strictly speaking, you don’t have to have a build tool. You could always compile manually, by typing javac, after all, and save yourself some work by maybe using a batch file.
Or, if you’re using a Java IDE like IDEA, Eclipse, or Netbeans, you could always use the IDE to build your project. In practice, your IDE will be compiling your project if only to run local tests and tell you about issues in your code, after all.
However… what you should be using is one of Maven, Gradle, SBT, or Kobalt (probably in order of desirability, and as with the other lists in this article, this is not exhaustive).
These build systems allow you to write a configuration that describes your build in such a way that the build is portable to other systems, including integration servers and, well, other users. If you rely on a batch file, you’re hoping that their filesystem and operating system match yours; if you rely on an IDE, you’re hoping that others use the same tools you do.
They don’t. Even if they do, they don’t.
A build system includes the ability to manage dependencies (the libraries your application might use) and other such things, and will also provide the ability to run tests automatically as part of your build process.
Each build system’s configuration can either be loaded by an IDE, or can export an IDE configuration, so you can use any IDE without worrying about the project.
In real terms: use Maven unless you have some process that you need fine-grained control over; if you do need fine-grained control over your build, use Gradle. If you’re using Scala, use SBT. If you’re interested in a new build tool’s development, try Kobalt. Don’t use Ant, make, or CMake, and for goodness’ sake don’t use javac directly after “Hello, World.” You’re not a barbarian.

Talking to a Database

If you’re working with a relational database (and you probably are, if you’re working with persistent data), you have a few ways to go: SQL (where you use JDBC to talk to the database in its own variant of SQL), object-relational mapping (where you use a library that manages data as if it were represented natively as Java objects), or a bridge between the two, where you sort of get objects but you are still thinking relationally.
Examples of ORM libraries: Hibernate and EclipseLink. You can use the JPA standard with either, although Hibernate has a native API that’s arguably more powerful. (EclipseLink probably does, too, but your author has no experience with EclipseLink’s native API, if it has one.) Note also that object-relational mapping is… imperfect. You’re gaining a lot by using Java’s data structures… and you’re losing some because those structures usually don’t map perfectly to a relational model.
Examples of others: jOOQ (“the easiest way to write SQL in Java,” according to their website), JDBI (“convenient SQL for Java”), and Spring Data (a flexible abstraction in front of nearly any persistence mechanism) – your mileage with each may vary, but they all seem to be pretty highly regarded.

Libraries

The Java ecosystem is one of Java’s greatest strengths. The nice thing about having a build tool is that it’s trivially easy to leverage the Java ecosystem, by simply specifying the “address” of a library, and then having the library and its dependencies included in your build by virtue of your build tool’s dependency management.
So: which libraries do you want to use?
There’s no real answer to that: “the ones you need” are probably the best candidates, and generally experience is how you learn which ones you need. Google searches for “java json parser” will give you workable answers for JSON parsing in Java, although they might not be the best answers – feel free to ask the ##java channel or its bot for suggestions on functionality.
However, here are some common libraries that many projects use without worrying about technical debt:

  • Guava (generalized utility library)
  • Lombok (annotations to reduce boilerplate with no runtime dependencies)
  • TestNG or JUnit (testing frameworks)

Quickstarts

If you need to get your project moving quickly, ##java has at least two quickstart projects ready for use, with a small amount of work.
If you want a Gradle project, see https://bitbucket.org/marshallpierce/java-quickstart.
For a Maven quickstart, see https://github.com/jottinger/starter-archetype.

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.