Saturday, March 10, 2012

Groovy: Regular Expressions and Multiple Lines

Regular expressions are sometimes used on text that spans multiple lines, which Groovy has support for. I had to search for how to enable multi-line searching, so I thought it would be good to post here.

To allow the expression to span multiple lines we can add (?ms) to the beginning of the expression.

Take the following example, where want to grab the entire book element from a single-line XML document:

    def xml = "<library><book><title>Effective Java</title><author>Bloch</author></book></library>"
def matcher = xml =~ /<book>.*<\/book>/
matcher.size() > 0 ? matcher[0] : "NOTHING"

This gives us an entire book:

    <book><title>Effective Java<title><author>Bloch<author><book>

If the XML was to span multiple lines however, we end up with NOTHING:

    def xml = """<library>
<book>
<title>Effective Java</title>
<author>Bloch</author>
</book>
</library>"""
def matcher = xml =~ /<book>.*<\/book>/
matcher.size() > 0 ? matcher[0] : "NOTHING"

Now if we add the (?ms), we will still get an entire book entry:

    def xml = """<library>
<book>
<title>Effective Java</title>
<author>Bloch</author>
</book>
</library>"""
def matcher = xml =~ /(?ms)<book>.*<\/book>/
matcher.size() > 0 ? matcher[0] : "NOTHING"

The above results in:

  <book>
<title>Effective Java<title>
<author>Bloch<author>
<book>

If you have any other tips or another way to accomplish the same thing, please feel free to leave a comment.

Injecting a Hostname with Spring

Sometimes our applications are required to know the name of the host or server they are running on. Usually, the hostname can be attained using plain old Java, however, in this post, I'll demonstrate a way to inject the name of the host an application is running on using Spring. This may sound like a case of over-engineering, but the main advantage of doing so is we can save our code from knowing how to obtain the hostname and avoid having to catch any exceptions related to retrieving the hostname.

As a use case, I'll recall a project I was working on that was tasked with consuming a service that required a client identifier be passed along in the request. The requirement stated that the ID be unique for every request and contain the hostname of the caller for tracking purposes inside the service. The form of the ID would be:

    <hostname>:<request_number>

Yes, this requirement could be considered a case of internal requirement of the service being called leaking into the implementation of the caller, but this a requirement we could not work around. To start, it made sense to task the creation of the identifier to a separate object. To fulfull the requirement that the ID be unique, we could use a UUID. The ugly part is deriving the hostname. Here is a first pass at the new class:

    public class RequestIdentifier {

public String requestId() {
return new StringBuilder()
.append(hostname())
.append(':')
.append(uuid())
.toString();
}

private String hostname() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException uhe) {
return defaultHostName;
}
}

private String uuid() {
return UUID.randomUUID().toString();
}

private static final String defaultHostName = "myHost";
}

Here we're forced to catch an UnknownHostException. As we still want the request to be made in the unlikely event that the exception is thrown, we default to a hostname (which would probably indicate the calling application) so that processing can proceed. We could improve on this implementation by caching the result of the first hostname lookup, but the potential for the exception to be thrown at least once would still exist.

Having to catch and deal with the exception places a burden on the class and adds complexity. Additionally, to fully cover the class during unit testing, we will have to find a way to simulate the exception, which could be difficult since the call InetAddress.getLocalHost() is static.

It might be better if the class was given its hostname, simplifying the code greatly, and removing the need for the default:

    public class RequestIdentifier {

private String hostname; // setter omitted for brevity

public String requestId() {
return new StringBuilder()
.append(hostname)
.append(':')
.append(uuid())
.toString();
}

private String uuid() {
return UUID.randomUUID().toString();
}
}

To make this situation usable, we can inject the hostname into the class:

    <beans xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="requestIdentifier" class="org.prystasj.service.validation.RequestIdentifier">
<property name="hostname" ref="hostname"/>
</bean>

<bean id="hostname" factory-bean="localhost" factory-method="getHostName"/>

<bean id="localhost" class="java.net.InetAddress" factory-method="getLocalHost"/>
</beans>

Now if there is an issue retrieving the hostname, we will know when the application starts up, before any processing is requested, and we have a cleaner, more usable class for creating the request identifier.

Monday, March 5, 2012

Subversion: Setting the MIME Type Property

As I'm tired of having to look this up every now and then when I need it, here's an example for how to add the MIME type for a file in Subversion:

 $ svn propset svn:mime-type "text/html" src/site/resources/design.html

The above command will cause the HTML file to be loaded as HTML in a browser when it is linked to in Subversion in the event your browser would like to display it as plain text.

Saturday, February 18, 2012

Linux: Burning an ISO Image from the Command Line

Here's a little tip (and reminder for myself) if you ever need to burn an ISO image to CD from the command line:

  $ cdrecord -v -eject speed=<speed> dev=<cdrom device> </path/to/iso>

Here's an example I used to burn the latest copy of Linux Mint Debian:

 $ cdrecord -v -eject speed=48 dev=/dev/cdrom \
/home/prystasj/Downloads/linuxmint-12-gnome-cd-nocodecs-64bit.iso

No GUI needed!

Addressing Database Connection Timeouts with c3p0

Many of our web applications run in Apache Tomcat and communicate with a MySQL database to persist data. After leaving one such development instance of an application up overnight, I was greeted with an error message when after trying to access it the next day. Looking at the Tomcat log, I found the following exception message:

   Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 
The last packet successfully received from the server was 241,479,103 milliseconds ago.
The last packet sent successfully to the server was 241,479,103 milliseconds ago. is longer than the server configured value of 'wait_timeout'.
You should consider either expiring and/or testing connection validity before use in your
application, increasing the server configured values for client timeouts, or using the
Connector/J connection property 'autoReconnect=true' to avoid this problem.

The application was using commons-dbcp from the Apache Commons project. Below was the Spring configuration of the data source that connected to the database.

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
</bean>

Apparently, the connection to the database had timed out and needed to reconnect. After some searching, several posts mentioned that adding autoReconnect=true to the end of the database URL would fix the problem, but an exception would still be thrown before a reconnect is attempted.

A more popular answer seemed to be replacing the use of commons-dbcp with c3p0. I swapped out the dependency on commons-dbcp with:

    <dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
<scope>runtime</scope>
</dependency>

Followed by a new definition of the data source:

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${batch.jdbc.driver}" />
<property name="jdbcUrl" value="${batch.jdbc.url}" />
<property name="user" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
<property name="maxPoolSize" value="${mysql.db.maxPoolSize}"/>
<property name="maxIdleTime" value="${mysql.db.maxIdleTime}"/>
<property name="maxConnectionAge" value="${mysql.db.maxConnectionAge}"/>
<property name="acquireRetryAttempts" value="${mysql.db.acquireRetryAttempts}"/>
<property name="maxIdleTimeExcessConnections" value="${mysql.db.max.idle.time.excess.connections}"/>
<property name="idleConnectionTestPeriod" value="${mysql.db.idle.connection.test.period}"/>
<property name="preferredTestQuery" value="${mysql.db.preferred.test.query}"/>
<property name="testConnectionOnCheckout" value="${mysql.db.test.connection.on.checkout}"/>
<property name="testConnectionOnCheckin" value="${mysql.db.test.connection.on.checkin}"/>
<property name="checkoutTimeout" value="${mysql.db.checkout.timeout}"/>
</bean>

As you can see, there are lot more properties that can be set on the ComboPooledDataSource. The following additional properties settings appear to do the trick, although I must admit not spending much time yet fine tuning them:

    mysql.db.maxPoolSize = 10
mysql.db.maxConnectionAge = 0
mysql.db.acquireRetryAttempts = 5
mysql.db.max.idle.time.excess.connections = 300
mysql.db.idle.connection.test.period = 540
mysql.db.preferred.test.query = SELECT 1
mysql.db.test.connection.on.checkout = false
mysql.db.test.connection.on.checkin = false
mysql.db.checkout.timeout = 60000
mysql.db.maxIdleTime = 500

For now, the connection issue has been resolved in the application. Hope this helps someone out in a similar situation. Thanks for reading.

Saturday, January 14, 2012

Xerces Parsing and the Dreaded FWK005 Exception

One of the Java/Groovy applications I'm currently works with multiple threads. In each thread, an XML service response is marshalled into an object using a method similar to:

    private def messageObjectFrom(String responseXml) {
def jaxbElement = (JAXBElement) unmarshaller().unmarshal(readerFor(responseXml))
(MessageType) jaxbElement.value
}

Under a reasonable amount of load (several threads), the application would report the following exception during an execution of the method:

    javax.xml.bind.UnmarshalException: null
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315) ~[na:1.6.0_24]
...
Caused by: org.xml.sax.SAXException: FWK005 parse may not be called while parsing.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) ~[com.springsource.org.apache.xerces-2.8.1.jar:na]
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) ~[com.springsource.org.apache.xerces-2.8.1.jar:na]
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:211) ~[jaxb-impl-2.1.13.jar:2.1.13]
... 43 common frames omitted

I've seen the error in the past when parsing XML in a multi-threaded application using Xerces. Several mailing lists have had questions about this error over the years which point to a concurrency issue in the Xerces parser. In my application, the parser is used inside multiple threads.

Most of the postings suggest synchronizing access to the parser. I attempted to do so by adding the synchronized keyword to the method signature:

    synchronized private def messageObjectFrom(String responseXml) {
def jaxbElement = (JAXBElement) unmarshaller().unmarshal(readerFor(responseXml))
(MessageType) jaxbElement.value
}

This indeed did resolve the issue as I haven't run into a FWK005 error since. Its unfortunate the parser itself is not thread-safe, but this solution will do for me for now.

Hope this may help someone else who runs into a similar situation. Thanks!

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.