EasyMock 5.2.0 is out!

Fixes problems with Java 17 for mocks in different modules. Also fixes the source jar that was empty.

Change log

  • EasyMock HEAD build fails on JDK21 (#442)
  • Error running tests after Java upgrade to IBM Semeru jdk-17.0.6+10 (from jdk1.8.0_311.jdk) (#393)
  • LinkageError when mocking certain classes (#373)
  • pom file error: the source.jar is not deployed correctly to maven (#369)
  • Can’t mock methods called from the constructor of a partial mock (#358)
  • Partial mocking Swing components in EasyMock 5.1.0 (#356)
  • java.lang.NoSuchMethodException on mock(Timestamp.class) (#256)
  • Bump com.puppycrawl.tools:checkstyle from 10.12.2 to 10.12.3 (#461)
  • Bump net.bytebuddy:byte-buddy from 1.14.6 to 1.14.7 (#460)
  • Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.3.0 to 3.4.0 (#458)
  • Bump net.bytebuddy:byte-buddy from 1.14.5 to 1.14.6 (#457)
  • Bump commonmarker from 0.23.9 to 0.23.10 in /website (#454)
  • Bump jmh.version from 1.36 to 1.37 (#452)
  • Bump com.puppycrawl.tools:checkstyle from 10.12.1 to 10.12.2 (#450)
  • Bump junit.jupiter.version from 5.9.3 to 5.10.0 (#449)
  • Bump depends-maven-plugin from 1.4.0 to 1.5.0 (#447)
  • Bump checkstyle from 10.12.0 to 10.12.1 (#446)
  • Bump maven-clean-plugin from 3.2.0 to 3.3.1 (#445)
  • Bump spotbugs-maven-plugin from 4.7.3.4 to 4.7.3.5 (#444)
  • Bump maven-shade-plugin from 3.4.1 to 3.5.0 (#443)
  • Bump surefire-testng from 3.1.0 to 3.1.2 (#440)
  • Bump versions-maven-plugin from 2.15.0 to 2.16.0 (#439)
  • Bump maven-project-info-reports-plugin from 3.4.4 to 3.4.5 (#438)
  • Bump maven-surefire-plugin from 3.1.0 to 3.1.2 (#437)
  • Bump surefire-junit-platform from 3.1.0 to 3.1.2 (#436)
  • Bump byte-buddy from 1.14.4 to 1.14.5 (#435)
  • Bump maven-project-info-reports-plugin from 3.4.3 to 3.4.4 (#434)
  • Bump checkstyle from 10.11.0 to 10.12.0 (#433)
  • Bump maven-dependency-plugin from 3.5.0 to 3.6.0 (#432)
  • Bump maven-checkstyle-plugin from 3.2.2 to 3.3.0 (#431)
  • Bump maven-source-plugin from 3.2.1 to 3.3.0 (#429)
  • Bump maven-bundle-plugin from 5.1.8 to 5.1.9 (#428)
  • Bump maven-pmd-plugin from 3.20.0 to 3.21.0 (#427)
  • Bump maven-assembly-plugin from 3.5.0 to 3.6.0 (#426)
  • Bump maven-remote-resources-plugin from 3.0.0 to 3.1.0 (#425)
  • Bump build-helper-maven-plugin from 3.3.0 to 3.4.0 (#424)
  • Bump checkstyle from 10.10.0 to 10.11.0 (#423)
  • Bump maven-surefire-plugin from 3.0.0 to 3.1.0 (#422)
  • Bump maven-gpg-plugin from 3.0.1 to 3.1.0 (#421)
  • Bump surefire-testng from 3.0.0 to 3.1.0 (#420)
  • Bump surefire-junit-platform from 3.0.0 to 3.1.0 (#419)
  • Bump junit.jupiter.version from 5.9.2 to 5.9.3 (#418)
  • Bump checkstyle from 10.9.3 to 10.10.0 (#417)
  • Bump jacoco-maven-plugin from 0.8.9 to 0.8.10 (#416)
  • Bump maven-checkstyle-plugin from 3.2.1 to 3.2.2 (#414)
  • Bump maven-project-info-reports-plugin from 3.4.2 to 3.4.3 (#413)
  • Bump nokogiri from 1.14.2 to 1.14.3 in /website (#412)
  • Bump commonmarker from 0.23.8 to 0.23.9 in /website (#411)
  • Bump spotbugs-maven-plugin from 4.7.3.3 to 4.7.3.4 (#410)
  • Bump byte-buddy from 1.14.3 to 1.14.4 (#409)
  • Bump maven-enforcer-plugin from 3.2.1 to 3.3.0 (#408)
  • Bump jacoco-maven-plugin from 0.8.8 to 0.8.9 (#407)
  • Bump byte-buddy from 1.14.2 to 1.14.3 (#406)
  • Bump checkstyle from 10.9.2 to 10.9.3 (#405)
  • Bump asm from 9.4 to 9.5 (#404)
  • Bump maven-deploy-plugin from 3.1.0 to 3.1.1 (#403)
  • Bump animal-sniffer-maven-plugin from 1.22 to 1.23 (#402)
  • Bump maven-install-plugin from 3.1.0 to 3.1.1 (#401)
  • Bump maven-resources-plugin from 3.3.0 to 3.3.1 (#400)
  • Bump license-maven-plugin from 4.1 to 4.2 (#399)
  • Bump spotbugs-maven-plugin from 4.7.3.2 to 4.7.3.3 (#398)
  • Bump checkstyle from 10.9.1 to 10.9.2 (#397)
  • Bump checkstyle from 10.8.1 to 10.9.1 (#396)
  • Bump logback-classic from 1.3.5 to 1.4.6 (#394)
  • Bump surefire-testng from 3.0.0-M9 to 3.0.0 (#392)
  • Bump surefire-junit-platform from 3.0.0-M9 to 3.0.0 (#391)
  • Bump maven-surefire-plugin from 3.0.0-M9 to 3.0.0 (#390)
  • Bump byte-buddy from 1.14.1 to 1.14.2 (#389)
  • Bump checkstyle from 10.8.0 to 10.8.1 (#388)
  • Bump byte-buddy from 1.14.0 to 1.14.1 (#387)
  • Bump maven-compiler-plugin from 3.10.1 to 3.11.0 (#386)
  • Bump checkstyle from 10.7.0 to 10.8.0 (#385)
  • Bump spotbugs-maven-plugin from 4.7.3.0 to 4.7.3.2 (#384)
  • Bump maven-assembly-plugin from 3.4.2 to 3.5.0 (#383)
  • Bump versions-maven-plugin from 2.14.2 to 2.15.0 (#382)
  • Bump byte-buddy from 1.13.0 to 1.14.0 (#381)
  • Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 (#379)
  • Bump surefire-junit-platform from 3.0.0-M8 to 3.0.0-M9 (#378)
  • Bump surefire-testng from 3.0.0-M8 to 3.0.0-M9 (#377)
  • Bump maven-surefire-plugin from 3.0.0-M8 to 3.0.0-M9 (#376)
  • Bump byte-buddy from 1.12.23 to 1.13.0 (#375)
  • Bump maven-deploy-plugin from 3.0.0 to 3.1.0 (#374)
  • Bump byte-buddy from 1.12.22 to 1.12.23 (#372)
  • Bump maven-enforcer-plugin from 3.1.0 to 3.2.1 (#371)
  • Bump checkstyle from 10.6.0 to 10.7.0 (#370)
  • Bump maven-pmd-plugin from 3.19.0 to 3.20.0 (#367)
  • Bump byte-buddy from 1.12.21 to 1.12.22 (#366)
  • Bump surefire-junit-platform from 3.0.0-M7 to 3.0.0-M8 (#365)
  • Bump surefire-testng from 3.0.0-M7 to 3.0.0-M8 (#364)
  • Bump maven-dependency-plugin from 3.4.0 to 3.5.0 (#363)
  • Bump maven-surefire-plugin from 3.0.0-M7 to 3.0.0-M8 (#362)
  • Bump maven-checkstyle-plugin from 3.2.0 to 3.2.1 (#361)
  • Bump maven-project-info-reports-plugin from 3.4.1 to 3.4.2 (#360)
  • Bump junit.jupiter.version from 5.9.1 to 5.9.2 (#359)
  • Bump byte-buddy from 1.12.20 to 1.12.21 (#357)
  • Bump checkstyle from 10.5.0 to 10.6.0 (#355)

EasyMock 5.1.0 is out!

Main a performance fix caused by ByteBuddy causing OOME.

Change log

  • Typecache for create mock classes (#353)
  • Bump versions-maven-plugin from 2.14.1 to 2.14.2 (#352)
  • Bump wagon-ssh-external from 3.5.2 to 3.5.3 (#351)
  • Bump byte-buddy from 1.12.19 to 1.12.20 (#350)
  • Bump versions-maven-plugin from 2.14.0 to 2.14.1 (#349)
  • Bump versions-maven-plugin from 2.13.0 to 2.14.0 (#348)
  • Bump testng from 7.5 to 7.7.0 (#347)
  • Bump maven-dependency-plugin from 3.3.0 to 3.4.0 (#345)
  • Bump checkstyle from 10.4 to 10.5.0 (#344)
  • java.lang.NullPointerException at org.easymock.internal.ClassProxyFactory.classPackage(ClassProxyFactory.java:178) (#343)
  • EasyMock 5.0.1 OOM on large project (#338)
  • Bump spotbugs-maven-plugin from 4.7.2.1 to 4.7.3.0 (#337)
  • Bump checkstyle from 10.3.4 to 10.4 (#336)
  • Bump maven-shade-plugin from 3.4.0 to 3.4.1 (#335)
  • Add cache for mocked types. (#334)
  • Mock serialization doesn’t work (#312)

EasyMock 5.0.1 is out!

Quick fix allowing package-private methods to be mocked.

Change log

  • Mocking package-private methods not working in 5.0.0 (#331)
  • Bump versions-maven-plugin from 2.12.0 to 2.13.0 (#333)
  • Bump nokogiri from 1.13.8 to 1.13.9 in /website (#332)
  • Bump spotbugs from 4.7.2 to 4.7.3 (#330)
  • Bump maven-javadoc-plugin from 3.2.0 to 3.4.1 (#329)
  • Bump nexus-staging-maven-plugin from 1.6.8 to 1.6.13 (#328)
  • Bump maven-compiler-plugin from 3.8.1 to 3.10.1 (#327)
  • Bump animal-sniffer-maven-plugin from 1.20 to 1.22 (#326)
  • Bump maven-deploy-plugin from 3.0.0-M1 to 3.0.0 (#325)
  • Bump maven-pmd-plugin from 3.14.0 to 3.19.0 (#324)
  • Bump maven-resources-plugin from 3.2.0 to 3.3.0 (#323)
  • Bump maven-site-plugin from 3.9.1 to 3.12.1 (#322)
  • Bump exec-maven-plugin from 3.0.0 to 3.1.0 (#321)
  • Bump maven-remote-resources-plugin from 1.7.0 to 3.0.0 (#319)

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.