Tuesday, December 6, 2011

Maven JAXB2 Plugin and Configuring Package Names

Several Maven plugins exist for generating classes from a schema definition. One I have yet to try is the Maven JAXB2 Plugin. Below I'll show the minimum setup for using the plugin in your project, as well as a couple of methods for dealing with the package name assigned to the generated classes.

Given the simplistic schema below, placed in src/main/resources of the project:

  <?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://example.org/message/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="message">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="text" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

We can add the plugin definition to our POM:

  <plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>

The classes generated by the plugin can be found in target/generated-sources/xjc. Below is the single class, Message.java, generated by the plugin (with the imports optimized and comments removed for brevity):

  package generated;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"text"})
@XmlRootElement(name = "message")
public class Message {

@XmlElement(required = true)
protected String text;

public String getText() {
return text;
}

public void setText(String value) {
this.text = value;
}
}

The first thing that stands out to me is the package name of generated. This might be ok if I wanted to use the generated classes within a single project, but if I wanted to distribute them, a more useful package name might be helpful.

The user guide for the plugin describes a list of configuration options. The one we're looking for might just be generatePackage, which we can add:

  <plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.0</version>
<executions>
<!-- ... -->
</executions>
<configuration>
<generatePackage>org.example.message</generatePackage>
</configuration>
</plugin>

The generated class can now be found in target/generated-sources/xjc/org/example/messsage/Message.java, with the new package name:

  package org.example.message;

public class Message {
// ...
}

There are a couple more options for setting the package name, one is to add an annotation to the schema:

  <?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://example.org/message"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xsd:annotation>
<xsd:appinfo>
<jaxb:schemaBindings>
<jaxb:package name="org.example.test"/>
</jaxb:schemaBindings>
</xsd:appinfo>
</xsd:annotation>
<xsd:element name="message">
<!-- ... -->
</xsd:element>
</xsd:schema>

If you find annotating a schema to for something like JAXB impurifies the schema, you could influence to derive a namespace by providing a targetNamespace attribute to the root element of the schema:

  <?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://example.org/message"
targetNamespace="http://example.org/message" ...>
<!-- ... -->
</xsd:schema>

If you have any other suggestions or feel like weighing in on the use of xjc annotations in schema definitions, please feel free to add a comment below.

Tuesday, November 15, 2011

Logging Thread Names with Log4j

In some applications that start multiple threads to handle some concurrent processing, tracking the activity for a particular thread can be tricky. Take the following log file snippet where a group of JMS messages are sent off all around the same time:


2011-11-15 10:08:25,460 INFO [JmsMessageSender:?] Sending message to queue: UPDATE.REQ.QUEUE
2011-11-15 10:08:25,460 INFO [JMSMessageReceiver:47] Using JMS Selector JMSCorrelationID='d6d3278b-7f7d-47f5-9d1f-a67e4100d800'
2011-11-15 10:08:25,461 INFO [JmsMessageSender:?] Sending message to queue: UPDATE.REQ.QUEUE
2011-11-15 10:08:25,489 INFO [JMSMessageSender:60] Using replyToQueue UPDATE.RESP.QUEUE
2011-11-15 10:08:25,486 INFO [JMSMessageReceiver:47] Using JMS Selector JMSCorrelationID='10287b5f-c061-4bba-8d9d-f92dbf6fb239'
2011-11-15 10:08:25,489 INFO [JMSMessageSender:60] Using replyToQueue UPDATE.RESP.QUEUE
2011-11-15 10:08:25,505 INFO [JMSMessageReceiver:47] Using JMS Selector JMSCorrelationID='b7892699-8f26-4260-ae36-62fa8b09c9c3'
2011-11-15 10:08:25,517 INFO [JmsMessageSender:?] Received message from queue UPDATE.RESP.QUEUE
2011-11-15 10:08:25,564 INFO [JmsMessageSender:?] Received message from queue UPDATE.RESP.QUEUE

With the case above, where many messages are sent and the responses will be eventually dealt with for further processing (which will also be logged), we could filter the log
Message on the thread to help track where something may have gone wrong.

The logging patterns for log4j allow for logging the name of the thread with %t. Here is the pattern used to output the messages above:

log4j.appender.outFile.layout.ConversionPattern=%d{ISO8601} %-5p [%c{1}:%L] %m%n

We can add the %t next to the class (%c):

log4j.appender.outFile.layout.ConversionPattern=%d{ISO8601} %-5p [%t:%c{1}:%L] %m%n

The next run produces similar logging statements with the thread name. As this is a Spring Batch application, the threads are named after the class handling their creation, SimpleAsyncTaskExecutor, with a number appened on as in: SimpleAsyncTaskExecutor-5

2011-11-15 10:57:51,643 INFO  [SimpleAsyncTaskExecutor-5:JMSMessageSender:47] Sending to destination queue UPDATE.REQ.QUEUE
2011-11-15 10:57:51,659 INFO [SimpleAsyncTaskExecutor-5:JMSMessageSender:60] Using replyToQueue UPDATE.RESP.QUEUE
2011-11-15 10:57:51,665 INFO [SimpleAsyncTaskExecutor-4:JmsMessageSender:?] Sending message to queue: UPDATE.REQ.QUEUE
2011-11-15 10:57:51,665 INFO [SimpleAsyncTaskExecutor-4:JMSMessageSender:47] Sending to destination queue UPDATE.REQ.QUEUE
2011-11-15 10:57:51,666 INFO [SimpleAsyncTaskExecutor-5:JMSMessageReceiver:47] Using JMS Selector JMSCorrelationID='846cc984-84fd-47a5-bfd3-c293da829927'
2011-11-15 10:57:51,687 INFO [SimpleAsyncTaskExecutor-4:JMSMessageSender:60] Using replyToQueue UPDATE.RESP.QUEUE
2011-11-15 10:57:51,695 INFO [SimpleAsyncTaskExecutor-4:JMSMessageReceiver:47] Using JMS Selector JMSCorrelationID='d44087e2-bd19-474a-a8d1-71ac0fc618a7'
2011-11-15 10:57:51,827 INFO [SimpleAsyncTaskExecutor-5:JmsMessageSender:?] Received message from queue UPDATE.RESP.QUEUE
2011-11-15 10:57:51,831 INFO [SimpleAsyncTaskExecutor-4:JmsMessageSender:?] Received message from queue UPDATE.RESP.QUEUE

Here we can now map request and responses to particular threads if we were to encounter a error (that's logged of course) later in processing.

I'm sure something similar can be done with the newer logging frameworks as well.

Sunday, November 13, 2011

Groovy: A Look at Mixins

Groovy's XML support is often cited as one of the bigger attractions of the language. I often find myself writing classes that parse XML messages of the form:

    class MyXmlParser {
def parse(String response) {
def parsedXml = parsed(response)
doSomethingWith(parsedXml)
}

def parsed(String response) {
new XmlSlurper().parseText(response)
}

// ...
}

One of the things that bothers me about the above pattern is the duplication in the parsed method that might spread throughout a group of classes. Using an inheritance scheme here might jump out as a possible solution at first, but that doesn't sit so well with me, as although the classes that use the duplicated method all parse XML, they all may not serve a similar substitutable purpose (one may send parsed results to a database, while another transforms the XML into an object, for example).

A newer feature of Groovy that I've been meaning to look into is the Mixin Transformation. Here, I could mixin the parsed method to all my classes that need to parse some XML. I started with the example linked to the left, but ran into a couple problems doing joint-compilation with Maven. Before we take a look at that, I'll demonstrate the mixin approach I used for this case.

The first step to adding mixins is to ensure the class you want to have make use of the mixin implement a common interface:

    package prystasj.groovy.xml

interface XmlParser {
def parse(String xml)
}

class MyXmlParser implements XmlParser {
def parse(String response) {
def parsedXml = parsed(response)
doSomethingWith(parsedXml)
}
// ...
}

The next step was to define the mixin class using the @Category annotation:

    package prystasj.groovy.xml

@Category(XmlParser)
class XmlParsing {
def parsed(String response) {
new XmlSlurper().parseText(response)
}
}

Finally, we can apply the @Mixin annotation and remove the parsed method for our parser:

    package prystasj.groovy.xml

@Mixin(XmlParsing)
class MyXmlParser implements XmlParser {
def parse(String response) {
def parsedXml = parsed(response)
doSomethingWith(parsedXml)
}
// ... method parsed(String response) removed ...
}

The MyXmlParser class now has the parsed method mixed in and no longer needs to define it. Is this a worthwile use of a mixin however, i.e. is the overhead worth having the duplication removed? In a more concrete situation, we might have many more duplicated methods between a group of classes that we would could add to the mixin, improving its worth.

Now back to the compilation problems I referred to earlier. When I went to compile, the GMaven plugin created the stubs required for joint compilation, and the Maven Compiler Plugin stumbled:


[ERROR] /home/prystasj/.../target/generated-sources/groovy-stubs/main/prystasj/groovy/xml/MyXmlParser.java:[..] cannot find symbol
[ERROR] symbol: variable XmlParsing

Everything in the stub looked legitimate, so I was rather stumped. I remembered running into a similar problem before, so I went ahead and tried fully qualifying the references inside the annotations:

    package prystasj.groovy.xml

@Category(prystasj.groovy.xml.XmlParser)
class XmlParsing {
def parsed(String response) {
new XmlSlurper().parseText(response)
}
}

@Mixin(prystasj.groovy.xml.XmlParsing)
class MyXmlParser implements XmlParser {
def parse(String response) {
def parsedXml = parsed(response)
doSomethingWith(parsedXml)
}
// ... method parsed(String response) removed ...
}

This resolved the issue and the project compile happily. If I'm not missing something, maybe this might be something worthwile to bring up with the GMaven developers? Thoughts? Thanks for reading.

Spring Batch: Deadlock Inserting Job Instances

I have been working on my first Spring Batch project and so far I'm a big fan. I think I'm pretty far along and the only real issue I've had is random occurrences of deadlock when the app tries to create instances of the same job simultaneously in the job database (in table BATCH_JOB_INSTANCE):

  2011-11-13 12:48:18,808 ERROR [AbstractStep:212] Encountered an error executing the step
org.springframework.dao.DeadlockLoserDataAccessException: PreparedStatementCallback;
SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)];
Deadlock found when trying to get lock; try restarting transaction;
nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:
Deadlock found when trying to get lock; try restarting transaction
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:265)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)

I'm using MySQL as the database backing the batch app. The Job Repository, I'm using seemed pretty stock and I never had given it much thought:

     <bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource"
p:transactionManager-ref="transactionManager"
p:lobHandler-ref="lobHandler"/>

One of the properties on the repository that can be set is isolationLevelForCache. I found that setting this value to ISOLATION_READ_UNCOMMITTED helped my deadlock issue.

     <bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
p:dataSource-ref="dataSource"
p:transactionManager-ref="transactionManager"
p:isolationLevelForCache="ISOLATION_READ_UNCOMMITTED"
p:lobHandler-ref="lobHandler"/>

Whether or not this is the solution to use come production time is yet to be seen. For now, I surmise this works because the app is starting enough jobs at the same time, that the framework is ready to proceed with one before the insert to the database table is formally committed.

Wednesday, November 9, 2011

Maven Tomcat Plugin: Selecting an XML Parser

The Tomcat Maven Plugin is a great tool for quickly working through the cycle of making and verifying changes in a webapp. One such app I was working with included an XML parser from Oracle:

  oracle:oracle_xmlparserv2:jar:10.2.0.3:compile

The inclusion of the parser created a problem as it did not take kindly to a document parsed during startup, causing an error:

  $ mvn tomcat:run 
...
Caused by: oracle.xml.parser.schema.XSDException: Duplicated definition for: 'identifiedType'
at oracle.xml.parser.schema.XSDBuilder.buildSchema(XSDBuilder.java:731)
at oracle.xml.parser.schema.XSDBuilder.build(XSDBuilder.java:435)
at oracle.xml.parser.schema.XSDValidator.processSchemaLocation(XSDValidator.java:879)
at oracle.xml.parser.schema.XSDValidator.startElement(XSDValidator.java:496)
at oracle.xml.parser.v2.NonValidatingParser.parseElement(NonValidatingParser.java:1224)
at oracle.xml.parser.v2.NonValidatingParser.parseRootElement(NonValidatingParser.java:311)
at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:278)
... 52 more

A colleague of mine at work pointed at that you can select another parser through system properties, so I wanted to share his solution here:

  $ mvn tomcat:run \
-DXMLPARSER=XERCES \
-DXSLENGINE=XERCES \
-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl \
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl \
-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl

The above selects a JAXP parser from Apache, requiring Xerces and Xalan:

  xerces:xercesImpl:${xercesImpl.version}
xalan:xalan:${xalan.version}

To avoid having to script the above command or have to remember it, you can add the settings to the plugin definition:

    <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<port>${tomcatPort}</port>
<path>/${project.artifactId}-${project.version}</path>
<systemProperties>
<env>${env}</env>
<tomcatPort>${tomcatPort}</tomcatPort>
<XMLPARSER>XERCES</XMLPARSER>
<XSLENGINE>XERCES</XSLENGINE>
<javax.xml.parsers.DocumentBuilderFactory>org.apache.xerces.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<javax.xml.transform.TransformerFactory>org.apache.xalan.processor.TransformerFactoryImpl</javax.xml.transform.TransformerFactory>
<javax.xml.parsers.SAXParserFactory>org.apache.xerces.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>
</systemProperties>
</configuration>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xercesImpl.version}</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>${xalan.version}</version>
</dependency>
</dependencies>
</plugin>

Hope this helps anyone else who may run into a similar situation.

Friday, November 4, 2011

Prompted for GNOME Keyring Password During a Subversion Commit

Out of the blue when trying a Subversion commit, I was presented with a prompt for the password to the GNOME Keyring:

  $ svn ci -m"adding module"
Password for '(null)' GNOME keyring:
svn: Commit failed (details follow):
svn: MKACTIVITY of '/svn/projectr/!svn/act/c5d9f7fb-76ee-4900-9a0b-b55928d418f0': authorization failed:
Could not authenticate to server: rejected Basic challenge (http://svn.myorginazation.org)

In my case, the password for my login took care of the problem. While I do not understand the reasons for the prompt, the same may work for someone else, as by default the login password is what is being asked for.

If anyone understands why the prompt may have occurred (I haven't done much research yet), please leave a comment. Thanks!

Saturday, October 29, 2011

Using Guava's LineReader in a Spring Batch Job

Reading data from source like flat files and databases are common theme in batch projects. Spring Batch provides a lot of support for reading from these data sources out of the box. The FlatFileItemReader<T> provides a great example. This class extends the abstract AbstractItemCountingItemStreamItemReader<T>, which for one reason or another, I wanted to implement myself for reading a flat file. Extensions of this inteface must implement three methods:

  1. doClose()
  2. doOpen()
  3. doRead()

Since I was implementing the interface myself, I had to come up with a way to actually read the contents of the file myself. In the Google Guava project, I found a class to use, LineReader, that seemed like a good candidate to help alleviate the need for the usual tedious boilerplate code required for reading the contents of the file.

Before describing the use of the LineReader in a Spring Batch project, I wanted to demonstrate an example of using the LineReader outside of the context of a Spring Batch project. The Maven coordinates for the current version of Guava are:

  • groupId: com.google.guava
  • artifactId: guava
  • version: 10.0.1

Below is a sample class that follows the same pattern that must be implemenented when extending the AbstractItemCountingItemStreamItemReader class using a LineReader. The class takes the name of a resource to read from and handles making the resource available to the LineReader in the doOpen() method. Reading from the resource and closing of the resource are handled by the doRead() and doClose() methods respectively.

    package prystasj.sample.guava;

import com.google.common.io.LineReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class ResourceLineReader {

private InputStream inputStream;
private LineReader lineReader;

public String doRead() throws Exception {
return lineReader.readLine();
}

public void doOpen(String resourceName) throws Exception {
inputStream = getClass().getClassLoader().getResourceAsStream(resourceName);
Reader reader = new InputStreamReader(inputStream);
lineReader = new LineReader(reader);
}

public void doClose() throws Exception {
inputStream.close();
}

}

To test the above class, we'll use a file, tests.txt that contains three lines:

  line1
line2
line3

As the doRead() method, by way of LineReader.readLine(), will return null when the data from the input resource has been exhausted, we can use that fact to know when to call the doClose() method. At the end of our test we have a check to verify that three lines were read from the file:

package prystasj.sample.guava;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class ResourceLineReaderTest {

ResourceLineReader resourceLineReader;

@Before
public void setup() {
resourceLineReader = new ResourceLineReader();
}

@Test
public void reads_lines_from_a_classpath_resource() {
List<String> itemsRead = new ArrayList<String>();
String itemRead;

try {
resourceLineReader.doOpen("test.txt");
while((itemRead = resourceLineReader.doRead()) != null) {
itemsRead.add(itemRead);
}
resourceLineReader.doClose();
}
catch(Exception e) {
fail(e.getMessage());
}

assertEquals(3, itemsRead.size());
}

}

We can use the same implementation pattern when extending the the AbstractItemCountingItemStreamItemReader<T> abstract class as mentioned earlier in this post:

    package prystasj.sample.batch;

import com.google.common.io.LineReader;
import org.springframework.batch.item.file.ResourceAwareItemReaderItemStream;
import org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader;
import org.springframework.core.io.Resource;
import org.springframework.util.ClassUtils;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

class BatchFileReader extends AbstractItemCountingItemStreamItemReader<String> implements ResourceAwareItemReaderItemStream<String> {

private InputStream inputStream;
private LineReader lineReader;
private Resource fileResource;

/** Fulfills execution context requirement that {@code name} is set for the keys prefix. */
public BibNumbersFileReader() {
setName(ClassUtils.getShortName(BibNumbersFileReader.class));
}

@Override
protected String doRead() throws Exception {
return lineReader.readLine();
}

@Override
protected void doOpen() throws Exception {
inputStream = fileResource.getInputStream();
Reader reader = new InputStreamReader(inputStream);
lineReader = new LineReader(reader);
}

@Override
protected void doClose() throws Exception {
inputStream.close();
inputStream = null;
}

@Override
public void setResource(Resource resource) {
this.fileResource = resource;
}

}

The above reader can be configured with the below definition to be referenced from within a batch job:

    <bean id="bibNumbersFileReader" class="prystasj.sample.batch.BatchFileReader" scope="step"
p:resource="file:#{jobParameters['file']}"/>

In the above configuration, the scope of step ensures the bean is reconfigured every time the reader is used within a job. Spring Expression Language is used to inject the the name of the file resource into the reader from the job's parameters.

Friday, October 21, 2011

Groovy 1.8 Playing Nice with JAXB

Getting Groovy and JAXB to play nice together has been previously discussed many times. A good solution to the problem is presented here: Stack Overflow.

However, I started running into some problems when I upgraded to Groovy 1.8. Take the following class definition:

    import javax.xml.bind.annotation.*

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class JobResult {
@XmlElement String status
@XmlElement String exitDescription
}

During compliation, I received the following error:

    symbol: variable XmlAccessType
@javax.xml.bind.annotation.XmlRootElement() @javax.xml.bind.annotation.XmlAccessorType(value=XmlAccessType.NONE) public class JobResult
/home/prystasj/workspace/project/target/generated-sources/groovy-stubs/main/org/oclc/controlledheading/admin/JobResult.java:[10,106] an enum annotation value must be an enum constant

Confused, I first tried using a static import:

    import javax.xml.bind.annotation.*
import static javax.xml.bind.annotation.XmlAccessType.NONE

@XmlRootElement
@XmlAccessorType(NONE)
public class JobResult {
@XmlElement String status
@XmlElement String exitDescription
}

Giving me a different error:

    [ERROR] /home/prystasj/project/target/generated-sources/groovy-stubs/main/prystasj/JobResult.java:[10,93] cannot find symbol
symbol: variable NONE
@javax.xml.bind.annotation.XmlRootElement() @javax.xml.bind.annotation.XmlAccessorType(value=NONE) public class JobResult

A solution I used was to fully qualify the path to field inside the XmlAccessorType annotation:

    import javax.xml.bind.annotation.*

@XmlRootElement
@XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.NONE)
public class JobResult {
@XmlElement String status
@XmlElement String exitDescription
}

Monday, September 26, 2011

Groovy: Reuse of Helper Test Methods in a Spec

There are a lot of message transformers in a lot of the projects I work that work primarily with XML. I want my tests to take a source XML document and verify the output transformation. The example input and output messages live on the classpath, say in directory src/test/resources, and their contents are accessed through the classloader.

Take this example spec written for the Spock framework for Groovy:

    class XmlTransformerSpec extends Specification {

XmlTransformer transformer = new XmlTransformer()

def "transforms xml messages for some business goal"() {
given:
def inputXml = textOf("input.xml")
def expectedOutputXml = textOf("expected-output.xml")
when:
def actualOutputXml = transformer.transform(inputXml)
then:
areIdentical(expectedOutputXml, actualOutputXml)
}

def areIdentical(String expected, String actual) {
XMLUnit.setIgnoreWhitespace true
new Diff(expected, actual).identical()
}

def textOf(resource) {
getClass().getClassLoader().getResourceAsStream(resource).text
}

}

The retrieval of the messages in the form of resources is contained within the textOf() method where it can be resued by additional tests within the spec. What if I wanted to reuse it other test classes? One option I found was to move the method to an abstract class that extends spock.lang.Specification:

    abstract class ResourceAwareSpecification extends Specification {

def textOf(resource) {
getClass().getClassLoader().getResourceAsStream(resource).text
}
}

Now my test spec, along with any others that need to retrieve the contents of classpath resources, can extend the new specification:

    class XmlTransformerSpec extends ResourceAwareSpecification {
// method textOf() has been removed...
}

I wonder if others find themselves loading resources in this way and may make use of an approach like this if it were builtin to a framework like Spock in this or some other form, like a mixin. The helper method comparing the XML using XMLUnit would be another candidate in my mind for such an addition. Thoughts?

Tuesday, September 20, 2011

Openbox: Defining a Keyboard Shortcut

The Openbox Window Manager has quickly become my favorite way to use my computer. It use it almost exclusively on all the machines that I use (Ubuntu at work, Mint at home).

Here I'll describe how to add a keyboard shortcut so that we do not have to reach for the mouse to do something common. As I spend most of my time in the terminal, one shortcut I make the most use of is Alt+T to open a terminal program, mrxvt.

The keyboard shortcuts, along with many other things, are defined in ~/.config/openbox/rc.xml. The keyboard element is a child element of the root openbox element. Below is a snippet of an example showing the default shortcut for switching to the desktop to the left. The shortcut C-A-Left describes pressing the Ctrl, Alt, and left arrow keys with the default mappings:

<?xml version="1.0" encoding="UTF-8"?>
<openbox_config xmlns="http://openbox.org/3.4/rc">
<!-- some config omitted... -->
<keyboard>
<chainQuitKey>C-g</chainQuitKey>
<!-- Keybindings for desktop switching -->
<keybind key="C-A-Left">
<action name="DesktopLeft">
<dialog>no</dialog>
<wrap>no</wrap>
</action>
</keybind>
<!-- some keyboard config omitted... -->
</keyboard>
<!-- some config omitted... -->
</openbox>

To add our terminal shortcut, we add a keybind entry with the Execute action, followed by the command to execute. The key of A-t corresponding to pressing the Alt key along with the t key:

<?xml version="1.0" encoding="UTF-8"?>
<openbox_config xmlns="http://openbox.org/3.4/rc">
<!-- some config omitted... -->
<keyboard>
<chainQuitKey>C-g</chainQuitKey>
<!-- my keybindings -->
<keybind key="A-t">
<action name="Execute">
<execute>mrxvt</execute>
</action>
</keybind>
<!-- some keyboard config omitted... -->
</keyboard>
<!-- some config omitted... -->
</openbox>

We can reload the new configuration from the command line with:

  $ openbox --reconfigure

Or by right-clicking on the desktop and selecting Reconfigure from the Openbox menu.




Note: In order to take the screenshot with the menu shown, I ran gnome-screenshot with a delay of 5 seconds:

  $ gnome-screenshot -d 5

During the delay, you can right click on the desktop to get the menu in the picture.


Installing Clojure 1.2 on Ubuntu

If you're looking to install the latest stable version of Clojure on Ubuntu or a derivative, below are a few options. Currently, I'm running Ubuntu 10.10, whose package list contains Clojure 1.1.0. We can install this version using apt-get:

  $ sudo apt-get install clojure
...
$ clojure
Clojure 1.1.0
user=> (System/exit 0)

The most recent stable release is 1.2.1 (see Clojure Releases). It looks like while there was a request to have the available package updated to 1.2 (Ubuntu Bug #731979), but it looks like it won't be included by default until the 11.10 release of Ubuntu.

If we want to use the most recent stable release, the bug report has a link to the package set to be included in 11.10, clojure1.2, which we can install with dpkg:

  $ sudo dpkg -i clojure1.2_1.2.1+dfsg-3_all.deb

This links the clojure.jar as:

  $ ls -l /usr/share/java/clojure.jar
lrwxrwxrwx 1 root root 29 2011-09-20 10:39 /usr/share/java/clojure.jar -> /etc/alternatives/clojure.jar

Alternatively, we can download the source from the releases page and build it with ant ourselves: Clojure 1.2.1 Source.

  $ unzip clojure-1.2.1.zip
$ cd clojure-1.2.1
$ ant
...
BUILD SUCCESSFUL
Total time: 1 minute 57 seconds

If the build succeeds, we can just copy the built jar to the install location:

  $ sudo cp clojure.jar /usr/share/java/clojure.jar
$ clojure
Clojure 1.2.1
user=> (System/exit 0)

This approach should also work if we want to run the most recent development versions as well.

Thursday, September 15, 2011

Fantom: Constructors, Required Fields, and More

This post is part of a series of sorts where I write about what I find while exploring the Fantom language. This time I'm going to share what I find out about declaring and using classes as I go. I imagine I will only scratch the surface.

To give you the chance to devote some of your valuable reading time elsewhere, below is a summary of some of the highlights covered below:

  • Declaring class fields that are required at object creation and throughout the lifetime of the object
  • Default class field values
  • Automatic getters and setters

A class can be declared using the class keyword as we're all probably used to. Let's declare a (boring) class Person with a name field and add a main method so we can try and create an instance.

Assignments in Fantom are done via the use of := instead of an equals sign. Here we'll start by simply creating an empty object and printing out to the console that we've succeeded:

    class Person {
Str name

static Void main(Str[] args) {
Person p := Person()
echo("Person created.")
}
}

The variable p is given what looks to be the result of a call to a default constructor. We can run the above with:

   $ fan Person.fan

Our first run gives us the following error:

   Non-nullable field 'name' must be assigned in constructor 'make'

The error hints that the call to Person() results in a call to a constructor named make. Also, the error descrption seems to go against what we may be used to in Java, where class properties can be null. Right of the bat to me, this could demonstrate a potential strength of Fantom as, as given the class definition above, a user cannot create an incomplete Person. If we want to create a Person without assigning a value to the name field, we can append a '?' to the field declaration:

    class Person {
Str? name

static Void main(Str[] args) {
Person p := Person()
echo("Person created.")
}
}

This time we'll get the "success" message indicating we've created a Person. Let's keep the name field required and assign a value to it when the Person is constructed. To do this, we can add a constructor and in the main method create a Person named 'Cosmo':

    class Person {

Str name

new make(Str name) {
this.name = name
}

static Void main(Str[] args) {
Person p := Person("Cosmo")
echo("Person created with name: " + p.name)
}
}

As you can see, the main method now also reports the name of the created Person via a call to the name method. Although it looks like we are accessing the field directly, getters and setters are automatically created for each field which helps us cut down on the amount of boilerplate code our class might contain, not unlike some of the newer JVM langauges. Running things through the interpreter again gives us:

    Person created with name: Cosmo

To demonstrate the generated setter, we can add the following:

    p.name = "George"
echo("Person renamed to: " + p.name)

The output of our program is now:

   Person created with name: Cosmo
Person renamed to: George

One question I now have is now that we have declared the name field as non-null at construction time, can we assign the value to null after the object has been created? Let's add the lines below to the main method:

    p.name = null
echo("Person with null name?: " + p.name)

With the above in place, we now get an error:

   'null' is not assignable to 'sys::Str'

Again, this restriction should in practice help keep our class instances safe and remove the usual null-checking concerns.

Now some might say a class with one field might be pretty boring (if not useless). Lets add another field, age, but not require a user of the class to do a Person's age at construction time by allowing a default value (since age can be a touchy subject anyway). Let's try adding another constructor to be used when both the name and the age of the Person are known:

    class Person {

Str name
Int age := 1

new make(Str name) {
this.name = name
}

new make(Str name, Int age) {
this.name = name
this.age = age
}

static Void main(Str[] args) {
Person cosmo := Person("Cosmo", 40)
Person marshall := Person("Marshall")
echo("Person " + cosmo.name + ", aged " + cosmo.age)
echo("Person " + marshall.name + ", aged " + marshall.age)
}
}

Here will create two Persons with an declared age and one with the default of 1, and report on both:

    Duplicate slot name 'make'

Ah, we get an error... are we not allowed to have two constructors? Turns out in Fantom, constructors are treated like methods, with the new keyword out in front, and can be either be named make or start with make. Since we will likely prefer for our users to fully populate the class fields, let's name the two parameter constructor make and rename the original:

    new makeNamed(Str name) {
this.name = name
}

new make(Str name, Int age) {
this.name = name
this.age = age
}

Here though, how do we differentiate between which constructor is used for each assignment? The Persons we create are made through a call to Person(...)? Turns out we can call the constructors by name by referring to them through the class definition:

    Person cosmo := Person.make("Cosmo", 40)
Person marshall := Person.makeNamed("Marshall")

We cannot it appears make calls to Person(...) like we did before and have the compiler infer with constructor to use asin:

    Person cosmo := Person("Cosmo", 40)
Person marshall := Person("Marshall")

This results in the error:

   Invalid args (sys::Str, sys::Int), not (sys::Str)

Back to the explicit calls, our class now reads:

    class Person {

Str name
Int age := 1

new makeNamed(Str name) {
this.name = name
}

new make(Str name, Int age) {
this.name = name
this.age = age
}

static Void main(Str[] args) {
Person cosmo := Person.make("Cosmo", 40)
Person marshall := Person.makeNamed("Marshall")
echo("Person " + cosmo.name + ", aged " + cosmo.age)
echo("Person " + marshall.name + ", aged " + marshall.age)
}
}

Giving this attempt a shot gives us...

   Person Cosmo, aged 40
Person Marshall, aged 1

...output for both Persons, with the second making use of the default age.

This looks like enough to cover for now in one post. Looking at the documentation further, there's looks like there's a lot more to cover at a later date. If I find I misstated any of the terminology or made things more difficult then they need to be, I'll be sure to come back and make corrections.

Tuesday, September 13, 2011

Creating a Marco in Vim

I'm a fan of the vim text editor, and try to use it as much as possible. I have hard time though making the effort to learn more than I already know. While I think I can use it pretty effectively, I know I've truly only scratched the surface.

Often I find myself retyping the same commands over and over to repeatedly accomplish the same task. I then make a mental note to learn about creating macros, which would of helped me out. I then proceed to forget about immediately.

Not today though. Today I'm going to create my first macro.

A macro is a series of commands that can be replaced. Marcos can be assigned to buffers so they can be saved and recalled. Buffers have single- character names in the ranges:

  • 0-9
  • a-z
  • A-Z

To start the definition of a macro in command mode, type 'q' followed by a single character in one of the ranges above.

I'm going to start with the text below and think of some reason to create a macro:

hello my name is george
hello my name is george
hello my name is george

How about we try and replace every occurence with "name" with "first name". We could do a global substitution by typing a colon followed by 's/name/first name/g' and hitting enter, but I want to try out a macro.

A marco could simply:

  1. Search for the next occurrence of name.
  2. Replace "name" with "first name" (or insert the text "first ")

Let's try it out. With my cursor on the first character in the file, if I:

  1. Type 'q' to declare I want to define a macro
  2. Type 'a' to assign the macro to buffer 'a'
  3. Type '/' followed by "name" then Enter to find the first occurence of "name"
  4. Type 'cw' followed by "first name" then Esc to change the word
  5. Type 'q' to complete the macro definition

The text should now have one occurrence of "first name" in place of "name":

hello my first name is george
hello my name is george
hello my name is george

Now we can run the macro typing '@a'. Running it twice will complete the remaning two substitutions, giving us:

hello my first name is george
hello my first name is george
hello my first name is george

We could also run the marco a number of times with one command. Say, given the text above where the first substitution was done, if we wanted to run the marco twice in one shot, instead of invoking it two separate times, we can type '2@a'.