EasyMock 5.0.0 is out!

This major release announce the move from Cglib to ByteBuddy. Sadly good old Cglib can’t cope with all the tricks needed to workaround JPMS and reflection limitations. It means you will most probably experience some issues until it stabilizes.

The good news are that this version is working up to Java 18.

Known issues:

  • Serialization of a mock is broken (#312)
  • Running in OSGi doesn’t work (#313)

All help is greatly appreciated.

Change log

  • Replace Cglib with Bytebuddy to support Java 9+ (#300)
  • Fix core source-jar, added maven-source-plugin (#283)
  • Upgrade to ASM 9.2 so that easymock can work with JDK18-EA #277 (#278)
  • Upgrade to ASM 9.2 so that easymock can work with JDK18-EA (#277)
  • Does not work with Java 17 (#274)
  • Allow @Mock to get a default name from the variable being mocked (#260)
  • Easymock doesn’t work in Java 11 with –illegal-access=deny (#235)

Objenesis 3.3 is out!

Support of Java 18 confirmed.

Change log for Version 3.3 (2022-08-01)

  • migrate from TravisCI to GitHub Actions (#88)
  • org.objenesis:objenesis-test missing in Maven Central (#85)
  • added instructions for running Android TCK for Windows users (#84)
  • Copyright and Owner is missing in license (#83)
  • add Dependabot (#77)

Traceroute

I’m not the best at diagnosing network issues.

Yes, in 99% of the cases, you think the problem is the network and it’s not. But in rare cases it actually is.

A friend of mine has written an awesome guide to diagnose network issues using traceroute. He also happens to have founded a startup named Okio doing network monitoring.

Read it, I have learned tons of things from it.

Full disclosure: In case of doubt, I have no interest in this company. I do think they have a great product and that the guide is a fabulous piece of work.

Books

We were talking about O’Reilly learning and books this morning. For those who don’t know, I’m giving a Java course on O’Reilly every 2 months.

I thought it will be useful to create my list of books I think everyone should read. I will keep it up to date so bookmark this page.

You can also find it on O’Reilly for the books available there (most of them).

In random order.

Technical

  • Refactoring - Martin Fowler
  • Working Effectively with Legacy Code - Michael Feathers
  • Head First Design Patterns - Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra
  • Effective Java - Joshua Bloch
  • Java Concurrency in Practice - Brian Goetz
  • JUnit in Action - Vincent Massol, Ted Husted (I haven’t read the third edition written by someone else)
  • Core Java - Cay Horstmann
  • Test-Driven Development by Example - Kent Beck
  • Modern JavaScript for the impatient - Cay Horstmann

Methodology

  • Continuous delivery - Jez Humble, David Farley
  • The Goal - Eliyahu M Goldratt, Jeff Cox
  • Accelerate - Nicole Forsgren, Jez Humble, Gene Kim
  • The Phoenix project - Gene Kim, Kevin Behr, George Spafford
  • Code Complete - Steve McConnell
  • Rapid Development - Steve McConnell
  • Clean Code (but don’t believe everything he says) - Robert Martin
  • Mythical Man-Month - Frederick Brooks

Personal growth

  • The Algebra of Happiness - Scott Galloway
  • Start with Why - Simon Sinek
  • Getting things done - David Allen

Market Finance

  • Flash boys - Michael Lewis
  • Options, Futures, and Other Derivatives - John C. Hull
  • Rogue Trader - Nick Leeson

Understand the world

  • Guns, Germs, and Steel - Jared Diamond
  • Collapse - Jared Diamond
  • 1491 - Charles C. Mann

The list is quite incomplete. I will add tons of books that worth your attention, but that’s a good start. If you think watching videos and reading blog posts is enough, sorry you are wrong.

You will learn more with any of these books than by reading months of blog posts.

Changing current directory

Update (2021-04-19): It’s a JDK bug. It was fixed in Java 11. You can’t change user.dir anymore (see this). But the behavior is consistent, user.dir is cached at the beginning.

I was playing with system properties lately. My goal was to change the current directory. The theory would be that the following code should do it.

System.setProperty("user.dir", Paths.get("build").toAbsolutePath().toString());

Surprisingly, it only half works.

If you use the good old File API, everything works well. But it you use the new Path API, it does.

Here is the demonstration.

// Initialize out two file/path
Path path = Paths.get("target");
File file = new File("target");

// Print the absolute path for them, all good so far
System.out.println("file = " + file.getAbsolutePath());
System.out.println("path = " + path.toAbsolutePath());

// Change the current directory to a sub-folder
System.setProperty("user.dir", Paths.get("build").toAbsolutePath().toString());

// Print the absolute path again
System.out.println("file = " + file.getAbsolutePath()); // current dir changed
System.out.println("path = " + path.toAbsolutePath()); // uh-oh!

When using Path, the current directory doesn’t move. Even if you create your Path after setting user.dir is doesn’t move.

It’s frightening because it’s not consistent.

Why do we have this behavior?

Because the java.nio.file.spi.FileSystemProvider implementation, UnixFileSystemProvider in my case, loads and cache the current directory. The same happens on Windows. It’s not a Unix thing.

I must confess that I do not like the lack of consistency. And I’m not sure I like not being able to fool around and change my system properties like I used to.

Objenesis 3.2 is out!

Support of Java 17 confirmed.

Change log for Version 3.3 (2022-08-01)

  • Add Dependencies Manifest Entry (#81)
  • Objenesis can’t be compiled on Android SDK < 26 (#79)
  • PercClassLoader misspelled in pom.xml (#76)

ArchUnit

Let’s talk architecture today.

ArchUnit is a test framework to test an application architecture.

It is an interesting concept that I wanted to try out for a while. So I did a little experiment on a Swing application I had.

It looks like unit tests with a fluent interface. It’s quite nice to use. I used Junit 5.

My two rules were simple:

  • Backend should not use Frontend classes
  • Backend should not use Swing or AWT classes

Using ArchUnit, it looks like this (in Kotlin):

@AnalyzeClasses(packages = ["pro.tremblay.myapp.."])
internal class BackendSegregationTest {

    @ArchTest
    val backend_doesnt_use_frontend = layeredArchitecture()
            .layer("backend").definedBy("pro.tremblay.myapp.backend..")
            .layer("frontend").definedBy("pro.tremblay.myapp.frontend..")
            .layer("app").definedBy("pro.tremblay.myapp")
            .whereLayer("frontend").mayOnlyBeAccessedByLayers("app")

    @ArchTest
    val no_ui_framework_on_backend = noClasses().that().resideInAPackage("pro.tremblay.myapp.backend..")
        .should().accessClassesThat().resideInAnyPackage("javax.swing..", "java.awt..");
}

Two simple rules.

  • One is defining my layers and how they should interact.
  • The other is telling which packages are forbidden.

Sure enough, the test was failing. I did some refactoring to repair everything and ta-da, for ever after, architecture will be enforced.

You might want to try it out on your own project.

I do recommend it.

Mocking Time

In many cases in our code we do something like that:

LocalDate today = LocalDate.now();

The problem is that your tests then needs to work based on the real current date (or time, or zone date time, whatever).

Sometime it’s fine, sometimes the test fails randomly. At end of day, month or year in particular. It also forces you to calculated the expected result instead of using a constant.

In the new Java date/time API, there is a built-in way to set a constant time called a Clock.

So instead of the code above, you do

Clock clock = ;
LocalDate today = LocalDate.now(clock);

Clock is an interface with multiple implementations.

If you want a real clock, you can do this.

Clock clock = Clock.systemDefaultZone();
Clock clock = Clock.systemUTC();
Clock clock = Clock.system(ZoneId.systemDefault());

But it you want a fake clock during your test, you can do this:

Clock clock = Clock.fixed(instant, ZoneOffset.UTC);

Sadly, I must confess, since the clock is using an Instant, it’s a bit more complicated to initialize then I would like. For example, to put it to a specific day, you do that:

LocalDate today = LocalDate.ofYearDay(2019, 200);
Clock clock = Clock.fixed(today.atStartOfDay().toInstant(ZoneOffset.UTC), ZoneOffset.UTC);

There are methods to make the clock tick or move forward. However, it’s an immutable class, so ticking the clock will return a new clock. Nothing prevents you from doing your own MutableClock. Here is an implementation.

public class MutableClock extends Clock {

  private volatile ZonedDateTime today;

  public MutableClock(ZonedDateTime today) {
    this.today = today;
  }

  @Override
  public ZoneId getZone() {
    return today.getZone();
  }

  @Override
  public Clock withZone(ZoneId zone) {
    return new MutableClock(today.withZoneSameInstant(zone));
  }

  @Override
  public Instant instant() {
    return today.toInstant();
  }

  public synchronized void addSeconds(int seconds) {
    today = today.plusSeconds(seconds);
  }
}

I found it a really useful tool to fix existing code. In a class where you want the time to move at your own pace.

  • Add a Clock attribute
  • Add a constructor taking the clock in parameter
  • The existing constructor uses the system clock Clock.systemDefaultZone()
  • Each time a now() (e.g LocalDate.now()) is called, you use now(clock) instead
  • You can now move the time when needed in your test

Happy clock mocking!

Refactoring Challenge

Hello everyone,

This week I have a refactoring challenge to propose. It’s something I did last year but that I should have advertised more.

I’ve coded a little service (ReportingService) that needs some love.

The idea is to make it easily testable and readable. Just open a pull request with your code to show me your ideas.

The code is on Github.

See where you can go!

My solution is in the ‘henri’ branch but please don’t look at it before trying it out.

Please refrain yourself from just show casing new Java features. That’s not what will improve readability, testability and so on.

All interesting ideas will be mentioned in a follow up post.

Have fun!

JPMS impact on accessibility

About a month about, I had a mysterious IllegalAccessException under Java 11.

A framework was trying to perform reflection on a generated proxy (from Proxy.newProxyInstance).

I was surprised because, so far, my understanding was that when I’m not using the module system, all classes are in the unnamed module. When they try to do reflection on something that was set accessible, it should always work although it will give you a warning on the console.

It’s quite a deep feature of JPMS that caused it.

Let’s get started.

When you are not using the Java 9 module system (aka JPMS aka Java Platform Module System aka Jigsaw), it means you are on the classpath like always. When you are on the classpath you are in a special module called “UNNAMED”. This module has special rights. One is that everything is open to it. Open means it can do reflection on anything. By default, you get a warning telling you are a bad citizen, but it works.

There is one pitfall.

If you try to access a class that is in a module and private to the module (not exported), it still fails.

“Why would something be in a module if I don’t use modules?”

I will if it’s a JDK class. Because JDK classes are always in a module. For example, many com.sun classes won’t be accessible.

In this case, you can add an –add-open flag to fix it.

But there is another pitfall.

You can create a module dynamically.

That’s what the Proxy class is doing. When you create a proxy, it creates a dynamic module for it. Even worst, it creates it in a layer above the boot layer.

Because modules are layered. A bit like class loaders. A class loader has a parent class loader and it goes down to the bootstrap class loader (which is stacked over an infinite number of turtles). With modules, you have the boot layer that contains all the modules loaded at startup and then child layers that are dynamically created. OSGi is using that to correctly work in a JPMS world.

Of course, you can dynamically open a module to another. But you can’t list all the modules (because the boot layer doesn’t have access to its children, just like a class loader). And one can be created at any moment to you can’t open everything upfront.

“Why would I want to perform reflection on some random unknown class?”

It is sometimes useful. For example, when trying to get the size (in bytes) of stash of objects. You have know idea what you will encounter but you still want to size them. It’s a genuinely useful thing to do.

The only solution here is to use a self-registering JVM agent that will open any new module to the UNNAMED module. You can use ByteBuddy for that.

In conclusion, let me thank the knowledgeable friends who help me figure this out:

Thank you.