Skip to main content

Posts

Showing posts from October, 2012

Request and response - discovering Akka

In the previous part we implemented our first actor and sent message to it. Unfortunately actor was incapable of returning any result of processing this message, which rendered him rather useless. In this episode we will learn how to send reply message to the sender and how to integrate synchronous, blocking API with (by definition) asynchronous system based on message passing.

Before we begin I must draw very strong distinction between an actor (extending Actor trait) and an actor reference of ActorRef type. When implementing an actor we extend Actor trait which forces us to implement receive method. However we do not create instances of actors directly, instead we ask ActorSystem:

val randomOrgBuffer: ActorRef = system.actorOf(Props[RandomOrgBuffer], "buffer") To our great surprise returned object is not of RandomOrgBuffer type like our actor, it's not even an Actor. Thanks to ActorRef, which is a wrapper (proxy) around an actor:

internal state, i.e. fields, of an act…

Your first message - discovering Akka

Akka is a platform (framework?) inspired by Erlang, promising easier development of scalable, multi-threaded and safe applications. While in most of the popular languages concurrency is based on memory shared between several threads, guarded by various synchronization mehods, Akka offers concurrency model based on actors. Actor is a lightweight object which you can interact with barely by sending messages to it. Each actor can process at most one message at a time and obviously can send messages to other actors. Within one Java virtual machine millions of actors can exist at the same time, building a hierarchical parent (supervisor) - children structure, where parent monitors the behaviour of children. If that's not enough, we can easily split our actors between several nodes in a cluster - without modifying a single line of code. Each actor can have internal state (set of fields/variables), but communication can only occur through message passing, never through shared data struct…

Java features applicability

Java language and standard library is powerful, but with great power comes great responsibility. After seeing a lot of user code misusing or abusing rare Java features on one hand and completely forgetting about most basic feature on the other, I decided to compose this summary. This is not a list of requirements and areas every Java developer should explore, know and use. It's quite the opposite! I group Java features in three categories: day to day, occasionally and never (frameworks and libraries only). The rule is simple: if you find yourself using given feature more often then suggested, you are probably over-engineering or trying to build something too general and too reusable. If you don't use given feature often enough (according to my subjective list), you're probably missing some really interesting and important opportunities.
Note that I only focus on Java, JVM and JDK. I do not suggest which frameworks and how likely you should use. Also I assume typical, serv…

Testing Quartz Cron expressions

Declaring complex Cron expressions is still giving me some headaches, especially when some more advanced constructs are used. After all, can you tell when the following trigger will fire "0 0 17 L-3W 6-9 ? *"? Since triggers are often meant to run far in the future, it's desired to test them beforehand and make sure they will actually fire when we think they will.

Quartz scheduler (I'm testing version 2.1.6) doesn't provide direct support for that, but it's easy to craft some simple function based on existing APIs, namely CronExpression.getNextValidTimeAfter() method. Our goal is to define a method that will return next N scheduled executions for a given Cron expression. We cannot request all since some triggers (including the one above) do not have end date, repeating infinitely. We can only depend on aforementioned getNextValidTimeAfter() which takes a date as an argument and returns nearest fire time T1 after that date. So if we want to find second schedul…

Java Coding Conventions considered harmful

There is an official Code Conventions for the Java Programming Language guide published on Oracle site. You would expect this 20+ pages document to be the most complete, comprehensive and authoritative source of good practices, hints and tips with regards to the Java language. But once you start to read it, disappointment followed by frustration and anger increases. I would like to point out the most obvious mistakes, bad practices, poor and outdated advices given in this guide. In case you are a Java beginner, just forget about this tutorial and look for better and more up-to-date reference materials. Let the horror begin!
2.2 Common File Names:
GNUmakefile The preferred name for makefiles. We use gnumake to build our software.gnumake to build Java projects? ant is considered old-school, so is maven. Who uses make to build WARs, JARs, generate JavaDocs...?
3.1.1 Beginning Comments:
All source files should begin with a c-style comment that lists the class name, version information, date…

Where do the stack traces come from?

I believe that reading and understanding stack traces is an essential skill every programmer should posses in order to effectively troubleshoot problems with every JVM language (see also: Filtering irrelevant stack trace lines in logs and Logging exceptions root cause first). So may we start with a little quiz? Given the following piece of code, which methods will be present in the stack trace? foo(), bar() or maybe both?
public class Main { public static void main(String[] args) throws IOException { try { foo(); } catch (RuntimeException e) { bar(e); } } private static void foo() { throw new RuntimeException("Foo!"); } private static void bar(RuntimeException e) { throw e; } } In C# both answers would be possible depending on how the original exception is re-thrown in bar() - throw e overwrites the original stack trace (originating in foo()) with the place where it was thrown again (…