JavaChannel’s Interesting Links podcast, episode 14

Welcome to the fourteenth ##java podcast. Your hosts, as usual, are Joseph Ottinger, dreamreal on the IRC channel, and Andrew Lombardi from Mystic Coders (kinabalu on the channel), and it’s Wednesday, February 7, 2018.
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-14”.

  1. javan-warty-pig is a fuzzer for Java. Basically, a fuzzer generates lots of potential inputs for a test; for example, if you were going to write a test to parse a number, well, you’d generate inputs like empty text, or “this is a test” or various numbers, and you’d expect that your tests would validate errors or demonstrate compliance to number conversion (this is a way of saying “it would parse the numbers.”) A Fuzzer generates this sort of thing largely randomly, and is a good way of really stressing the inputs for the methods; the fuzzer has no regard for boundary conditions, so it’s usually a good way of making sure you’ve covered cases. The question, therefore, becomes: would you use a fuzzer, or HAVE you used a fuzzer? Do you even see the applicability of such a tool? There’s no doubt that it can be useful, but potential doesn’t mean that the potential will be leveraged.

  2. Simon Levermann, mentioned last week for having released pwhash, wrote up an article for the channel blog detailing its use and reason for existing. Thank you, Simon!

  3. Scala is in a complex fight to overthrow Java, from DZone. Is the author willing to share the drugs they’re on? Scala’s been getting a ton of public notice lately – it’s like the Scala advocates finally figured out that everything Scala brought to the table, Kotlin does better, and with far less toxicity. If kotlin wanted to take aim at Scala, there’d be no contest – Kotlin would win immediately, unless “used in Spark and Kafka” were among the criteria for deciding a winner. It’s a fair criterion, though, honestly; Spark and Kafka are in fairly wide deployment. But Scala is incidental for them, and chances are that their developers would really rather have used something a lot more kind to them, like Kotlin, rather than Scala.

  4. More of the joys of having a super-rapid release cycle in Java: according to a post on the openjdk mailing list, bugs marked as critical are basically being ignored because the java 9 project is being shuttered. It’s apparently on to Java 10. This is going to take some getting used to. It’s good to have the new features, I guess, after wondering for years if Java would get things like lambdas, multiline strings, and so forth, but the rapid abandonment of releases before we even have a chance to see widespread adoption of the runtimes is… strange.

  5. James Ward posted Open Sourcing “Get You a License”, about a tool that allows you to pull up licenses for an entire github organization – and issue pull requests that automatically add a license for the various projects that need one. Brilliant idea. Laziness is the brother of invention, that’s what Uncle Grandpa always said.

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 7

Welcome to the seventh ##java podcast. I’m Joseph Ottinger, dreamreal on the IRC channel, and it’s Monday, 2017 November 6. Today feels slightly less anonymous than yesterday.
This week we have a co-host, Andrew Lombardi – kinabalu on ##java – and we also offer our humblest apologies to Ms. Debbie Gibson.
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. Increment Development posted “Center stage: Best practices for staging environments,” an article by Alice Goldfuss that defends and describes the use of the staging environment. “Staging is where you gain confidence in your systems by consensus,” she writes – pointing out that development and testing are for testing known things (“when I do this, does that happen?”), and staging is for testing those things that you think might happen in production but can’t necessarily anticipate as part of development or explicit testing. The author points out that there’s an ongoing debate about this, with some well-known people saying “just test better!” but I’m on Alice’ side personally – staging is where you validate that all that testing didn’t let something get through before deployment to production.

  2. Chase Roberts has written “How to unit test machine learning code.” It’s an interesting article – in that it focuses on expected results for a long pipeline of operations for stuff that’s really hard to test well. Machine learning libraries tend to be black-box tested – throw an input at it, pray a bit, hope you get the expected output, suffer for a while if you don’t – and he’s trying to show a way to avoid this cycle. Short summary: testing is hard. Long summary: know what your algorithms are doing, and test every step along the way.

  3. One of the changes for Java 9’s release was unlimited strength cryptography. Well, all of you laggards on older JVMs might be getting it as well, assuming you update and/or patch – which might be questionable, depending on how far back in the revision cycle you are. If you’re still running Java 6, chances are you don’t update, ever, and this might be a scary process for you because it’s so rare. Do I sound like I’m filled with scorn? I don’t mean to be – pity, maybe, and confusion, but not scorn. (Seriously, folks: update to 8. Or 9. Something moderately current. The pain is coming; putting it off will only make it hurt worse when you run out of time.)

  4. The first of multiple DZone articles for this edition of the podcast: “Switching Java Versions on MacOS” shows you how to use the java_home command on OSX to switch between your multiple JVM installations on OSX easily. This is apparently not a perfect process according to some on ##java, but it’s always worked for me when I’ve tried it – but that’s a very small sample set, so try it yourself and see. (The context of the failure was apparently Apache Ant, and my “success” was really just kicking the tires of Java 9. I’m not saying that the failure is incorrect or user error, by any means.)

  5. Another DZone article: “The JSON-P API: A JSON Processing Primer” shows you a high level overview of JSON-P, with both an object model and a streaming model. The streaming model is more interesting; the object model is a lot like org.json, which… no. Just no. In the end, though, Jackson is probably still your best bet for JSON processing in Java.

  6. Kafka has gone to version 1.0, according to Apache. Kafka is a distributed streaming platform – one way of thinking of it is that it’s a distributed event log, where you can write events that are processed at very high volume by various clients. Every client can have its own offset into the event log, so there’s a lot of flexibility in how you use it. Like most such types of data stores, it’s not a magic bullet for … anything, really, but leveraged properly it really can provide amazing throughput. Administration is great fun; I think I’d rather chew off my own neck than manage a Kafka cluster, but … again, if you need the features, it’s a great product.

  7. Yet another DZone article: “https://dzone.com/articles/an-introduction-to-http2-support-in-java-9” shows us the new HTTP/2 client that’s being incubated in Java 9 – which means it probably won’t be fully realized until the next release of Java (which is itself the subject of another news item.) There are already HTTP/2 libraries for Java: Jetty, Netty, vert.x, OkHttp, and Firefly (among others, probably) – but this one will be part of the Java runtime itself. It looks pretty similar to some of the others already mentioned, but that’s not a bad thing; idiom is good and there probably are only so many ways you can think of building a request and issuing it.

  8. Our third entry from DZone this week: “Machine Learning Algorithms: Which One to Choose for Your Problem” Tries to provide an overview of some of the core factors involved in choosing a machine learning algorithm: supervised vs. unsupervised (or semi-supervised, or reinforced) models, along with some of the models themselves and their applications. There are some examples of problems and math, but it’s got no code whatsoever (and if it did, would probably use Python) – still, it does a good job of going over some of the models and capabilities.

  9. Oh, this seems relevant: Java 10 is coming! … maybe. In an email to the OpenJDK mailing list, Mark Reinhold has revised the version string for Java again – so we might actually get Java 10 instead of Java 18.3 for the next release. Versions are hard to get right – but I think going to a major release version scheme like this (or, rather, staying with a major version scheme) is a good idea, even if the release frequency is boosted. Of course, I also think a major version every year or two is a good thing, so now I’ll probably be complaining about the frequency, but … first world problems, I guess.

  10. Speaking of Java 10, early access builds are available. I don’t know if they have variable inference – “var“, in other words – because I haven’t even truly migrated to Java 9 yet, so I’m far from being ready to test an early access build of 10! But if that’s your stimulant of choice, the builds are there for OSX, Linux, Windows, and even Solaris on SPARC, since even that guy Mike needs to play with Java 10 every now and then.

  11. The next two entries are from DZone, too; they’re on fire. The first one is “Null Safety: Calling Java From Kotlin,” which shows the use of annotations in Java code such that Kotlin doesn’t have to pretend the Java method call can return null. It still can, of course, but in Kotlin, nullable types look and act differently than non-nullable types, so this annotation (@Nonnull(when = When.ALWAYS), if you’re interested) is really a way to suggest to Kotlin that the result is never expected to be null. Really pretty neat stuff.

  12. Lastly, DZone came through with an article about the human mind, applied to programming: “Transcending the Limitations of the Human Mind.” It’s about cognitive capacity, a subject I’ve written about myself in the past; when I wrote about it, I referred to it as “chunking” (we manage only so many chunks of information at a time) and here, it’s the same concept with different terminology. The author – Robert Brautigam – walks through some of the tricks we developers use to manage incredibly detailed deployments with limited cognitive capacity through decomposition, generalization, abstract concept management; he also discusses ways in which our development processes work against our cognitive capacity (where our processes make a given mechanism more expensive cognitively than it otherwise should be, perhaps.) Good article.

Interesting Links podcast, episode 3

Welcome to the third ##java podcast. I’m your host, dreamreal on the IRC channel, and it’s Monday, 2017 October 9.
As usual, this podcast is built from interesting content submitted to the channel bot, using the ~submit command. If you’re on the channel, it’s very easy to use: ~submit and a URL is all you need, although it’s very helpful if you include a comment about what makes the content interesting. That saves your host – me – a lot of work trying to figure out why something was submitted.

  1. First up, we have “Reverse Engineering an Eclipse Plugin,” a long (but good) post from someone trying to figure out a security issue in the a popular Eclipse plugin – I don’t use it, but he says that apparently the Eclipse Class Decompiler Plugin as deployed on the Eclipse Marketplace has a “phone home” feature that isn’t shown in the github repository for the plugin. The author did some basic security auditing and found that the plugin apparently does something after a number of classes have been decompiled, and that the open source version of the plugin does not show this functionality. Good call by the author; he doesn’t actually reverse engineer the plugin, but actually dives into the security aspects of it, but it’s an excellent walkthrough nonetheless.
  2. Common Excuses Why Developers Don’t Test Their Software, as the title might suggest, walks through some of the reasons software tests don’t get written and run. For the most part, it’s laziness and self-deception; headings include “My code runs perfectly, why do I need to test,” “I don’t know what to test,” Barbie’s favorite excuse of “testing is hard!,” “testing increases development time.” Well worth checking out – and sending to your co-workers.
  3. Zircon is an extensible text UI library that targets multiple platforms and was designed specifically for game developers. It actually looks neat – you could imagine Dwarf Fortress or Nethack‘s user interface with something like this. I still content that while Nethack lacks the twitchy adrenaline rush of first person shooters and other such games with high frame rates, it’s still one of the best – if not THE best – computer game ever written. And yes, I know, I sound old. Now get off my lawn.
  4. Sticking to the user interface theme, Say no to Electron! Using JavaFX to write a fast, responsive desktop application, addressing the growing use of Electron. Electron is a web browser that hosts only your web application, leveraging a common approach these days that uses Java for a backend and renders the front end with HTML and Javascript. Electron isolates your app into its own browser window. While this gets you a lot of capabilities (people are used to how the web renders things, and it’s easier) it mostly reflects a failure on the part of Java to render cleanly and consistently on every platform – you can usually smell a pure Java application by the user interface features and feel it has. So people use other technologies for the user interface, which makes the apps feel more “native,” I guess, even though that’s an abuse of that term. This article actually walks through some of the alternatives to the HTML user interface in Java, and settles on JavaFX for an example. It doesn’t go very deep, but it hits the beginning aspects pretty well.
  5. The Atlantic – a hotbed of coder information, I’m sure we’ll all agree – has “The Coming Software Apocalypse,” an article going into how programmers construct code. There are people out there for whom 4GL is not dead; they want to snap things together to program. It’s not a bad idea, really, and done well it even works – like everything done well. But the problem is that it’s not easy to do well; maybe they have a solution that’ll work this time. The JavaBeans specification was actually meant to enable this sort of thing, even, but nobody uses it that way because it’s hard to do properly, and let’s face it, we as programmers tend to be conservative in our methods; we like writing code, we don’t care for connecting boxes to each other very much.
  6. Announced at JavaOne – or, well, exposed better at JavaOne, more like, was FN, aan equivalent to Amazon’s Lambda functionality. As a really poor summary of both Lambda and FN, what you would do is write a simple function that accepted input – presumably – and wrote output, and you’d connect these functions to build more complex functionality – almost like programming, you might say. It tends to have determinate latency (it’s not fast) and indeterminate scalability (it will scale out) – and with Java 9 potentially being far lighter on resources than prior JVMs thanks to things like JLink, this could be really nice to have on hand.
  7. Lastly, we have Oracle. The United States Government asked for commentary on how to modernize government IT, and Oracle responded – with a long PDF. It’s an interesting paper, for various reasons, but what’s really interesting is how… outdated and self-serving it sounds. It comes off as telling the government “you need people like us and not those silly hippies from Silicon Valley!” even though Oracle is based in Silicon Valley. Basically their paper is a repudiation of modern software practices, even though the older methods of coding are the whole reason the government is asking for how to modernize in the first place. (Techdirt‘s article on the Oracle comment points out a number of failures given us by what Oracle is propositioning.) Actually, the TechDirt article does a good job of decomposing Oracle’s commentary altogether – it’s a worthwhile read, too. Oracle comes across as whining about new-fangled, agile methodologies, saying “That’s now how we made our money back in the day! We earned it like real men, by crushing our competition because we could absorb losses they couldn’t and making sure they were iced out of big contracts. Let’s go back to that, shall we?”

Interesting Links – 17 Oct 2016

  • JEP 295: Ahead-of-Time Compilation offers deployers a chance to compile the base Java modules to native code. This can save time on some optimizations, but it’s understandably limited (and should be).
  • The Halstead Metrics (also known as “Halsted metrics”) discusses code complexity in Java. Worth considering; this particular explanation comes courtesy of JHawk, a commercial code metrics tool, not to be confused with “j-hawk“, an open source testing tool.
  • Experimenting with “mutation testing” and Kotlin is a neat post describing PIT, a testing tool that changes your source code and runs your tests – if your tests don’t fail, your tests are probably bad (or your code’s awful.)

Interesting Links, 1 Mar 2016

Happy March 1, it’s April Fool’s Day! Oh, wait…

  • From ##java itself: Anthaas_> 99.7% of people who say C++ is faster are not capable of using the highly-skilled techniques required to make that true. Now, about how he collected the data to validate that statement…
  • Gradle.org posted “Gradle vs Maven Feature Comparison“, with a description of “At long last, a comprehensive feature comparison of Maven vs Gradle that shows in detail what Build Automation requires in the Age of Continuous Delivery.” Surprisingly – or not – Gradle comes out well ahead, but most of the features sound more useful than they actually are for most users. (Until, that is, you really need that feature.)
  • Maven Testing Module describes using a Maven module solely for holding resources used for testing. It’s a module that’s included in other project modules at test scope; it has the testing frameworks and other dependencies in it, so your other modules will no longer be cluttered by test resources or artifacts. Cool idea. (For example, you can put H2 in your test project, along with some stored procedures and a test schema for it, and import them into your application for validation… just kidding, avoid stored procedures unless they’re used for every last bit of your data manipulation. And don’t do that.)
  • Heinz Kabutz is back, with “Checking HashMaps with MapClashInspector” – which walks through some of the things you should, and could, think about when designing hash codes for your objects. Highly recommended. Precis: “Java 8 HashMap has been optimized to avoid denial of service attacks with many distinct keys containing identical hash codes. Unfortunately performance might degrade if you use your own keys. In this newsletter we show a tool that you can use to inspect your HashMap and view the key distribution within the buckets.”
  • Of course the announcement propagates right after the links get published… but Flyway 4.0 has been released. This is a database migration tool – if your schema changes during development (or for any other reason), tools like Flyway are beyond valuable in terms of keeping your schema versioned. Highly recommended. The main alternative to Flyway is Liquibase – that’s not an endorsement of either project, just a plea to save your devops people by using tools designed to help them, instead of making them issue manual SQL to update a schema.

Interesting Links, 27 Jan 2016

  • Mutation Testing: Watching the Watchmen talks about the need for mutation testing, in addition to addressing the desire for unit testing. His point is: unit testing is good – do it. But it’s often not enough, and he promises to go more into mutation testing as an enhancement in future posts.
  • JOOQ has published If Java Were Designed Today: The Synchronizable Interface, discussing what could have been designed as opposed to what we got with the synchronized keyword – a Synchronizable interface, that could have been used for specific situations a lot like we use Iterable in more recent Java coding.
  • The Double Colon Operator in Java 8 discusses, of all things, the double colon operator in Java 8 (surprise!), which is a shorthand way to refer to a method reference. You find this used very often when working with streams, because the shorthand is so useful.
  • RedPen 1.4 has been released (back in October 2015, but I didn’t know about the project until it showed up on homebrew.) RedPen is a proofreading tool for technical documents, NOT for programming, and as such won’t be very useful for most readers of JavaChannel.org, but it’s still pretty interesting. For some reason, it complained a lot about the content of this post…

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.

A set of testing tools

Petri Kainulainen posted “12 Tools That I Use for Writing Unit and Integration Tests,” which does a pretty good job of describing a set of testing tools and approaches, including solutions in the following categories:

  • Running Tests
  • Mock and Stub frameworks
  • Writing Assertions
  • Testing Data Access
  • Testing Spring

It’s not comprehensive (nor does it claim to be), with no mention of things like TestNG, Arquillian, Liquibase or Flyway, or testing CDI in general (see Arquillian), but that doesn’t mean it’s not a good start on an interesting idea. What tools would you suggest for testing?

Junit 4 examples

There seems to be some repeated questions about using JUnit. So I made a short example using JUnit 4 with ant.
First here is the directory structure of my files.

build
build/build.sh
build/build.xml
lib
lib/hamcrest-core-1.3.jar
lib/junit-4.11.jar
src
src/org
src/org/javachannel
src/org/javachannel/SimulatedSpring.java
test
test/org
test/org/javachannel
test/org/javachannel/SimulatedSpringTest.java

The class I want to test is a simulation of a mass on a spring:

package org.javachannel;
public class SimulatedSpring{
  public double velocity = 0;
  public double position = 0;
  public double time = 0;
  private double kom;
  private double bom;
  private double A,B,omega;
  public SimulatedSpring(double mass, double friction, double xnot){
    kom = 1/mass;
    bom = friction/mass;
    position = xnot;
    omega = Math.sqrt(kom - bom*bom*3.0/4.0);
    B = xnot;
    A = 0.5*bom/omega*xnot;
  }
  public void update(double dt){
    // ma = -kx - bv
    double a = -position*kom - bom*velocity;
    // v_n+1 = v_n + a
    velocity = velocity + a*dt;
    position = position + velocity*dt;
    time+=dt;
}
  public double exactPosition(){
    return Math.exp(-0.5*bom*time)*(A*Math.sin(omega*time) + B*Math.cos(omega*time));
  }
  public double exactVelocity(){
    return -Math.exp(-0.5*bom*time)*(0.5*bom*A+omega*B)*Math.sin(omega*time);
  }
  public static void main(String[] args){
    SimulatedSpring spring = new SimulatedSpring(1, 0.1, 1);
    SimulatedSpring s2 = new SimulatedSpring(1, 0.1, 1);
    double dt =0.5;
    double time = 0;
    int sub_divisions = 32;
    for(int j = 0; j<100; j++){
      System.out.printf("%f\t%f\t%f\t%f\t%f\t%f\t%f",
        time, spring.position, s2.position, spring.exactPosition(),
        spring.velocity, s2.velocity, spring.exactVelocity()
      );
      spring.update(dt);
      for(int i = 0; i<sub_divisions; i++){
        s2.update(dt/sub_divisions);
      }
      time+=dt;
    }
  }
}

The class contains an update method that updates the spring and the exact solutions. The test is to show that the update method improves when a smaller timestep is used.

package org.javachannel;
import org.junit.Test;
import org.junit.Assert;
public class SimulatedSpringTest{
  @Test
  public void updateTest(){
    SimulatedSpring s1 = new SimulatedSpring(1, 1, 1);
    SimulatedSpring s2 = new SimulatedSpring(1,1,1);
    double dt = 0.5;
    int sub = 2;
    double delta_s1 = 0;
    double delta_s2 = 0;
    for(int j = 0; j<10; j++){
      s1.update(dt);
      for(int i=0; i<sub; i++){
        s2.update(dt/sub);
      }
      delta_s1 += Math.abs(s1.position - s1.exactPosition()) + Math.abs(s1.velocity - s1.exactVelocity());
      delta_s2 += Math.abs(s2.position - s2.exactPosition()) + Math.abs(s2.velocity - s2.exactVelocity());
    }
    Assert.assertTrue(delta_s2<delta_s1 || (delta_s2==0 && delta_s1==0));
  }
}

I have two ways to build and test these classes, the first method is using just a bash script:

#!/bin/bash
if [ ! -d "../out" ]; then
mkdir ../out
fi
if [ ! -d "../out/classes" ]; then
mkdir ../out/classes
fi
if [ ! -d "../out/tests" ]; then
mkdir ../out/tests
fi
CLASSPATH="-cp ../out/classes:../out/tests:../lib/hamcrest-core-1.3.jar:../lib/junit-4.11.jar"
javac -sourcepath ../src -d ../out/classes ../src/org/javachannel/SimulatedSpring.java
javac -sourcepath ../test  $CLASSPATH -d ../out/tests ../test/org/javachannel/SimulatedSpringTest.java
java $CLASSPATH org.junit.runner.JUnitCore org.javachannel.SimulatedSpringTest

The second way consists of using an ant build.xml file.

<project>
  <property name="lib.dir"     value="../lib"/>
  <property name="src.dir" value="../src"/>
  <property name="test.dir" value="../test"/>
  <property name="out.dir" value="../out"/>
  <property name="class.dir" value="classes"/>
  <target name="clean">
    <delete dir="${out.dir}"/>
  </target>
  <target name="compile">
    <mkdir dir="${out.dir}/${class.dir}"/>
    <javac srcdir="${src.dir}" destdir="${out.dir}/${class.dir}"/>
 </target>
 <target name="compile.tests" depends="compile">
    <mkdir dir="${out.dir}/${test.dir}"/>
    <javac srcdir="${test.dir}" destdir="${out.dir}/${test.dir}">
      <classpath>
        <pathelement path="${out.dir}/${class.dir}"/>
      </classpath>
    </javac>
    <junit>
      <classpath>
        <pathelement path="${out.dir}/${class.dir}"/>
        <pathelement path="${out.dir}/${test.dir}"/>
      </classpath>
      <test name="org.javachannel.SimulatedSpringTest"/>
    </junit>
  </target>
</project>

Turns out my version of ant comes with junit 4 and I did not have to use the jar files I included in libs.
To use the build script navigate to the build folder and run (you would have to make it executable):

./build.sh

To use the ant build.xml navigate to the build folder and run:

ant compile.tests

Voila, maybe this could be improved by having a maven example. Also, when the test passes nothing is displayed.