24
2007 No. 1 V olume  13 Java ME Testing Done Right Signing MIDlets - the whys and hows Essential Java Generics Problems with object creation Neo – a netbase Interview: Martin Fowler – man in the know JayView  

Jay View 13

Embed Size (px)

Citation preview

Page 1: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 1/20

2007 No. 1 Volume 13

Java ME Testing Done Right

Signing MIDlets - the whys and hows

Essential Java Generics

Problems with object creation

Neo – a netbase

Interview: Martin Fowler –man in the know

JayView 

Page 2: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 2/20

2

Java ME Testing

Done Right

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, PortugalBjörn Granvik 

Layout and Graphic Design

Roger Petersson

Subscription of JayView

Send an email with your address [email protected]

Page 3: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 3/20

3

JayView 

Is 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 ProblemJava Micro Edition (Java ME) is the most ubiquitous application platform for mobiledevices. However, testing Java ME applications is not a simple task. The constraintson 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 manyan occasion this has led to an unsound application design that isn’t test friendly. Ina test friendly design, the collaborators of an object can easily be stubbed. Such adesign 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 thisis 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 createfake 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 goodarticles 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, wehave lighter versions of JUnit, such as J2MEUnit, JMUnit and Mobile JUnit. As theConnected Limited Device Configuration (CLDC) VM doesn’t support dynamicobject 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 youchange your objects, otherwise you may encounter version conflicts. This is whydynamic frameworks like EasyMock have gained such popularity.

• Running unit tests on the target platform takes time. Even if it only takes a minuteto 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 howmany 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 yourbuild server to run your tests.

• The test suite setup is done manually with Java ME unit testing frameworks. Eachtime you add or remove a test, you have to update your test suite setup. This takesunnecessary time and is error prone.

These issues lead the Java ME developers to the darker side of testing: integrationunit 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. Thereare however some problems with integration unit testing: It catches errors too late inthe 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 withyour 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 MockMEFor Java ME developers, there is an underlying assumption that unit tests need to berun on the target device. This is not true. Consider a Java EE project: An enterpriseapplication may be targeted to run on an application server on other hardware andJVM vendor from our development environment. The unit tests are still run inthe development environment. How does it work? The ability to ”write once, run

everywhere” is one of the greatest strengths of Java. However, any experienced Javadeveloper knows that this is not completely true. There can be some compatibilityissues (e.g. threading), but for unit tests this will not be a problem. We’re only testinga 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 doesit work? MockME contains empty objects for CLDC, Mobile Information DeviceProfile (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: ”Whynot create the mock objects from the classes in a wireless toolkit (WTK)”? Unfor-tunately, these toolkits contain native methods that can’t be mocked. Even if it waspossible, EasyMock can’t mock static methods, such as RecordStore.openRecordStore(String,boolean). MockME solves this by delegating static method invocationsto a static delegate instance with a special method name. Let’s have a look at theinner workings:

Page 4: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 4/20

4

JayView 

RecordStore.java

public class RecordStore {

// Used to delegate static method invocations

private static RecordStore _delegate;

// Used to set static delegate, i.e. a mock object

public static void setStaticInstance(RecordStore delegate) {

_delegate = delegate;

}

// The static method delegates to a non-static equivalent

public static RecordStore openRecordStore(String recordStoreName,

boolean createIfNecessary)

throws RecordStoreException,

RecordStoreFullException,

RecordStoreNotFoundException {

return _delegate.static_openRecordStore(recordStoreName, createIfNeces-

sary);

}

// This method represent the static method and can be mocked!

protected RecordStore static_openRecordStore(String recordStoreName,

boolean createIfNecessary)

throws RecordStoreException,

RecordStoreFullException,

RecordStoreNotFoundException {

return null;

}

// ...}

By creating a mock object and setting the static instance, we fake the static methodinvocations. No real magic here, but it’s important to make the development of JavaME unit tests much simpler.

MockME In ActionOK, after motivating MockME, let’s look at a small example:

MessageDao.java

public class MessageDao {

private static fi nal String RECORD_STORE_NAME = ”MessageDao”;

public void addMessage(Message message) throws RecordStoreException {

RecordStore recordStore = null;

try {

// This static method invocation is normally hard to mock

recordStore = RecordStore.openRecordStore(RECORD_STORE_NAME, true);

byte[] bytes = encodeMessage(message);if (message.getId() == -1) {

message.getId() = recordStore.addRecord(bytes, 0, bytes.length);

} else {

recordStore.setRecord(message.getId(), bytes, 0, bytes.length);

}

} fi nally {

if (recordStore != null) {

recordStore.closeRecordStore();

}

}

}

private byte[] encodeMessage(Message message) {// Convert message to bytecode

byte[] bytes = ...;

// Not important for the example and therefore omitted

return bytes;

}

}

The class above is an example of a simple Data Access Object (DAO). It allows usto 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

// Called by JUnit to initialize the test

public void setUp() {

// Create mock object for RecordStore and use the special method// provided by MockME to set the static instance

recordStoreMock = createMock(RecordStore.class);

RecordStore.setStaticInstance(recordStoreMock);

// Create object under test

messageDao = new MessageDao();

}

// Called by JUnit to clean up after each test run

public void tearDown() {

messageDao = null;

recordStoreMock = null;

}

public void testAddMessage() throws Exception {

// Set up expected behaviour

byte[] expectEncMess = ”\u0004from\u0004text”.getBytes();

expect(RecordStore.openRecordStore(”MessageDao”, true))

.andReturn(recordStoreMock);

expect(recordStoreMock.addRecord(aryEq(expectEncMess), eq(0), eq(10)))

.andReturn(42);

recordStoreMock.closeRecordStore();

// Put the mock object in test state

recordStoreMock.replay();

// Executing the code we want to test

Message message = new Message(”from”, ”text”);

Page 5: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 5/20

5

JayView 

messageDao.addMessage(message);

// Verify the behaviour

recordStoreMock.verify();

 

assertEquals(”Wrong message ID”, 42, message.getId());

}

public void testRecordStoreFull() throws Exception {

// Set up expected behaviour

expect(RecordStore.openRecordStore(”MessageDao”, true))

.andReturn(recordStoreMock);

expect(recordStoreMock.addRecord(eq(42), (byte[]) anyObject(),

eq(0), eq(10)))

.andThrow(new RecordStoreFullException());

recordStoreMock.closeRecordStore();

 

// Put the mock object in test state

recordStoreMock.replay();

// Executing the code we want to test

try {

Message message = new Message(”from”, ”text”);

messageDao.addMessage(message);

fail(”Expected exception”);

} catch (RecordStoreFullException e) {

assert(true); // Ok, expected

}

// Verify the behaviour

recordStoreMock.verify();

}

}

Lets look at the setUp() method. First we use EasyMock to create a mockedRecordStore object dynamically, that the MessageDao is going to write its data to.Then we invoke RecordStore.setStaticInstance() to mock all static methodsin 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 methodunder test is called. If a method has a return value, you need to use a (staticallyimported) expect() method. By using the andReturn() method, we can return amocked 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 thebehavior 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 usesthe 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. Atest 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.

Eyes On The Prize We’ve now seen how MockME has given us the opportunity to use Java SE tools,such as EasyMock, for Java ME unit tests. But there is so much more, for examplecode coverage. A code coverage tool is used to detect what parts of your code areexecuted. This is a great tool for motivating developers to write test code. A codecoverage report indicates the percentage of your code that was tested (covered),normally indicated with a green bar of variable length. It’s highly motivating, andfun, to see how the green bar grows. Remember that it is not the number of test cas-es that is important, but what parts of your code are executed by your test cases.

You are not limited to the above mentioned tools. You could use any Java SE unit testing tool or testing library. For example, there are libraries that simplify testing of multi-threaded classes, comparing XML documents, and so on. This would not bepossible, or at least it would be very hard, if you were to use one of the traditionalJava ME testing frameworks.

ConclusionIn 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. Wehave stressed the use of true unit tests in Java ME, something rarely seen in JavaME 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 befewer and more focused on integration issues.

 Magnus Robertsson and Johan Karlsson

Jayway

ReferencesDependency 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

Page 6: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 6/20

6

JayView 

 With today’s functionality

and information-crammed

mobile devices the threat

of malicious code is a real concern,

especially for those of us that like to

download and install third party ap-

plications. It is essential for the growthof the mobile content market that cus-

tomers can feel safe using their appli-

cations without worries of stolen data

or unexpected billing. The Java ME

platform addresses this problem by

protection domains, permissions and

trusted MIDlet suites.

In short, a trusted MIDlet is one whosesupplier can be securely identified astrustworthy at the time of installation incontrast to other MIDlet suites wherenothing can be guaranteed about thesupplier. The trustworthiness is provenby a certificate and allows the applica-tion to run in a permissive protectiondomain where a selected set of poten-

tially risky functionalities on the deviceare made available, no questions asked(or at least not more than once). Thisrelieves the end user from repeatedlyhaving to allow access to the file system,

network connections or similar which isoften the case otherwise.

Certificates and codesigning - quick and dirtyCode signing and certificates rely onthe principles of asymmetric encryptionschemes such as RSA, where each in-dividual has a freely distributed publickey and a secret private key. The twokeys work in reverse when using theRSA algorithm, so that if one of themis used to transform plain data into anencrypted form then the other one can

be used for recovery.So when shipping a piece of software,

the vendor creates a signature of thecode (or rather a hash value of it) us-ing the private key. The end user in turncalculates a hash value of the receivedcode, applies the public key on the ven-dor’s signature and then compares thetwo hash values. If the code has not 

Signing MIDlets

Page 7: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 7/20

7

JayView 

– the whys and howsbeen tampered with they should matchexactly, while a match would be veryimprobable in any other case. So, theend user can verify the integrity of thecode but what about the integrity of thevendor, how can one be sure that the

public key really belongs to the partyclaiming it?

Certificates to the rescue! Whenbuying a mobile phone a number of public keys are already embedded inthe device’s firmware, these keys be-long to certificate authorities (CA) suchas Thawte and Verisign and can be as-sumed to be genuine because of the

extensive control measures taken at thephone manufacturing plant. An applica-tion vendor can apply for a certificatewhich essentially is a document bindingthe vendor’s public key to its identityinformation by means of a CA signa-ture. This certificate is then used by theend user’s system to verify the vendor’spublic key and identity, relying on the

trustworthiness of the CA.

Sounds great, where doI sign up?Let’s study the case of the fictitious soft-ware publisher FooBar Soft. Their best selling file system management product is now to be released on the mobile plat-

form, and the technicians have made abrilliant job porting it using the file sys-tem access API, JSR-75.

However, the application turns out to be a real nuisance to use because of the ever-occurring security popups ask-ing the user to allow the software to dothis and that. FooBar Soft realizes that signing the application would be a goodidea because it allows instant access tothe file system, no questions asked. Asan additional benefit, the customerswould have increased trust in the ap-plication and be even more keen to tryit out.

The first step is to generate a key-store with a public/private key pair anda certificate signing request (CSR) us-ing the Java SDK command line toolkeytool . The CSR is then submitted toa CA bundled with information prov-ing the identity of FooBar Soft. Afterthe CA has accepted the request and a

Page 8: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 8/20

8

JayView 

fee has been paid, a signed certificate including the public key is made available fordownload or sent to FooBar via mail so that it can be imported to the keystore usingkeytool again.

There is normally no reason to keep the certificate secret so it can be transferredusing an insecure channel. Essentially, the keystore now holds the private key usedfor 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 allthe 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 theapplication uses have to be listed in the JAD and the manifest file. In FooBar Soft’scase, this means adding the following line:

MIDlet-Permissions: javax.microedition.io.Connector.fi le.read, javax.microedi-

tion.io.Connector.fi le.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 actualdata fields that the mobile phone will use for verification during installation, i.e. thesignature and certificate:

MIDlet-Certifi cate: <certifi cate (Base64 encoded)>

MIDlet-Jar-RSA-SHA1: <signature (Base64 encoded)>

Signing a suite is a quick operation, which is often included in the build process alsoduring development. It is important that the customer has a root certificate on thephone belonging to the CA that issued the application vendor certificate, otherwisethe installation will fail. This is also the case if the validity period of the certificatehas run out or on some platforms if the certificate has been revoked. In practicethere are only a few CAs whose root certificates are widespread in mobile devicesand one of these CAs is typically the best choice for the developer.

What’s in a signature and what’s not /The other side of thestoryIt is important to realize what a certificateand signature really says. It does say that the origin of the software can be settledand that the software has not changedsince being shipped. If the supplier is wellknown, this usually implies a high level of confidence that the software will do what it is supposed to without harming the

phone. However, the CA is only responsi-ble for binding keys to identities, and not to guarantee the function of every appli-cation signed using those keys. In essence,the signature does not say that a trustedMIDlet suite is necessarily well-behavedand a healthy dose of cautiousness is al-ways recommended. It is also vital that the private key really is kept private by

the vendor, if not then anyone in posses-sion of it could pose as the rightful owner.Also, as much as code signing increasesthe trust in applications it also has thepotential of locking developers out of aplatform. The cost of a certificate can bean unfeasible expense for a small scalebusiness or hobbyist. Network operatorsmay also limit the number of root certifi-

cates available in their branded devices, possibly only including their own.Erik Rydgren

Realway

Page 9: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 9/20

9

JayView 

Once 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.

SubtypingThe 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>.

// Example why generic elements are not proper subtypes:

List<Integer> integers = new LinkedList<Integer>;

List<Number> numbers = integers; // Won’t compile!

numbers.add(3.14); // Integers cannot contain 3.14

The fact that the Liskovs Substitution Principle does not apply to generics restricts

their usefulness; we need wildcards to loosen some of these restrictions.

WildcardsTo loosen the constraint above, wildcards may be used. Wildcards are used with thekeywords 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 astructure. 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 therecipient 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.

// Extends wildcard violation

List<Integer> integers = new LinkedList<Integer>();

List<? extends Number> numbers = integers;

numbers.get(i); // Works fi ne!

numbers.add(3); // Won’t compile!

// Super wildcard violation

List<Number> numbers = new LinkedList<Number>();

List<? super Integer> integers = numbers;

integers.add(3); // Works fi ne!

int i = integers.get(0); // Won’t’ compile!

Object o = integers.get(0); // Works fi ne, object is upper bound!

// Copy all elements, subclasses of T, from source to dest which con-

tains elements that are superclasses of T.

Essential

Java Generics

 A real tapir in the wild

Page 10: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 10/20

10

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:

List<?> integers = new LinkedList<?>(); // Won’t compile, instance

creation!

List<?> integers = Lists.<?>factory(); // Won’t compile, generic

 method!

class AnyList implements List<?> {} // Won’t compile, extend su-

perclass!

The syntax above is valid if any of the question marks is replaced by a proper class.The generic method is shown here in case the syntax looks unfamiliar.class Lists {

static <T> List<T> factory() {

return new LinkedList<T>();

}

}

BoundsBounds 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 fi ne since Person extends Entity!

Dao<Person> personDao = new Dao<Person>();

// Wont compile since String does not extend Entity!

Dao<String> stringDao = new Dao<String>();

Bounds may also be used in more advanced ways. The example below is a simplifiedversion from java.util.Collections and show a recursive bound. The genericparameter T is also used inside the bound Comparable<T> to make sure that theobjects contained in the collection are comparable amongst themselves.

// The method max takes a parameter which must contain elements of a

subclass of Comparable.

// In addition the Comparable class must be comparable with the declared

type

 public static <T extends Comparable<T>> T max(Collection<T> collection)

{

T currentMax = collection.iterator().next();

  for (T element: collection) {

  if (currentMax.compareTo(element) < 0) currentMax = element;

}

return currentMax;

}

By far the most difficult generic declaration comes from java.lang.Enum and lookslike this Class Enum<E extends Enum<E>> implements Comparable<E>. Like theabove declaration this is a recursive bound but it is even more constrained than theabove. The key to understanding this is to know how enums are implemented inJava.

// Declaring an enum

enum Tapir {MALAYAN, BRAZILIAN, BAIRD, MOUNTAIN}

// creates a class similar to this!

 public fi nal class Tapir extends Enum<Tapir> implements Comparable<Tapir>

{

 private Tapir(String name, int ordinal) {super(name, ordinal)}

   public static fi nal Tapir MALAYAN = new Tapir(”MALAYAN”, 0);

   public static fi nal Tapir BRAZILIAN = new Tapir(”BRAZILIAN”, 1);

   public static fi nal Tapir BAIRD = new Tapir(”BAIRD”, 2);

   public static fi nal Tapir MOUNTAIN = new Tapir(”MOUNTAIN”, 3);

   private static fi nal Tapir[] VALUES = {MALAYAN, BRAZILIAN, BAIRD,

MOUNTAIN};

   public static Tapir[] values() {return VALUES.clone()}

Page 11: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 11/20

11

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 surethat enums of one type can only be compared with enums of the same type. Theinnermost generic parameter, Enum<E extends Enum<E>>, makes the subclass’ typeavailable to the superclass, allowing it to define methods whose parameters andreturn values are that of the subclass’.

Generic parameters may also have multiple bounds. The signature of the simplifiedexample above actually looks like this:

// Actual signature of max from Java Collections

 public static <T extends Object & Comparable<? super T>> T max(Collection<?

extends T> collection);

 When multiple bounds appear the first bound is used for erasure and the reason forthe 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 themethod more generic.

The method takes a collection of Ts or a collection of Ts subclasses (Collection<? ex-

tends T>) where T or one of Ts superclasses implements Comparable with erasureObject (<T extends Object & Comparable<? super T>>).

ErasureJava Generics is implemented by erasure. This means that the generic informationis 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.

Another thing to be aware of is that the implementation of generics with erasureforces the compiler to insert additional methods into the class files.

// Additional methods are compiled into generic classes

 public interface Foo<T> {

   void foo(T param);

}

 public class Bar implements Foo<Bar> {

 

// This method will appear twice once with Object as parameter and

once with Bar.   public void foo(Bar param) {}

 

 public static void main(String[] args) {

  for (Method m : Bar.class.getMethods())

  if (m.getName().startsWith(”foo”))

System.out.println(m.toGenericString());

}

}

 

$ 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 parametertoo. 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:

Error:line (6)name clash: foo(java.lang.Object) in Bar and foo(T) in 

Foo<Bar> have the same erasure, yet neither overrides the other

CompatibilityAll in all, the implementation of generics in Java is a wonderful example of crafts-manship. The solution is binary compatible both backwardly and forwardly, allowingnew 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.

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

Page 12: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 12/20

12

JayView 

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 problemA while ago a colleague of mine discovered a weird behavior when writing someintegration tests. He first noticed that the test worked in JDeveloper, but not inEclipse. Then he noticed that he could make a small change to the test setup andthe test would pass. Another small change and it would fail again. He got some helpand managed to reduce the problem to the following:

Original code

import junit.framework.TestCase;

public class ObjectCreationTest extends TestCase {

class MyObject {

Object temp;

public MyObject() {

set();

}

void set() {

}

Object get() {

return temp;

}}

public void testWithNewString() throws Throwable {

fi nal String value = new String(”Value”);

assertEquals(”Value”, value);

 

MyObject tested = new MyObject() {

void set() {

temp = value;

}

};

String result = (String) tested.get();

assertEquals(”Value”, result);

}

}

This test fails in some environments and works in others. When the test fails it isbecause result is null. How can this be? But it gets even stranger: By changing howthe value is initialized the test always pass:

Using a String constantpublic void testWithConstant() throws Throwable {

fi nal String value = ”Value”;

assertEquals(”Value”, value);

 

MyObject tested = new MyObject() {

void set() {

temp = value;

}

};

String result = (String) tested.get();

assertEquals(”Value”, result);

}

Problems withobject creation

Page 13: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 13/20

Page 14: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 14/20

14

JayView 

super. This is normally not allowed in Java, but consider what would happen if thecompiler didn’t work this way. MyObject constructor would be called, which thencalls set and tries to use val$value which has not been initialized yet. Because of abug 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 designThe problem with the design is that the base class MyObject is calling methods in theanonymous 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 {

class Base {

Base() {

doStuff();

}

void doStuff() {

}

}

class Sub extends Base {

private fi nal int fi nalField = 5;

private int normalField = 5;

void doStuff() {

assertEquals(5, fi nalField);

assertEquals(5, normalField);

}

}

 

public void testSub() {

Sub s = new Sub();

}

}

The test case will fail at the second assertEquals. Why? Two things are happening.

First of all ”finalField” is a constant variable and the compiler automatically uses 5instead of referencing the variable, see above. Secondly, the constructor for Base iscalled before the fields of Sub are initialized! Things are actually happening in thisorder:

1. The fields in Base are initialized2. Base constructor is run3. The fields in Sub are initialized4. Sub constructor is run

This is not a bug! This is exactly according to JLS ”§12.5 Creation of New ClassInstances”. 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;

}

}

 

public void testBase() {

Sub s = new Sub();

assertEquals(7, s.normalField);

}

}

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.

class Sub extends Base {

private int normalField;

void doStuff() {

normalField = 7;

}

}

This works as expected. However, try to avoid constructions like this as it is veryeasy to forget that the fields might not be initialized yet. There are actually moreproblems with this construction as it might affect thread safety. For instance if thesubclass starts a thread in the overridden method this thread might be given accessto 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 andfixing bugs.

• Avoid calling non final methods from the constructor. If you have to, be awarethat the object might not be initialized yet.

• Do not perform unnecessary initialization of fields.

Jan Kronquist 

Jayway

Page 15: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 15/20

15

JayView 

Neo 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 couldmean we can go agile all the way into the persistence layer.

The relational database represents one of the most important developments in thehistory of computer science. Upon its arrival some 30 years ago, it revolutionized theway 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. Couldthere 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:

• The mismatch between relational data and object oriented programming.• Schema evolution – updating your data model when the domain model changes

– is just so much manual labor.• Semi-structured or network-oriented data is difficult to handle.

The Neo DatabaseNeo is a database that is built with a different philosophy. Where the relational da-tabase squeezes all data into static tables, Neo uses a flexible and dynamic network model. This model allows data to evolve more naturally as business requirementschange. There’s no need for “alter table...” on your production databases after youintroduce a new version of the business layer and no need to rewire and migrateyour O/R mapping configurations. The network will evolve along with your busi-ness logic. This spells agility.

Neo is an embedded persistence engine, which means it’s a small, lightweight andnon-intrusive Java library that is easy to include in your development environment.

It has been designed for performance and scalability and has been proven to handlelarge networks of data (100+ millions of nodes, relationships and properties).

Neo is a newly founded open source project, but the software is robust. It hasbeen in commercial production in a highly demanding 24/7 environment for al-most four years and has full support for enterprise-grade features such as distributedACID transactions, configurable isolation levels and full transaction recovery.But so much for sweet talk, let’s cut to some code!

Model and Code

RepresentationIn the Neo model, everything is represented by nodes, relationships and properties.A relationship connects two nodes and has a well-defined, mandatory type. Prop-erties are key-value pairs that are attached to both nodes and relationships. Whenyou combine nodes, relationships between them and properties on both nodes andrelationships they form a node space – a coherent network representing your busi-ness domain data.This may sound fancy, but it’s all very intuitive. Here is how a simple social network might be modeled:

Neo– a netbase

Page 16: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 16/20

16

JayView 

Figure 1: An example of a social network from a somewhat famous movie. Note the differenttype on the relation between Agent Smith and his creator The Architect.

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 tolook 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, allrelationships have an “age” property to describe how long two people have knowneach other and some relationships have a “disclosure” property to describe whetherthe acquaintance is secret.

 Working with nodes and relationships is easy. The basic operations are as follows:

This is an intuitive representation of a network and probably similar to many otherimplementations that want to represent a network of data in an object-orientedlanguage.

It’s worth noting, however, that relationships in this model are full-blown objectsand not just implicit associations between nodes. If you have another look at thesocial network example, you’ll see that there’s more information in the relationshipsbetween nodes than in the nodes themselves. The value of a network is in the con-nections between the nodes and Neo’s model captures that.

Creating a Node SpaceAnd now, finally some code. Here’s how we would create the Matrix social network from figure 1:

Transaction tx = Transaction.begin();

EmbeddedNeo neo = ... // Get factory

// Create Thomas ’Neo’ Anderson

Node mrAnderson = neo.createNode();

 mrAnderson.setProperty( ”name”, ”Thomas Anderson” );

 mrAnderson.setProperty( ”age”, 29 );

// Create Morpheus

Node morpheus = neo.createNode();

 morpheus.setProperty( ”name”, ”Morpheus” );

 morpheus.setProperty( ”rank”, ”Captain” );

 morpheus.setProperty( ”occupation”, ”Total bad ass” );

// Create a relationship representing that they know each other

 mrAnderson.createRelationshipTo( morpheus,

MatrixRelationshipTypes.KNOWS );

// Create Trinity, Cypher, Agent Smith, Architect similarly

...

tx.commit();

As you can see in the code above: It is rather easy to construct the node space for ourMatrix example. And, of course, our network is made persistent once we commit.

Traversing a Node SpaceNow that we know how to represent our domain model in the node space, how dowe get information out of it? Unlike a relational database, Neo does not support adeclarative query language. Instead, Neo provides an object-oriented traverser frame-work that allows us to express complex queries in plain Java.

 Working with the traverser framework is very straight-forward. The core abstrac-

tion is, unsurprisingly, the Traverser interface. A Traverser is a Java Iterable that encapsulates a “query” – i.e. a traversal on the node space such as “give me all Mor- pheus’ friends and his friends’ friends” or “does Trinity know someone who is acquainted with an agent?” . The most complex part of working with a Traverser is instantiatingit. Here’s an example of how we would create a Traverser that will return all the(transitive) friends of the “Thomas Anderson” node of the example above:

// Instantiate a traverser that returns all mrAnderson’s friends

Traverser friendsTraverser = mrAnderson.traverse(

Traverser.Order.BREADTH_FIRST,

StopEvaluator.END_OF_NETWORK,

ReturnableEvaluator.ALL_BUT_START_NODE,

MatrixRelationshipTypes.KNOWS,

Direction.OUTGOING );

Page 17: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 17/20

17

JayView 

Here we can see that traversers are created by invoking the traverse(...) methodon 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 (ratherthan 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? Afterwe’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 runthrough the entire network along the KNOWS relationship type, breadth first, andreturned 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 asmall, contrived example. But the code would work equally well on a network withhundreds of millions of nodes, relationships and properties.

Now, let’s look at a more complex traversal. Going with our example, supposethat we wanted to find all “hackers of the Matrix,” where we define a hacker of theMatrix as any node that you reach through a CODED_BY relationship. How wouldwe 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, wewant 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 );

Now it’s getting interesting! The ReturnableEvaluator.ALL_BUT_START_NODE con-stant from the previous example was actually a convenience implementation of the

ReturnableEvaluator interface. This interface contains a single method and youcan supply a custom implementation of it to the traverser framework. It turns out that this is a simple but powerful way to express complex queries.

Setting aside the anonymous inner class cruft surrounding the code in bold, webasically pass in a snippet of code that checks whether we traversed a relationship of type CODED_BY to get to the current node. If this statement is evaluated to “true”then the current node will be included in the set of nodes that is returned from thetraverser.

 When executed with a simple print loop, the above code prints the following:

$ bin/run-neo-example

The Architect

$

StopEvaluators work the same way. In our experience, writing custom evaluatorsis very easy. Even the most advanced applications we have developed with Neo– applications that traverse extremely large and complex networks – are based onevaluators that are rarely more than a few lines of code.

ConclusionNeo 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

 just need to go truly agile, give the Neo database a run for your money. We hopeyou find it, as we do, to be an elegant and flexible alternative that is both robust andfast.

Emil EifrémNeo Persistence

Björn GranvikJayway

LinksNeo specification

www.neo4j.org

Page 18: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 18/20

18

JayView 

Iam in search of an empty room at

the Øredev conference. Normally

this is an easy task, but I’ve got

Martin Fowler on my tail. My mindis still blank. What on earth can I ask

him that he hasn’t already written

himself?

Finally, an empty room, well almost.Another speaker, Erik Dörnenburg, issitting half way into his screen and mut-ters.

- What’s up, I ask.- I’ve updated my machine and my

demo doesn’t work. I’ve got 45 minutesuntil the presentation.

  We sat down next to him. Do not disturb a developer while he’s coding...

So I got a man who has coined phraseslike Dependency Injection and POJO infront of me. What next? Martin is easily

recognizable both in accent and appear-ance, a frequent and brilliant speaker.

He has an excellent web site, www.martinfowler.com, which contains loadsabout his work. Articles and referencesabound. That is when it suddenly hitsme - who is he as a programmer andperson?

 When was the last time you coded? Well, I do code my own website. But it’sbeen a while since I had any paying cus-tomers. I’ve been pairing quite recentlythough. A real delivery? That was sometime ago. I’m actually afraid to lose con-tact with code, but I have smart peoplearound me.

But what makes you tick?

I enjoy trying to figure out new tech-

niques - to organize knowledge. I seemyself as a conduit [ledning] for trans-ferring knowledge, to process what is out 

there and make some kind of structureout of it. Brian Foot actually describedme as an ”intellectual jackal with a goodtaste in carrion” [intellektuell schackalmed god smak för kadaver].

I look around for interesting stuff andtry to make sense of it.

The ”Refactoring” is a good exam-ple. I figured out how to describe it and

wrote a book that came out when it could make a difference and move thearea forward.

I also enjoy writing a lot, that’s a bigthing. I’m better now at speaking, but that’s not what makes me tick.

 You’ve written quite a few books - how 

do they compare?

Out of the five, ”Uml Distilled” soldmore copies than the others put togeth-er. Usually you can’t make a living out of your books, I guess I could though.All of the books had their good sides,but I would have to say that it was funto write with Kent Beck [red: wrote”Extreme Programming”, created JUnit etc]. We were in tune and could support each other through the dull bits.I would have to say though that I’mmost proud of ”Refactoring”. It’s animportant technique and didn’t get theattention it should have received – thebook helped.

How did you start out?

I was an independent consultant formany years. Giving talks was a good wayof getting jobs. Articles same thing - it 

Page 19: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 19/20

19

JayView 

Interview 

Martin Fowler

– man in the know

got my name known.Also, I write something because I

don’t understand a certain area or tech-nology. It’s a good way to learn.

Erik is now on the phone with Califor-nia. We calculate that time is roughly 6:30there – in the morning.

Then what? How come you started

 working for Thoughtworks (TW)?

I’ve been there for six years and done alot of consulting. I never wanted to work for a company, but there was somethingabout TW that made me interested.Get the work done and tons of bright people. But more importantly is that it is a sort of social experiment. A notionthat good people makes a difference.I hope we can affect IT, which is a dif-ficult and skilled exercise at best.

 What is the most difficult part of being

a celebrity?

I’m not an extrovert person. I’m not good at the ”person to person”. I get 

emails with questions like ”I got a prob-lem on…what is the magic trick”. Theyworked for months on it and I can only

point to a book. That clearly wasn’t ananswer they liked. It’s frustrating.

However, celebrity is also a nice thing– it opens a few doors. I can email peoplelike Rod Johnson [red CEO of Interface21 that created the Spring framework]if I have a question about something.And he will answer.

People tend to think I’m an ingenious

programmer. I’m not. I’m pretty good,but not necessarily that great.

Erik suddenly spits out:- F---!...ok the demo will be shorter.

Looking forward, what’s next?

Oh, there is tons of stuff to write about.The design patterns area for instance.I’m also interested in DSL [domain spe-

cific languages] and agile development.But in agile there are too many writersand I don’t like competition. There aretoo many smart people in agile develop-ment.My strategy is to look for topics that noone has written about. Basically I don’t foretell the future.

 What are your top three pieces of ad-

 vice to a programmer?

My first advice must be to learn to col-laborate with the user or purchaser. Thereally good ideas usually come fromthem. You don’t have to be an expert todo this. This I found to be a good generaladvice.

Secondly, it would be ”continuouslearning”. It’s like running up a down-wards-moving escalator – you have tokeep running.

The third one is difficult…

”Buy lots of books by good authors”would be it.

Erik suddenly releases a big:

- Yes!I saw Erik’s demo some twenty min-

utes later – it was really good.As for Martin, our discussions con-

tinued well into the debate panel andbeyond. He would frequently forget hisback pain and sip into some extra en-ergy pack. I wonder how he did that.

Björn GranvikJayway

Page 20: Jay View 13

8/14/2019 Jay View 13

http://slidepdf.com/reader/full/jay-view-13 20/20

Java NewsTerracotta goes open sourceTerracotta clusters objects at the JVM level without the need of codechanges or serialization. For instance, this will enable open source appli-cation servers to use Terracotta for clustering. Also Terracotta ships withexamples showing how to cluster a Spring application.http://tinyurl.com/yfq4rf

Eclipse Mylar 1.0 releasedMylar extends Eclipse user interface with the ability to focus on a singletask. Mylar removes all the clutter and keeps only those things related to thecurrent task, for example a Bugzilla bug.http://www.eclipse.org/mylar/doc/release-1.0.php

TopLink open sourcedAt EclipseCon Oracle announced it will contribute TopLink to Eclipse.TopLink is a persistence framework for databases, XML and more and im-

plements standards such as JPA, JAXB and SDO (next release).http://tinyurl.com/2nfvwh

Atlassian Bamboo 1.0 releasedBamboo is a commercial product for continuous integration that builds,tests and generates reports. Besides simple web configuration, Bamboo alsogenerates statistics and graphs which enables you to see trends in your buildprocess.http://www.atlassian.com/software/bamboo/ 

Jaway

Malmö: Hans Michelsensgatan 9 , 211 20 Malmö, +46 40 12 72 83, Sweden