Writing a bookmarklet

A bookmarklet is a piece of javascript that you store as a bookmark. It’s a neat way of adding functionality to a web page that you don’t control. As part of my job, my team develops code in branches and after it has passed testing it needs to be ported to the trunk. Although we generate a branch report using CruiseControl which lists outstanding code ports, the page doesn’t have any totals on it. I’d like to be able just to view the totals of outstanding ports for my team. Although I could ask our build team to change how the page is generated, you can actually achieve this fairly simply using a bookmarklet. Here is the code I wrote:
javascript:(function(){
    /* count the occurences of each person */
    /* the branch report is in a pre formatted tag */
    var reportInfo = document.getElementsByTagName("pre");
    var textContent = reportInfo[0].innerHTML;
    var names = ["jsmith","jbloggs","tblair","gbrown"];
    var results = "";
    /* count the occurences of a name by splitting */
    /* the string on it and subtracting one from the total */
    for (var i=0; i<names.length; i++) {
        var count = textContent.split(names[i] + "@").length;
        if (count > 0) {
            count = count - 1;
        }
        results = results + names[i] + ": " + count + "<br>";
    }
    /* create a div to display the results */
    var s=document.createElement('div');
    s.innerHTML=results;
    s.style.color='black';
    s.style.padding='20px';
    s.style.position='fixed';
    s.style.zIndex='9999';
    s.style.fontSize='1.0em';
    s.style.border='2px solid black';
    s.style.right='40px';
    s.style.top='40px';
    s.style.background='white';
    document.body.appendChild(s);
})();
You can see that it is pretty easy to count the occurrences of the developer names by using the trick of splitting a string on the name and then subtracting one from the length of the resulting array. After that you just create a new div on the page to display the results.
Posted in Javascript | Tagged | Leave a comment

Gradle – Groovy based build system

An interesting new build system, based on Groovy:

http://www.gradle.org/overview.html

 

Posted in Groovy, Java | Tagged , | Leave a comment

Running Struts 1 actions from Spring

I’ve now successfully updated our app so that the Struts 1 actions can be run from Spring. The method was pretty much as I originally described, but there are a few gotchas, so I’ll detail it:

  1. Use the Spring ContextLoaderPlugin in the struts-config file.
  2. Override the Struts request processor with Spring’s delegating request processor.
  3. Write an action-servlet.xml file to declare all of your Struts actions as Spring beans. The beans just need a name and class, as the other properties will still be read from your struts config file.

The gotchas I found are:

  1. If you are using Tiles as well as Struts, you need to use Spring’s DelegatingTilesRequestProcessor rather than just the DelegatingRequestProcessor.
  2. Struts permits two actions to be declared with the same URL path (I assume the second definition overrides the first one), but you can’t have two Spring beans with the same name so if you have duplicate entries in your struts config you need to exclude them from your Spring beans file.
  3. You need to exclude Struts definitions that just forward to other places rather than invoking actions as these obviously won’t require a Spring bean definition. e.g. ones that forward to tiles layouts

Next step: migrating from EJB2 to Spring beans.

Posted in Groovy, Spring | Tagged , | Leave a comment

Groovy performance for file IO

As part of the work I’m doing trying to automate a migration from Struts to Spring MVC, I’ve been writing a Groovy script to process the struts config file. I need to add a couple of lines to the file. Unfortunately, editing a file in this way is something that is always rather fiddly to do. What you usually end up doing is reading the file line by line, writing each line to a second file, adding or removing lines where you need to. Then you delete the old file and rename the second one. However, Groovy has good support for both file IO and regular expressions, so you can easily write something like the following :
oldStrutsFile.eachLine{ line ->
	// copy the line in
	newStrutsConfig.append(line + "n")
	// add controller
	if (line =~ /</action-mappings/) {
		newStrutsConfig.append('spring controller info here')
	}
	// plug in
	if (line =~ /END MERGED RESOURCES/) {
		newStrutsConfig.append('spring plug-in info here')
	}	
}
However, when I ran the Groovy script I was amazed at how slow it was. It took approximately a minute to update the struts file. It is a reasonable size (177k) but even so the time is excessive. For comparison, I then rewrote this part of the code using Java. (I still kept it embedded within the Groovy script though):
FileReader reader = new FileReader(oldStrutsFile)
FileWriter writer = new FileWriter(newStrutsConfig)
String line = null;
while ( (line = reader.readLine()) != null) {
	// copy the line in
	writer.write(line + "n")
	// controller
	if (line =~ /</action-mappings/) {
		// write the extra lines
		writer.write('spring controller info here')
	}
	// plug in
	if (line =~ /END MERGED RESOURCES/) {
		writer.write('spring plug-in info here')
	}
}
This took 141 milliseconds to run, a phenomenal difference. For me, the lesson here is that if you are an experienced Java programmer, and you want to use Groovy, don’t feel that you have to use Groovy syntax all time, just because it is there. One of the great things about knowing more than one programming language is that you can choose the best tool for any particular job. With Groovy this is particularly true, as you can embed regular Java within Groovy whenever you like, to get the best of both languages.
Posted in Groovy | Tagged | Leave a comment

Migrating from Struts to Spring MVC – using Groovy!

To migrate from Struts 1 to Spring MVC, the easiest route is:
  1. Add the Spring ContextLoaderPlugin to your struts-config file. This plugin will load your bean definitions file.
  2. Update struts-config so that rather than using the default Struts request processor it uses Spring’s delegating request processor.
  3. Write a bean definition file to declare all of your Struts actions as Spring beans.
The third of these tasks could be a tedious manual task – why not script it with Groovy? It provides a good example of Groovy’s XML and GPath capabilities. GPath is the Groovy syntax for navigating in XML or object trees. It allows you to do the following:
  • Use the dot notation to traverse from one object or XML node to the next.
  • Find objects with specified properties.
For my very first attempt at scripting this, I wrote the following (it doesn’t deal with all of the Struts properties, just demonstrates the concept):
// read the struts file in as XML
GPathResult strutsConfig = new XmlSlurper().parse(inputFile)

// get all of the "action" nodes by traversing from the top level
// struts-config node
def actions = strutsConfig."action-mappings".action

// write the Spring action-beans.xml file
actions.each{ action ->
	outputFile.append('<bean name="' + action.@path + '"n')
	outputFile.append('  class="' + action.@type + '"n')
	outputFile.append('</bean>n')
}
You can see easy and concise the Groovy code is compared to Java. Reading the file in is a single line, as is getting the set of <action> nodes. For more info on Groovy’s XML capabilities, check out: http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper http://groovy.codehaus.org/GPath
Posted in Groovy, Spring | Tagged , | Leave a comment

Http coding and testing

A few days ago I blogged about writing a dummy server to use for testing. However, rather than just writing on a socket, the code I’m writing uses http and as it happens, there are some useful libraries you can use to write and test http code. To write a client, you might like to look at the Apache Commons HttpComponents: http://hc.apache.org/httpcomponents-client-ga/ For writing a server, there is actually some code bundled with the Sun Java distribution. It is in the com.sun package, so is not officially part of Java, but it is included in rt.jar. http://download.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/index.html To write a server, you need to:
  1. Create your server.
  2. Create at least one HttpHandler.
  3. Map the HttpHandler to a context path.
  4. Bind the server to an IP address and port.
  5. Start the server.
My trial code was:
// create a dummy server
HttpServer server = HttpServer.create();
// define an anonymous class to act as an httphandler
HttpHandler myHandler = new HttpHandler() {
BufferedReader reader;
PrintWriter out;

public void handle(HttpExchange exchange) {
  System.out.println(exchange.getRequestMethod());
  try {
    // http response code 200 is success
    exchange.sendResponseHeaders(200, 0);
  }
  catch (IOException e1) {
    log.error(e1);
  }

  System.out.println(exchange.getRequestURI().toString());

  reader = new BufferedReader(new InputStreamReader(exchange.getRequestBody()));
  try {
    System.out.println("Input: " + reader.readLine());
  }
  catch (IOException e) {
  log.error(e);
  }

  out = new PrintWriter(exchange.getResponseBody());
  out.println("Hello from server");
  out.flush();
  exchange.close();
  }
};

server.createContext("/",myHandler);
InetSocketAddress address = new InetSocketAddress("localhost", 35297);
server.bind(address, 5);
server.start();
You can see that this handler just prints out the various parts of the http request. For the client code, I used the old v3.1 Apache Commons httpclient:
HttpClient httpclient = new HttpClient();
HttpMethod postBasket = new PostMethod("http://localhost:35297?data=something");
int statusCode = httpclient.executeMethod(postBasket);

if (statusCode != HttpStatus.SC_OK) {
System.out.println("Method failed: " + postBasket.getStatusLine());
}

String response = postBasket.getResponseBodyAsString();
System.out.println("Response from server: " + response);
The output from running this code is:
POST
/?data=something
Input: null
Response from server: Hello from server
This is as expected – on this occasion the client has only issued a POST request, it hasn’t written anything into the body of the request, so the input stream opened on the body is null.
Posted in Java | Tagged | Leave a comment

Socket code – answer

Did you spot the bug? The server writes to the socket using:
 out.write("From server: " + nextResponse);
The client reads using:
while ((fromServer = in.readLine()) != null) {
However, the PrintWriter write method doesn’t put a carriage return at the end of the data. Hence, no matter how much data the server sends, the client will never receive any of it.
Posted in Java | Tagged | Leave a comment

Socket code – spot the bug

Recently I’ve been trying to test some code that interacts with a third party over http. I’d like to test as much of the code as possible, not just the code that prepares the data, but also the code that connects to the third party. Obviously I don’t want the test to actually connect to the third party, so I quickly coded up a little server that would listen on a socket for the code to connect. However, testing the code showed the client hanging. The code contains a pretty basic error, but it took me quite a while to notice it. From the code below, can you figure out what it is? For the server, I followed the standard procedure:
  • Create a server socket.
  • Wait for the client to connect and then open a new socket for communication, so that the server can continue to listen on the old socket.
  • Open streams for reading and writing.
I set the server to sleep and periodically send data to the client, to make it easy to check the code was working properly. The code was:
try {
  System.out.println("Trying to start server on port: " + port );
  serverSocket = new ServerSocket(port);
  System.out.println("Server successfully started on port: " + port);
}
catch (IOException e) {
  System.out.println("Could not listen on port: " + port);
  System.exit(-1);
}

Socket clientSocket = null;
try {
  clientSocket = serverSocket.accept();
}
catch (IOException e) {
  System.out.println("Accept failed: " + port);
  System.exit(-1);
}

System.out.println("Client has connected.");
PrintWriter out = null;
try {
  out = new PrintWriter(clientSocket.getOutputStream(), true);
  reader = new BufferedReader(
    new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e) {
 e.printStackTrace();
 }

for (int i = 1; i&lt;100; i++) {
  out.write("From server: " + nextResponse);
  try {
    Thread.currentThread().sleep(500);
  }
  catch (InterruptedException e) {
    e.printStackTrace();
  }
}
For the client, I did the following:
  • Started the server on a different thread.
  • Connected to the server.
  • Opened streams for reading and writing.
The code was:
Socket socket = new Socket("localhost",35297);
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(
  new InputStreamReader(socket.getInputStream()));

String fromServer;
while ((fromServer = in.readLine()) != null) {
      	Thread.currentThread().sleep(500);
       	System.out.println("Client trying to read from server...");
        System.out.println("Server: " + fromServer);
}

// shutdown the server
System.out.println("Shutting down server");
s.close();
The code looks fine, but it will hang. Why?
Posted in Java | Tagged | Leave a comment

Showing unused TestNG tests

We use TestNG for our system tests. One of the slight problems is that if a new test is written, but not added to the testng.xml file, it won’t be run. I like to monitor our testing progress, so I decided it would be nice to be able to see what tests exist in the code, but aren’t currently configured to run. There are a few different ways you can achieve this, depending on your test configuration, and how accurate you need the report to be. We store all of our system tests in a specific directory, so it is easy to access the classes. However, not all of the classes in the directory have to be tests, some of them could be helper files. For this reason, I used the directory to get an initial list of classes to work from, but then used reflection to check what classes actually have the TestNG “Test” annotation. The code was:
 // first get a list of all the system test classes
 List&lt;File&gt; systemTestFiles
   = FileListing.getFileListing(new File(systemTestSourceDirectory));
 // not all of these will be tests. Some of them will be helper classes,
 // so iterate over the corresponding class files and check which ones
 // have test methods in.
 for (File testFile : systemTestFiles) {
   // need to ignore the testng.xml file
   if (testFile.getName().endsWith(".java")) {
     // get the package name. The format is:
     // package
     // one or more spaces s
     // package name, which is non-whitespace S - put brackets round this
     // to capture it
     // semi-colon
     Set&lt;GrepMatch&gt; matches = Grep.search("packages+(S+);", testFile);
     // there really should be only one match
     final String packageName = matches.iterator().next().group1;
     // now get the class name. It is the name of the file, up to the .java
     final int endOfName = testFile.getName().indexOf(".");
     final String fullyQualifiedClassName = packageName + "."
       + testFile.getName().substring(0, endOfName);
     // load this class and check if it has test methods
     Class c = Class.forName(fullyQualifiedClassName);
     for (Method m : c.getMethods()) {
       if (m.isAnnotationPresent(Test.class)) {
         testClasses.add(fullyQualifiedClassName);
       }
     }
 }
I then used another grep to get the test classes in the testng.xml file:
Set&lt;String&gt; classesInTestNGXML =
  Grep.searchAndReturnCapturingGroup("&lt;classs+name="(S+)"",
                   new File(testNGXMLFileName));
After this it is easy to compare the two lists and print out the names of the tests that aren’t being run. The grep code I used was an enhanced version of the example given by Sun: http://download.oracle.com/javase/1.4.2/docs/guide/nio/example/Grep.java and the file listing code is based on: http://www.javapractices.com/topic/TopicAction.do?Id=68
Posted in Testing | Tagged | 1 Comment

Hibernate aliases

My colleague Raj was recently updating a Hibernate criteria query which made use of aliases. He wanted to add a criterion that a value in a linked table must be null, so the most obvious change to make was to add another alias and the appropriate condition. e.g.
.addAlias("product","p")
.add(Restrictions.isNull(p.sku)
However, this query produced no results. Why? The answer lies in how an alias works. Creating an alias actually performs an inner join. However, on this occasion, the “sku” column is the foreign key that is used for the join. Hence, the join produces no results. To achieve the desired query, you can use the overloaded version of the addAlias method, that allows to chose the join type: createCriteria(String associationPath, int joinType) Alternatively, you can remove the alias and simply tweak the syntax of the restriction.
Posted in Hibernate | Tagged | 1 Comment