Wednesday, December 18, 2013

Try-With-Resource in Java

Starting from Java 1.7 we have new syntax: try-with-resource. Recently I had a chance to use it in a project. Main usage I had was for logging contexts.

This code looks feasible for small examples, but things got complicated when one has big code block under try/finally. Next approach is to use Java 1.7 try-with-resource. The approach is similar to using construction in C#.

CloseableResource is an interface inherited from Java's standard AutoCloseable. The only reason for it is to avoid declared exceptions. The implementation of an interface is following:

In Java 1.7 it's unfortunately not allowed to use expression as resource in the try-with-resource statement. So I was forced to have a dummy variable declaration there. So I named the variable with underscores to make it be unusable. I with I could write something like this: try(foo()) { /*code*/ }. Nowadays this is not supported.

Meanwhile the pattern was good to use and I start using it in many places. In some places I added catch clause for the try.

This code looks good, but it does not work as it was expected! I expected from it to call logger.error under ProjectMDC.mdc() resource but it turned out the logger.error() method is called AFTER ProjectMDC.mdc() context is closed. The problem is that logging was expected to be logged with ProjectMDC but it was not. So the only right code should be patched as follows

This code is similar ugly as pre 1.7 code:

The only lack in the older code is that one have to declare CloseableResource variable and than explicitly close it at end. There is one extra variable in code to take care of.

Outcome

The sad outcome here is that brand new try-with-resource statement has the following misses

  • It's not clear that resource is disposed before catch block call
  • It's not allowed to put expression(s) as resources (remember using in C#)
  • Real usage code turns out to be quite ugly (still)

The Kotlin Way

All this time I was recalling how easy once could create one's own using in Kotlin. For example:

Here I declared my own construction that is more useful in my project! So the usages are following

For more Kotlin details, you may follow to the documentation.

The only thing is that this code looks more easy-to-understandable. In the long run, I'd say, this code is more unlikely to contain bugs. Again this is only because simplicity of code

Done

Be careful with new Java syntax and read manuals with more attention. Happy coding and Happy Christmass and New Year

2 comments:

gleb Chermennov said...

I set it up just the way you described - doesn't work for me :(

gleb Chermennov said...

My mistake, included .dll in the assembly names. Coverage works as expected. Thanks :)