Tuesday, November 24, 2015

Elwood Maven Surefire Integration

I thought of adding a feature to Elwood to display failed Maven tests in real-time.

Below are my options:
1. Constantly watch and scrape the test results produced by Surefire plugin
2. Augment a test listener1 to Surefire plugin and expose the failed statistics back to Elwood

Since this is an experimental project, I decided to take the slightly complicated approach - option two. From my original thinking, I need to write a Maven model converter, hunt down the Surefire plugin and add the necessary test listener before I feed this pom back to Elwood (see Figure 1)

Figure 1 - Maven Model Converter to add a Surefire test listener


There are a few challenges here. Firstly, writing this converter is not a straightforward exercise as I originally anticipated. It requires deep a knowledge on Maven internals, plus an extra hurdle on the lack of API documentation. I've searched high and lows and luckily found what I was looking for from a test code found in Maven Model Builder project2. Secondly, I need to find a way to pass back the failed stats to Elwood through some mechanism. I can choose to do this by writing to a file, but then, how is this different from scraping the result as described in option one?

I've created a local branch containing the model converter and yet to push this to the remote repository as I still have to figure out how to hand the numbers back to Elwood. At this point, I'm not certain if this solution is achievable, so please stay tuned...

Update (24/11): The initial implementation is now available at:
https://bitbucket.org/lyeung/elwood-parent/commits/4b64304870bf58bf6041cdaf7bf6460575c2d04d?at=master


1https://maven.apache.org/surefire/surefire-api/apidocs/org/apache/maven/surefire/report/RunListener.html 2https://github.com/apache/maven/blob/master/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java

Wednesday, October 28, 2015

Elwood sources now available in Bitbucket

For the past few weeks, I've been squeezing every last drop of my own time to get Elwood working. From a simple process executor to a functional web application, where I could trigger a build by clicking a link. I have to say that this app is simple and crude, but is really fun to work on!

Think about this for a moment - we're writing a tool to build the tool itself!

Elwood is made up of a back-end REST service and a front-end AngularJS app. The REST service requires Redis 3 (never tested this on Redis 2+). The app keeps a list of projects and tracks the build results. Currently, it only supports Git with SSH (with or without passphrase).

"Elwood threw down his fork. He pushed his chair back and stood up. Liz stared up in astonishment at him, her cup half raised. Bob's mouth hung open, his sentence unfinished. Little Toddy said nothing."

The sources are available in Bitbucket:



 Looking ahead, this is going to be a very long journey...

Tuesday, August 18, 2015

Elwood - Building the build server (a prototype)

Things are coming together right now! It all started from an imaginary concept filled with dragons, knights and fairy god-mothers - well yeah, you know what I mean.

At the most basic level, a build server has to satisfy 3 requirements:
  • Get the source code
  • Build the code
  • Report if the build is successful

What I have right now is a work in progress. It's quite rudimentary and clunky. It clones your sources (currently Git only) and runs your build command (e.g. mvn clean package). The UI constantly polls for the log but goes endlessly. I have to manually kill the poller to stop this activity - how shameful of me!
He builds a boat in his back yard, to great annoyance to his wife and neighbors. When they ask him why he builds it, he tells them he doesn't know.

What's next?
I need to capture and store the build number, as well as the build result.

Saturday, August 27, 2011

Keeping Barbarians at the Gate

My workstation sits at the further end of five workstations aligned adjacently in a row. The walls of the entire floor are painted in white, seemingly dull but immaculate. The dark grey carpet covered across the floor adds sombre to the yet harsh cold August winter.

Looking at the distant window from where I sit,
        I know it’s another bleak day.


I can’t remember if I had seen sunlight two or three days ago. Perhaps four? Maybe there was one yesterday. Seriously, I can’t recall and I can’t be bothered at all.

I’m glued to my screen that I can’t hear the noise around me – because I’m busy keeping the barbarians at the gate.


class User {
private TimeInterval accessibleTime;
private Set<String> accessCodes;

public User(TimeInterval accessibleTime) {
this.accessibleTime = accessibleTime;
}
}


Add null pointer check to parameter and ensure the API validates against incorrect time interval:

public User(TimeInterval accessibleTime) {
if (accessibleTime== null) {
throw new IllegalArgumentException(
"accessibleTime parameter cannot be null");
if (accessibleTime.getFromTime() > accessibleTime.getToTime()) {
throw new IllegalArgumentException("accessibleTime time from [" + acc
essibleTime.getTimeFrom() + "] is later than time to [" + accessibleTime.getTime
To() + "]");
this.accessibleTime = accessibleTime;
}


Generate getter and setter methods:

@YetAnotherNotNullValidation(message = "access codes cannot be null")
public String getAccessCodes() {
return accessCodes;
}

public String setAccessCodes(Set<String> accessCodes) {
this.accessCodes = accessCodes;
}



Hang on, should I expose this setter method even though I have a validation annotation of NotNull hoisted up there? It should be alright I guess, as the validation framework should catch this during runtime. But then again, it requires extra effort to check null values.


// Someone accidentally wipes out accessCodes somewhere in the code
user.setAccessCodes(null);

// and I need to add null check to prevent NPE
if (user.getAccessCodes() == null) {
user.setAccessCodes(new HashSet<String>());
}


Do I want to see this sprinkled everywhere? Perhaps not. It is easy to misuse the setter method and leave accessCode variable in limbo. Better get rid of this, I would rather not have "Midas Touch" effect here.


doSomething(user.getAccessCodes());
// to clear out values
user.getAccessCodes().clear();


Tuesday, April 26, 2011

Java Inner Class vs Static Inner Class

On one lazy Friday afternoon, I find myself mesmerised by the fact that I subconsciously write statically nested inner class as oppose to writing the usual nested class in Java. For every small nestable class that I can think of, I somehow feel obliged to prepend it with a static keyword.

If my recollection serves me right, it was from a code review that I had years ago. A colleague pointed his finger on my screen and loudly exclaimed, “This nested class is inefficient!”

Yes, he is right! But how inefficient is inefficient? How does the instance look like if I were to draw it on a piece of paper? How big does this affect the VM’s memory?

"See Colonel Sartoris. I have no taxes in Jefferson."


Time to roll up our sleeves and have a look under the hood.

OuterEmily.java
package aroseforemily;

public class OuterEmily {
public void dontPayTax() {
}

public class InnerEmily {
public void buyArsenic() {
}
}
}


Running javap -c aroseforemily.OuterEmily gives us:

Compiled from "OuterEmily.java"
public class aroseforemily.OuterEmily extends java.lang.Object{
public aroseforemily.OuterEmily();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

public void dontPayTax();
Code:
0: return
}

Running javap -c aroseforemily.OuterEmily\$InnerEmily gives us:
Compiled from "OuterEmily.java"
public class aroseforemily.OuterEmily$InnerEmily extends java.lang.Object{
final aroseforemily.OuterEmily this$0;

public aroseforemily.OuterEmily$InnerEmily(aroseforemily.OuterEmily);
Code:
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:Laroseforemily/OuterEmily;
5: aload_0
6: invokespecial #2; //Method java/lang/Object."":()V
9: return

public void buyArsenic();
Code:
0: return
}


By looking at aroseforemily.OuterEmily$InnerEmily, the compiler inserts a synthetic final OuterEmily member variable this$0, at the same time adds a synthetic non-default constructor. From line 7-9 we can see that it assigns the final member variable from the constructor parameter.

The druggist named several. "They'll kill anything up to an elephant. But what you want is—"

"Arsenic," Miss Emily said. "Is that a good one?"


What happens if we set the inner class to static?

package aroseforemily;

public class OuterEmily {
public void dontPayTax() {
}

public static class InnerEmily {
public void buyArsenic() {
}
}
}


Rerunning javap -c aroseforemily.OuterEmily\$InnerEmily yields:
Compiled from "OuterEmily.java"
public class aroseforemily.OuterEmily$InnerEmily extends java.lang.Object{
public aroseforemily.OuterEmily$InnerEmily();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

public void buyArsenic();
Code:
0: return
}


The second disassembled code suggests that for every instance of inner class, they will always contain an extra reference to the outer class; hence nested classes are less optimal compared to static nested classes, especially when inner classes are strongly referenced and prevents weak referenced outer class from GCed.

Sunday, June 6, 2010

Java Generics and Synthetic Bridge Method

I'll take you to a Java-landia magical mystery tour, this time it's got something to do with generics.

Take a look at the example below.

MeanMeter.java:


public interface MeanMeter < T > {
boolean isMean(T t);
}


Compile this class and run "javap -c MeanMeter" produces:


Compiled from "MeanMeter.java"
public interface MeanMeter{
public abstract boolean isMean(java.lang.Object);

}


What happened to our parameter type T?!

OK. Park that for now. Let's look at another example.

JimsCreation.java:


public class JimsCreation implements MeanMeter< JimsCreation.Garfield > {
public boolean isMean(Garfield garfield) {
return true;
}

public static void main(String[] args) {
JimsCreation jimsCreation = new JimsCreation();
jimsCreation.isMean(new Garfield());
}

public static class Garfield {
}
}


Now, take a deep breath. Compile then run "javap -p JimsCreation" from command line.

Below is the result:


Compiled from "JimsCreation.java"
public class JimsCreation extends java.lang.Object implements MeanMeter{
public JimsCreation();
public boolean isMean(JimsCreation$Garfield);
public static void main(java.lang.String[]);
public boolean isMean(java.lang.Object);
}


We got 2 "isMean" methods?!!! What's going on here?!

Rub your eyes. Yes, Javac gave us 2 methods with different argument type!

"Is this some kind of black magic?"


So what happened here was that the compiler tricked us by introducing a "bridge" method - another word for "smart-overloaded-method-created-by-javac". It cleverly erased our generic type "T" and replaced it with "java.lang.Object" in MeanMeter interface; it also inserted the said signature into JimsCreation class. This is because Java promised backward compatibility to support non-generic sources from pre-JDK5 days.

By typing "javap -c JimsCreation" produces:


Compiled from "JimsCreation.java"
public class JimsCreation extends java.lang.Object implements MeanMeter{
public JimsCreation();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."< init >":()V
4: return

public boolean isMean(JimsCreation$Garfield);
Code:
0: iconst_1
1: ireturn

public static void main(java.lang.String[]);
Code:
0: new #2; //class JimsCreation
3: dup
4: invokespecial #3; //Method "< init >":()V
7: astore_1
8: aload_1
9: new #4; //class JimsCreation$Garfield
12: dup
13: invokespecial #5; //Method JimsCreation$Garfield."< init >":()V
16: invokevirtual #6; //Method isMean:(LJimsCreation$Garfield;)Z
19: pop
20: return

public boolean isMean(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #4; //class JimsCreation$Garfield
5: invokevirtual #6; //Method isMean:(LJimsCreation$Garfield;)Z
8: ireturn

}


LO AND BEHOLD!!!"


Look at the last method at line 28! It casts the object type parameter to JimsCreation$Garfield^ at line 32 and invokes the overloaded method at line 33!

So the main question is what happens if we invoke JimsCreation.isMean(Garfield) method? Does it invoke the bridge method or the original method? Answer - it still invokes the original method. See line 24.


^JimsCreation$Garfield represents Garfield as static class to JimsCreation.

Wednesday, June 2, 2010

My DeLorean Package

I'm tasked by Dr. Emmett Brown to help Marty McFly travel to different time periods successfully on Doc's time machine - DeLorean!

However, I must ensure DeLorean must at least hit the speed of 88 miles per hour (142 km/h) for the flux capacitor to kick-in, then a big ZAP and vanishes from sight.

Below is the source code:
package delorean;
import java.util.Date;

public class DeLorean {
private static final int MAX_SPEED_MPH = 88;

public boolean timeTravel(Date date, int speedMPH) {
System.out.println("Setting DeLorean target date " + date);

if (prepareTimeTravel(speedMPH)) {
System.out.println("Time travel was successful, we are now on " + date);
return true;
}

System.out.println("Time travel failed");
return false;
}

private boolean prepareTimeTravel(int speedMPH) {
// we need at least 88 mph or equivalent to 142 km/h
// to activate flux capacitor for time travel
if (speedMPH >= MAX_SPEED_MPH) {
System.out.println("Activating flux capacitor");
return true;
}

return false;
}
}


I also wrote a unit-test to ensure the flux capacitor activates once speed is at 88 mph during Marty's travel:

package delorean;
import java.util.Calendar;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;

public class DeLoreanTest {
private static Calendar future;
private DeLorean deLorean;

static {
future = Calendar.getInstance();
future.set(Calendar.YEAR, 2015);
future.set(Calendar.DAY_OF_MONTH, 21);
future.set(Calendar.MONTH, Calendar.OCTOBER);
}

@Before
public void init() {
deLorean = new DeLorean();
}

@Test
public void testTimeTravelSuccess() {
Assert.assertTrue(deLorean.timeTravel(future.getTime(), 88));
}

@Test
public void testTimeTravelFailed() {
Assert.assertFalse(deLorean.timeTravel(future.getTime(), 87));
}
}


Below is the result of the test:

Setting DeLorean target date Wed Oct 21 03:03:50 EST 2015
Activating flux capacitor
Time travel was successful, we are now on Wed Oct 21 03:03:50 EST 2015
Setting DeLorean target date Wed Oct 21 03:03:50 EST 2015
Time travel failed

Everything looks fine, but...


OK I admit I'm test infected and I really feel the urge to also test "prepareTimeTravel" method alone by itself. However, how am I suppose to do this when it's defined as a private method? Surely I can turn this to public but I'd rather keep this abstracted away from Marty as he doesn't need to know the nitty-gritty details between the car's acceleration and the flux capacitor. All he needs to know is to step on accelerator pedal to reach 88 miles per hour and *poof* he goes.



*Thinking, thinking, thinking...*



What about setting this method as package scope? This means "prepareTimeTravel" method will only be visible to classes of the same package, including DeLoreanTest class (same package name)^. This also ensure classes from other packages won't see this method. This sounds like what I'm looking for.


package delorean;
import java.util.Date;

public class DeLorean {
private static final int MAX_SPEED_MPH = 88;

public boolean timeTravel(Date date, int speedMPH) {
System.out.println("Setting DeLorean target date " + date);

if (prepareTimeTravel(speedMPH)) {
System.out.println("Time travel was successful, we are now on " + date);
return true;
}

System.out.println("Time travel failed");
return false;
}

boolean prepareTimeTravel(int speedMPH) {
// we need at least 88 mph or equivalent to 142 km/h
// to activate flux capacitor for time travel
if (speedMPH >= MAX_SPEED_MPH) {
System.out.println("Activating flux capacitor");
return true;
}

return false;
}
}



The updated unit-test looks like this:

package delorean;
import java.util.Calendar;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;

public class DeLoreanTest {
private static Calendar future;
private DeLorean deLorean;

static {
future = Calendar.getInstance();
future.set(Calendar.YEAR, 2015);
future.set(Calendar.DAY_OF_MONTH, 21);
future.set(Calendar.MONTH, Calendar.OCTOBER);
}

@Before
public void init() {
deLorean = new DeLorean();
}

@Test
public void testTimeTravelSuccess() {
Assert.assertTrue(deLorean.timeTravel(future.getTime(), 88));
}

@Test
public void testTimeTravelFailed() {
Assert.assertFalse(deLorean.timeTravel(future.getTime(), 87));
}

@Test
public void testPrepareTimeTravelSuccess() {
Assert.assertTrue(deLorean.prepareTimeTravel(88));
Assert.assertTrue(deLorean.prepareTimeTravel(89));
Assert.assertTrue(deLorean.prepareTimeTravel(90));
}

@Test
public void testPrepareTimeTravelFailed() {
Assert.assertFalse(deLorean.prepareTimeTravel(87));
Assert.assertFalse(deLorean.prepareTimeTravel(86));
}
}

Vroooom... ZAP - *poof*



^ When using Maven, DeLorean class sits under "src/main/java directory" and DeLoreanTest class sits under "src/test/java" directory. Both classes contains same package name, hence package-scope method "prepareTimeTravel" will be visible to test class.