EasyMock used in a reactive environment


I was asked today to fulfill the following use case with EasyMock.
  • The tested method emit an asynchronous call
  • The mocked method receive the call
  • Before continuing, we want to make sure the asynchronous call had time to finish
It's always nice to see new usage emerge with EasyMock. The solution to this one was to use an IAnswer and a CountDownLatch.

To do something like this:
final CountDownLatch latch = new CountDownLatch(4);
mock.asyncProcess();
expectLastCall().andAnswer(new IAnswer<Object>() {

@Override
public Object answer() throws Throwable {
latch.countDown();
return null;
}
}).times(4);
replay(mock);

tested.doSomething();

latch.await(10, TimeUnit.SECONDS);

// Do some verifications...
verify(mock);
That feels kinda nice. And, to be honest, the actual code was in fact in Scala using EasyMockSugar. So they can use an implicit converter to make the code shorter.
// implicit converter definition
implicit def convertFnToAnswer[T](fn: => T) :IAnswer[T] = new IAnswer[T] {
def answer(): T = fn
}

// Record expectations
mock.asyncProcess() andAnswer {latch.countDown}

To remove an UTF-8 BOM from a file

Today I've encounter a bunch of nasty UTF-8 files beginning with a BOM.

And of course, they were read by a tool that couldn't read and UTF-8 file beginning with a BOM.

Here's the solution (the files were js files):

find . -type f *.js -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;

Lambdas and Generics, an explosive cocktail

I had a great time last week at the Toulouse and Bordeaux JUG.

I talked about mostly unknown facts about Java generics but also how they will blend with the fast coming lambdas.

Can be a helpful survival guide I hope. The slides are on Slideshare.

Objenesis 2.1 is out!

Objenesis 2.1 is out. This version was mainly aiming at supporting Android API level 18 and improving the support of OpenJDK.

Here are the full release notes:

  • Support for Android API level 18 (#23)
  • Have the tck returning a value different from zero in case of failures (#24)
  • Make it easier to call the TCK programmatically (#25)
  • Show the actual instantiator implementation used by the TCK (#26)
  • Explicit support for OpenJDK (#27)
Enjoy!

Jekyll on Windows

Jekyll used to simply not work on Windows. Now it does.

I'm using ruby 2.0.0p195 and jekyll 1.2.1 in case it might help anyone. On Windows 8.

But when trying to serve a website (jekyll serve), you will probably get

Conversion error: There was an error converting '_posts/2013-06-05-my-files.md.

error: incompatible character encodings: CP850 and UTF-8. Use --trace to view backtrace

The solution is to do a chcp 65001 (information I miraculously found here).

Like magic, it will start to work.

Regression testing on Android

Having Objenesis now working on Android is forcing me to make sure it keeps working. This is a call for automated regression tests.

The original idea was to test on Cloudbees on all the supported API levels (8 to 18 as of now). Luckily there is an SDK installed in their instances. And two nice blog posts explaining how to configure it.

However, I ended up using a local VM because I had some stability issues. Random parts of the build were

Everything starts with the Android Emulator Plugin. We also need the EnvInject Plugin on Cloudbees.

Then, follow these steps:

  • Create a multi-configuration project
  • Add three user-defined axis
    •  os (android-8 android-10 android-11 android-12 android-13 android-14 android-15 android-16 android-17 android-18)
    • resolution (HVGA WXGA)
    • abi (armeabi armeabi-v7a)
Now it gets funny because you need to find a combination filter mixing these three axis to create valid configurations.
  • Combination filter: (os==~/android-1[1,2,3]/).implies(resolution=="WXGA") && (!(os==~/android-1[1,2,3]/)).implies(resolution=="HVGA") && (!(os==~/android-1[4,5,6,7,8]/)).implies(abi=="armeabi") && (os==~/android-1[4,5,6,7,8]/).implies(abi=="armeabi-v7a")
From there you might ask why I'm using android-18 instead of 4.3 as the target id. That's because it doesn't work. All other versions can be named using the Android version but not 4.3. It looks like a bug of the SDK.

Run each configuration sequentially if you're in local. You won't need it on Cloudbees since it can parallelize the build on many instances.

Then, you now to configure the emulator.
  • Check "Run an emulator during build"
  • Select "Run emulator with properties"
    • Android OS version: ${os}
    • Screen density: mdpi
    • Screen resolution: ${resolution}
    • Device locale: en_US
    • Target ABI: ${abi}
  • Check "Reset emulator state at start-up"
  • Check "Use emulator snapshots"
  • Emulator options: -no-audio -gpu off
Finally, just add your Android build using the emulator. And hopefully, everything should be alright.

Reload a Google App Engine web app

Google provides a really nice plugin to work with Google App Engine in Eclipse.

Strangely, there is no obvious way to reload the web app when the code is modified. This is kind of odd because it’s the kind of feature everyone would need.

The trick to allow a reload is to touch the appengine-web.xml file.

On Linux, you can, of course, use touch.

On Windows, touch doesn’t exist. However, there is a really obvious replacement for it: copy appengine-web.xml +,,. It needs to be called from the WEB-INF directory. Not path allowed here it seems.

The best way I’ve found so far to use it is to add an external tool.

External tools

I would also suggest to go to the Common tab to add it to your favorite tools and to have it as a shared file so you can make it accessible to all your team.

I also tried to add the tool as a builder of the project to make it auto-reload. It didn’t work.

If anybody has a better solution, I’m listening.

Objenesis 2.0 is out!

Quickly after version 1.4, it's time for Objenesis 2.0 to go out and travel the world

The main goal was to migrate to Java 5. To get a nice generified API but also to be able to use
java.util.concurrent.

This is now done and, thanks to juc, you now have a 10x performance improvement when retrieving an instantiator from the cache.

Now available on the website and in the Maven Central.

Enjoy!

Objenesis 1.4 is out!

Objenesis 1.4 is now available. 

The release notes:
  • Android Gingerbread support (#18)
  • New instantiator using Unsafe.allocateInstance() (#19)
  • Optimisation when instantiator cache isn't used (#14)
I had some fun benchmarking the different instantiators. If you want to check that the fastest one on your JVM is the default one, fell free to check out the code and try it. Don't forget to give me some feedback!

Enjoy!

SELinux or how to loose an hour

If your on RedHat (but it seems it can occur on any Linux) and you get a "Permission denied" coming out of nowhere. You did chmod -R 777 / and still get the issue, then you probably met SELinux. It's security above the usual security.

To desactivate it temporarily just to check it's really your current issue, do

sudo sudo sh -c 'echo 0 > /selinux/enforce'