JCrete

After years missing it, I finally went to JCrete last year for the first time. I went with my family and we had a great time. This year, I went back again but alone.

For those who never went, it is hard to describe the event. The boring way would be to say that it is a Java unconference.

But it is a really bad way to describe it.

Here is my current explanation.

Close your eyes. Imagine you can gather all the almighty experts in your field and put them in one place. Then imagine this place has multiple beaches, great (cheap!) food and good wine. That everyone is friendly and wants to help each other without judging. And that you will talk will all these experts all day, in formal classrooms and on the beach. You will gather a tremendous amount of knowledge.

This is JCrete.

This was my experience last year. This was my experience this year. It almost feels surreal.

I still don’t know how it happened. Is it Crete? Is it Heinz and Kirk’s magical touch? Is it the Java community that is awesome? Probably all of the above sincerely.

Then, if you have never heard of JCrete let me explain a bit more what it is about.

First, it’s an unconference with a limited number of participants. Those participants are selected for their accomplishments. It means that you are well-known in the Java community for something. Of course, a lot of Java Champions are attending. To prevent too much inbreeding, a little amount of entropy coming from random senior lead developers is added. However, the rule is that anyone attending should be able to propose a subject and talk about it. You can see it as a conference with only speakers talking to one another.

Then, a typical day looks like that:

  1. Waking up
  2. Go jogging with some of the attendees (chatting about interesting stuff)
  3. Shower
  4. Get breakfast with the attendees (chatting about interesting stuff)
  5. Gather in the main room
  6. Morning briefing and subject proposition for the day
  7. Attend sessions with subjects you care about. Learn
  8. Lunch (chatting about interesting stuff)
  9. Go to some beach (chatting about interesting stuff)
  10. Hack a bit. When stuck, there are high chances that one of the lead committers on the thing you are stuck on is attending too
  11. Get unstuck by the lead committer (this year it was Matt Raible)
  12. Go dinner to some restaurant or at an evening event (chatting about interesting stuff, around a bottle of wine)
  13. Go to bed happy

Last year, this article when out of it. This year, some cool stuff that I will talk about when it’s ready.

See you in JCrete! Or possibly one of its clones.

Mac UI

Edited 2021-01-04: I do not use this trick anymore. It was freezing my computer once in a while. I haven’t retried for a while. If you are successful using it, please tell me.

In a previous post, I wrote about the UI using I had on a Mac. A Mac lover was fairly confident he could save me (sadly, no).

Today, thanks to BetterTouchTool and its developers, I can strike one item on my list.

  • Cmd+ù should behave as Cmd+` when using a ca-fr keyboard.

The solution is to add in BTT a shortcut to Cmd+ù. Then bind it to a predefined action “Run Apple Script”.

tell application "System Events"
	keystroke "`" using command down
end tell

Voilà!

EasyMock 3.6 is out!

This release adds a better support to Java 9 and Java 10 and fixes an issue for interface default methods.

  • Java 10 support through an update of ASM and cglib
  • Add Java 9 automodule
  • Allow mocking interface default methods on a partial mock

Change log for Version 3.6 (2019-08-05)

  • Add Java 9 automodule (#212)
  • Update asm, cglib and surefire for Java 10 support (#211)
  • Mocking interface default methods (#203)

EasyMock 3.5 is out!

Here is the long awaited 3.5 version. It contains many bug fixes and some improvement. We allowed ourselves to possibly break the compatibility with older versions for the greater good. So please read these notes thoroughly.

  • Java 5 is no longer supported. I dearly hope this won’t harm anyone
  • Java 9 is supported
  • TestNG support is added. Have a look at EasyMockListener
  • Class Mocking now works correctly for cross bundle mocking
  • verify() now checks for unexpected calls in case an AssertionError was swallowed during the test. It is in general what you want but you can use verifyRecording() to bring back the old behavior
  • Default matcher for an array argument is now aryEq instead of eq. This should as well make sense for everyone and should allow you to remove tons of aryEq all over your code. If you don’t like it, you can specify eq explicitly for the array argument

Change log for Version 3.5 (2017-09-12)

  • isNull and notNull with generic class parameter (#93)
  • Return a meaningful error when null on a primitive (#92)
  • Create opportunity to disable SingleThread checks (#88)
  • slightly more intuitive error message (#80)
  • Enhancement for andAnswer / andStubAnswer (#79)
  • Make easymock and easymock-ce OSGi-ready (#78)
  • Enable Multiple Captures (#77)
  • Improve multithreading error report in MocksBehavior (#73)
  • Stack trace clobbered when exception thrown by IAnswer impl (#34)
  • Possible bug with captures() (#30)
  • Actual value in byte array failure is not helpful (#29)
  • Regression caused by new threadsafe API and defaults (#27)
  • Capturing parameters from single argument methods (#24)
  • NPE with varargs in record state (#22)
  • capture(Capture) only captures last method call (#21)

Type of Mocks

A long time ago (year 2000), the mock objects were invented. It is now one of the most important parts of unit testing.

For those you don’t know, the idea of a mock object is to simulate a dependency to easily test a class. Quick example.

I have a class Pricer.

public class Pricer {
  private PriceFeed priceFeed;
  
  public BigDecimal getPrice(String symbol) {
    BigDecimal latest = priceFeed.getLatestPrice(symbol);
    // ... do some calculations ...
    return value;
  }
}

Being a nice human being, I want to test my calculations but I don’t want to use a real PriceFeed. The real implementation has to an actual MQSeries queue that received prices from Reuters. It’s not something you want to do during your unit tests (if at all).

So you will instead do a mock object, an object that will behave as you see fit for your test but that isn’t a real PriceFeed. It just mimics it.

Not so long ago, Uncle Bob did a blog post about mock objects. He classifies them into five different types or levels. Levels because each type is wiser than the previous one. He calls them “Test Doubles”.

I’ve decided to show you how to code them. Using EasyMock (of course), Mockito and by hand.

Type of mocks

From the most basic to the most advanced type.

Dummy

A class that you pass into something when you don’t care how it’s used. e.g. As part of a test, when you must pass an argument, but you know the argument will never be used.

public class DummyAuthorizer implements Authorizer {
  public Boolean authorize(String username, String password) {
    return null;
  }
}

In this EasyMock world, it is called a nice mock (Authorized mock = niceMock(Authorized.class)).

In the Mockito world, it’s just a mock (Authorized mock = mock(Authorized.class)).

In general, if a dummy is used, you will want it to throw an exception to tell you something is wrong. So, with Mockito, you will in general get a NullPointerException (or not) if you do something like

if(mock.authorize(user, password)) // NPE

With EasyMock, you will generally prefer to use a normal mock (Authorized mock = mock(Authorized.class)) that will make sure nothing unintended is called.

if(mock.authorize(user, password)) // AssertionError: Unexpected method call

Stub

A class that returns a valid answer but always the same one.

public class AcceptingAuthorizerStub implements Authorizer {
  public Boolean authorize(String username, String password) {
    return true;
  }
}

In the EasyMock language, this is any mock with an expectation recorded (expect(mock.authorize(anyString(), anyString()).andStubReturn(true)).

In the Mockito language, this is a mock with behavior set on a method (when(mock.authorize(any(), any()).thenReturn(true).

Spy

You use a spy when you want to be sure that the authorize() method is called by the system.

public class AcceptingAuthorizerSpy implements Authorizer {
  public boolean authorizeWasCalled = false;

  public Boolean authorize(String username, String password) {
    authorizeWasCalled = true;
    return true;
  }
}

In EasyMock, it means you are not stubbing anymore. You want to record a precise call (expect(mock.authorize(anyString(), anyString()).andReturn(true)) and then verify that the call actually occurred (verify(mock)).

In Mockito, you still stub the call and then verify the call occurred (verify(authorizer).authorize(any(), any())). Note that Mockito has its own concept of a spy, which is different. A Mockito spy is a shell over an actual class that allows to verify calls to them. It is indeed useful but it isn’t a mock. So don’t get lost in the semantic.

True Mock

A true mock is a mock that knows how to verify itself. In fact, EasyMock and Mockito mocks are always true mocks. So their implementations of a true mock is the same as for the spy.

public class AcceptingAuthorizerVerificationMock implements Authorizer {
  public boolean authorizeWasCalled = false;

  public Boolean authorize(String username, String password) {
    authorizeWasCalled = true;
    return true;
  }

  public boolean verify() {
    return authorizedWasCalled;
  }
}

Fake

A Fake has business behavior. You can drive a fake to behave in different ways by giving it different data. They are usually used for integration testing to simulate other parts of your system.

public class AcceptingAuthorizerFake implements Authorizer {
  public Boolean authorize(String username, String password) {
        return "Bob".equals(username);
      }
}

I rarely use a mocking framework for them. It tends to make the code more complicated than coding by hand. Still, a mocking framework can be used.

// Easymock
expect(authorizer.authorize(anyString(), anyString())).andStubAnswer(() -> "Bob".equals(getCurrentArguments()[0]));

// Mockito
when(authorizer.authorize(any(), any())).thenAnswer(invocationOnMock -> "Bob".equals(invocationOnMock.getArgument(0)));

Conclusion

When jumping from one flavor to another, you should make sure you really need to. Because the more complicated your mocking is, the more coupling you will have with the actual implementation. It makes the test more fragile. But you still need to make sure everything is working as expected!

Testing advice

Modify to test

If your code isn’t easy to test, modify your code. Do whatever is needed. You will end up with a better design anyway. A test should not be complicated. If it needs to, something is wrong.

Provide a testing framework

If you build something, you should provide a nice framework to test it. Spring has spring-test. You are responsible for making what you do testable, mockable, etc.

Use as less mocks as possible

Usually, unit tests should use at worst 3 mocks. It you have more, you probably should split your code in smaller parts. A lot of mocks makes the code unreadable.

Explain and document your tests

Tests are harder to understand than actual production code. When someone reads test code, he should understand the purpose. So use a nice test name to explain what you wanted to do. Use javadoc. Use line comments to explain the flow.

Refactor them

I’m refactoring my tests a lot. A lot. Nice methods preventing copy & paste. Testing frameworks. Fixtures. Base test classes. Everything to make it as pretty as my production code.

Cancel CompletableFuture

I felt on some code yesterday and had to think a bit about it before deciding that it wasn’t working as expected. And then went on to wonder if I could make it work. I found it interesting so I thought I should tell you about it.

@Test
public void testListGetsFilled() throws Exception {
  List<String> list = Collections.emptyList();
  
  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(!list.isEmpty()) {
        return list.size();
      }
    }
  });
  
  // ... do some async task that should fill the list in less than 1 second ...
  
  assertThat(future.get(1, TimeUnit.SECONDS)).isGreaterThan(0);
}

So. What’s going on here?

  1. We have a list
  2. A CompletableFuture is waiting for the list to be filled
  3. We wait on the future until is has finished
  4. If it takes too long, we timeout

It works. If the list is filled, the test will be successful, if the list is never filled, the get will timeout after 1 seconds (throwing a TimeoutException) and the test will fail.

The only problem is that if the test does fail, the future task itself will never finish. It is still stuck in the while loop.

Why?

Because nothing can stop it. supplyAsync is submitting a task to the common pool. This task will run in a thread we are not managing. The task won’t stop until the list isn’t empty anymore. That’s it.

A timeout of the CompletableFuture won’t change anything. It just means that we are not waiting on the get anymore. But it has no power over the task itself.

What can we do?

Maybe we can interrupt it? Let’s try.

@Test
public void testListGetsFilled_withInterrupt() throws Exception {
  List<String> list = Collections.emptyList();

  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(!list.isEmpty()) {
        return list.size();
      }
      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        return 0;
      }
    }
  });

  // ... do some async task that should fill the list in less than 1 second ...

  assertThat(future.get(1, TimeUnit.SECONDS)).isGreaterThan(0);
}

In the original loop, nothing could be interrupted. Now we introduce a sleep. It can be interrupted. However, it won’t.

The timeout on the get doesn’t trigger an interrupt on the thread running the task.

That doesn’t work either?

Can it be cancelled you say?

@Test
public void testListGetsFilled_cancelled() throws Exception {
  List<String> list = Collections.emptyList();

  AtomicReference<CompletableFuture<Integer>> ref = new AtomicReference<>();

  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(ref.get() != null && ref.get().isCancelled()) {
        return list.size();
      }
      if(!list.isEmpty()) {
        return list.size();
      }
    }
  });

  ref.set(future);

  // ... do some async task that should fill the list in less than 1 second ...

  assertThat(future.get(1, TimeUnit.SECONDS)).isGreaterThan(0);
}

Here the code is a bit more complicated. We can’t access the future from the lambda directly. Because the lambda starts before the assignment is made. So we use an AtomicReference, wait until its content isn’t null anymore and then wait for cancellation… that never arrives.

Yes. The timeout on the get won’t trigger a cancellation. This is on purpose. There is nothing preventing you from waiting a bit on the get, do something else, and come back to get again.

Enough of that! Tell me what works!

OK. OK. Calm down. I’ll show you but it’s not pretty.

@Test
public void testListGetsFilled_cancelledForReal() throws Exception {
  List<String> list = Collections.emptyList();

  AtomicReference<CompletableFuture<Integer>> ref = new AtomicReference<>();

  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(ref.get() != null && ref.get().isCancelled()) {
        return 0;
      }
      if(!list.isEmpty()) {
        return list.size();
      }
    }
  });

  ref.set(future);

  // ... do some async task that should fill the list in less than 1 second ...

  try {
    future.get(1, TimeUnit.SECONDS);
  } catch (TimeoutException e) {
    future.cancel(false);
  }
  
  assertThat(future.get()).isGreaterThan(0);
}

So now we are cancelling the task ourselves. That works. The task correctly finishes. One funny thing to mention is that the assert won’t fail. In fact, it’s the call to future.get() in assertThat that will throw a CancellationException and make the test fail.

OK. We now have a pretty ugly and complicated solution that works.

Can we simplify?

You might have noticed that cancel() take a parameter named mayInterruptIfRunning. That sounds promising! We can get an interruption! Let’s try.

@Test
public void testListGetsFilled_cancelledToInterrupt() throws Exception {
  List<String> list = Collections.emptyList();

  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(Thread.interrupted()) {
        System.out.println("Done");
        return 0;
      }
      if(!list.isEmpty()) {
        return list.size();
      }
    }
  });

  // ... do some async task that should fill the list in less than 1 second ...

  try {
    future.get(1, TimeUnit.SECONDS);
  } catch (TimeoutException e) {
    future.cancel(false);
  }

  assertThat(future.get()).isGreaterThan(0);
}

No atomic reference anymore. But doesn’t work. The task doesn’t get interrupted. If I quote the javadoc for cancel():

mayInterruptIfRunning this value has no effect in this implementation because interrupts are not used to control processing.

Basically, that means CompletableFuture are not supposed to be interrupted. They are at a higher level of abstraction.

Here is the nicest solution I know about.

@Test
public void testListGetsFilled_cancelledByFlag() throws Exception {
  List<String> list = Collections.emptyList();

  AtomicBoolean cancelled = new AtomicBoolean(false);

  CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    while(true) {
      if(cancelled.get()) {
        return list.size();
      }
      if(!list.isEmpty()) {
        return list.size();
      }
    }
  });

  // ... do some async task that should fill the list in less than 1 second ...

  try {
    future.get(1, TimeUnit.SECONDS);
  } catch (TimeoutException e) {
    cancelled.set(true);
  }

  assertThat(future.get()).isGreaterThan(0);
}

Yes, it’s just a simple flag. But it works nicely.

Still, you might ask me: “Why is it that complicated?”

In fact, I’m not totally sure. I think CompletableFuture are not meant to be used like this. They are supposed to complete. Or to fail exceptionally. Normal Future are the ones that are supposed to loop like that.

But I’ll need more digging to be more conclusive. Right now, I only wanted to share my How to cancel a CompletableFuture? discovery.

Java Data Visibility

I was at JCrete two weeks ago. For those who don’t know, it is an awesome Java unconference where everyone with their family to talk about Java. It has been created by Heinz Kabutz a.k.a The Java Specialist. I was really happy to see a bunch of heads I haven’t seen since moving back to Montreal.

One of the sessions I’ve led was about data visibility according to the JMM. I didn’t care about lock and synchronization. Just data visibility.

If I write to this variable, will this other thread see the new value for sure?

I was lucky enough to gather with a handful of subject-matter experts.

My goal was to give really simple examples of what works or not. The final code can be found on JCrete’s github.

But I will still describe it here. It’s based on the concept of “Will the thread ever get out of the loop?”. All the examples are almost identical.

@Test
public void test() {
    new Thread(() -> {
        while (!field);
        System.out.println("Done");
    }).start();
    field = true;
}
  1. A thread is started
  2. It loops until a field is flipped to true
  3. The main thread flips the field to true

If the field visibility is correct, when the main thread flips the field, the child thread will see the value and correctly exit the loop. If it’s not, the thread might go in an infinite loop according to the JMM. I’m saying “might” because depending on the CPU architecture, JVM version and the way the wind is blowing, it might see the value correctly on your machine. That doesn’t mean it will work ever after.

I recommend that you first guess the result before looking at the answer.

The first example is when we just flip the field in same thread.

@Test
public void test() {
    new Thread(() -> {
        field = true;
        while (!field);
        System.out.println("Done");
    }).start();
}

Does it work: Yes

We will call this one the obvious example because it obviously works. But, even if it’s obvious, the JMM still have a rule for it.

Each action in a thread happens-before every subsequent action in that thread.

Let’s move to something less obvious. We will start with a normal field (no final or volatile) without any kind of synchronization.

private boolean stopNormalField;

@Test
public void normalField() {
    new Thread(() -> {
        while (!stopNormalField);
        System.out.println("Done");
    }).start();
    stopNormalField = true;
}

Does it work: No

Data visibility to another thread is not guaranteed by a normal field. The child thread might never see stopNormalField ever value changed.

Now, let’s turn it to a volatile field.

private volatile boolean stopVolatileField;

@Test
public void volatileField() {
    new Thread(() -> {
        while (!stopVolatileField);
        System.out.println("Done");
    }).start();
    stopVolatileField = true;
}

Does it work: Yes

Volatile ensure data visibility.

A write to a volatile field happens-before every subsequent read of that volatile.

When a volatile field is changed, all other threads are seeing the value right away. Volatile tells the JVM that the value shouldn’t be kept local to the thread.

Happens-before is JMM jargon. It has a strict definition. That means what it means in English. That you are sure something happened before something else.

So, in the JMM jargon, a volatile write happens-before any subsequent read of the volatile field.

The volatile also has the added bonus of ensuring the atomicity of the update. It means the value is updated in one shot. No half-written value.

So far so good.

What about a volatile array?

private volatile boolean[] stopArrayField = new boolean[1];

@Test
public void volatileArrayField() {
    new Thread(() -> {
        while (!stopArrayField[0]);
        System.out.println("Done");
    }).start();
    stopArrayField[0] = true;
}

Does it work: No

Data visibility of array elements is not guaranteed. Elements of a volatile array are not volatile. Yes, it is non-intuitive.

Let’s now start with higher abstraction from java.util.concurrent (JUC). First, an atomic field.

private AtomicBoolean stopAtomicField;

@Test
public void atomicField() {
    stopAtomicField = new AtomicBoolean();
    new Thread(() -> {
        while (!stopAtomicField.get());
        System.out.println("Done");
    }).start();
    stopAtomicField.set(true);
}

Does it work: Yes

Of course it works. Data visibility of the content of an atomic is guaranteed. Note, however, that it doesn’t apply to the field referencing the atomic field (stopAtomicField). It still works on our case because we assign (stopAtomicField = new AtomicBoolean()) before starting the thread. The JVM makes sure a starting thread will see everything that happened-before.

Now. What about synchronization?

@Test
public void synchronizedField() {
    new Thread(() -> {
        while (true) {
            synchronized (this) {
                if(stopNormalField) {
                    break;
                }
            }
        }
        System.out.println("Done");
    }).start();
    synchronized (this) {
        stopNormalField = true;
    }
}

Does it work: Yes

JMM says:

An unlock on a monitor happens-before every subsequent lock on that monitor.

Which means two threads synchronizing on the same mutex are seeing the same thing inside the synchronized section. All words in bold are really important.

For instance, not synchronizing on the same mutex means all bets are off.

@Test
public void synchronizedOnDifferentMutexField() {
    new Thread(() -> {
        while (true) {
            synchronized (new Object()) { // Wrong mutex
                if(stopNormalField) {
                    break;
                }
            }
        }
        System.out.println("Done");
    }).start();
    synchronized (this) {
        stopNormalField = true;
    }
}

Does it work: No

By the way, watch out for lambda and inner classes. They don’t have the same this. For a lambda, this is the class where the lambda is defined. For an inner class, it is the inner class.

@Test
public void synchronizedInnerClassField() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                synchronized (DataVisibilityTest.this) { // Specify the this from the outer class
                    if (stopNormalField) {
                        break;
                    }
                }
            }
            System.out.println("Done");
        }
    }).start();
    synchronized (this) {
        stopNormalField = true;
    }
}

Does it work: Yes

Synchronization works. Fair enough. But can I use a lock? I was told locks are better than synchronization.

private Lock lock = new ReentrantLock();

@Test
public void lockField() {
    new Thread(() -> {
        while (true) {
            lock.lock();
            try {
                if(stopNormalField) {
                    break;
                }
            } finally {
                lock.unlock();
            }
        }
        System.out.println("Done");
    }).start();
    lock.lock();
    try {
        stopNormalField = true;
    } finally {
        lock.unlock();
    }
}

Does it work: Yes

Locking provides the same data visibility as synchronizing.

In fact, all JUCs are providing the necessary memory barriers to get the correct visibility. Below, countDown and await will make sure the child thread sees the world correctly.

@Test
public void latchField() {
    CountDownLatch latch = new CountDownLatch(1);
    new Thread(() -> {
        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        while (!stopNormalField);
        System.out.println("Done");
    }).start();
    stopNormalField = true;
    latch.countDown();
}

Does it work: Yes

As soon as you use JUC abstractions, things tend to magically work in fact. Which is a good thing even though everything magically working is always a bit frightening.

Now, something strange when asked.

@Test
public void setBeforeThreadField() {
    stopNormalField = true;
    new Thread(() -> {
        while (!stopNormalField);
        System.out.println("Done");
    }).start();
}

We set the normal field before starting the thread.

Does it work: Yes

That one, you probably guessed right. Because if it was not working, it would mean that the thread would never see the value of a field set before it started. But of course there’s a rule for that.

A call to start() on a thread happens-before any actions in the started thread.

What about this one?

@Test
public void joinThread() throws InterruptedException {
    stopNormalField = true;
    Thread t = new Thread(() -> {
        while (!stopNormalField); 
        System.out.println("Done");
        stopNormalField = false;
    });
    t.start();
    t.join();
    System.out.println(stopNormalField);
}

It’s a bit different because we are wondering if the main thread will see the value set by the child thread after the join.

Does it work: Yes

Why? Because the JMM says so, of course.

All actions in a thread happen-before any other thread successfully returns from a join() on that thread.

Quite useful.

OK. We will finish this post with the Don’t do this at home example. It means it is trickier to get right, and you won’t need it for business as usual.

@Test
public void mutexField() {
    new Thread(() -> {
        while (!stopVolatileField);
        while (!stopNormalField);
        System.out.println("Done");
    }).start();
    stopNormalField = true;
    stopVolatileField = true;
}

Does it work: Yes

Here we cause the synchronization of the normal field by using a volatile field. Writing to stopVolatileField causes a happens-before relationship. And happens-before are transitive as per the JMM.

If an action a happens-before an action b, and b happens before an action c, then a happens before c.

In our case, it means the value written to stopNormalField will be seen by the child thread after it reads stopVolatileField.

Thanks again to all the contributors to this session (you will find some of them on the readme.

Spring GAE Java 8 Objenesis

Objenesis went out last week partly because Google App Engine is now supporting Java 8 in beta. And they are no security manager anymore preventing Objenesis to work.

The problem was that Objenesis was checking if it was running on GAE to pick an instantiating strategy. So it was still running in degraded more on GAE Java 8. It is now fixed.

However, Spring uses an embedded version of Objenesis. So they need to upgrade. Luckily, they are super fast to do so. You can follow the issue but it will be in Spring 4.3.10 and Spring Boot 1.5.5.

Meanwhile, you might be eager to test your shiny new app on this new Google App Engine platform and would be really happy to make it work.

I have a solution for you. It isn’t pretty but it works.

In Java, in case you don’t know, you just need to put your class file in front of another one in the classpath to “shadow” it. It means your class will be used instead of the original implementation. In a war, everything in WEB-INF/classes goes before WEB-INF/lib. So you can easily shadow a class.

That’s what I did. My SpringObjenesis.java version shadows Spring one. It delegates to the real Objenesis implementation instead of the Spring embedded one. You only need to add the latest Objenesis (2.6) as a dependency to your project.

Voilà!

Objenesis 2.6 is out!

An all new shiny Objenesis is out. The framework everybody uses without even knowing it.

It had fun playing with the brand new Google App Engine platform supporting Java 8. They dropped the terrible security manager they used to have to know Objenesis is working perfectly on it. This was brought to my attention by GAE developers. They are now testing mainstream frameworks on their platform to make sure it works. This should make GAE adoption easier.

Java 9 was pretty much already working but I got rid of all the “Illegal accesses”. Not that obvious since in Objenesis, this is how we roll.

Finally, a bit of cleanup in the serialization specification was done. So now a serializing instantiator should instantiate a class by calling the no-arg constructor of the first non-serializable class in the hierarchy. And do nothing else. See the documentation for details.

Change log

Mac UI

I’ve mentioned already why I am now using a mac after years of beloved Windows.

But I’m still complaining about the really bad UI behavior of macOS (I’m on Sierra). And the ca_fr keyboard that should have had the exact same layout that Windows had for years instead of trying to be wiser… But that’s hardware so there’s nothing I can do about it.

During my last round of complains I was asked to write an article about it. So here it is.

First, one of the first things I’ve fixed is the random behavior of Home and End keys. By default, depending on the app you are in, the behave differently. This is plainly insane. Here is the fix:

cd ~/Library
mkdir KeyBindings
cd KeyBindings
vi DefaultKeyBinding.dict

Put these lines in that file, including the curly braces:

{
/* Remap Home / End keys to be correct */
"\UF729" = "moveToBeginningOfLine:"; /* Home */
"\UF72B" = "moveToEndOfLine:"; /* End */
"$\UF729" = "moveToBeginningOfLineAndModifySelection:"; /* Shift + Home */
"$\UF72B" = "moveToEndOfLineAndModifySelection:"; /* Shift + End */
"^\UF729" = "moveToBeginningOfDocument:"; /* Ctrl + Home */
"^\UF72B" = "moveToEndOfDocument:"; /* Ctrl + End */
"$^\UF729" = "moveToBeginningOfDocumentAndModifySelection:"; /* Shift + Ctrl + Home */
"$^\UF72B" = "moveToEndOfDocumentAndModifySelection:"; /* Shift + Ctrl + End */
}

Then, macOS is lacking Windows docking. So I’ve installed BetterTouchTool for that.

Back to complaining. Here are the things I wasn’t able to fix so far.

  • Cmd+Tab should bring to front the requested window. Always. It doesn’t matter if the window is minimized, in background or whatever. Just bring it in front
  • Cmd+Tab should bring the last used window of an application to the front. Not my 6 Chrome windows. Only the latest one
  • Cmd+ù should behave as Cmd+` when using a ca-fr keyboard. I can probably use the remap trick for that. I tried BTT, it doesn’t work
  • When switching desktop, it shouldn’t matter where my mouse is. Especially to access the dashboard. It should just switch all screens. It there a shortcut to switch screen 1?
  • Cmd+X should cut everywhere. Cmd+C and then Cmd+Alt+V is just not the way my brain works. I think about copy or cut when seeing the file. Not when pasting it. Am I the only one?
  • I use 2 keyboard layouts (US-en and CA-fr). Because of the dumb keyboard. macOS should remember which application is using which keyboard. However, I don’t need it for each Chrome tab

That’s it for the day. Can you help me?