JayView HTML5 Web Sockets

Arya MirInternet and Web Development

Dec 15, 2011 (5 years and 8 months ago)

1,670 views

A quantum leap in scalability for the web

The New Old JayView!
OpenGL ES on Android
Microlog, Logging in Java ME
An in-depth look at the Bluetooth features
Introducing Akka
Simpler scalability, fault-tolerance, concurrency & remoting through actors
Swing Rocks
The last dance?
Agile Testing
– a new profile for testers
Cop and Qi4j
Reviving object-orientation
Sneaky Throw
HTML5
Web Sockets:
A quantum leap in scalability for the web
2010 No. 1 Volume 21
Passion for IT on paper. For us, by all of us.
Jayview
home u
Details page
2
2
We’ve been hard at work on JayView since
2001. Our first efforts were, well, humbling.
Though JayView has always been the place
where Jayway – the founding company – put
its passion for sharing knowledge on cellu-
lose. It was, and still is, for the fun of it all. So
pretty print wasn’t a high priority at first.
We never wrote about ourselves or, for
that matter, how beautiful our customers are
The New Old JayView!
(which they happen to be :-). Not only can
you find our own words in the magazine,
but also that of interesting people from other
companies. We just write about things we like
– or not. Subjects that hopefully affects us all.
It used to be that JayView was all about
Java development and agile methodologies.
However, we matured and finally felt ready
for a reboot and to cover more ground.
In your hand, you hold the first issue of
the new JayView – new subject sections, new
format. What hasn’t changed is the attitude or
our passion for knowledge.
I hope you will enjoy the new old JayView.
Björn Granvik
Chief Editor, JayView
Publication Officer: Thomas Dagsberg / CEO Jayway | Editors: Björn Granvik, Darius Katz, Patrik Nilsson, Katarina Wiberg
Contact: jayview@jayway.com | Jayway: Addresses and telephone numbers on the back | Cover Picture: iStockphoto.com 33981225
Layout and Graphic Design: Peter Kleine / Jayway, Holmbergs i Malmö AB | Print: Holmbergs i Malmö AB, 2010
Free subscription of JayView – enter your information at: http://bit.ly/subscribeJayView
Finally a way to get rid of checking those an-
noying checked exceptions:
public class Sneak {
public static RuntimeException sneakyThrow(Throwable t) {
if ( t == null ) throw new NullPointerException(“t”);
Sneak.<RuntimeException>sneakyThrow0(t);
return null;
}
@SuppressWarnings(“unchecked”)
private static <T extends Throwable> void sneakyThrow0(Throwable t) throws T {
throw (T)t;
}
}
Credit goes to Reinier Zwitserloot and his
mail on Java Posse (http://bit.ly/abYCCF).
Sneaky Throw
Jan Kronquist/Jawyay
3
HTML5 Web Sockets:
A quantum leap
in scalability for the web
Peter Lubbers & Frank Greco/Kaazing Corporation
Lately there has been a lot of buzz around
HTML5 Web Sockets, which defines a full-
duplex communication channel that operates
through a single socket over the Web. HTML5
Web Sockets is not just another incremental en-
hancement to conventional HTTP communica-
tions; it represents a colossal advance, especially
for real-time, event-driven web applications.
HTML5 Web Sockets provides such a dra-
matic improvement from the old, convoluted
“hacks” that are used to simulate a full-duplex
connection in a browser that it prompted
Google’s Ian Hickson – the HTML5 specifica-
tion lead – to say:
Let’s take a look at how HTML5 Web Sockets
can offer such an incredibly dramatic reduc-
tion of unnecessary network traffic and laten-
cy by comparing it to conventional solutions.
Polling, Long-Polling, and
Streaming – Headache 2.0
Normally when a browser visits a web page,
an HTTP request is sent to the web server
that hosts that page. The web server ac-
knowledges this request and sends back the
response.   In many cases – for example, for
stock prices, news reports, ticket sales, traffic
patterns, medical device readings, and so on
– the response could be stale by the time the
browser renders the page. If you want to get
the most up-to-date “real-time” information,
you can constantly refresh that page manu-
ally, but that’s obviously not a great solution.
Current attempts to provide real-time web
applications largely revolve around polling
and other server-side push technologies, the
most notable of which is Comet, which de-
lays the completion of an HTTP response to
deliver messages to the client. Comet-based
push is generally implemented in JavaScript
and uses connection strategies such as long-
polling or streaming.
With polling, the browser sends HTTP
requests at regular intervals and immediately
receives a response.   This technique was the
first attempt for the browser to deliver real-
time information. Obviously, this is a good
solution if the exact interval of message de-
livery is known, because you can synchronize
the client request to occur only when infor-
mation is available on the server. However,
real-time data is often not that predictable,
making unnecessary requests inevitable and
as a result, many connections are opened and
closed needlessly in low-message-rate situa-
tions.
With long-polling, the browser sends a re-
quest to the server and the server keeps the
request open for a set period. If a notifica-
tion is received within that period, a response
containing the message is sent to the client.
If a notification is not received within the set
time period, the server sends a response to
terminate the open request. It is important
to understand, however, that when you have
a high message volume, long-polling does
not provide any substantial performance im-
provements over traditional polling. In fact,
it could be worse, because the long-polling
might spin out of control into an unthrottled,
continuous loop of immediate polls.
With streaming, the browser sends a com-
plete request, but the server sends and main-
tains an open response that is continuously
updated and kept open indefinitely (or for a
set period of time). The response is then up-
dated whenever a message is ready to be sent,
but the server never signals to complete the
response, thus keeping the connection open
to deliver future messages. However, since
streaming is still encapsulated in HTTP, in-
tervening firewalls and proxy servers may
choose to buffer the response, increasing the
latency of the message delivery. Therefore,
many streaming Comet solutions fall back to
long-polling in case a buffering proxy server
is detected. Alternatively, TLS (SSL) connec-
tions can be used to shield the response from
being buffered, but in that case the setup and
tear down of each connection taxes the avail-
able server resources more heavily.
Ultimately, all of these methods for pro-
“Reducing kilobytes of data to 2 bytes… and
reducing latency from 150ms to 50ms is far more
than marginal. In fact, these two factors alone are
enough to make Web Sockets seriously interesting
to Google.”
ARCHITECTURE
4
viding real-time data involve HTTP request
and response headers, which contain lots of
additional, unnecessary header data and in-
troduce latency. On top of that, full-duplex
connectivity requires more than just the
downstream connection from server to cli-
ent. In an effort to simulate full-duplex com-
munication over half-duplex HTTP, many of
today’s solutions use two connections: one for
the downstream and one for the upstream.
The maintenance and coordination of these
two connections introduces significant over-
head in terms of resource consumption and
adds lots of complexity. Simply put, HTTP
wasn’t designed for real-time, full-duplex
communication as you can see in the follow-
ing figure, which shows the complexities asso-
ciated with building a Comet web application
that displays real-time data from a back-end
data source using a publish/subscribe model
over half-duplex HTTP.
Figure 1 – The complexity of
Comet applications
It gets even worse when you try to scale out
those Comet solutions to the masses. Simu-
lating bi-directional browser communica-
tion over HTTP is error-prone and complex
and all that complexity does not scale. Even
though your end users might be enjoying
something that looks like a real-time web ap-
plication, this “real-time” experience has an
outrageously high price tag. It’s a price that
you will pay in additional latency, unneces-
sary network traffic and a drag on CPU per-
formance.
HTML5 Web Sockets
to the Rescue!
Defined in the Communications section
of the HTML5 specification, HTML5 Web
Sockets represents the next evolution of web
communications – a full-duplex, bidirec-
tional communications channel that operates
through a single socket over the Web. HTML5
Web Sockets provides a true standard that
you can use to build scalable, real-time web
applications. In addition, since it provides a
socket that is native to the browser, it elimi-
nates many of the problems Comet solutions
are prone to. Web Sockets removes the over-
head and dramatically reduces complexity.
To establish a WebSocket connection, the
client and server upgrade from the HTTP
protocol to the WebSocket protocol during
their initial handshake, as shown in the fol-
lowing example:
Example 1 – The WebSocket handshake
(browser request and server response)
GET /text HTTP/1.1\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
Host: www.websocket.org\r\n
…\r\n
HTTP/1.1 101 WebSocket Protocol
Handshake\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
…\r\n
Once established, WebSocket data frames can
be sent back and forth between the client and
the server in full-duplex mode. Both text and
binary frames can be sent full-duplex, in ei-
ther direction at the same time. The data is
minimally framed with just two bytes. In the
case of text frames, each frame starts with a
0x00 byte, ends with a 0xFF byte, and con-
tains UTF-8 data in between. WebSocket text
frames use a terminator, while binary frames
use a length prefix.
Note: although the Web Sockets protocol
is ready to support a diverse set of clients, it
cannot deliver raw binary data to JavaScript,
because JavaScript does not support a byte
type. Therefore, binary data is ignored if the
client is JavaScript – but it can be delivered to
other clients that support it.
The Showdown: Comet vs.
HTML5 Web Sockets
So how dramatic is that reduction in unnec-
essary network traffic and latency? Let’s com-
pare a polling application and a WebSocket
application side by side.
For the polling example, I created a simple
web application in which a web page requests
real-time stock data from a RabbitMQ mes-
sage broker using a traditional publish/sub-
scribe model. It does this by polling a Java
Servlet that is hosted on a web server. The
RabbitMQ message broker receives data from
a fictitious stock price feed with continuously
updating prices. The web page connects and
subscribes to a specific stock channel (a topic
on the message broker) and uses an XML-
HttpRequest to poll for updates once per
second. When updates are received, some
calculations are performed and the stock data
is shown in a table as shown in the following
image.
Figure 2 – A JavaScript stock ticker
application
Note: The back-end stock feed actually pro-
duces a lot of stock price updates per second,
so using polling at one-second intervals is
actually more prudent than using a Comet
long-polling solution, which would result in
a series of continuous polls. Polling effectively
throttles the incoming updates here.
It all looks great, but a look under the hood
reveals there are some serious issues with this
application. For example, in Mozilla Firefox
Internet
LAN
Your RIA client
application
Silverlight or
Flash plug-in
Browser
Lots to build
Costly server resources
devoted to translating
LAN protocol to HTTP
Can’t manage the actual
client — end user and data
source aren’t really connected
Messy, slow, error prone
HTTP - Long polling, etc.)
Messaging
Broker
$
datasource
App
Server
HTTP
Server
AMQP
Client
Custom code to
simulate a realtime
2-way connection
C OMPANY S Y MB OL P R I C E C HANGE S PAR K L I NE OP E N L OW HI GH
T HE WALT DI S NE Y C OMPANY DIS
27.65 0.56 27.09 24.39 29.80
GAR MI N LT D. GRMN
35.14 0.35 34.79 31.31 38.27
S ANDI S K C OR P OR AT I ON
SNDK 20.11 -0.13 20.24 18.22 22.26
GOODR I C H C OR P OR AT I ON GR
49.99 -2.35 52.34 47.11 57.57
NV I DI A C OR P OR AT I ON NVDA
13.92 0.07 13.85 12.47 15.23
C HE V R ON C OR P OR AT I ON CVX
67.77 -0.53 68.30 61.49 75.11
T HE AL L S TAT E C OR P OR AT I ON ALL
30.88 -0.14 31.02 27.92 34.12
E X X ON MOB I L C OR P OR AT I ON XOM
65.66 -0.86 66.52 59.87 73.17
ME T L I F E I NC. MET
35.58 -0.15 35.73 32.16 39.30
Figure 1
Figure 2
ARCHITECTURE
5
with Firebug (a Firefox add-on that al-
lows you to debug web pages and monitor
the time it takes to load pages and execute
scripts), you can see that GET requests
hammer the server at one-second intervals.
Turning on Live HTTP Headers (another
Firefox add-on that shows live HTTP header
traffic) reveals the shocking amount of head-
er overhead that is associated with each re-
quest. The following two examples show the
HTTP header data for just a single request
and response.
Example 2 – HTTP request header
GET /PollingStock//PollingStock HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
Accept: text/html,application/xhtml+xml,application/
xml;q=0.9,*/*;q=0.8
Accept-Language: en-us
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.example.com/PollingStock/
Cookie: showInheritedConstant=false; showInheritedProtectedConst
ant=false; showInheritedProperty=false; showInheritedProtectedPr
operty=false; showInheritedMethod=false; showInheritedProtectedM
ethod=false; showInheritedEvent=false; showInheritedStyle=false;
showInheritedEffect=false
Example 3 – HTTP response header
HTTP/1.x 200 OK
X-Powered-By: Servlet/2.5
Server: Sun Java System Application Server 9.1_02
Content-Type: text/html;charset=UTF-8
Content-Length: 21
Date: Sat, 07 Nov 2009 00:32:46 GMT
Just for fun, I counted all the characters. The
total HTTP request and response header
information overhead contains 871 bytes
and that does not even include any data! Of
course, this is just an example and you can
have less than 871 bytes of header data, but
I have also seen cases where the header data
exceeded 2000 bytes. In this example applica-
tion, the data for a typical stock topic message
is only about 20 characters long. As you can
see, it is effectively drowned out by the exces-
sive header information, which was not even
required in the first place!
So, what happens when you deploy this
application to a large number of users? Let’s
take a look at the network throughput for just
the HTTP request and response header data
associated with this polling application in
three different use cases.
• Use case A: 1,000 clients polling every
second:
Network throughput is (871 x 1,000) =
871,000 bytes = 6,968,000 bits per second
(6.6 Mbps)
• Use case B: 10,000 clients polling every
second:
Network throughput is (871 x 10,000) =
8,710,000 bytes = 69,680,000 bits per sec-
ond (66 Mbps)
• Use case C: 100,000 clients polling every
1 second:
Network throughput is (871 x 100,000) =
87,100,000 bytes = 696,800,000 bits per
second (665 Mbps)
That’s an enormous amount of unnecessary
network throughput! If only we could just
get the essential data over the wire. Well,
guess what? You can with HTML5 Web Sock-
ets! I rebuilt the application to use HTML5
Web Sockets, adding an event handler to the
web page to asynchronously listen for stock
update messages from the message broker
(check out the many how-tos and tutorials
on www.tech.kaazing.com/documentation
for more information on how to build a Web-
Socket application). Each of these messages is
a WebSocket frame that has just two bytes of
overhead (instead of 871). Take a look at how
that affects the network throughput overhead
in our three use cases.
• Use case A: 1,000 clients receive 1 message
per second:
Network throughput is (2 x 1,000) = 2,000
bytes = 16,000 bits per second (0.015
Mbps)
• Use case B: 10,000 clients receive 1 mes-
sage per second:
Network throughput is (2 x 10,000) =
20,000 bytes = 160,000 bits per second
(0.153 Kbps)
• Use case C: 100,000 clients receive 1 mes-
sage per second:
Network throughput is (2 x 100,000) =
200,000 bytes = 1,600,000 bits per second
(1.526 Kbps)
As you can see in the following figure, HTML5
Web Sockets provide a dramatic reduction of
unnecessary network traffic compared to the
polling solution.
Figure 3 – Comparison of the
unnecessary network throughput
overhead between the polling
and the WebSocket applications
And what about the reduction in latency?
Take a look at the following figure. In the top
half, you can see the latency of the half-duplex
polling solution. If we assume, for this exam-
ple, that it takes 50 milliseconds for a message
to travel from the server to the browser, then
the polling application introduces a lot of ex-
tra latency, because a new request has to be
sent to the server when the response is com-
plete. This new request takes another 50ms
and during this time the server cannot send
any messages to the browser, resulting in ad-
ditional server memory consumption.
In the bottom half of the figure, you see
the reduction in latency provided by the
WebSocket solution. Once the connection is
upgraded to WebSocket, messages can flow
from the server to the browser the moment
they arrive. It still takes 50 ms for messages
to travel from the server to the browser, but
the WebSocket connection remains open so
there is no need to send another request to
the server.
ARCHITECTURE
6
HTML5 Web Sockets and the
Kaazing WebSocket Gateway
Today, only Google’s Chrome browser sup-
ports HTML5 Web Sockets natively, but oth-
er browsers will soon follow. To work around
that limitation, however, Kaazing WebSocket
Gateway provides complete WebSocket emu-
lation for all the older browsers (I.E. 5.5+,
Firefox 1.5+, Safari 3.0+, and Opera 9.5+), so
you can start using the HTML5 WebSocket
APIs today.
WebSocket is great, but what you can do
once you have a full-duplex socket connec-
tion available in your browser is even greater.
To leverage the full power of HTML5 Web
Sockets, Kaazing provides a ByteSocket li-
brary for binary communication and high-
er-level libraries for protocols like Stomp,
AMQP, XMPP, IRC and more, built on top of
WebSocket.
For example, if you use a high-level library
for protocols such as Stomp or AMQP (sup-
plied with the Kaazing Gateway), you can talk
directly to backend message brokers like the
RabbitMQ broker described in the exam-
ple. By having a direct connection to services,
there is no need for additional application
server logic to translate those bi-directional,
full-duplex TCP backend protocols to uni-
directional, half-duplex HTTP connections;
the browser can simply understand these pro-
tocols natively.
Summary
HTML5 Web Sockets provides an enormous
step forward in the scalability of the real-time
web. As you have seen in this article, HTML5
Web Sockets can provide a 500:1 or – depend-
ing on the size of the HTTP headers – even a
1000:1 reduction in unnecessary HTTP head-
er traffic and 3:1 reduction in latency. That is
not just an incremental improvement; that is
a revolutionary jump – a quantum leap!
Kaazing WebSocket Gateway makes
HTML5 WebSocket code work in all the
browsers today, while providing additional
protocol libraries that allow you to harness
the full power of the full-duplex socket con-
nection that HTML5 Web Sockets provides
and communicate directly to back-end ser-
vices. For more information about Kaazing
WebSocket Gateway, visit www.kaazing.com
and the Kaazing technology network at
tech.kaazing.com.
700,000,000
600,000,000
500,000,000
400,000,000
300,000,000
200,000,000
100,000,000
0
Bits per second
Polling
Web Sockets
Use Case A Use Case B Use Case C
6,968,000
16,000
69,680,000
160,000
696,800,000
1,600,000
Request 1
Response 1
Request 2
Response 2
Request n
Response n
WebSocket
Upgrade
WebSocket
Frame 1
WebSocket
Frame 2
WebSocket
Frame 3
WebSocket
Frame 4
WebSocket
Frame n
Server
Message
Message
Message
Web SocketsPolling
Browser
Server
Browser
Message
Message
Message
Message
Message
Time 50ms 100ms 150ms 200ms 250ms
Time 50ms 100ms 150ms 200ms 250ms
Messaging
Service
Kaazing
WebSocket
Gateway
Internet
Trading Gateway
News Feed
Payment System
Database Storage
Application Logic
Web Service
ERP/CRM System
Desktop Solution
Figure 4 – Latency comparison between
the polling and WebSocket applications
Figure 5 – Kaazing WebSocket Gateway
extends TCP-based messaging to the
browser with ultra high performance
Figure 3
Figure 4
Figure 5
ARCHITECTURE
7
About the Authors
Peter Lubbers is the Director of Documen-
tation and Training at Kaazing where he
oversees all aspects of documentation and
training. Peter is the co-author of the Apress
book Pro HTML5 Programming and teaches
HTML5 training courses. An HTML5 and
WebSocket enthusiast, Peter frequently
speaks at international events.
Prior to joining Kaazing, Peter worked as
an information architect at Oracle, where he
wrote many books, such as the award-win-
ning Oracle Application Server Portal Con-
figuration Guide and the Oracle Application
Server Developer’s Guide for Microsoft Of-
fice. Peter also develops documentation au-
tomation solutions and two of his inventions
are patented.
Before joining Oracle, Peter architected
and developed the internationalized Micro-
soft Office User Specialist Testing Frame-
work. Peter was also a technical reviewer for
the book “Pro JSF and Ajax: Building Rich
Internet Components” (Apress, 2006).
A native of the Netherlands, Peter served
as a Special Forces commando in the Royal
Dutch Green Berets. In his spare time (ha!)
Peter likes to run ultra-marathons. He is the
2007 and 2009 ultrarunner.net series champi-
on and three-time winner of the Tahoe Super
Triple marathon. Peter lives on the edge of the
Tahoe National Forest and loves to run in the
Sierra Nevada foothills and around Lake Ta-
hoe (preferably in one go!).
Frank Greco is the founder of the New
York Java Special Interest Group (NYJava-
SIG), one of the largest Java Users Groups
(JUGs) on the planet with almost 5,000 active
members in the local Java community. The
References
• HTML5 Web Sockets Specification: http://dev.w3.org/html5/websockets/
• WebSockets.org: http://www.websockets.org
• Kaazing corporation: http://www.kaazing.com
• Download the Kaazing WebSocket Gateway: http://www.kaazing.com/download
• Skills Matter HTML5 Communication Training Courses: http://skillsmatter.com/expert-profile/java-jee/peter-lubbers
• Book: Pro HTML5 Programming: Powerful APIs for Richer Internet Application Development (Link)
Frank Greco
NYJavaSIG has had some of the most famous
Java luminaries speak at their meetings; in-
cluding Java Champions: Rod Johnson, Brian
Goetz, Doug Lea and Josh Bloch. Their mem-
bers are very enthusiastic and, like most New
Yorkers, don’t hesitate to ask tough questions
of their monthly speakers.
Frank has a long history as a “Champion”
of the Java Platform; he taught a developer
track session at the very first Java Day back in
September 1995 in New York and started the
NYJavaSIG that afternoon. Frank has been
involved with software development for over
10 years and has worked on sophisticated ar-
chitectures, innovative user interfaces, mobile
computing and next-generation collaborative
financial systems. Frank is both a Java com-
munity leader as well as a luminary technolo-
gist working for Kaazing.
Peter Lubbers
ARCHITECTURE
8
Setting up
an OpenGL ES View
Setting up an OpenGL view has never been
hard, and on Android it is still very easy.
There are only two things you need to get
started. The surface to draw on and the class
that draws.
GLSurfaceView
GLSurfaceView is a API class in Android 1.5
and later, that helps you write OpenGL ES
applications. It’s a really good start because it
connects the OpenGL ES to the view system.
It is also constructed to fit in with the Activity
life-cycle. If you want to get going fast with
your OpenGL ES application this is where
you should start.
The only thing you need to do when you
create a GLSurfaceView is to tell what render-
er to use. It’s done with this function:
public void setRenderer(
GLSurfaceView.Renderer renderer)
GLSurfaceView.Renderer
GLSurfaceView.Renderer is a generic ren-
der interface. In your implementation of this
renderer you should put all your calls to the
OpenGL ES system. There are three functions
to implement in this interface:
onSurfaceCreated
onSurfaceCreated is called when the surface
is created or recreated. Here you should put
the things you only want to call on once or
OpenGL ES on Android
Open Graphics Library Embedded Systems or OpenGL
ES is the most obvious way to go if you want 3D on
your device. As a former game developer I am thrilled
about being able to write 3D graphics on my device.
This article is an attempt to get you going with your
own 3D creations.
Per-Erik Bergman/Jayway
EMBEDDED
9
things that you don’t need to change within
the rendering cycle. Turning on and off the
z-buffer or setting the color that OpenGL ES
will use to clear the screen with are typical
things to have here.
public void onSurfaceCreated(
GL10 gl, EGLConfig config)
onDrawFrame
onDrawFrame is called every time the cur-
rent frame should be drawn. You put every-
thing that you want to be drawn here.
public void onDrawFrame(GL10 gl)
onSurfaceChanged
onSurfaceChanged is called when the sur-
face changes size. If you flip the device and
it changes orientation this function is called.
A good thing to put here is the ratio calcula-
tions. Since OpenGL ES by default have the
ratio 1:1 it will look weird unless you have a
square display.
public void onSurfaceChanged(
GL10 gl, int width, int height)
Putting it together
First thing that we need to do is to create our
Activity. Most times this is done when you
create the project. I call this Activity Open-
GLExample.
GLSurfaceView
package se.jayway.opengl.tutorial;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class OpenGLExample extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView view = new GLSurfaceView(this);
view.setRenderer(new OpenGLRenderer());
setContentView(view);
}
}
GLSurfaceView.Renderer
The renderer takes a little bit more work to
setup.
EMBEDDED
10
OpenGLRenderer.java
package se.jayway.opengl.tutorial;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
public class OpenGLRenderer implements Renderer {
/*
* (non-Javadoc)
*
* @see
* android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.
* microedition.khronos.opengles.GL10, javax.microedition.khronos.
* egl.EGLConfig)
*/
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the background color to black ( rgba ).
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // OpenGL docs.
// Enable Smooth Shading, default not really needed.
gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.
// Depth buffer setup.
gl.glClearDepthf(1.0f);// OpenGL docs.
// Enables depth testing.
gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.
// The type of depth testing to do.
gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.
// Really nice perspective calculations.
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
GL10.GL_NICEST);
}
/*
* (non-Javadoc)
*
* @see
* android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.
* microedition.khronos.opengles.GL10)
*/
public void onDrawFrame(GL10 gl) {
// Clears the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
GL10.GL_DEPTH_BUFFER_BIT);
}
/*
* (non-Javadoc)
*
* @see
* android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.
* microedition.khronos.opengles.GL10, int, int)
*/
public void onSurfaceChanged(GL10 gl, int width, int height) {
// Sets the current view port to the new size.
gl.glViewport(0, 0, width, height);// OpenGL docs.
// Select the projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.
// Reset the projection matrix
gl.glLoadIdentity();// OpenGL docs.
// Calculate the aspect ratio of the window
EMBEDDED
11
GLU.gluPerspective(gl, 45.0f,
(float) width / (float) height,
0.1f, 100.0f);
// Select the modelview matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.
// Reset the modelview matrix
gl.glLoadIdentity();// OpenGL docs.
}
}
Fullscreen
Just add these lines in the OpenGLExample
class and you will get fullscreen.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); // (NEW)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); // (NEW)
... // Previous code.
}
This is pretty much all you need to get your
view up and running. If you compile and run
it you will see a nice black screen.
Building a polygon
3D models are built up with smaller elements
(vertices, edges, faces, and polygons) which
can be manipulated individually.
Vertex
A vertex (vertices in plural) is the smallest
building block of a 3D model. A vertex is a
point where two or more edges meet. In a 3D
model a vertex can be shared between all con-
nected edges, faces and polygons. A vertex
can also represent the position of a camera or
a light source. You can see a vertex in the im-
age to the right marked in yellow.
To define the vertices on android we de-
fine them as a float array that we put into a
byte buffer to gain better performance. Look
at the image and code to the right and match
the vertices marked on the image to the code.
private float vertices[] = {
// 0, Top Left
-1.0f, 1.0f, 0.0f,
// 1, Bottom Left
-1.0f, -1.0f, 0.0f,
// 2, Bottom Right
1.0f, -1.0f, 0.0f,
// 3, Top Right
1.0f, 1.0f, 0.0f,
};
Vertex
EMBEDDED
Don’t forget that a float is 4 bytes and to multi-
ply it by the number of vertices to get the right
size on the allocated buffer.
// a float is 4 bytes, therefore we
// multiply the number of
// vertices by 4.
ByteBuffer vbb
= ByteBuffer.allocateDirect(
vertices.length * 4);
vbb.order(
ByteOrder.nativeOrder());
FloatBuffer vertexBuffer
= vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
12
OpenGL ES has a pipeline with functions to
apply when you tell it to render. Most of these
functions are not enabled by default so you
have to remember to turn on the ones you
like to use. You might also need to tell these
functions what to work with. So in the case of
our vertices we need to tell OpenGL ES that
it’s okay to work with the vertex buffer we cre-
ated and we also need to tell where it is.
// Enabled the vertex buffer for writing and to be used during rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
When you are done with the buffer don’t for-
get to disable it.
// Disable the vertices buffer.
gl.glDisableClientState(
GL10.GL_VERTEX_ARRAY);
Edge
An edge is a line between two vertices. They
are border lines of faces and polygons. In a
3D model an edge can be shared between two
adjacent faces or polygons. Transforming an
edge affects all connected vertices, faces and
polygons. In OpenGL ES you don’t define
the edges, you rather define the face by giv-
ing them the vertices that would build up the
three edges. If you would like modify an edge
you change the two vertices that makes the
edge. You can see an edge in the image to the
right marked in yellow.
Face
A face is a triangle, a surface between three
corner vertices and three surrounding edges.
Transforming a face affects all connected ver-
tices, edges and polygons.
The order does matter
When winding up the faces it’s important to
do it in the right direction, because the direc-
tion defines what side will be the front face
and what side will be the back face. Why this
is important is because to gain performance
we don’t want to draw both sides so we turn
off the back face. So it’s a good idea to use the
same winding all over your project. It’s pos-
sible to change what direction that defines the
front face with glFrontFace.
gl.glFrontFace(GL10.GL_CCW);
To make OpenGL skip the faces that are turned
into the screen, you can use something called
back-face culling. This determines whether a
polygon of a graphical object is visible by check-
ing if the face is wound up in the right order.
Edge
Face
EMBEDDED
13
gl.glEnable(GL10.GL_CULL_FACE);
It’s of cource possible to change what face side
should be drawn or not.
gl.glCullFace(GL10.GL_BACK);
Polygon
Time to wind the faces. Remember, we have
decided to go with the default winding,
meaning counter-clockwise. Look at the im-
age and the code to the right to see how to
wind up this square.
private short[] indices = {
0, 1, 2, 0, 2, 3 };
To gain some performance we also put these
ones in a byte buffer.
// short is 2 bytes, therefore we multiply the number of vertices by 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indicesBuffer = ibb.asShortBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
Don’t forget that a short is 2 bytes and to mul-
tiply it by the number of indices to get the right
size on the allocated buffer.
Render
Time to get something on the screen, there
are two functions used to draw and we have
to decide which one to use.
The two functions are:
public abstract void
glDrawArrays(int mode,
int first, int count)
glDrawArrays draws the vertices in the order
they are specified in the construction of our
verticesBuffer.
public abstract void glDrawElements(
int mode, int count, int type,
Buffer indices)
glDrawElements need a little bit more infor-
mation to be able to draw. It needs to know
the order in which to draw the vertices, it
needs the indicesBuffer.
Since we already created the indicesBuffer
I’m guessing that you’ve figured out that’s the
way we are going.
What’s common with these functions is
that they both need to know what it is they
should draw, what primitives to render. Since
there are various ways to render the indices
and some of them are good to know about for
debugging reasons, I’ll go through them all.
Polygon
EMBEDDED
14
What primitives to render
GL_POINTS
Draws individual points on the screen.
GL_LINE_STRIP
Series of connected line segments.
GL_LINE_LOOP
Same as above, with a segment added be-
tween last and first vertices.
GL_LINES
Pairs of vertices interpreted as individual line
segments.
GL_TRIANGLES
Triples of vertices interpreted as triangles.
GL_TRIANGLE_STRIP
Draws a series of triangles (three-sided poly-
gons) using vertices v0, v1, v2, then v2, v1, v3
(note the order), then v2, v3, v4, and so on.
The ordering is to ensure that the triangles are
all drawn with the same orientation so that
the strip can correctly form part of a surface.
GL_TRIANGLE_FAN
Same as GL_TRIANGLE_STRIP, except that
the vertices are drawn v0, v1, v2, then v0, v2,
v3, then v0, v3, v4, and so on.
I think that the GL_TRIANGLES is the
easiest to use so we go with that one for now.
v1
v2
v3
v4
v7
v5
v6
v0
v1
v2
v3
v4
v7
v5
v6
v0
v1
v2
v3
v4
v7
v5
v6
v0
v1
v2
v3
v4
v7
v5
v6
v0
v1
v2
v3
v4
v5
v0
v1
v2
v3
v4
v5
v0
v1
v2
v3
v4
v5
v0
EMBEDDED
15
Putting it all together
So let’s put our square together in a class.
package se.jayway.opengl.tutorial;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Square {
// Our vertices.
private float vertices[] = {
-1.0f, 1.0f, 0.0f, // 0, Top Left
-1.0f, -1.0f, 0.0f, // 1, Bottom Left
1.0f, -1.0f, 0.0f, // 2, Bottom Right
1.0f, 1.0f, 0.0f, // 3, Top Right
};

// The order we like to connect them.
private short[] indices = { 0, 1, 2, 0, 2, 3 };

// Our vertex buffer.
private FloatBuffer vertexBuffer;
// Our indice buffer.
private ShortBuffer indicesBuffer;

public Square() {
// a float is 4 bytes, therefore we multiply the number of
// vertices by 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);

// short is 2 bytes, therefore we multiply the number of
// vertices by 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indicesBuffer = ibb.asShortBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
}

/**
* This function draws our square on screen.
* @param gl
*/
public void draw(GL10 gl) {
// Counter-clockwise winding.
gl.glFrontFace(GL10.GL_CCW);
// Enable face culling.
gl.glEnable(GL10.GL_CULL_FACE);
// What faces to remove with the face culling.
gl.glCullFace(GL10.GL_BACK);

// Enable the vertices buffer for writing and to be used during
// rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Specifies the location and data format of an array of vertex
EMBEDDED
16
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indicesBuffer);

// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
// Disable face culling.
gl.glDisable(GL10.GL_CULL_FACE);
}
}
We have to initialize our square in the
OpenGLRenderer class.
// Initialize our square.
Square square = new Square();
And in the draw function call on the square
to draw.
public void onDrawFrame(GL10 gl) {
// Clears the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Draw our square.
square.draw(gl); // ( NEW )
}
If you run the application now the screen is
still black. Why? Because OpenGL ES renders
from where the current position is, that by
default is at point: 0, 0, 0 the same position
that the view port is located. And OpenGL ES
doesn’t render the things that are too close to
the view port. The solution to this is to move
the draw position a few steps into the screen
before rendering the square:
// Translates 4 units into the
// screen.
gl.glTranslatef(0, 0, -4);
I will talk about the different transformations
in the next tutorial.
Run the application again and you will see
that the square is drawn but quickly moves
further and further into the screen. OpenGL
ES doesn’t reset the drawing point between
the frames. That you will have to do yourself:
// Replace the current matrix with
// the identity matrix gl.
glLoadIdentity();
Now if you run the application you will see
the square on a fixed position.
References
The info used in this tutorial is collected from:
• Android Developers | http://developer.android.com/
• OpenGL ES 1.1 Reference Pages | http://www.khronos.org/opengles/sdk/1.1/docs/man/
If you are interested in more information, go to our team blog at: http://blog.jayway.com/
EMBEDDED
17
Microlog, Logging in Java ME
– An in-depth look at the Bluetooth features
Microlog is an open-source logging library that consists
of a large number of features. It will feel familiar to
anyone who has used Log4J before since it provides
very similar APIs and configuration options. Built and
designed for small and resource constrained devices,
it is specifically created to provide a lightweight and
flexible logging solution for Java ME. The project is
licensed under the Apache Software License V2 and is
therefore considered safe to use in both open-source
and commercial proprietary software.
Jarle Hansen/Brunel University & EDB Business Partner
EMBEDDED
18
This article will start with a quick introduc-
tion on how you use Microlog and the basic
features. Then, after the basics a more in-
depth look at the Bluetooth features is pre-
sented. All examples in this article was cre-
ated with Microlog version 2.2.4.
The Basics
Microlog can be configured in several ways.
You have the option to hard code the append-
ers and patterns you want to use directly into
the code. This is obviously not recommended
as it becomes hard to change. For all updates
you would have to re-compile the code. Also,
mixing configuration parameters and appli-
cation logic is often not a good practice in
general. The best ways to configure Microlog
is to either use a properties file or add the con-
figuration values to the JAD-file of the proj-
ect. The examples shown in this article only
use a properties-file for the configuration. If
you want to use the JAD-file you simply add
the MidletPropertyConfigurator instead of
the PropertyConfigurator.
There are a large number of appenders
available in Microlog. This article gives a de-
tailed description of the BluetoothSerialAp-
pender, but the table to the right shows the
different options that are available.
Let’s start by looking at a very simple ex-
ample that consists of a MIDlet and a micro-
log.properties file. A simple microlog.proper-
ties example:
microlog.level=DEBUG
microlog.appender=ConsoleAppender
microlog.formatter=SimpleFormatter
A very simple logger MIDlet:
Appender Description
ConsoleAppender Use the emulator and log in the output win-
dow.
CanvasAppender View the log on the device.
FormAppender View the log on the device.
RecordStoreAppender View the log on the device.
FileAppender To have a log-file to view on your computer.
MemoryBufferAppender View the log on the device.
BluetoothSerialAppender Log from the device to your computer and
view the log in real time.
HttpAppender Log to a HTTP server.
SMSBufferAppender Send an SMS when something goes wrong.
MMSBufferAppender Send an MMS or e-mail when something goes
wrong.
SocketAppender Log to a socket server.
SyslogAppender Log to a syslog daemon on a remote server.
A syslog daemon is a standard logging server
that is available on most common operating
systems.
S3BufferAppender/S3FileAppender Log to the cloud, such as an Amazon S3 ac-
count. Any S3 browser can view the file.
EMBEDDED
public class LoggingMidlet extends MIDlet implements CommandListener {
private static final Logger logger
= LoggerFactory.getLogger(LoggingMidlet.class);
private final Form form = new Form(“LoggingMidlet”);
private final Command logCommand
= new Command(“Log”, Command.OK, 1);
private final Command exitCommand
= new Command(“Exit”, Command.EXIT, 1);
public LoggingMidlet() {
// Configure Microlog
PropertyConfigurator.configure();
}
protected void startApp() throws MIDletStateChangeException {
form.addCommand(logCommand);
form.addCommand(exitCommand);
form.setCommandListener(this);

Display.getDisplay(this).setCurrent(form);
logger.info(“MIDlet started”);
}
19
In the constructor of the MIDlet the microlog.
properties file is loaded. By using the MIDlet
constructor you are certain that it is only ex-
ecuted once. The application will simply log
a text when it starts and then the user can ei-
ther push the “Log”-button to create new log
statements or the “Exit”-button to shutdown
the application. In the destroyApp() method
LoggerFactory.shutDown() is called. This will
shutdown Microlog gracefully by closing all
open resources before exiting.
The Logger variable is added as a static fi-
nal constant with the class name as input. By
simply calling logger.fatal/error/warn/info/
debug/trace you are able to log a message. It
is also possible to log an exception that has
occurred in the application by using the same
method names as previously mentioned.
These methods take two input values, the log
message and the exception.
logger.debug(“Unable to open the “
+ “network connection”,
throwableobj);
The microlog.formatter-property is used to
select the format of the log output. In the mi-
crolog.properties shown in the example we
used the SimpleFormatter. As the name sug-
gests this provides a simple format that uses a
default pattern to print the output messages.
2222:[DEBUG]-The Log button was pushed
If you want to change the format it is possible
to customize the output. Maybe you want the
date and the classname in the beginning of all
log statements, this is where the PatternFor-
matter comes in handy. This formatter gives
you the opportunity to provide your own pat-
tern that is used to format the log statements.
The PatternFormatter is easily configured by
adding these properties to your configuration:
microlog.formatter=PatternFormatter
microlog.formatter.PatternFormatter
.pattern=%d %c [%P] %m %T
EMBEDDED
protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
logger.info(“Exiting MIDlet”);
LoggerFactory.shutdown();
}
protected void pauseApp() {}
public void commandAction(final Command command, final Displayable displayable) {
if(command == logCommand) {
logger.debug(“The Log button was pushed”);
} else if(command == exitCommand) {
logger.debug(“The Exit button was pushed”);
notifyDestroyed();
}
}
}
20
The ConsoleAppender now prints the log
statements like this:
17:20:11,121 LoggingMidlet [DEBUG] The Log button was pushed
The PatternFormatter provides many cus-
tomization options. Take a look at the table
below and use them in the combination that
works best for you.
Pattern Prints
%i The client id
%c The name of the logger
%d The absolute time
%m The logged message
%P The priority, i.e. level of the message
%r The relative time of the logging
%t The thread Name
%T The throwable object
Now that you have seen the basics of what
Microlog can do, lets move on to one of the
really exciting features; the Bluetooth Ap-
pender.
Using the Bluetooth logging
features
Using Bluetooth for logging in Java ME de-
vices provides several benefits:
• Most mobile phones include Bluetooth
capabilities so hardware support is usually
not an issue.
• The Microlog Bluetooth GUI provides
real-time logging. You will be able to
monitor your application when it is run-
ning and do not need to read a file or the
RMS memory (Record Management Store,
using the RecordStoreAppender) after the
application is closed.
• You can connect several devices to the
Bluetooth server at the same time.
• It is easy to set up. Microlog handles all the
network communication for you.
• Connecting and sending information with
Bluetooth to the Microlog Server is fast.
This section provides a few useful tips on how
you can get the most out of the Bluetooth fea-
tures that are available in Microlog. Be aware
that the Bluetooth appender is not always the
best choice. In certain cases you might be de-
pendent on the Bluetooth connection in your
own application. Microlog will in these cases
affect the overall Bluetooth performance in
the system and it might be better to use other
features like HttpAppender or RecordSto-
reAppender. With that being said, the Blue-
tooth appender does provide several interest-
ing features and will in many situations be
one of the best ways to use Microlog.
The receiving application
The Microlog distribution comes packaged
with an application that receives the logs
called Microlog Bluetooth Server. This is a
Java SE application (requiring Java 1.5 or
newer) and runs perfectly on both Windows
and Linux. For all Bluetooth communication
the server application uses an open-source li-
brary called BlueCove (http://bluecove.org/).
EMBEDDED
21
The Microlog Bluetooth Server has several
useful features. When you start the applica-
tion it will present the Server URL. This is
the entire connection String and includes the
Bluetooth address. It is also possible to find
the Bluetooth address by pressing Help ->
Server Bluetooth address. This is important,
since you should use this address in your cli-
ent configuration. When a client connects a
new entry will appear on the left side of the
window, “Nokia-e61” in the screenshot. The
name that is shown is the Bluetooth name of
your device. It is possible to connect several
clients simultaneously and any new connec-
tions will just be shown in this list. All logging
data is added to the main part of the window.
This text area that consists of the logging
statements is updated runtime. Any new log
messages received from the clients are added
instantly to the UI. It is also possible to save
the log content to a file, you can save it as a
txt-file and open it in your favourite editor
later. A very convenient option since text
highlighting and search functions in external
editors are a powerful and very useful tool.
In the example MIDlet previously shown
in this article the LoggerFactory.shutDown()
method was used when exiting the MIDlet.
This will make sure all resources are cleaned
up properly. For the BluetoothSerialAppend-
er this will close the open connection and the
Microlog Bluetooth server will remove the
mobile device from the list of connected cli-
ents.
Configuration
As previously mentioned we recommend us-
ing a properties- or JAD-file to configure the
appenders. One of the most productive ways
of using Microlog in the development stage
of your project is to add both the Console-
Appender and BluetoothSerialAppender as
shown in the example below. The advantage
of this setup is flexibility. When you run the
MIDlet in an emulator you will be able to
view all logging statements in the Console.
Then, when you decide to deploy the applica-
tion on the mobile device the BluetoothSeri-
alAppender will be used. No need to change
the configuration, it will simply work on both
the emulator and mobile device with exactly
the same configuration.
Microlog.properties using both the Blue-
toothSerialAppender and ConsoleAppender:
microlog.level=DEBUG
microlog.appender=BluetoothSerialAppender;ConsoleAppender
microlog.formatter=SimpleFormatter
microlog.appender.BluetoothSerialAppender.btAddress=002608BDB48C
Another important aspect to notice in this
configuration is the microlog.appender.Blue-
toothSerialAppender.btAddress-property.
This tells Microlog where it should connect
to, the server Bluetooth address. Adding this
property in an external resource and not in
the actual source code makes it much easier
to change in the future. In most cases there
are no differences in your code if you are
using a ConsoleAppender or BluetoothSeri-
alAppender, or any other appender for that
matter. This is how it should be, you should be
able to change the appender in the configura-
tion file and it should simply work.
Summary
Using a logging library is in most software
development projects a very useful tool to
help the developer understand exactly what
is happening in an executing application and
is especially useful when there are bugs and
other problems. For Java ME projects the Mi-
crolog open-source library is available to pro-
vide a flexible and Log4J-like structure to the
logging and configuration. This article gave a
quick overview of the basics and then contin-
ued by going more in-depth when looking at
the Bluetooth logging features.
Hopefully you have gained little insight
into how Microlog works and how to use it
in your own projects. The main recommenda-
tions presented in this article are:
1. Using multiple appenders is a very useful
and flexible way of configuring Microlog.
One good tip is to use the both the Con-
soleAppender and BluetoothSerialAp-
pender in the development stage of your
project to get log statements sent directly
to your computer. This configuration will
work in an emulator as well as on a real
device by using the Microlog Bluetooth
server.
2. Use an external resource, like microlog.
properties or JAD-file, for the configura-
tion. Remember to add the microlog.
appender.BluetoothSerialAppender.btAd-
dress-property when using the Bluetooth-
SerialAppender. This is the Bluetooth
address of the computer running the
Microlog Bluetooth server application.

EMBEDDED
22
Introducing Akka –
Simpler scalability, fault-tolerance,
concurrency & remoting through actors
Writing correct concurrent, fault-
tolerant and scalable applications is
too hard. Most of the time it’s because
we are using the wrong tools and the
wrong level of abstraction. Akka is an
attempt to change that. Akka uses the
Actor Model together with Software
Transactional Memory to raise the
abstraction level and provide a better
platform to build correct concurrent
and scalable applications.
Jonas Bonér/Jayway
For fault-tolerance Akka adopts the “Let it
crash”, also called “Embrace failure”, model
which have been used with great success
in the telecom industry to build applica-
tions that self-heals, systems that never
stop. Actors also provides the abstraction
for transparent distribution and the ba-
sis for truly scalable and fault-tolerant
applications. Akka is Open Source and
available under the Apache 2 License.
In this article we will introduce you to Akka
and see how we can utilize it to build a highly
concurrent, scalable and fault-tolerant net-
work server. But first let’s take a step back and
discuss what Actors really are and what they
are useful for.
Actors
The Actor Model provides a higher level of
abstraction for writing concurrent and dis-
tributed systems. It alleviates the developer
from having to deal with explicit locking
and thread management. It makes it eas-
ier to write correct concurrent and paral-
lel systems. Actors are really nothing new,
they were defined in the 1963 paper by Carl
Hewitt and have been popularized by the Er-
lang language which emerged in the mid 80s.
It has been used by for example at Ericsson
with great success to build highly concur-
rent and extremely reliable (99.9999999 %
availability – 31 ms/year downtime) telecom
systems.
Actors encapsulate state and behavior into
a lightweight process/thread. In a sense they
are like OO objects but with a major semantic
difference; they do not share state with any
other Actor. Each Actor has their own view of
the world and can only have impact on other
Actors by sending messages to them. Messag-
es are sent asynchronously and non-blocking
in a so-called “fire-and-forget” manner where
the Actor sends off a message to some other
Actor and then do not wait for a reply but
goes off doing other things or are suspended
by the runtime. Each Actor has a mailbox
(ordered message queue) in which incoming
messages are processed one by one. Since all
processing is done asynchronously and Ac-
tors do not block and consume any resources
while waiting for messages, Actors tend to
give very good concurrency and scalability
characteristics and are excellent for building
event-based systems.
Creating Actors
Akka has both a Scala API and a Java API.
In this article we will only look at the Scala
API since that is the most expressive one. The
article assumes some basic Scala knowledge,
but even if you don’t know Scala I don’t think
it will not be too hard to follow along anyway.
Akka has adopted the same style of writing
Actors as Erlang in which each Actor has an
explicit message handler which does pattern
matching to match on the incoming mes-
sages.
Actors can be created either by:
• Extending the ‘Actor’ class and implement-
ing the ‘receive’ method.
• Create an anonymous Actor using one of
the ‘actor’ methods.
JAVA
Akka
23
Here is a little example before we dive into a
more interesting one.
class MyActor extends Actor {
def receive = {
case “test” => println(“received test”)
case _ => println(“received unknown message”)
}
}
val myActor = new MyActor
myActor.start
Here is the same Actor with the anonymous
syntax. Anonymous Actors are implicitly
started:
val myActor = actor {
case “test” => println(“received test”)
case _ => println(“received unknown message”)
}
Akka Actors are extremely lightweight. Each
Actor consume ~600 bytes, which means
that you can create 6.5 million on 4 G RAM.
Messages are sent using the ‘!’ operator:
myActor ! “test”
Sample application
We will try to write a simple chat/IM system.
It is client-server based and uses remote Ac-
tors to implement remote clients. Even if it
is not likely that you will ever write a chat
system I think that it can be a useful exercise
since it uses patterns and idioms found in
many other use-cases and domains.
We will use many of the features of Akka
along the way. In particular; Actors, fault-tol-
erance using Actor supervision, remote Ac-
tors, Software Transactional Memory (STM)
and persistence.
But let’s start by defining the messages that
will flow in our system.
Creating messages
It is very important that all messages that will
be sent around in the system are immutable.
The Actor model relies on the simple fact that
no state is shared between Actors and the
only way to guarantee that is to make sure we
don’t pass mutable state around as part of the
messages.
In Scala we have something called case
classes. These make excellent messages since
they are both immutable and great to pattern
match on.
Let’s now start by creating the messages
that will flow in our system.
JAVA
24
/**
* ChatServer’s internal events.
*/
sealed trait Event
case class Login(username: String) extends Event
case class Logout(username: String) extends Event
case class ChatMessage(fromUser: String, message: String)
extends Event
case class GetChatLog(fromUser: String) extends Event
case class ChatLog(messages: List[String]) extends Event
As you can see with these messages we can
log in and out, send a chat message and ask
for and get a reply with all the messages in the
chat log so far.
Client: Sending messages
Our client wraps each message send in a
function, making it a bit easier to use. Here
we assume that we have a reference to the chat
service so we can communicate with it by
sending messages. Messages are sent with the
‘!’ operator (pronounced “bang”). This sends
a message of asynchronously and do not wait
for a reply.
Sometimes however, there is a need for se-
quential logic, sending a message and wait for
the reply before doing anything else. In Akka
we can achieve that using the ‘!!’ (“bangbang”)
operator. When sending a message with ‘!!’
we do not return immediately but wait for a
reply using a Future (see references). A ‘Fu-
ture’ is a promise that we will get a result later
but with the difference from regular method
dispatch that the OS thread we are running
on is put to sleep while waiting and that we
can set a time-out for how long we wait before
bailing out, retrying or doing something else.
The ‘!!’ function returns a scala.Option (see
ref) which implements the Null Object pat-
tern (see ref) . It has two subclasses; ‘None’
which means no result and ‘Some(value)’
which means that we got a reply. The ‘Option’
class has a lot of great methods to work with
the case of not getting a defined result. F.e. as
you can see below we are using the ‘getOrElse’
method which will try to return the result
and if there is no result defined invoke the “...
OrElse” statement.
/**
* Chat client.
*/
class ChatClient(val name: String) {
import Actor.Sender.Self
def login = ChatService ! Login(name)
def logout = ChatService ! Logout(name)
def post(message: String) = ChatService ! ChatMessage(name, name
+ “: “ + message)
def chatLog: ChatLog = {
JAVA
25
val option = ChatService !! (GetChatLog(name), 1000) // timeout 1s
option.getOrElse(
throw new Exception(“Couldn’t get the chat log”))
}
}
Session: Receiving messages
Now we are done with the client side and let’s
dig into the server code. We start by creating
a user session. The session is an Actor and is
defined by extending the ‘Actor’ trait. This
trait has one abstract method that we have to
define; ‘receive’ which implements the mes-
sage handler for the Actor.
In our example the session has state in
the form of a ‘List’ with all the messages sent
by the user during the session. In takes two
parameters in its constructor; the user name
and a reference to an Actor implementing the
persistent message storage. For both of the
messages it responds to, ‘ChatMessage’ and
‘GetChatLog’, it passes them on to the stor-
age Actor.
If you look closely (in the code below) you
will see that when passing on the ‘GetChat-
Log’ message we are not using ‘!’ but ‘forward’.
This is similar to ‘!’ but with the important
difference that it passes the original sender
reference, in this case to the storage Actor.
This means that the storage can use this refer-
ence to reply to the original sender (our cli-
ent) directly.
/**
* Internal chat client session.
*/
class Session(user: String, storage: Actor) extends Actor {
private val loginTime = System.currentTimeMillis
private var userLog: List[String] = Nil
log.info(“New session for user [%s] has been created at [%s]”,
user, loginTime)
def receive = {
case event: ChatMessage =>
userLog ::= event.message
storage ! event
case event: GetChatLog =>
storage forward event
}
}
Let it crash: Implementing
fault-tolerance
Akka’s approach to fault-tolerance (doc.ak-
kasource.org/fault-management); the “let
it crash” model, is implemented by linking
Actors. It is very different to what Java and
most non-concurrency oriented languages/
frameworks have adopted. It’s a way of deal-
ing with failure that is designed for concur-
rent and distributed systems.
Looking at concurrency first: Let’s assume
we are using non-linked Actors. Throwing an
exception in concurrent code, will just simply
blow up the thread that currently executes the
Actor. There is no way to find out that things
went wrong (apart from see the stack trace in
the log). There is nothing you can do about
it. Here linked Actors provide a clean way of
both getting notification of the error so you
know what happened, as well as the Actor
that crashed, so you can do something about
it.
Linking Actors allow you to create sets of
Actors where you can be sure that either:
• All are dead
• All are alive
This is very useful when you have hundreds
of thousands of concurrent Actors. Some Ac-
tors might have implicit dependencies and
together implement a service, computation,
user session etc. for these being able to group
them is very nice.
Akka encourages non-defensive program-
ming. Don’t try to prevent things from go
wrong, because they will, whether you want
it or not. Instead; expect failure as a natural
state in the life-cycle of your app, crash early
and let someone else (that sees the whole pic-
ture), deal with it.
Now let’s look at distributed Actors. As
you probably know, you can’t build a fault-
tolerant system with just one single node,
but you need at least two. Also, you (usu-
ally) need to know if one node is down and/
or the service you are talking to on the other
node is down. Here Actor supervision/link-
ing is a critical tool for not only monitoring
the health of remote services, but to actually
manage the service, do something about the
problem if the Actor or node is down. This
could be restarting him on the same node or
on another node.
To sum things up, it is a very different way
of thinking but a way that is very useful (if
not critical) to building fault-tolerant highly
concurrent and distributed applications.
Supervisor hierarchies
A supervisor is a regular Actor that is respon-
sible for starting, stopping and monitoring its
child Actors. The basic idea of a supervisor
is that it should keep its child Actors alive by
restarting them when necessary. This makes
for a completely different view on how to
write fault-tolerant servers. Instead of trying
all things possible to prevent an error from
happening, this approach embraces failure. It
shifts the view to look at errors as something
JAVA
26
natural and something that will happen and
instead of trying to prevent it; embrace it. Just
“let it crash” and reset the service to a stable
state through restart.
Akka has two different restart strategies;
All-For-One and One-For-One.
• OneForOne: Restart only the component
that has crashed.
• AllForOne: Restart all the components
that the supervisor is managing, including
the one that have crashed.
The latter strategy should be used when you
have a certain set of components that are
coupled in some way that if one is crashing
they all need to be reset to a stable state before
continuing.
Chat server: Supervision,
Traits and more
There are two ways you can define an Actor
to be a supervisor; declaratively and dynami-
cally. In this example we use the dynamic ap-
proach. There are two things we have to do:
• Define the fault handler by setting the
‘faultHandler’ member field to the strategy
we want.
• Define the exceptions we want to “trap”,
e.g. which exceptions should be handled
according to the fault handling strategy we
have defined. This in done by setting the
‘trapExit’ member field to a ‘List’ with all
exceptions we want to trap.
The last thing we have to do to supervise Ac-
tors (in our example the storage Actor) is to
‘link’ the Actor. Invoking ‘link(actor)’ will
create a link between the Actor passed as ar-
gument into ‘link’ and ourselves. This means
that we will now get a notification if the linked
Actor is crashing and if the cause of the crash,
the exception, matches one of the exceptions in
our ‘trapExit’ list then the crashed Actor is re-
started according the the fault handling strat-
egy defined in our ‘faultHandler’. We also have
the ‘unlink(actor)’ function which disconnects
the linked Actor from the supervisor.
In our example we are using a method
called ‘startLink(actor)’ which starts the Ac-
tor and links him in an atomic operation.
The linking and unlinking is done in ‘init’
and ‘shutdown’ callback methods, which are
invoked by the runtime when the Actor is
started and shut down (shutting down is done
by invoking ‘actor.stop’). In these methods we
initialize our Actor, by starting and linking
the storage Actor and clean up after ourselves
by shutting down all the user session Actor-
sand the storage Actor.
That is it. Now we have implemented the
supervising part of the fault-tolerance for
the storage Actor. But before we dive into the
‘ChatServer’ code there are some more things
worth mentioning about its implementation.
It defines an abstract member field hold-
ing the ‘ChatStorage’ implementation the
server wants to use. We do not define that in
the ‘ChatServer’ directly since we want to de-
couple it from the actual storage implementa-
tion.
The ‘ChatServer’ is a ‘trait’, which is Scala’s
version of mixins. A mixin can be seen as an
interface with an implementation and is a
very powerful tool in Object-Oriented design
that makes it possible to design the system
into small, reusable, highly cohesive, loosely
coupled parts that can be composed into larg-
er object and components structures.
I’ll try to show you how we can make use
Scala’s mixins to decouple the Actor imple-
mentation from the business logic of man-
aging the user sessions, routing the chat
messages and storing them in the persistent
storage. Each of these separate parts of the
server logic will be represented by its own
trait; giving us four different isolated mixins;
‘Actor’, ‘SessionManagement’, ‘ChatManage-
ment’ and ‘ChatStorageFactory’ This will give
us as loosely coupled system with high cohe-
sion and reusability. At the end of the article
I’ll show you how you can compose these
mixins into a complete runtime component
we like.
/**
* Chat server. Manages sessions and redirects all
* other messages to the Session for the client.
*/
trait ChatServer extends Actor {
faultHandler = Some(OneForOneStrategy(5, 5000))
trapExit = List(classOf[Exception])
val storage: ChatStorage
log.info(“Chat service is starting up...”)
// actor message handler
def receive = sessionManagement orElse chatManagement
// abstract methods to be defined somewhere else
protected def chatManagement: PartialFunction[Any, Unit]
protected def sessionManagement: PartialFunction[Any, Unit]
protected def shutdownSessions: Unit
override def init = startLink(storage)
override def shutdown = {
log.info(“Chat server is shutting down...”)
shutdownSessions
unlink(storage)
storage.stop
}
}
JAVA
27
If you look at the ‘receive’ message handler
function you can see that we have defined it
but instead of adding our logic there we are
delegating to two different functions; ‘ses-
sionManagement’ and ‘chatManagement’,
chaining them with ‘orElse’. These two func-
tions are defined as abstract in our ‘Chat-
Server’ which means that they have to be
provided by some another mixin or class
when we instantiate our ‘ChatServer’. Natu-
rally we will put the ‘sessionManagement’
implementation in the ‘SessionManagement’
trait and the ‘chatManagement’ implemen-
tation in the ‘ChatManagement’ trait. First
let’s create the ‘SessionManagement’ trait.
Chaining partial functions like this is a great
way of composing functionality in Actors.
You can for example put define one default
message handle handling generic messages in
the base Actor and then let deriving Actors
extend that functionality by defining addi-
tional message handlers. There is a section on
how that is done, see references Akkas docu-
mentation on Actors.
Session management
The session management is defined in the
‘SessionManagement’ trait in which we
implement the two abstract methods in the
‘ChatServer’; ‘sessionManagement’ and ‘shut-
downSessions’.
The ‘SessionManagement’ trait holds a
‘HashMap’ with all the session Actors mapped
by user name as well as a reference to the stor-
age (to be able to pass it in to each newly cre-
ated ‘Session’).
The ‘sessionManagement’ function per-
forms session management by responding to
the ‘Login’ and ‘Logout’ messages. For each
‘Login’ message it creates a new ‘Session’ Ac-
tor, starts it and puts it in the ‘sessions’ Map
and for each ‘Logout’ message it does the op-
posite; shuts down the user’s session and re-
moves it from the ‘sessions’ Map.
The ‘shutdownSessions’ function simply
shuts all the sessions Actors down. That com-
pletes the user session management.
/**
* Implements user session management.
* <p/>
* Uses self-type annotation ‘this: Actor =>’
* to declare that it needs to be mixed in with an Actor.
*/
trait SessionManagement { this: Actor =>
val storage: ChatStorage // needs someone to provide the ChatStorage
val sessions = new HashMap[String, Actor]
protected def sessionManagement: PartialFunction[Any, Unit] = {
case Login(username) =>
log.info(“User [%s] has logged in”, username)
val session = new Session(username, storage)
session.start
sessions += (username -> session)
case Logout(username) =>
log.info(“User [%s] has logged out”, username)
val session = sessions(username)
session.stop
sessions -= username
}
protected def shutdownSessions =
sessions.foreach { case (_, session) => session.stop }
}
Chat message management
Chat message management is implemented
by the ‘ChatManagement’ trait. It has an ab-
stract ‘HashMap’ session member field with
all the sessions. Since it is abstract it needs to
be mixed in with someone that can provide
this reference. If this dependency is not re-
solved when composing the final component,
you will get a compilation error.
It implements the ‘chatManagement’ func-
tion, which responds to two different messag-
es; ‘ChatMessage’ and ‘GetChatLog’. It simply
gets the session for the user (the sender of the
message) and routes the message to this ses-
sion. Here we also use the ‘forward’ function
to make sure the original sender reference is
passed along to allow the end receiver to reply
back directly.
/**
* Implements chat management, e.g. chat message dispatch.
* <p/>
* Uses self-type annotation ‘this: Actor =>’
* to declare that it needs to be mixed in with an Actor.
*/
trait ChatManagement { this: Actor =>
val sessions: HashMap[String, Actor] // someone to provide Session map
protected def chatManagement: PartialFunction[Any, Unit] = {
case msg @ ChatMessage(from, _) => sessions(from) ! msg
case msg @ GetChatLog(from) => sessions(from) forward msg
}
}
JAVA
28
Using an Actor as a message broker, as in
this example, is a very common pattern with
many variations; load-balancing, master/
worker, map/reduce, replication, logging etc.
It becomes even more useful with remote Ac-
tors when we can use it to route messages to
different nodes.
STM and Transactors
Actors are excellent for solving problems
where you have many independent processes
that can work in isolation and only interact
with other Actors through message passing.
This model fits many problems. But the Actor
model is unfortunately a terrible model for
implementing truly shared state. E.g. when
you need to have consensus and a stable view
of state across many components. The classic
example is the bank account where clients can
deposit and withdraw, in which each opera-
tion needs to be atomic. For detailed discus-
sion on the topic see the JavaOne presenta-
tion in the references.
Software Transactional Memory (STM)
on the other hand is excellent for problems
where you need consensus and a stable view
of the state by providing compositional trans-
actional shared state. Some of the really nice
traits of STM are that transactions compose
and that it raises the abstraction level from
lock-based concurrency.
Akka has a STM implementation that is
based on the same ideas as found in the Clo-
jure language; Managed References working
with immutable data.
Akka allows you to combine Actors and
STM into what we call Transactors (short for
Transactional Actors), these allow you to op-
tionally combine Actors and STM provides
IMHO the best of the Actor model (simple
concurrency and asynchronous event-based
programming) and STM (compositional
transactional shared state) by providing
transactional, compositional, asynchronous,
event-based message flows. You don’t need
Transactors all the time but when you do
need them then you really need them.
Akka currently provides three different
transactional abstractions; ‘Map’, ‘Vector’ and
‘Ref ’. They can be shared between multiple
Actors and they are managed by the STM.
You are not allowed to modify them outside
a transaction, if you do so, an exception will
be thrown.
What you get is transactional memory in
which multiple Actors are allowed to read and
write to the same memory concurrently and if
there is a clash between two transactions then
both of them are aborted and retried. Abort-
ing a transaction means that the memory is
rolled back to the state it were in when the
transaction was started.
In database terms STM gives you ‘ACI’ se-
mantics; ‘Atomicity’, ‘Consistency’ and ‘Isola-
tion’. The ‘D’ in ‘ACID’; ‘Durability’, you can’t
get with an STM since it is in memory. This
however is addressed by the persistence mod-
ule in Akka.
Persistence:
Storing the chat log
Akka provides the possibility of taking
the transactional data structures we dis-
cussed above and making them persis-
tent. It is an extension to the STM which
guarantees that it has the same semantics.
The persistence module (doc.akkasource.org/
persistence) has pluggable storage back-ends.
At the time of the writing it has three different
storage back-ends:
• Cassandra – A distributed structured stor-
age database.
• MongoDB – A high performance schema-
free, document oriented data store with
SQL like query facilities.
• Redis – An advanced key-value store, also
called a data structure server, with lists,
ordered sets etc.
They all implement persistent ‘Map’, ‘Vector’
and ‘Ref ’. Which can be created and retrieved
by id through one of the storage modules.
val map = RedisStorage.newMap(id)
val vector = CassandraStorage.newVector(id)
val ref = MongoStorage.newRef(id)
Chat storage: Backed by Redis
Now let’s implement the persistent storage.
We start by creating a ‘ChatStorage’ trait al-
lowing us to have multiple different storage
backend. For example one in-memory and
one persistent.
/**
* Abstraction of chat storage holding the chat log.
*/
trait ChatStorage extends Actor
Let’s use Redis to implementation the per-
sistent storage. Redis is an excellent storage
backend, blazingly fast with a rich data model.
Our ‘RedisChatStorage’ extends the
‘ChatStorage’ trait. The only state it holds
is the ‘chatLog’ which is a ‘Vector’ man-
aged by Redis. We give it an explicit id (the
String “akka.chat.log”) to be able to retrieve
the same vector across remote nodes and/or
through server restarts.
It responds to two different messages;
‘ChatMessage’ and ‘GetChatLog’. The ‘Chat-
Message’ message handler takes the ‘message’
JAVA
29
attribute and appends it to the ‘chatLog’ vec-
tor. Here you can see that we are using the
‘atomic { ... }’ block to run the vector opera-
tion in a transaction. Redis works with binary
data so we need to convert the message into
a binary representation. Since we are us-
ing Strings we just have to invoke ‘message.
getBytes(“UTF-8”)’, but if we would have had
a richer message that we wanted to persist
then we would have had to use one of the
Akka’s serialization traits or serializers. You
can read more about that at doc.akkasource.
org/serialization.
The ‘GetChatLog’ message handler re-
trieves all the messages in the chat log storage
inside an atomic block, iterates over them us-
ing the ‘map’ combinator transforming them
from ‘ArrayByte to ‘String’. Then it invokes
the ‘reply(message)’ function that will send
the chat log to the original sender; the ‘Chat-
Client’.
You might rememeber that the ‘ChatServ-
er’ was supervising the ‘ChatStorage’ actor.
When we discussed that we showed you the
supervising Actor’s view. Now is the time for
the supervised Actor’s side of things. First, a
supervised Actor need to define a life-cycle in
which it declares if it should be seen as a:
• ‘Permanent’: which means that the actor
will always be restarted.
• ‘Temporary’: which means that the actor
will not be restarted, but it will be shut
down through the regular shutdown pro-
cess so the ‘shutdown’ callback function
will called.
We define the ‘RedisChatStorage’ as ‘Perma-
nent’ by setting the ‘lifeCycle’ member field to
‘Some(LifeCycle(Permanent))’.
The idea with this crash early style of de-
signing your system is that the services should
just crash and then they should be restarted
and reset into a stable state and continue
from there. The definition of “stable state” is
domain specific and up to the application de-
veloper to define. Akka provides two callback
functions; ‘preRestart’ and ‘postRestart’ that
are called right before and right after the Ac-
tor is restarted. Both of these functions take a
‘Throwable’, the reason for the crash, as argu-
ment. In our case we just need to implement
the ‘postRestart’ hook and there re-initialize
the ‘chatLog’ member field with a fresh per-
sistent ‘Vector’ from Redis.
/**
* Redis-backed chat storage implementation.
*/
class RedisChatStorage extends ChatStorage {
lifeCycle = Some(LifeCycle(Permanent))
private var chatLog = RedisStorage.getVector(“akka.chat.log”)
log.info(“Redis-based chat storage is starting up...”)
def receive = {
case msg @ ChatMessage(from, message) =>
log.debug(“New chat message [%s]”, message)
atomic {
chatLog + message.getBytes(“UTF-8”)
}
case GetChatLog(_) =>
val messageList = atomic {
chatLog.map(bytes => new String(bytes, “UTF-8”)).toList
}
reply(ChatLog(messageList))
}
override def postRestart(reason: Throwable) =
chatLog = RedisStorage.getVector(“akka.chat.log”)
}
The last thing we need to do in terms of per-
sistence is to create a ‘RedisChatStorageFac-
tory’ that will take care of instantiating and
resolving the ‘val storage: ChatStorage’ field
in the ‘ChatServer’ with a concrete imple-
mentation of our persistence Actor.
/**
* Creates and a RedisChatStorage.
*/
trait RedisChatStorageFactory {
val storage: ChatStorage = new RedisChatStorage
}
Composing the full
Chat Service
We have now created the full functionality for
the chat server, all nicely decoupled into iso-
lated and well-defined traits. Now let’s bring
all these traits together and compose the
complete concrete ‘ChatService’.
/**
* Object encapsulating the full Chat Service.
*/
object ChatService extends
ChatServer with
SessionManagement with
ChatManagement with
RedisChatStorageFactory
JAVA
30
Making the ChatService
remote
Now that we have the ‘ChatService’ object
how do we make it into a remote service that
we can use from different nodes?
It is very simple. We only need to do two
things. First we need to start up a remote serv-
er to run the ‘ChatService’. Then for each cli-
ent that wants to use the ‘ChatService’ we just
need to invoke ‘ChatService.makeRemote’ to
get a handle to the remote ‘ChatService’.
Starting the first step. We have two options
on how we can start up a remote server. Either
start up the ‘RemoteNode’ in some part of the
code that runs on the machine you want to
run the server on (can just be a simple class
with a ‘main’ method).
We start the ‘RemoteNode’ by invoking
‘start’ and passing in the host name and port.
RemoteNode.start(“darkstar”, 9999)
You can also choose to use the version of
‘start’ that takes a ‘ClassLoader’ as argument
if you want to be explicit on through which
class loader you want to load the class of the
Actor that you want to run as remote service.
The second option is to put your ap-
plication in a JAR file and drop it into the
‘AKKA_HOME/deploy’ directory and then
start up the Akka microkernel. This will de-
ploy your application and start the ‘Remote-
Node’ for you. Then you use the ‘AKKA_
HOME/config/akka.conf ’ configuration file
to configure the remote server (among many
other things). The microkernel is started up
like this:
export AKKA_HOME=...
cd $AKKA_HOME
java -jar $AKKA_HOME/dist/akka-0.6.jar
That was the server part. The client part is
just as simple. We only need to tell the run-
time system that we want to use the ‘Chat-
Service’ as a remote Actor by invoking the
‘makeRemote(hostname, port)’ function on
it. This will instantiate the Actor on the re-
mote host and turn the local Actor instance
into a proxy or handle through which we can
use the remote Actor transparently with the
exact same semantics as if it was a regular lo-
cal Actor.
That’s it. Now let’s run a sample client ses-
sion.
ChatService.makeRemote(“darkstar”, 9999)
ChatService.start
That’s it. Were done. Now we have a, very sim-
ple, but scalable, fault-tolerant, event-driven,
persistent chat server that can without prob-
lem serve a million concurrent users on a
regular workstation.
Let’s use it.
Sample client chat session
Now let’s create a simple test runner that logs
in posts some messages and logs out.
/**
* Test runner emulating a chat session.
*/
object Runner {
// create a handle to the remote ChatService
ChatService.makeRemote(“localhost”, 9999)
ChatService.start
def run = {
val client = new ChatClient(“jonas”)
client.login
client.post(“Hi there”)
println(“CHAT LOG: “ + client.chatLog.log)
client.post(“Hi again”)
println(“CHAT LOG: “ + client.chatLog.log)
client.logout
}
}
Sample code
All this code is available as part of the Akka
distribution. It resides in the ‘akka-samples-
chat’ module and have a ‘README’ file ex-
plaining how to run it as well as a Maven
‘pom.xml’ build file so it is easy to build, run,
hack, rebuild, run etc.
Or if you rather browse it online please see
ref.
Run it
First we need to start up Redis:
1. Download Redis from here – http://code.
google.com/p/redis/downloads/list.
2. Run redis-server: ‘./redis-server’.
For details on how to set up Redis server have
a look here: http://code.google.com/p/redis/
wiki/QuickStart
Now when the storage server is up and
running let’s run the sample application:
1. Set ‘AKKA_HOME’ to the root of the
Akka distribution.
2. Open up a shell. Step into the ‘akka-sam-
ples-chat’ module in the Akka distribu-
tion and first invoke ‘mvn install’. This will
build the sample application and deploy it
to the ‘AKKA_HOME/deploy’ directory.
JAVA
31
3. Open up a new shell. Step up to the
‘AKKA_HOME’ root. Invoke ‘java -jar
$AKKA_HOME/dist/akka-0.6.jar’ to start
up the microkernel.
4. Then go back to the first shell and invoke
‘mvn scala:console -o’. This will give you
a REPL with the application and all its
dependency JARs on the classpath. Here
you can simply paste in the ‘Runner’
above and invoke ‘Runner.run’ and it will
connect to the running server in the mi-
crokernel.
5. Invoke ‘Runner.run’ again and again...
Onward
There is much much more to Akka than what
we have covered in this article. For example
Active Objects, Cluster Membership API,
a Comet module, REST (JAX-RS) integra-
tion, a Security module, AMQP integration,
Spring integration, Google Guice integra-
tion, Lift integration, a rich Transaction
API, tons of configuration possibilities etc.
Have fun.
References
• The Actor Model: en.wikipedia.org/wiki/Actor_model
• Akka Documentation: doc.akkasource.org/
• Actors API in Akka: doc.akkasource.org/actors
• Scala Case classes: www.scala-lang.org/node/107
• Future and Promises: en.wikipedia.org/wiki/Futures_and_promises
• Scala Option Pattern: www.codecommit.com/blog/scala/the-option-pattern
• Null Object Pattern: en.wikipedia.org/wiki/Null_Object_pattern
• JavaOne Presentation bit.ly/ifcJU
• Software transactional memory: en.wikipedia.org/wiki/Software_transactional_
memory
• Clojure: clojure.org/
• Transactors: doc.akkasource.org/transactors
• Cassandra: wiki.apache.org/cassandra/
• MongoDB: www.mongodb.org/display/DOCS/Home
• Redis: code.google.com/p/redis/
• The Akka source: github.com/jboner/akka
• Akka: www.akkasource.org/
Jayway Stockholm Knowledge Network
invites you to a series of free seminars!
www.jayway.com
If you want to have invitations, pls sign up to our Google Group and
you will be added to the Jayways Knowledge Network email list!
http://groups.google.se/group/jwsknownet
Topics:
Akka
Scala
Android
Scalability
Cloud computing
Content Delivery Networks
Neo4j / NOSQL
... more subjects to come!
JAVA
32
We have been talking about rich user interfaces
under the name Swing Rocks at several big con-
ferences throughout the years. In the spirit of
the book Filthy Rich Clients, written by Chet
Haase and Romain Guy, our weapons of choice
has always been Swing and Java2D. Being GUI
geeks, we have of course also followed the de-
velopment of JavaFX closely, and from its some-
what shaky start, we’ve been impressed with the
great improvements in every new version.
When we were asked to write a Swing ar-
ticle, we sat down and discussed the subject
for quite some time, struggling to find a new
and interesting angle, but for every problem
we came up with, the most elegant solution
always seemed to be JavaFX. Why should we
waste our readers’ time talking about how to
implement effects and animations in Swing
and Java2D when there is a whole language de-
signed for exactly that, just waiting to be used?
We’re now leaving Swing and Java2D be-
hind when it comes to rich user interfaces,
and in this article we’ll explain why we think
JavaFX is a better tool for the job.
Code showdown
The biggest difference between Swing/Java2D
and JavaFX, at least for us developers, is the
language. JavaFX applications are written in
JavaFX script, which is nothing short of a do-
main specific language for graphics and user
interfaces. JavaFX script differs from Java in
many ways (see JayView 2/2009 for an intro-
duction). One of the biggest differences is that
JavaFX code is, or at least can be, a lot more
declarative than Java code. When defining
a user interface in Java2D, you tell the com-
puter what to do in a very detailed way. As a
result of this, you have to write a lot of code,
even for fairly simple operations. A lot of the
methods in Java2D take many numerical ar-
guments, and without looking at the docu-
mentation, it can be very hard to tell what all
these parameters (and the rest of the code as
well, to be honest) actually does.
In JavaFX script on the other hand, you
rarely tell the computer to do anything at all.
Instead, you set up a scene, fill it with objects,
and that’s it. This is a big advantage when it
comes to performance, when you as a devel-
oper specify what you want done, instead of
exactly how to do it, the underlying imple-
mentation can decide upon the most effective
way of fulfilling your requests.
Let’s have a look at a code example, we’re
going to implement a simple blur effect called
a box blur in Swing/Java2D and JavaFX re-
spectively, just to get a feeling for what the
code looks like.
Swing Rocks
– The last dance?
BoxBlur.java Result
@Override
protected void paintComponent(Graphics g) {
// Draw source image
BufferedImage source = new BufferedImage(
getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics sg = source.getGraphics();
sg.setColor(Color.RED);
sg.fillOval(50, 50, 200, 200);

// Create blur effect
int radius = 5;
int size = radius * 2 + 1;
float weight = 1.0f / (size * size);
float[] data = new float[size * size];
for (int i = 0; i < data.length; i++) {
data[i] = weight;
}
Kernel kernel = new Kernel(size, size, data);
ConvolveOp blur = new ConvolveOp(kernel);
g.drawImage(blur.filter(source, null), 0, 0, null);
}
JAVA
Pär Sikö & Martin Gunnarson/Epsilon
33
Shown above is the paintComponent imple-
mentation of our Swing component, which
draws a blurred, red circle. We won’t go
through the code in detail, but this is a good
example of what Java2D code looks like. We
have borrowed the code for the blur effect
from Filthy Rich Clients, and the reason for
this is a very strong argument against Java2D:
the code for even a simple blur effect is way
too complicated to remember off the top of
your head. Like we said before, it’s also very
hard to understand what the code actually
does. Kernel? ConvolveOp? I’m sorry, what?
Let’s have a look at the same code in JavaFX.
Now that’s more like it, the JavaFX code is
short, clean, and easy to understand. Things
have familiar names like stage, scene and
circle, and every parameter is preceded by its
name, making the code very self explanatory.
One of the main reasons why the JavaFX ex-
ample looks so much better is of course that
we’ve lied and cheated. We’ve compared a box
blur implementation to some code simply us-
ing a ready made box blur, which, you might
argue, is totally unfair. In our defense, this is
a pretty realistic comparison after all. JavaFX
comes with almost any effect you can think
of built in, where as soon as you want to do
something similar in Swing, there are a lot of
hoops to be jumped through.
Capabilities
There are things that you can do in Swing but
not in JavaFX, for example scaling images
with a specific algorithm, and painting on the
glass pane.
1
Are these features missing from
JavaFX? It’s easy to think so, but the truth is
that there’s no place for them in JavaFX, since
details like these are taken care of in the back-
ground. There are other things in Java2D that
you might miss in JavaFX, but you can always
fall back on a Java2D implementation since
JavaFX integrates well with Java.
JavaFX is still missing some important
components like table and tree, but that is
temporary and not something that will both-
er us in the future (version 1.3 will likely pro-
vide many of the missing components) and if
you expect JavaFX to meet the same require-
ments that Swing have then, yes, it’s not yet
ready. But JavaFX was never intended to be
a replacement for Swing, it was built for an-
other purpose, namely to bring RIA to the
Java market.
Now let’s look at it from the other side of
the fence: What can JavaFX do that Swing/
Java2D can’t? A lot we say. This is not a Ja-
vaFX tutorial and we are not going to go into
details but it’s important to understand all
the things that JavaFX can do so much bet-
ter than Swing/Java2D. Language support for
animations, built in effects, binding and other
things that Swing never could do easily, be-
cause the language was never meant for that.
The aforementioned can be achieved in Swing
as well but at a high cost. Countless bugs have
been introduced by developers who were try-
ing to do it themselves. The upsides of JavaFX
vs. Swing/Java2D weigh in far heavier than
the downsides.
Performance
When Christopher Oliver wrote F3 (Form
Follows Function), the forerunner to JavaFX,
he didn’t implement a completely new graph-
ics stack. Instead he reused the already exist-
ing power of Swing and just mapped JavaFX
components into Swing components, e.g.
a JavaFX Button turned into a JButton. The
result was stunning, even though it was still
Swing in the end, and he showed the world
some really impressive demos.
2
But if JavaFX
is built on top of Swing and Java2D, doesn’t
that mean that it will never be faster than
what it’s built on top of? Yes that’s correct and
also one of the reasons why some of the early
JavaFX demos had bad performance. Luck-
ily the JavaFX architecture has evolved and
today (the current 1.2 release is much faster
than the previous versions and 1.3 will be
even faster) JavaFX components don’t rely on
Swing, instead a new scene graph has been
built from scratch (the new scene graph is
named Prism and will be introduced in 1.3)
which in turn relies on OpenGL to achieve
high performance.
Not only is JavaFX easier to read and write
and supports animations and effects, it’s faster
too and that’s perhaps the main reason why
we gladly nail the Swing coffin shut, at least
when it comes to building RIA applications.
Don’t get us wrong, Swing is still useful, and
the right tool, for writing normal applications
without effects and animations, it’s just that a
piece of the responsibility that Swing had be-
fore has now been lost to JavaFX.
Custom components
and skinning
It’s possible to write your own custom compo-
nents with Swing and Java2D but if you ever
tried it you know how painful it can be. Yes
the result can be fantastic, but it doesn’t make
it any less painful. Developers were forced to
use one of the few available look and feels, and
none of them were really good looking, which
means that most of all swing applications ever
written relies on an ugly look and feel. With
that in mind it should be no surprise that Java
GUIs have such a bad reputation. Guess what
would have happened if someone, back in
1995, had said: “We need to make sure that it’s
easy to skin Java GUIs”. The impact on today’s
Java developers would have been enormous.
At least they got it right this time. JavaFX
has three different ways of skinning com-
ponents, the first one being the same as in
Swing, simply do it yourself. Even though
it’s powerful it fails for the same reason that
Swing did. It’s simply too much work, at least
for most cases. The second way of skinning is
not yet fully implemented but the idea is that
BoxBlur.fx Result
Stage {
title: “JavaFX Blur”
scene: Scene {
width: 300
height: 300
content: [
Circle {
translateX: 150
translateY: 150
radius: 100
fill: Color.RED
effect: BoxBlur {
width: 10
height: 10
}
}
]
}
}
1 If you want to know more of how you can get the most out of Swing then the book “Filty Rich Clients” is for you.
2 http://blogs.sun.com/chrisoliver/resource/demo2.jnlp
JAVA
34
all graphical artifacts are created in Photo-
shop or Illustrator and imported into JavaFX
as a skin. The third and perhaps easiest way
to handle skinning is through CSS. If your
application is developed with CSS skinning
in mind then a total redesign without any
changes to the code. All you need to change
is in a CSS file, a simple example is shown
below.
Style.css
/* Style.css */
“Text”#MainText {
fill: navy;
font: bold italic 35pt “sans-serif”;
}
Main.fx
/* Main.fx */
Stage {
title: “Style Sheet in Action”
scene: Scene {
stylesheets: [“{__DIR__}Style.css”]
content: Text {
id: “MainText”
x: 10 y: 10
content: “CSS styled text”
}
}
}
Tool support
There are a lot of Swing tools and editors out
there, but most of them are complicated, bug-
gy and hard to use. The best one we’ve used is
Matisse, the visual editor that was introduced
in NetBeans 5.0. Since JavaFX has only been
around for a few years, it’s easy to assume that
its tool support would be even worse, but there
are actually a number of really good and use-
ful tools to choose from. The first and the one
that’s been available the longest is the JavaFX
Production Suite,
3
a tool that exports graph-
ics from Photoshop and Illustrator to JavaFX
making it available to the developers through
regular JavaFX objects. The second tool, Ja-
vaFX Composer
4
is a Rapid Application De-
velopment tool that lets developers create
GUIs by dragging and dropping components
on the screen, much like we do with Matisse
in NetBeans. The last and perhaps most im-
portant tool is the JavaFX Authoring Tool,
5
a
tool for non developers that lets them create
RIA applications without writing a single line
of code, that includes support for all standard
components, effects, and animations.
Conclusions
Now, a shiny new tool that makes cool effects
and smooth animations more accessible to all
developers doesn’t necessarily mean the web
will be flooded with awesome user interfaces.
As a matter of fact, it might have the oppo-
site effect. The first thing you need to create
something really good looking is talent, and
it seems like people who are good at cod-
ing are really bad at drawing and designing
user interfaces. A lot of people seem to have
got this all wrong, especially one speaker at
JavaOne, who proclaimed to the developers
in the audience that “You are the designers
now”. Nothing could be more wrong, what
he should have said was “You now have bet-
ter tools than ever to work together with the
designers, focus on the code and leave the vi-
suals to them”.
Another thing that bugs us is that many of
the most important JavaFX evangelists, au-
thors, Sun representatives delivering keynote
speeches and so on, seem to be satisfied with
showing off really ugly demos. If you want
to impress your audience, whether they are
readers or sitting in front of you, you can’t
bring something that looks like it was slapped
together on a lunch break. Sun should have
a team of artists and programmers who do
nothing but create absolutely stunning exam-
ples of what JavaFX is capable of. It’s a great
piece of technology, but without the right in-
troduction to the market, people won’t take
their time and get to know it.
For traditional, form based user interfaces,
Swing is still the best tool for the job, and Ja-
vaFX was never meant to change that. For rich
GUIs, the torch has been passed on, and Ja-
vaFX is definitely the way to go. It’s faster, eas-
ier to read and write, and allows designers and
developers to work more closely together. It’s
a way to break free from the old ways, and fi-
nally, after 15 years of struggling, we’re ready to
change the way people think of Java GUIs.
3 http://javafx.com/docs/gettingstarted/production_suite/
4 http://wiki.netbeans.org/JavaFXComposer
5 http://www.youtube.com/watch?v=5NGDdXdQgU0&feature=related (not yet released)
Resources
Useful reading:
• JavaFX Developing Rich Internet Applications by Jim Clarke, Jim Connors and Eric Bruno
• Filthy Rich Clients by Chet Haase and Romain Guy
• JavaFX Special Effects by Lucas L. Jordan
Blogs worth reading:
• http://fxexperience.com/
• http://www.java.net/blogs/joshy/
• http://learnjavafx.typepad.com/weblog/
JAVA
35
Agile development has during the past years
become more and more popular with many
organizations involved with software. Unfor-
tunately many organizations tend to forget
the QA department when developing soft-
ware using agile processes. I have worked as
a consultant for many different companies
and organizations where they talked about
how ‘agile’ they were when developing soft-
ware. If we scratch the surface of their devel-
opment processes its often turn out to be just
another classic waterfall where the developer
gets a bunch of requirements or features to
implement before an end date, usually several
months ahead. This gives us long develop-
ment cycles. The only real elements of agile
in use are the daily meetings in which they
discuss what has been achieved, what is out-
standing and any impediments encountered.
When the developers have implemented the
requirements, the software is handed over to
the QA department to test the software in a
classic manner.
At the end of the cycle there is usually a
release, a milestone taking pressure from two
sides: On one side are the developers who
want their new features in the release, and on
the other side is the QA department that is in-
terested in getting the bugs fixed before ship-
ping to customers. Clearly, these two forces
do not push in the same direction, which can
lead to hostility between the two groups. To
complicate the situation further, we then have
the product management, marketing and
sales pushing to get the new features onto the
market as fast as possible, even if this means
a reduction in quality. We end up with the
business side butting heads with R&D. This
scenario describes a very common way of de-
veloping software today.
What is agile?
Before we get ahead of ourselves here, let’s take
a closer look at the agile manifesto, which was
written in February 2001 by seventeen people
that needed an alternative to the document-
driven, heavy-weight software development
processes that were predominant at that time.
What make a process agile are the follow-
ing values:
• Individuals and interactions over pro-
cesses and tools
• Working software over comprehensive
documentation
• Customer collaboration over contract
negotiation
• Responding to change over following
plans
One of the principal misunderstandings of
the agile manifesto is the part regarding doc-
umentation. Many think that agile processes
are all about coding and not documenting
anything. The agile manifesto says nothing
about not writing documents, and many peo-
ple in the agile community want to restore the
credibility lost to the methodology due to this
Agile Testing
– a new profile
for testers
Are you an agile tester? Do you work in an agile
process and feel lost, or is it still just waterfall? Do
you need new skills as a tester to contribute to an
agile team? These questions and many more beg for
attention from us testers.
Henrik Andersson/Jayway Test
TEST
36
misunderstanding. It is about finding a bal-
ance between what documentation to write,
and what not to write. In many companies
large amounts of documentation is written,
stored in some repository, and then left where
it will often remain untouched, unread and
(even worse) unmaintained.
Two of the twelve principles behind the
agile manifesto are:
• Working software is the primary measure
of progress
• Deliver working software frequently, from
a couple of weeks to a couple of months,
with a preference to the shorter time scale.
So we should deliver working software within
a couple of weeks if we want to be agile. In
short, we have to program and test the new
features in very short time scales. Having
both the development and testing teams work
as one is a must and an accepted fact in the ag-
ile world. The agile manifesto talks about co-
operation within the team and that the team
should have the flexibility to change direction
when required. I have worked with many or-
ganizations seeing a connection between the
agile manifesto and how they develop their
software. But when it comes to testing, the
connection is lost, and they stick to having a
‘phase’ between the point when development
stops and the delivery of the product to the
customer. This phase is the test phase where
the QA team does their ‘stuff’.
Classic testing
I am using the term ‘classic testing’ to make
a distinction between agile testing and test-
ing as many of us know it. Classic testing is
a process that starts with planning the test,
creation of test cases in form of written in-
structions, manual execution of the test cases,
creation of test reports, and finally evaluation
to see if more testing is needed. This process
can be started as the project starts up, but of-
ten has no or minimal involvement with the
development process. Rather, it forks off on a
parallel track to the development.
Why doesn’t this kind of testing work in a
true agile project?
Let’s take an example. In an agile project
there is continuous integration, and we get a
new piece of software every morning when
we come to the office ready for being tested.
If we are to follow the process taught by the
ISTQB, the first thing to do would be to plan
the test.
After you planned, you will come to more
insight regarding the test coverage. Are the
existing test cases enough? Do we need to de-
sign new test cases for the new functionalities?
If you decide to design new test cases, you
have to do that before starting to test the new
version of software. Please don’t forget your
regression testing, so that you know whether
previous features or requirements still work.
As the software grows, both in complexity
and number of features, regression testing
will consume more and more valuable testing
time. To keep up the same pace as before, you
can go to your manager to get other people
from the team to help you, but this will slow
down other parts of the team. As my beloved
testing friends try to say that we don’t need to
run the regression tests each day, run them as
a last overall test at the end of each sprint. So
don’t we then have a classic waterfall, where
we do development and then test? By testing
this way, you will have a long start time before
you can start to test and a lot of overhead time
in which to plan and design your test cases.
However, we want to have as short a start time
as possible. This cannot be done by this ap-
proach of testing.
How to test in an agile project?
Now finally the big questions: How can we
make testing agile and what is agile testing?
The first thing, from my perspective, is
that testing has to become a natural part of
an agile project and not just a phase after the
developers have stopped coding and before
customers receives their software. It’s about
reaching the same goal as a team, i.e. to de-
liver working software within as short a space
of time as possible. With this short time scale,
we as testers need to change our working
methods. We need to step away from the nag-
ging position we have in a waterfall process
and become more active in the process of de-
veloping the software. Active does not mean
that we should be sitting down hammering
in code, but we should be involved from the
beginning and be giving the developers feed-
back instantly on how the new feature works,
instead of complaining at the end when ev-
erything is built. To make this possible, we
need to have frequent integration of new
features, for example through nightly builds,
where every morning there is new software
ready to be tested. The testing should be per-
formed manually as an exploratory test, since
this is a rapid way of testing instantly, no extra
documentation, no extra work, just the mini-
mum effort required to succeed, namely test-
ing the new features.
But how can we possibly do regression
testing when we have no test cases? When I
talk to fellow testers who are into classic test-
ing, we soon run into disagreements:
• We need the test cases for regression test-
ing later on when the product has come in
to a maintenances phase, they say.
• Let’s spend time to automate these test
cases, so we don’t need to spend time run-
ning them manually later on, I reply.
Let me explain how I see things. Assume that
we have a software project that is at the be-
ginning of its life cycle. Not too complex, the
GUI has started to fall in place, let’s say it is a
web application. We need to start to test au-
tomatically as soon as possible, which can be
easily achieved using a tool that records our
clicks and key strokes. After each nightly run
of the automated tests, we then add new test
cases the next morning. This means that we
get some extra time to add new automated
test cases, or do some exploratory testing,
since we don’t need to test the existing ones
manually.
Does it need a new profile
for the testers?
The profile for an agile tester is not the same
as the profile of a classic tester. I see the ag-
ile tester as a person with a more technically,
more programming oriented profile, a person
that enjoys developing, debugging and test-
ing. This profile is wanted in agile projects,
since it will help the developers to find where
the bug is, instead of just pointing out the
symptom of the bug.
Summary
To summarize, in agile testing you need to
start to execute tests fast. Having working
software early is a key aspect, and this means
you have to have testable software early. Ex-
ploratory testing is ideal for you to be able to
make a fast evaluation of the software with a
minimum of preparation, and experience has
shown that it is also very effective for finding
problems in the software. Critical parts of the
software should never fail, and you need to
make sure that they are not broken in the fast
development cycle. Because of this, it is worth
putting effort into implementing automated
regression tests. As an agile tester you must be
able to tackle these things, which calls for an
interest in technology and a deeper technical
understanding. Programming and debugging
are key skills for the agile tester.
TEST
37
COP and Qi4j:
Reviving object-orientation
Have you ever had the feeling that you are really
productive, but not getting things done? Did you too
notice that while we are getting better at generating
code and leaner syntax for this and that, it doesn’t
really help us focus on the important things?
Rickard Öberg/Jayway
Expressing your domain models in a way that
allows you to define a concept once, and then
reuse it whenever it appears, is something
that can really allow you to spend the time
necessary to get things right. The key to ac-
complishing this is the insight that classes are
the wrong abstraction for objects, and that
breaking them into smaller and more focused
pieces is the solution to this problem.
This article will describe the issues at hand,
and how to solve them using Composite Ori-
ented Programming (COP), which is imple-
mented by the Qi4j framework on the Java
platform.
The dark age of
POJO-programming
For some time now so-called “POJO-pro-
gramming” has been all the rage. The prob-
lem is that the main thing it allows you to do
is create the wrong thing faster instead of do-
ing the right thing. Trying to squeeze a rich,
highly contextual reality into a programming
model where everything has to fit into a Java
class causes unnecessary repetition. It would
be better if objects were composed of smaller
parts, each of which had its own purpose
separate from all the others. By comparison,
atoms were for a long time thought to be in-
divisible, as a law of nature. However, just as
we found that atoms are composed of elec-
trons and protons, we now realize that objects
are composed of smaller fragments. These
smaller fragments can be composed in many
different ways to create different objects, and
this enables reuse on a whole new level. This
is simply impossible to achieve using class-
based POJO-programming.
So what are the main problems with PO-
JO-programming that COP tackle?
On the simplest level, consider this sce-
nario: you have ten entities in your model.
All of them should have a textual description
that you want to use for presenting instances
in a UI. You may have some rules for it, such
as “a description may only contain letters and
spaces and may not be longer than 20 charac-
ters”. This usually translates into a JavaBean
property “description” of type String. Put it
into your POJO, generate the setters and get-
ters, add the validation logic in the setter, and
go! This is great, except that you have to du-
plicate this code ten times. Even worse, your
client code has to explicitly understand these
ten different properties and handle them sep-
arately. So not only do you have duplication
in your model, but you also have duplication
in the client code. How do you deal with it?
You might get a tool to generate all this code
for you, but you would just be generating
waste at breakneck speeds. Is there a better
way to solve this?
Light in the tunnel
In COP objects have no class. Instead, they
are declared as being a collection of mixins.
Each mixin implements an interface that you
want your object to expose. In Java this trans-
lates to an interface for the object itself, which
extends a number of interfaces, one for each
context that the object has to be able to deal
with. The mixins are just regular Java classes.
In this context Java classes are just fine; don’t
try to use them for implementing objects,
that’s all!
To give you an example of what this would
look like I will use the description case as an
example. Let’s start with the typical POJO-
version.
“... you would just be generating waste
at breakneck speeds.”
ARCHITECTURE
38
This may seem like a perfectly normal class
with a simple property, but there are a num-
ber of problems with it. First of all, if you want
this description capability in several entities
you would have to duplicate the code in those
entities. This is just one property. Any con-
cept that occurs in many places would have
to be duplicated, leading to waste in terms of
coding. Also keep in mind that clients have to
deal with each description as a separate kind
of domain notion, rather than having gener-
alized code for dealing with “entities that have
description”.
Another issue with the above is that the
constraint for the newDescription param-
eter is hidden within the implementation of
the setter. The only way a client could know
about it is if the JavaDoc is properly written.
Even if the JavaDoc is written, in this and all
the other nine places where descriptions are
used, the developer also needs to ensure that
it is kept in synch with the actual validation as
the system evolves.
In short, there are a lot of issues with even
such a simple example when using POJO-
based programming as it is commonly prac-
ticed today.
Let’s mix it up!
Can we avoid these issues? Is it possible to
allow the developer to write this code only
once, and also make the constraint more vis-
ible? Let’s take a look at the Qi4j version of the
same example. Here’s the mixin interface and
implementation (see Listing 1).
As you can see this is just regular Java-
code. What we have is a class that deals with
exactly one thing: handling a description. The
parameter constraint is implemented using
an annotation, which Qi4j will use to validate
the input parameter. Parameters are by de-
fault defined as non-null, so there’s no need
to perform a null-check either. The quality of
your code will increase immensely just by us-
ARCHITECTURE
public class MyEntity {
String description;
public void setDescription(String newDescription) {
if (newDescription == null ||
!Pattern.matches( “[\\p{Alnum}\\s]{0,20}”, newDescription)) {
throw new IllegalArgumentException(“Descriptions “
+ “must only contain letters and numbers”);
}
description = newDescription;
}
public String getDescription() {
return description;
}
...
}
Listing 1
public interface Describable {
void changeDescription(@Matches(“[\\p{Alnum}\\s]{0,20}”) String
newDescription);
String getDescription();
}
public class DescribableMixin implements Describable {
String description;
public void changeDescription(String newDescription) {
this.description = newDescription;
}
public String getDescription() {
return this.description;
}
}
39
ing these parameter constraint features and
with only a little effort on your behalf.
Notice also that since the constraint is now
declared in the interface, rather than being an
implementation detail, it’s ok to not have any
JavaDoc for it. There’s also no risk of the doc-
umentation and implementation to get out of
synch. For large models that need to evolve
over time this will ensure that your model is
always consistent and easy to understand and
use.
Now we can create an entity that uses this
mixin:
@Mixins(DescribableMixin.class)
interface MyEntity
extends Describable,
..., EntityComposite
{}
The interface for the entity extends the inter-
face exposed by the mixin. We can add any
number of these, for as many contexts as we
want our entity to be able to handle. Finally
we add the EntityComposite interface, which
is a Qi4j-specific interface that contains all
methods that you want to be able to use on
an entity, such as getting its identity. Qi4j tries
to use the terminology from Domain Driven
Design as much as possible. This means that
things like entities, values and services are
explicitly modelled as such, which makes it
easier to express such design concepts.
What we would want now is to somehow
be able to instantiate an object that imple-
ments MyEntity. When the methods on De-
scribable are called we want to delegate to the
mixin implementing that interface. If we had
more interfaces, then the object would in-
ternally know how to delegate to each of the
mixins that together are composed to create
the MyEntity object. We could theoretically
implement this interface in one single Java
class, but then it would be very big. Every
entity that wanted to expose the Describable
interface would have to reinvent the imple-
mentation of it, which would be a waste. Us-
ing inheritance to fix it doesn’t work either, at
least not if the list of interfaces is large and
you want to reuse them in many different
combinations in various entities.
Enter Qi4j
Qi4j does indeed provide a way to implement
this interface, without requiring all of the im-
plementation to be in a single class. It knows
how to instantiate a proxy object that imple-
ments the entity interface and can perform
this delegation to the composed mixins. The
@Mixins annotation tells Qi4j what to use
for the implementation. This makes it very
clear what the implementation of this inter-
face is, which helps readability. It is basically
an interface that will “glue” everything in an
entity together, so that Qi4j can know how to
instantiate it. It also serves as a reference for
the developer about what to expect from in-
stances of this composite type.
So what do you gain by this? First, of all,
you did not have to duplicate the code for
handling descriptions ten times, so that’s a
good start. But, perhaps even more impor-
tantly, client code now does not have to know
about the description property in MyEntity.
Instead you can write generic client code that
knows how to deal with something that is
Describable. This will be a tremendous gain
for you in the long run, and can allow you to
really leverage the fact that you can reuse do-
main model code, since there’s less repetition
in the client, and you can spend time getting
it right and know that it’s a good investment.
In today’s projects we need to have tools that al-
low us to be more effective in the long run, and
the COP model does just this.
Conclusion
This was a very simple example of how PO-
JO-programming doesn’t really work well
to implement rich domain models, and how
COP as implemented in Qi4j can avoid these
issues. It gets even more interesting when you
have a number of roles implemented by mix-
ins that refer to each other, and where using
standard POJO programming would com-
pletely tangle up the code to handle all the
cross-references between entities. By using
mixins such dependencies can be extracted
into specific contexts, which makes the code
much more manageable, and it also makes it
possible to apply such mixins to any entity
where it makes sense, without the mixin code
having to know about the specific entities at
all. We finally have a model where reuse on a
large scale is possible, since the abstractions
are at a level where each physical Java class
can deal with one thing, and one thing only.
In this article I have focused on one of the
key benefits of the COP model, which is the
ability to use mixins as a way to create reus-
able domain model fragments. This is just one
part of how to reuse domain code, and there
are many other such features in Qi4j, such as
handling crosscutting concerns and method
side effects. All of these features help you ex-
press your domain model as effectively and
concisely as possible, and ensures that you
will get a maintainable model in the long run.
By contrast, the current POJO-oriented pro-
gramming model promotes short-term gains
but causes long-term waste, both in the mod-
el itself and in any code that uses the model.
After two years of hard work Qi4j ver-
sion 1.0 is now available from www.qi4j.org,
along with documentation, tutorials and an
SDK that contains everything you need to get
started with COP. Check it out, and see how it
can improve your domain models!
ARCHITECTURE
“... deal with one thing, and one thing only.”
Certified Java Super HeroeS!
Möt oss på Sveriges största Javakonferens,
Jfokus, den 26 -27 januari 2010 på Filmstaden
Sergel i Stockholm.
Läs mer på
jfokus.se
Sweden
Malmö: Hans Michelsensgatan 9, SE-211 20 Malmö, +46 40 602 31 00
Stockholm: Drottninggatan 108, SE-113 60 Stockholm, +46 8 750 88 20
Helsingborg: Möllegränden 22, SE-252 23 Helsingborg, +46 42 453 53 00
Halmstad: Science Park, Pilefeltsgatan 73, SE-302 50 Halmstad, +46 35 12 59 97
Linköping: Teknikringen 8, SE-583 30 Linköping, +46 704 106 982
Göteborg: Lilla bommen 6, SE-411 04 Göteborg, +46 31 745 00 22
Karlskrona: Campus Gräsvik 5, SE-371 75 Karlskrona, +46 702 19 74 11
Denmark
København: Jakob Dannefærds Vej 6B, 1973 Frederiksberg C, +45 26 62 64 34
Malaysia
Kuala Lumpur: Jayway Malaysia Sdn. Bhd., B-7-6, Megan Avenue 1, 189 Jalan Tun Razak, 50400 Kuala Lumpur
France
Sophia Antipolis: Way France SARL, Drakkar Bâtiment C et D, 2405 route des Dolines, BP65, 06902 Sophia Antipolis
info@jayway.com | www.jayway.com