Académique Documents
Professionnel Documents
Culture Documents
Neo – a netbase
JayView
Publication Officer
Thomas Dagsberg, MD Jayway AB
Editors
Leif Uller, Björn Granvik,
Darius Katz, Patrik Nilsson
Jayway
You will find the addresses and telephone
numbers of the various offices on the back.
Cover Picture
Capo da Roca, Portugal
Björn Granvik
Layout and Graphic Design
Roger Petersson
Subscription of JayView
Send an email with your address to
info@jayway.se
I
s there a right or wrong way to unit test applications? We believe so. Espe-
cially when it comes to testing Java ME applications. Down-scaled copies of
our faithful testing frameworks are popping up everywhere in the Java ME
community. But has anyone dared to ask the question: Why?
The Problem
Java Micro Edition (Java ME) is the most ubiquitous application platform for mobile
devices. However, testing Java ME applications is not a simple task. The constraints
on the Virtual Machine (VM), the limited resources and the not-always-so-well-
designed APIs are all contributors to this statement. The limited environment has
”forced” application developers to write their code as compact as possible. On many
an occasion this has led to an unsound application design that isn’t test friendly. In
a test friendly design, the collaborators of an object can easily be stubbed. Such a
design is often called a testable design. There are architectural patterns such as de-
pendency injection that can be used to achieve a testable design. Even though this
is mostly used in enterprise applications, it can be used with most modern program-
ming languages and environments.
The ability to stub collaborating objects is great when testing code. We can create
fake or ”mock” instances of our collaborating objects and set up an expected behav-
ior for them. By doing this, we can isolate the code being exercised and verify that
the behavior of the collaborating objects was met, i.e. verify that the code under test
actually did what we intended it to do. This is known as unit testing based on mock
objects. Those who are inexperienced with this kind of testing can find some good
articles on the subject in the References section located at the end of this article.
In the Java SE world, there are excellent tools like JUnit and EasyMock for creat-
ing unit tests based on mock objects. Since Java ME doesn’t support reflection, we
have lighter versions of JUnit, such as J2MEUnit, JMUnit and Mobile JUnit. As the
Connected Limited Device Configuration (CLDC) VM doesn’t support dynamic
object creation, we can’t use EasyMock and have to write the mock objects our-
selves.
Even if you have a testable design, there are more issues that make unit testing dif-
ficult in Java ME:
• Creating mock objects is tedious and error prone. There are tools that can help
you generate code for your mock objects, but you have to regenerate these if you
change your objects, otherwise you may encounter version conflicts. This is why
dynamic frameworks like EasyMock have gained such popularity.
• Running unit tests on the target platform takes time. Even if it only takes a minute
to install and run some tests, it may be enough to make you not want to run the
tests every time you change your code. Running JUnit tests in Eclipse takes a cou-
ple of seconds. Furthermore, the limited environment puts a constraint on how
many tests you can run on your Java ME device. This forces you to split your test
cases between several test suites, creating even longer turn-around times.
• Automation of tests is difficult. You’ll need a physical device attached to your
build server to run your tests.
• The test suite setup is done manually with Java ME unit testing frameworks. Each
time you add or remove a test, you have to update your test suite setup. This takes
unnecessary time and is error prone.
These issues lead the Java ME developers to the darker side of testing: integration
unit testing. Integration unit testing means that you don’t fully isolate your unit un-
der test, but rather let it talk to real instances of all or some of its collaborators. There
are however some problems with integration unit testing: It catches errors too late in
the development process, it’s complex to set up, and it often causes seemingly end-
less problems when trying to manage the test data. Unit tests based on mock objects,
on the other hand, require a minimum of test data, they are written together with
your production code, and they verify that your code actually does what you want it
to do. Java SE has elegant solutions to all of the above issues. Why not use them?
Introducing MockME
For Java ME developers, there is an underlying assumption that unit tests need to be
run on the target device. This is not true. Consider a Java EE project: An enterprise
application may be targeted to run on an application server on other hardware and
JVM vendor from our development environment. The unit tests are still run in
the development environment. How does it work? The ability to ”write once, run
everywhere” is one of the greatest strengths of Java. However, any experienced Java
developer knows that this is not completely true. There can be some compatibility
issues (e.g. threading), but for unit tests this will not be a problem. We’re only testing
a small unit in a controlled setup.
Given that the above statement is true, we could run our tests in a Java SE en-
vironment and utilize all its excellent tools! This is the basic idea behind MockME;
to write unit tests for Java ME applications and run them in Java SE. So how does
it work? MockME contains empty objects for CLDC, Mobile Information Device
Profile (MIDP), and other JSRs designed to run in Java SE. Then we use EasyMock
to create mock objects dynamically from MockME. Now, some might ask: ”Why
not create the mock objects from the classes in a wireless toolkit (WTK)”? Unfor- 3
tunately, these toolkits contain native methods that can’t be mocked. Even if it was
possible, EasyMock can’t mock static methods, such as RecordStore.openRecordS
tore(String,boolean). MockME solves this by delegating static method invocations
to a static delegate instance with a special method name. Let’s have a look at the
inner workings:
JayView
RecordStore.java
public class RecordStore {
// Used to delegate static method invocations
private static RecordStore _delegate;
// ...
}
By creating a mock object and setting the static instance, we fake the static method
invocations. No real magic here, but it’s important to make the development of Java
ME unit tests much simpler.
MockME In Action
OK, after motivating MockME, let’s look at a small example:
MessageDao.java
public class MessageDao {
private static final String RECORD_STORE_NAME = ”MessageDao”;
The class above is an example of a simple Data Access Object (DAO). It allows us
to store and access messages from a record store. Now, we’d like to create a unit test
for the addMessage() method. It’s especially important to make sure that we always
close the record store after use. This should be done even if we get a RecordStore-
FullException. Let’s create test methods for both cases:
MessageDaoTest.java
public class MessageDaoTest extends TestCase {
private MessageDao messageDao; // Object under test
private RecordStore recordStoreMock; // Mock object
JayView
messageDao.addMessage(message);
Lets look at the setUp() method. First we use EasyMock to create a mocked
RecordStore object dynamically, that the MessageDao is going to write its data to.
Then we invoke RecordStore.setStaticInstance() to mock all static methods
in RecordStore. Static method invocations will be delegated to static_<method
name>() equivalents.
Next is the test method testAddMessage(). The method starts preparing the en-
coded message and continues by setting up the expected behavior of the mock
object. You do this in EasyMock by invoking methods directly on the mock object.
In a sense, EasyMock ”records” these expected method invocations so it can com-
pare, or replay, the expectations with the actual invocations later, when the method
under test is called. If a method has a return value, you need to use a (statically
imported) expect() method. By using the andReturn() method, we can return a
mocked value.
Before executing the code we want to test, we invoke replay() to stop the mock
object from recording and set it to the replay state. All recorded method invocations
will be verified from now on. After executing the code under test, we verify the
behavior by calling verify() on all mock objects. Finally, we use a standard JUnit
assert() method to assert the message ID. That’s it! The next test method uses
the same principle, except that we let EasyMock throw an exception during ad-
dRecord() to test that we really close the record store even if we get an exception. A
test that could be quite difficult if running in a Java ME environment. This is one ex-
ample of how to use MockME and EasyMock for unit testing Java ME applications.
Once you get the hang of it, it’s easy to unit test your Java ME code in Java SE.
Conclusion
In this article we have shown how to write true unit tests for Java ME applications.
Running the tests in a Java SE environment gives us a lot of advantages and is pos-
sible thanks to MockME. So, should we throw away all our Mobile JUnit test code?
No. It’s important to distinguish between unit tests and integration unit tests. We
have stressed the use of true unit tests in Java ME, something rarely seen in Java
ME projects. There is always a need to test parts of your application on the target
platform, but in combination with true unit tests, the integration unit tests will be
fewer and more focused on integration issues.
5
References
Dependency Injection: http://www.martinfowler.com/articles/injection.html
Mock Objects: http://www.connextra.com/aboutUs/mockobjects.pdf
MockME: http://www.mockme.org/
JUnit: http://www.junit.org/
EasyMock: http://www.easymock.org/
J2MEUnit: http://j2meunit.sourceforge.net/
JMUnit: http://sourceforge.net/projects/jmunit/
Mobile JUnit: http://developer.sonyericsson.com/site/global/docstools/java/p_java.jsp
JayView
Signing MIDlets
W
ith today’s functionality network connections or similar which is
and information-crammed often the case otherwise.
mobile devices the threat
of malicious code is a real concern,
especially for those of us that like to Certificates and code
download and install third party ap- signing - quick and dirty
plications. It is essential for the growth Code signing and certificates rely on
of the mobile content market that cus- the principles of asymmetric encryption
6 tomers can feel safe using their appli- schemes such as RSA, where each in-
cations without worries of stolen data dividual has a freely distributed public
or unexpected billing. The Java ME key and a secret private key. The two
platform addresses this problem by keys work in reverse when using the
protection domains, permissions and RSA algorithm, so that if one of them
trusted MIDlet suites. is used to transform plain data into an
encrypted form then the other one can
In short, a trusted MIDlet is one whose be used for recovery.
supplier can be securely identified as So when shipping a piece of software,
trustworthy at the time of installation in the vendor creates a signature of the
contrast to other MIDlet suites where code (or rather a hash value of it) us-
nothing can be guaranteed about the ing the private key. The end user in turn
supplier. The trustworthiness is proven calculates a hash value of the received
by a certificate and allows the applica- code, applies the public key on the ven-
tion to run in a permissive protection dor’s signature and then compares the
domain where a selected set of poten- two hash values. If the code has not
tially risky functionalities on the device
are made available, no questions asked
(or at least not more than once). This
relieves the end user from repeatedly
having to allow access to the file system,
JayView
– the whys and hows
been tampered with they should match Sounds great, where do
exactly, while a match would be very I sign up?
improbable in any other case. So, the Let’s study the case of the fictitious soft-
end user can verify the integrity of the ware publisher FooBar Soft. Their best
code but what about the integrity of the selling file system management product
vendor, how can one be sure that the is now to be released on the mobile plat-
public key really belongs to the party form, and the technicians have made a
claiming it? brilliant job porting it using the file sys-
Certificates to the rescue! When tem access API, JSR-75.
buying a mobile phone a number of However, the application turns out
public keys are already embedded in to be a real nuisance to use because of
the device’s firmware, these keys be- the ever-occurring security popups ask-
long to certificate authorities (CA) such ing the user to allow the software to do
as Thawte and Verisign and can be as- this and that. FooBar Soft realizes that
sumed to be genuine because of the signing the application would be a good
extensive control measures taken at the idea because it allows instant access to
phone manufacturing plant. An applica- the file system, no questions asked. As
tion vendor can apply for a certificate an additional benefit, the customers
which essentially is a document binding would have increased trust in the ap-
the vendor’s public key to its identity plication and be even more keen to try
information by means of a CA signa- it out.
ture. This certificate is then used by the The first step is to generate a key-
end user’s system to verify the vendor’s store with a public/private key pair and
public key and identity, relying on the a certificate signing request (CSR) us-
trustworthiness of the CA. ing the Java SDK command line tool
keytool. The CSR is then submitted to
a CA bundled with information prov-
ing the identity of FooBar Soft. After
the CA has accepted the request and a
JayView
8
fee has been paid, a signed certificate including the public key is made available for
download or sent to FooBar via mail so that it can be imported to the keystore using
keytool again.
There is normally no reason to keep the certificate secret so it can be transferred
using an insecure channel. Essentially, the keystore now holds the private key used
for signing and the certificate that is shipped with every signed delivery.
A MIDlet suite is distributed in two parts; a Java archive (JAR) file including all
the classes of the application, and a Java archive description (JAD) file containing
metadata about the suite. Some metadata is also duplicated in a manifest file in-
cluded in the JAR. For a signed MIDlet suite, the protected API functions that the
application uses have to be listed in the JAD and the manifest file. In FooBar Soft’s
case, this means adding the following line:
MIDlet-Permissions: javax.microedition.io.Connector.file.read, javax.microedi-
tion.io.Connector.file.write
Adding permissions to the JAD file is preferably handled by an IDE, as is the sign-
ing. The alternative is to use the command line tool jarsigner, found in Java SDK.
Two more items need to be added to the JAD during signing. These are the actual
data fields that the mobile phone will use for verification during installation, i.e. the
signature and certificate:
MIDlet-Certificate: <certificate (Base64 encoded)>
MIDlet-Jar-RSA-SHA1: <signature (Base64 encoded)>
Signing a suite is a quick operation, which is often included in the build process also
during development. It is important that the customer has a root certificate on the
phone belonging to the CA that issued the application vendor certificate, otherwise
the installation will fail. This is also the case if the validity period of the certificate
has run out or on some platforms if the certificate has been revoked. In practice
there are only a few CAs whose root certificates are widespread in mobile devices
and one of these CAs is typically the best choice for the developer.
JayView
Essential
Java Generics
O
nce you get past simple usage of Java Generics and start implementing
generic classes yourself it may seem quite intimidating. It is tricky, so
it is important to remember a few rules.
Subtyping
The Liskov Substitution Principle, the rule that says that subclasses should be sub-
stitutable for their base classes, does not apply to generic elements!
• Integer is a subtype of Number.
• Integer is a subtype of Comparable.
• List is a subtype of Collection.
• List<Integer> is a subtype of Collection<Integer>.
• List<Integer> is not a subtype of List<Number>.
• List<Integer> is not a subtype of List<Comparable>.
The fact that the Liskovs Substitution Principle does not apply to generics restricts
their usefulness; we need wildcards to loosen some of these restrictions.
Wildcards
To loosen the constraint above, wildcards may be used. Wildcards are used with the
keywords extends and super.
• <? extends Number> means all types that are subclasses of Number are allowed.
• <? super Integer> means all types that are superclasses of Integer are al-
lowed.
The Get and Put Principle: use extends only when you intend to get values out of a
structure. Use super only when you intend to put values into a structure.
The container that you get something out of is guaranteed to contain elements that
are instances of the expected class or of a subclass and may be used properly by the
recipient of the get.
The container that you put something into is guaranteed to contain at least in-
stances of the expected class or a superclass ensuring that the put is valid.
This also implies: don’t use any wildcards when you intend to both get and put
values into and out of a structure.
JayView
public static <T> void copy(List<? super T> dest, List<? extends T>
source) {
for (int i = 0; i < source.size(); i++) {
dest.set(i, source.get(i));
}
}
In addition to the above principle there are also a few restrictions on wildcards:
Don’t use wildcards when creating instances, specifying generic method calls or ex-
tending superclasses:
Bounds
Bounds are used to make sure that generic parameters are of a specified subtype.
// The generic parameter of Query must extend (or implement) Entity and
Entity must have a getId method!
public class Dao<T extends Entity> {
T createOrUpdate(T entity) {
if (entity.getId() != null) {
return update(entity);
} else {
return create(entity);
}
}
}
// Using Dao
// Works fine since Person extends Entity!
Dao<Person> personDao = new Dao<Person>();
Bounds may also be used in more advanced ways. The example below is a simplified
version from java.util.Collections and show a recursive bound. The generic
parameter T is also used inside the bound Comparable<T> to make sure that the
objects contained in the collection are comparable amongst themselves.
By far the most difficult generic declaration comes from java.lang.Enum and looks
like this Class Enum<E extends Enum<E>> implements Comparable<E>. Like the
above declaration this is a recursive bound but it is even more constrained than the
above. The key to understanding this is to know how enums are implemented in
Java.
// Declaring an enum
enum Tapir {MALAYAN, BRAZILIAN, BAIRD, MOUNTAIN}
JayView
public static Tapir valueOf(String name) {
for (Tapir t: VALUES) if t.getName().equals(name) return t;
throw new IllegalArumentException();
}
}
As can be seen in the code above E extends Enum<E> maps to Tapir extends
Enum<Tapir> and Comparable<E> maps to Comparable<Tapir>. This makes sure
that enums of one type can only be compared with enums of the same type. The
innermost generic parameter, Enum<E extends Enum<E>>, makes the subclass’ type
available to the superclass, allowing it to define methods whose parameters and
return values are that of the subclass’.
Generic parameters may also have multiple bounds. The signature of the simplified
example above actually looks like this:
When multiple bounds appear the first bound is used for erasure and the reason for
the Object in the signature above is that it makes the signature backwardly compat-
ible. The reason for the super and the extends are the same as above to make the
method more generic.
Erasure
Java Generics is implemented by erasure. This means that the generic information
is removed when the class is compiled:
• The erasure of List<Integer>, List<String>, List<List<Integer>> is List.
• The erasure of Comparable<? super T> is Comparable.
• The erasure of Object & Comparable is the leftmost, Object.
// This method will appear twice once with Object as parameter and
once with Bar.
public void foo(Bar param) {}
$ java Bar
public void Bar.foo(Bar)
public volatile void Bar.foo(java.lang.Object)
This can trip you up if you try to overload a method to accept Object as a parameter
too. It has never been a good idea to overload with Object as well as a subclass of
Object but now it will not even compile:
Compatibility
All in all, the implementation of generics in Java is a wonderful example of crafts-
manship. The solution is binary compatible both backwardly and forwardly, allowing
new code to use old libraries as well as allowing old code to use new libraries. I do,
however, wish that they had skipped the compatibility and made generic classes
aware of what they are at runtime.
11
If you want to know more about generics I highly recommend the book Java Gener-
ics by Philip Wadler and Maurice Naftalin.
Anders Janmyr
Ortelius AB
JayView
Problems with
object creation
12
E
very programming language has tricky details that you need to be aware
of. This article will look at several such issues in Java related to the Java
compiler. Test your Java skills and see if you know the answer!
The problem
A while ago a colleague of mine discovered a weird behavior when writing some
integration tests. He first noticed that the test worked in JDeveloper, but not in
Eclipse. Then he noticed that he could make a small change to the test setup and
the test would pass. Another small change and it would fail again. He got some help
and managed to reduce the problem to the following:
Original code
import junit.framework.TestCase;
public MyObject() {
set();
}
void set() {
}
Object get() {
return temp;
}
}
This test fails in some environments and works in others. When the test fails it is
because result is null. How can this be? But it gets even stranger: By changing how
the value is initialized the test always pass:
JayView
This test works for all environments. Why does the initialization of value affect
result? Very strange indeed!
Finally, by changing the type of the value we are back to the situation where the test
case fails in some environments, but not all.
Challenge
Here are some challenges for you! Try to solve them before reading the solution!
• Explain the difference between the middle test case and the other two (easy).
• Explain why the initial test case fails in some environments and works in others
(hard).
• Find the bad design that might cause problems (and indeed does in this case!).
I can give you a hint. The differences are both related to the Java compiler. Don’t
cheat! You should at least be able to answer the irst question before reading on.
Solution
There are several things going on here. I’ll start by explaining what is going on when
we change the variable named ”value” and then I’ll look more closely at anonymous
inner classes. Finally I will describe the problem with the design.
Constant variables
According to the Java Language Specification (JLS) ”We call a variable, of primitive
type or type String, that is final and initialized with a compile-time constant expres-
sion (§15.28) a constant variable”. Lets go through each variable:
• ”value1” is not a constant since it does not have a compile-time constant expres-
sion! That is, the compiler does not know what the String constructor is doing and
therefore assumes that this needs to be evaluated at runtime.
• ”value2” is a constant variable since it is clearly of type String and also initialized
with a compile-time constant value.
• ”value3” is not a constant since it is not a primitive type or a String. Yes, the object
it refers to is a String, but the variable itself is an Object.
This means that only the middle case is a constant. When the compiler spots a
constant it automatically replaces all references with the constant value, ie in the
compiled class a constant variable is never referenced! The result is that the next
problem I will describe does not occur and the test case works.
Now it is easy to see that there is no magic going on! The compiler has simply added
a constructor and two instance variables. The set method is not using the final vari-
able from the method, instead it is simply using its own reference to the value.
Well, this is all very nice, but why did the test case fail in some environments?
Notice how the generated constructor first initializes the members and then calls
JayView
super. This is normally not allowed in Java, but consider what would happen if the
compiler didn’t work this way. MyObject constructor would be called, which then
calls set and tries to use val$value which has not been initialized yet. Because of a
bug in the compiler this is exactly what happened in Java compilers before release
1.4.
OK, so if this problem is fixed in 1.4 and later, why should you care? Take a look
at the next problem!
Bad design
The problem with the design is that the base class MyObject is calling methods in the
anonymous subclass before the subclass instance variables have been created. Unfor-
tunately this is not only a problem with anonymous classes, but a problem in general.
Take a look at the following test case and see if you know what will happen.
public class BaseCallingSubTest extends TestCase {
14 class Base {
Base() {
doStuff();
}
void doStuff() {
}
}
class Sub extends Base {
private final int finalField = 5;
private int normalField = 5;
void doStuff() {
assertEquals(5, finalField);
assertEquals(5, normalField);
}
}
This is not a bug! This is exactly according to JLS Ӥ12.5 Creation of New Class
Instances”. The following is perhaps even more surprising:
public class BaseCallingSub2Test extends TestCase {
class Base {
Base() {
doStuff();
}
void doStuff() {
}
}
class Sub extends Base {
private int normalField = 5;
void doStuff() {
normalField = 7;
}
}
This test case also fails because after Base and doStuff have been called, Sub is ini-
tialized and the normalField is assigned to 5. This is possible to solve by not initial-
izing normalField.
This works as expected. However, try to avoid constructions like this as it is very
easy to forget that the fields might not be initialized yet. There are actually more
problems with this construction as it might affect thread safety. For instance if the
subclass starts a thread in the overridden method this thread might be given access
to the uninitialized object. Brian Goetz (author of ”Java Concurrency in Practice”)
goes as far as calling this ”not properly constructed”.
Lessons learned
• Make sure you understand constant variables and how they are used by the com-
piler
• Use a recent version of Java compiler. Sun is constantly adding improvements and
fixing bugs.
• Avoid calling non final methods from the constructor. If you have to, be aware
that the object might not be initialized yet.
• Do not perform unnecessary initialization of fields.
Jan Kronquist
Jayway
JayView
Neo– a netbase
N
eo is a network-oriented database for semi-structured information.
Too complicated, let us try again. Neo handles data in networks
– nodes, relationships and properties – instead of tables. This means
entirely new solutions for data that is difficult to handle in static tables. It could
mean we can go agile all the way into the persistence layer.
The relational database represents one of the most important developments in the
history of computer science. Upon its arrival some 30 years ago, it revolutionized the
way the industry views data management and today it is practically ubiquitous.
In fact, it is so taken for granted that we, as an industry, have stopped thinking. Could
there be a better way to represent and store our data? In some cases the answer is
– yes, absolutely. The relational database is showing its age. Some telltale signs:
JayView
Figure 1: An example of a social network from a somewhat famous movie. Note the different
type on the relation between Agent Smith and his creator The Architect.
16
Note how all nodes have integer identifiers and how all relationships have a type
(KNOWS or CODED_BY). In this example, all nodes have a “name” property. But
some nodes have other properties, for example, an “age” property (node 1) or a
“last name” property (node 3). There’s no overall schema that forces all nodes to
look the same. This allows Neo to capture so-called semi-structured information:
information that has a small amount of mandatory attributes but many optional at-
tributes. Furthermore, the relationships have properties as well. In this example, all
relationships have an “age” property to describe how long two people have known
each other and some relationships have a “disclosure” property to describe whether
the acquaintance is secret.
Working with nodes and relationships is easy. The basic operations are as follows:
// Create Morpheus
Node morpheus = neo.createNode();
morpheus.setProperty( ”name”, ”Morpheus” );
morpheus.setProperty( ”rank”, ”Captain” );
morpheus.setProperty( ”occupation”, ”Total bad ass” );
tx.commit();
As you can see in the code above: It is rather easy to construct the node space for our
Matrix example. And, of course, our network is made persistent once we commit.
JayView
Here we can see that traversers are created by invoking the traverse(...) method
on a start node with a number of parameters. The parameters control the traver-
sal and in this example they tell Neo to traverse the network breadth-first (rather
than depth-first), to traverse until it has covered all reachable nodes in the network
(StopEvaluator.END_OF_NETWORK), to return all nodes except the first (Returna-
bleEvaluator.ALL_BUT_START_NODE), , and to traverse all OUTGOING relation-
ships of type KNOWS.
How would we go about if we wanted to list the output of this traversal? After
we’ve created a Traverser, working with it is as easy as working with any Java Iter-
able:
// Traverse the node space and print out the result
for ( Node friend : friendsTraverser )
{
System.out.println( friend.getProperty( “name” ) + “ at depth “ +
friendsTraverser.currentPosition().getDepth() );
}
Running the traversal above on the Matrix example would yield the following out-
put:
$ bin/run-neo-example
Morpheus at depth 1
Trinity at depth 1
Cypher at depth 2
Agent Smith at depth 3
$
As you can see, the Traverser has started at the “Thomas Anderson” node and run
through the entire network along the KNOWS relationship type, breadth first, and
returned all nodes except the first one. “The Architect” is missing from this output
since the relationship connecting him is of a different type, CODED_BY. This is a
small, contrived example. But the code would work equally well on a network with
hundreds of millions of nodes, relationships and properties.
Now, let’s look at a more complex traversal. Going with our example, suppose
that we wanted to find all “hackers of the Matrix,” where we define a hacker of the
Matrix as any node that you reach through a CODED_BY relationship. How would
we create a Traverser that gives us those nodes?
First off, we want to traverse both our relationship types (KNOWS and COD-
ED_BY). Secondly, we want to traverse until the end of the network and lastly, we
want to return only nodes which we came to through a CODED_BY relationship.
Here’s the code:
// Instantiate a traverser that returns all hackers of the Matrix
Traverser hackerTraverser = mrAnderson.traverse(
Traverser.Order.BREADTH_FIRST,
StopEvaluator.END_OF_NETWORK,
new ReturnableEvaluator()
{
public boolean isReturnableNode( TraversalPosition pos )
{
return pos.getLastRelationshipTraversed().
isType( MatrixRelationshipTypes.CODED_BY );
}
},
MatrixRelationshipTypes.CODED_BY,
Direction.OUTGOING,
MatrixRelationshipTypes.KNOWS,
Direction.OUTGOING );
StopEvaluators work the same way. In our experience, writing custom evaluators
is very easy. Even the most advanced applications we have developed with Neo
– applications that traverse extremely large and complex networks – are based on
evaluators that are rarely more than a few lines of code.
Conclusion
Neo is not a silver bullet and some areas needs to improve, for instance tools, stand-
ardizing the model and a query language.
However, if your data is naturally ordered in a network or is semi-structured or you
17
just need to go truly agile, give the Neo database a run for your money. We hope
you find it, as we do, to be an elegant and flexible alternative that is both robust and
fast.
Emil Eifrém
Links Neo Persistence
Neo specification
www.neo4j.org Björn Granvik
Jayway
JayView
18
I
am in search of an empty room at niques - to organize knowledge. I see
the Øredev conference. Normally myself as a conduit [ledning] for trans-
this is an easy task, but I’ve got ferring knowledge, to process what is out
Martin Fowler on my tail. My mind there and make some kind of structure
is still blank. What on earth can I ask out of it. Brian Foot actually described
him that he hasn’t already written me as an ”intellectual jackal with a good
himself? taste in carrion” [intellektuell schackal
med god smak för kadaver].
Finally, an empty room, well almost. I look around for interesting stuff and
Another speaker, Erik Dörnenburg, is try to make sense of it.
sitting half way into his screen and mut- The ”Refactoring” is a good exam-
ters. ple. I figured out how to describe it and
- What’s up, I ask. wrote a book that came out when it
- I’ve updated my machine and my could make a difference and move the
demo doesn’t work. I’ve got 45 minutes area forward.
until the presentation. I also enjoy writing a lot, that’s a big
We sat down next to him. Do not thing. I’m better now at speaking, but
disturb a developer while he’s coding... that’s not what makes me tick.
So I got a man who has coined phrases
like Dependency Injection and POJO in You’ve written quite a few books - how
front of me. What next? Martin is easily do they compare?
recognizable both in accent and appear- Out of the five, ”Uml Distilled” sold
ance, a frequent and brilliant speaker. more copies than the others put togeth-
He has an excellent web site, www. er. Usually you can’t make a living out
martinfowler.com, which contains loads of your books, I guess I could though.
about his work. Articles and references All of the books had their good sides,
abound. That is when it suddenly hits but I would have to say that it was fun
me - who is he as a programmer and to write with Kent Beck [red: wrote
person? ”Extreme Programming”, created JUnit
etc]. We were in tune and could support
When was the last time you coded? each other through the dull bits.
Well, I do code my own website. But it’s I would have to say though that I’m
been a while since I had any paying cus- most proud of ”Refactoring”. It’s an
tomers. I’ve been pairing quite recently important technique and didn’t get the
though. A real delivery? That was some attention it should have received – the
time ago. I’m actually afraid to lose con- book helped.
tact with code, but I have smart people
around me. How did you start out?
I was an independent consultant for
But what makes you tick? many years. Giving talks was a good way
I enjoy trying to figure out new tech- of getting jobs. Articles same thing - it
JayView
got my name known. Looking forward, what’s next?
Also, I write something because I Oh, there is tons of stuff to write about.
don’t understand a certain area or tech- The design patterns area for instance.
nology. It’s a good way to learn. I’m also interested in DSL [domain spe-
Erik is now on the phone with Califor- cific languages] and agile development.
nia. We calculate that time is roughly 6:30 But in agile there are too many writers
there – in the morning. and I don’t like competition. There are
too many smart people in agile develop-
Then what? How come you started ment.
working for Thoughtworks (TW)? My strategy is to look for topics that no
I’ve been there for six years and done a one has written about. Basically I don’t
lot of consulting. I never wanted to work foretell the future.
for a company, but there was something
about TW that made me interested. What are your top three pieces of ad-
Get the work done and tons of bright vice to a programmer?
people. But more importantly is that it My first advice must be to learn to col-
is a sort of social experiment. A notion laborate with the user or purchaser. The
that good people makes a difference. really good ideas usually come from
I hope we can affect IT, which is a dif- them. You don’t have to be an expert to
ficult and skilled exercise at best. do this. This I found to be a good general
advice.
What is the most difficult part of being Secondly, it would be ”continuous
a celebrity? learning”. It’s like running up a down-
I’m not an extrovert person. I’m not wards-moving escalator – you have to
good at the ”person to person”. I get keep running.
The third one is difficult…
Interview
Martin Fowler
– man in the know
emails with questions like ”I got a prob- ”Buy lots of books by good authors”
lem on…what is the magic trick”. They would be it.
worked for months on it and I can only Erik suddenly releases a big:
point to a book. That clearly wasn’t an - Yes!
answer they liked. It’s frustrating. I saw Erik’s demo some twenty min-
However, celebrity is also a nice thing utes later – it was really good.
– it opens a few doors. I can email people As for Martin, our discussions con-
like Rod Johnson [red CEO of Interface tinued well into the debate panel and
21 that created the Spring framework] beyond. He would frequently forget his
if I have a question about something. back pain and sip into some extra en-
And he will answer. ergy pack. I wonder how he did that.
People tend to think I’m an ingenious
programmer. I’m not. I’m pretty good, Björn Granvik
but not necessarily that great. Jayway
Erik suddenly spits out:
- F---!...ok the demo will be shorter.
19
JayView
Java News
Terracotta goes open source
Terracotta clusters objects at the JVM level without the need of code
changes or serialization. For instance, this will enable open source appli-
cation servers to use Terracotta for clustering. Also Terracotta ships with
examples showing how to cluster a Spring application.
http://tinyurl.com/yfq4rf
Jaway
Malmö: Hans Michelsensgatan 9 , 211 20 Malmö, +46 40 12 72 83, Sweden
København: Fruebjergvej 3, 2100 København Ø, +45 3917 9691, Denmark
Helsingborg: Norra Storgatan 8, 252 20 Helsingborg , +46 42 37 35 22, Sweden
Malaysia; Sdn. Bhd. B-7-6, Megan Avenue 1, 189 Jalan Tun Razak, 50400 Kuala Lumpur, Malaysia
info@jayway.se | www.jayway.se