Tag Archives: java

A Quick Spring Security Lock-Down

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

My new shiny web application is fantastically useful, but only to a certain group of people (i.e. my team), and should only be accessible by them.

So, before being able to put it into real production, I needed a security framework around it.

A legacy JAAS component of ours exists, but given my application was making use of the Spring framework, I compared Spring’s offering to the JAAS infrastructure.

Popular opinion seems to be that JAAS was build for J2SE, not J2EE, and is designed for things at a much ‘lower level’ than web applications, such as client-side applets rather than server-side applications.

Maven

First things first: Maven dependencies.

I’m using spring-webmvc 2.5.6, so I’d like to get security working with the application as it stands now – the latest pre-3.0 release of spring-security is 2.0.6-RELEASE:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>2.5.6</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-core</artifactId>
  <version>2.0.6.RELEASE</version>
</dependency>

web.xml

The web context requires two things:

1. Context location

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
  </param-value>
</context-param>

(we’ll create the security context in the next step)

2. Filter definition

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The url-pattern will mean all requests pass through the filter (which will have more explicit criteria).

Security Context

Now we get to the real meat of the security layer!

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.springframework.org/schema/security
                         http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">

    <http auto-config="true">
        <intercept-url pattern="/**" access="ROLE_USER" />
        <http-basic />
    </http>

    <authentication-provider>
        <password-encoder hash="md5"/>
        <user-service>
            <user name="user" password="aabbccddeeff001122334455667788ff" authorities="ROLE_USER" />
	    </user-service>
	</authentication-provider>
</beans:beans>

Here we can see the configuration for http requests. The ‘auto-config’ sets the defaults (refer to the doco in the references), which are overridden by the contents of the tag. We’ll let in one user for now with the role ‘ROLE_USER’, defined in the authentication-provider section.

Including http-basic just puts the preference on using the basic HTTP prompt, but removing that line would use Spring’s default login page (with user/pass and ‘remember me’ checkbox).

And its done! Deploying the application and loading the page demands a login before progressing.

Next

Future improvements might involve setting up a styled login page, hooking up an LDAP connection (but with restrictions).
Oh, and Selenium tests..

References

Spring Source, Spring Security Reference Documentation <http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ns-config.html>
Peter Mularien, 5 Minute Guide to Spring Security <http://www.mularien.com/blog/2008/07/07/5-minute-guide-to-spring-security/>

Continuous Deployment: Deploying to Glassfish with Maven and TeamCity

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

A later stage of the continuous integration process – continuous deployment. The sooner we can deploy a tested and verified piece of software, the better!

Here I’m describing an automated deployment process that uses Maven to deploy to a Glassfish application server. TeamCity facilitates the build and test stages, with an additional deployment of the packaged web application. Using the glassfish plugin for maven 2, we can integrate the application server deployment into the continuous integration cycle, and provide a constantly up-to-date development/test environment.

Glassfish

I’ll create a new domain from scratch for the maven apps, using the default port values (i.e. admin port 4848, http port 8080), but setting the admin password and master password.

In setting up the glassfish domain we generate a password file so that we are not storing any passwords in plain text – such as in the pom or settings.xml

cd ${glassfish.home}/bin
./asadmin create-domain --savemasterpassword=true my-apps

the –savemasterpassword switch generates an encrypted ‘master-password’ file in the domains/my-apps directory.

Maven

Maven profiles makes it easy to have machine-specific variables so that moving to other platforms in the future is straightforward.

On the on the host machine I’ve created the file ~/.m2/settings.xml.

<?xml version="1.0" encoding="UTF-8"?>
xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <profiles>
    <profile>
      <id>glassfish-context</id>
      <properties>
        <local.glassfish.home>/Users/brass/bin/glassfishv3</local.glassfish.home>
        <local.glassfish.user>admin</local.glassfish.user>
        <local.glassfish.domain>my-apps</local.glassfish.domain>
        <local.glassfish.passfile>
${local.glassfish.home}/glassfish/domains/${local.glassfish.domain}/master-password
        </local.glassfish.passfile>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>glassfish-context</activeProfile>
  </activeProfiles>
</settings>

This gives us the parameters for the glassfish instance that we will use in our pom.

Update: I found that while the above works for v3.1, my dev machine’s glassfish v3.0.1 needed to reference glassfish home one directory deeper:

<local.glassfish.home>/Users/brass/bin/glassfishv3/glassfish
</local.glassfish.home>
...
<local.glassfish.passfile>
${local.glassfish.home}/domains/${local.glassfish.domain}/master-password
</local.glassfish.passfile>


In the project pom.xml, we define a profile for glassfish deployment:

<profile>
  <id>glassfish-deploy</id>
  <pluginRepositories>
    <pluginRepository>
      <id>maven.java.net</id>
        <name>Java.net Maven2 Repository</name>
        <url>http://download.java.net/maven/2</url>
      </pluginRepository>
    </pluginRepositories>
    <build>
      <plugins>
      <plugin>
        <groupId>org.glassfish.maven.plugin</groupId>
        <artifactId>maven-glassfish-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
          <user>${local.glassfish.user}</user>
          <passwordFile>${local.glassfish.passfile}</passwordFile>
          <autoCreate>true</autoCreate>
          <debug>true</debug>
          <echo>false</echo>
          <terse>true</terse>
          <domain>
            <name>${local.glassfish.domain}</name>
            <adminPort>4848</adminPort>
            <httpPort>8080</httpPort>
            <httpsPort>8443</httpsPort>
            <iiopPort>3700</iiopPort>
            <jmsPort>7676</jmsPort>
            <reuse>false</reuse>
          </domain>
          <components>
            <component>
              <name>${project.artifactId}</name>
              <artifact>
${project.build.directory}/${project.build.finalName}.war
              </artifact>
            </component>
          </components>
        </configuration>
      </plugin>
    </plugins>
  </build>
</profile>

The repository for the glassfish plugin repository is specified within the profile since its not part of the larger project in this case.

As you see the variables from the local settings.xml are used for the glassfish config.

TeamCity

The TeamCity setup needs to include two things in the maven2 runner config:

  • Glassfish goals
  • Profile parameters

TeamCity - maven runner configuration

The glassfish goals that are used should be able to start the domain if it isn’t running, and replace the application.

The ‘redeploy’ goal would allow a hot-swap deployment, if for example we were running other applications on the domain.

See the plugin page (http://maven-glassfish-plugin.java.net/) for more info.

Next

So now this process provides us with continuous deployment – a commit will be built, tested and deployed automatically, allowing changes to the software to be seen and used almost immediately!

How to programmatically ‘ping’ a port using Telnet

As part of a larger application, I needed to determine if particular services were running on remote servers – i.e. if a particular port on the server was accessible.

I wrote this utility class to perform this function, using the telent client supplied by Apache Commons-net.

import org.apache.commons.net.telnet.TelnetClient;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.ConnectException;
import java.net.UnknownHostException;

/**
 * Execute a telnet connection to determine if the server and port are accessible.
 *
 * @author will
 */
public final class TelnetExecutor implements Executor {
    private static final Logger LOG = Logger.getLogger(TelnetExecutor.class);
    private static final int PORT_MIN = 0;
    private static final int PORT_MAX = 65535;

    private final String _server;
    private final int _port;

    public TelnetExecutor(final String server, final int port) {
        if (server == null || server.trim().length() == 0) {
            LOG.warn("Server name has a length of zero. Status result will fail.");
            _server = null;
        } else {
            _server = server;
        }

        if (port < PORT_MIN || port > PORT_MAX) {
            LOG.warn("Server port is out of bounds. Status result will fail.");
            _port = -1;
        } else {
            _port = port;
        }
    }

    /**
     * Determine the result of the port request.
     * <p/>
     * A return value of <code>Success</code> indicates successful connection, <code>Error</code> indicates a 
     * configuration problem, <code>Fail</code> indicates a failed connection, and <code>Unknown</code> indicates an 
     * unexpected problem.
     *
     * @return A {@link Status} representing the result.
     */
    @Override
    public Status getResult() {
        if (_server == null || _port < 0) {
            return Status.ERROR;
        }

        Status status;
        final TelnetClient telnetClient = new TelnetClient();
        try {
            telnetClient.connect(_server, _port);
            telnetClient.disconnect();
            status = Status.SUCCESS;
        } catch (ConnectException ce) {
            LOG.info("Could not connect to server '" + _server + "' _port " + _port);
            status = Status.FAIL;
        } catch (UnknownHostException e) {
            LOG.error("Unknown host: " + _server);
            status = Status.ERROR;
        } catch (IOException e) {
            LOG.error("Error connecting to server: " + _server + " - " + e.getMessage(), e);
            status = Status.UNKNOWN;
        }

        return status;
    }
}

The Status objects are an enumeration.

I can test this using variations on this [integration] JUnit testcase:

@Test
public void shouldConnectToExamplePort80() {
    Assert.assertSame(Status.SUCCESS, new TelnetExecutor("example.com", 80).getResult());
}

Whoops! IntelliJ broke my JAAS config…

One of IntelliJ’s features is maintenance of copyright headers in source and text files. The update of the header can be selected to run upon commit (so that your commited code always has the latest copyright!).

/*
* SomeClass.java - 11 Nov 2010
* Copyright (c) 2010 - My Organisation
*/

Kind of cool and useful depending on your coding standards.

I’m updating a module of ours that uses Java Authentication and Authorization service (JAAS) to hook into LDAP.

The JAAS configuration file, unlike most properties and config files, uses Java-style block comments (such as the example above), and not hash comments. IntelliJ has recognized my jaas.config as a properties file, and upon committing to source control, inserts the copyright as a hash-comment block:

#
# jaas.test.config - 11 Nov 2010
# Copyright (c) 2010 - My Organisation
#

The result – My tests fail because JAAS config loader throws an exception!

Solutions?

I hoped that I could somehow indicate that a JAAS config file should be matched to the same style used in Java files.

I can set up a file type for the file easily enough:

But I can’t find a way to apply a copyright template to the file type…damn! The copyright templates seem static.

We could, in theory, apply one of those static file types to out JAAS config file; Add “jaas*.config” to Java or Javascript file types – but you’d have to be willing to put up with the errors and warnings!

For now, using the custom file type will do – IntelliJ doesn’t modify the copyright since it doesn’t know what the file is anymore. At least it won’t update to the wrong format by accident this way..!

Unit Testing XML – Evaluating Diffs

I am trying to test code that merges two XML files. In the unit test that I am attempting to implement, I want to compare the difference between the merge result and one of the XML files (the larger of the two).

This is a description of the file contents:

  • The right-hand XML file has 13 elements underneath the root, while the left-hand file has 4.
  • Two elements in both files are equivalent, so the left-hand version is discarded.

What I’m expecting is that the two remaining elements in the left hand file are merged into the resultant XML, so that in reference to the right-hand file, the merged content has two additional elements underneath the root.

XMLUnit

I’ve used XMLUnit previously to compare generated XML with expected output. In this case however, I am more concerned with evaluating the differences between the source and resultant XML.

XMLUnit has a Diff object – org.custommonkey.xmlunit.Diff – which I realised, after some investigation, doesn’t quite offer a diff in the traditional UNIX diff/patch command sense. It evaluates a document in terms of being identical, similar or different, and holds a message describing the first difference encountered.

This has some use of course, my testcase could look something like this:

...
Diff myDiff = new Diff(originalXml, mergedXml);
assertFalse("Expected differences in XML", myDiff.identical());

The message contained in myDiff here is:

[different] Expected number of child nodes '13' but was '17' - comparing  at /Group[1] to  at /Group[1]

I’m not quite contented with that as a robust unit test. I want to ensure that the two files have specific differences. When I think of comparing two files with a diff, I’m picturing a visual diff:

..and the concept of a patch – that the set of +/- lines differences are collected and made available for inspection/verification.

XMLUnit does have some alternatives that, while not exactly what I’m looking for, I could use and are worth discussing:

DetailedDiff

DetailedDiff is an extension of Diff, which will give me a list of all the Differences in the comparison.

final DetailedDiff diff = new DetailedDiff(myDiff);
assertTrue("Expected a difference in child nodes", 
    diff.getAllDifferences()
        .contains(DifferenceConstants.CHILD_NODE_NOT_FOUND));

..will assert that the comparison has resulted in a mismatch in the number of children between the two XMLs (Javadoc). A few of those assertions could describe the expected differences between the XMLs.

Counting Nodes

CountingNodeTester is another alternative that allows us to assert the total number of elements contained in the XML:

CountingNodeTester countingNodeTester = 
    new CountingNodeTester(38);
assertNodeTestPasses(mergedXml, 
    countingNodeTester, Node.ELEMENT_NODE);

Or alternatively, comparing the counts of the two XMLs (7 additional nodes):

final int countOriginal = 31;
final int countMerged = countOriginal + 7;
CountingNodeTester countingNodeOriginal = 
    new CountingNodeTester(countOriginal);
CountingNodeTester countingNodeMerged = 
    new CountingNodeTester(countMerged);
assertNodeTestPasses(originalXml, 
    countingNodeOriginal, Node.ELEMENT_NODE);
assertNodeTestPasses(mergedXml, 
    countingNodeMerged, Node.ELEMENT_NODE);

XPath

Finally we could also use XPath evaluations to assert the existence or lack of certain structures:

assertXpathNotExists("/Group/PageContainer[6]", 
   mergedXml);
...
assertXpathExists("/Group/PageContainer/External-Group/File[@Location='/Sites/centre/dcita/site.xml']", 
    mergedXml);
assertXpathEvaluatesTo("/Sites/centre/dcita/site.xml", 
    "/Group/PageContainer/External-Group/File/@Location", mergedXml);

So while XMLUnit gives us a pretty good toolset for XML comparisons, I’m still wondering if there’s a more diff-oriented tool I could use.

java-diff-utils

I found java-diff-utils, which looks like it could be a good option for handling diffs the way I’m imagining. Lets have a go!

The sample code on the website shows us the basic usage:

// Compute diff. Get the Patch object. Patch is the container for computed deltas.
Patch patch = DiffUtils.diff(original, revised);

..where original and revised are List objects.

The Patch object gives us a list of Deltas, containing the ‘original’ and ‘revised’ segments. Perfect!

This matches what we have in the image (disregarding the empty elements formatted differently)

Assert.assertEquals(1, patch.getDeltas().size());

The Delta itself contains a list of text lines, so we could potentially verify the list of strings manually.

System.out.println(patch.getDelta(0).getRevised().getLines());

..outputs something like:

[<PageContainer>
, <External-Group>
, <File Location="/Sites/centre/dcita/site.xml">, </File>
, </External-Group>
, </PageContainer>
, <PageContainer>
, <Page Title="">
, <File Location="/Content/centre/dcita/index.xml">, </File>
, <Description>Migrated from previous CMS1 Homepage, </Description>
, </Page>
, </PageContainer>
    ]

A cleaner scenario could involve saving the expected delta text to a file (/src/test/resources/merged_xml.diff), and comparing the file contents to the lines in the actual patch delta

final String target = resourceToString("/merged_xml.diff");
final String actual = 
    listToString(patch.getDelta(0).getRevised().getLines());
Assert.assertEquals(target, actual);

This needs a couple of helper functions to load the diff file into a String, and convert the delta List into a String also.

    private String resourceToString(String filename) {
        StringBuffer lines = new StringBuffer();
        String line = "";
        try {
            BufferedReader in = new BufferedReader(
                new FileReader(getClass().getResource(filename).getPath()));
            while ((line = in.readLine()) != null) {
                lines.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines.toString();
    }

    private String listToString(List list) {
        StringBuffer buff = new StringBuffer(list.size());
        for (Object o : list) {
            buff.append(((String) o).trim());
        }
        return buff.toString();
    }

Finally…

So in the end, my test case ends with combining the above diff utils snippets:

        ...
        Patch patch = DiffUtils.diff(original, revised);
        Assert.assertEquals(1, patch.getDeltas().size());

        final String target = resourceToString("/merged_xml.diff");
        final String actual = 
            listToString(patch.getDelta(0).getRevised().getLines());
        Assert.assertEquals(target, actual);

Unit testing JAXB marshalling and XJC-generated classes

JAXB – the Java Architecture for Xml Binding provides a simple way of mapping XML to POJOs. It give the ability of painlessly marshalling and unmarshalling objects to and from XML.

JAXB’s usefulness is enhanced by the ‘xjc’ tool that is included in the SDK, which converts an XML schema to a set of Java classes.

A portion of the XML schema (which itself is generated from an XML file):

  <xs:complexType name="MetaType">
      <xs:attribute type="xs:string" name="Name" use="optional"/>
      <xs:attribute type="xs:string" name="Scheme" use="optional"/>
      <xs:attribute type="xs:string" name="Value" use="optional"/>
  </xs:complexType>

Because the XML schema I’m working with has been auto-generated from sample XMLs and not hand-written (and fairly complex!), I’d like to ensure that the XML coming out of the marshalling is what I expect.

The following JUnit 4 test creates and populates the object, then verifies that the object is marshalled to XML properly:

public class MetaTypeTest {
    private final String _xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";

    @Test
    public void shouldMarshalAllAttributes() throws Exception {
        final MetaType type = new MetaType();
        type.setName("MetaName");
        type.setScheme("MetaScheme");
        type.setValue("MetaValue");

        // Can't be certain @XmlRootElement annotation has been generated, so wrap obj in JAXBElement
        final JAXBElement element = new JAXBElement(new QName("Meta"), MetaType.class, type);

        // Marshal to output stream
        JAXBContext context = JAXBContext.newInstance(MetaType.class);
        final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        context.createMarshaller().marshal(element, outStream);

        final String xmlContent = "";
        Assert.assertEquals(_xmlHeader + xmlContent, outStream.toString());
    }
}

More..

Monitoring OSCache statistics with JMX

Given an existing web application that uses OSCache, we can pretty easily add support for JMX monitoring.

A couple of things first:

  • We are using Sun’s Glassfish application server
  • The application is not yet spring-enabled
  • The project uses maven for dependancy management

Since we are using Glassfish, we already have an MBean server and connector, so we don’t have to worry about configuring those parts of the stack. (An MBean is a Managed JavaBean)

As for Spring support, we are restricting its introduction to a small aspect of the application (for now!), so we are minimizing the impact on the rest of the application.

What we need to do:

  • Modify oscache.properties and add an event listener
  • Add a dependancy on spring-web
  • Add a spring context for the JMX exporter
  • Modify web.xml to load the spring context

OSCache event listener

Firstly, we need to set a listener for OSCache that will publish the statistics we are interested in.

In oscache.properties, there is a section for event listeners. We want to implement a statistical listener:

cache.event.listeners=com.opensymphony.oscache.extra.StatisticListenerImpl

Spring dependancies

If you’re using maven, add a dependency on spring-web. This has dependancies on spring-core, spring-context and spring-beans (At the time of writing, 3.0.2.RELEASE was the latest version in the maven repositories).

Otherwise download these manually and chuck them in your WEB-INF/lib.

Spring Context

I made a separate spring context file (cacheContext.xml) for the cache MBean exporter:

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

        <!-- OSCache stats listener bean -->
        <bean id="statisticListener" class="com.opensymphony.oscache.extra.StatisticListenerImpl"/>

        <!-- Export the OSCache stats beans -->
        <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
            <property name="beans">
                <map>
                    <entry key="oscache-bean:name=Statistics" value="statisticListener"/>
                </map>
            </property>
        </bean>
    </beans>

The map in the exporter links the statistics bean to a key that will be visible in JConsole.

Note: The OpenSymphony link in the references below gives you code to expose an arbitrary JMX connector and port. This is unnecessary since we’re accessing via the application server.

Adding the Spring context loader

The web.xml then needs to be updated to be told to load the new cacheContext.xml.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/cacheContext.xml</param-value>
    </context-param>

	...

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

JMX Clients

JDK 1.5 includes two JMX clients that you can use.

jconsole is the legacy monitoring application, which has been superseded by the fancy UI of jvisualvm.

Either application will allow you to monitor the statistics bean, however in jvisualvm you will need to install the plugin VisualVM-MBeans under Tools > Plugins. Meanwhile jconsole has an MBeans tab by default.

When your application is running, use one of these utilities to connect to the application server (either directly or via localhost:8686 for glassfish). Under the oscache-bean > Statistics, you should be able to see counts generated by cache attributes. Double-clicking the numbers will pop up a graph, and right-clicking will allow you to export the recorded values.

Graph of OSCache statistics

References

  1. http://www.opensymphony.com/oscache/wiki/JMX%20Monitoring.html
  2. http://java.sun.com/docs/books/tutorial/jmx/mbeans/standard.html
  3. http://java.sun.com/developer/technicalArticles/J2SE/jmx.html

Loading custom-named BDD scenario files for JBehave

Now that I’m using JBehave in a commercial project, I’ve rewritten the loading of the scenario files in such a way that I can call my tests something like com.example.login.InvalidLoginScenario and have the corresponding scenario file under {project}/src/test/resources/invalid_login.scenario.

Previously…

The standard JBehave scenario file is loaded with UnderscoredCamelCaseResolver, which converts the classname from camel-case to underscore-seperated classname. A resource path is constructed from the package plus the underscored filename to locate the file – e.g. {src.test}/com/example/login/invalid_login_scenario.

Previously (with inspiration), I modified the testcase to override the default Configuration object, which allowed the loading of the scenario file with an extension – so it would now look for {src.test}/com/example/login/invalid_login_scenario.scenario.

Goal

To make the creation and maintenance of the JBehave scenarios and testcases easier, I decided on some standards:

  • JBehave testcase classes should be suffixed with ..Scenario, to clearly communicate their purpose.
  • Scenario filenames should map to their corresponding test classes.
  • Scenario files should reside in the same location under resources/.
  • Scenario files should have the extension .scenario, to improve readability.

But instead of having a file named invalid_login_scenario.scenario, I want the test class InvalidLoginScenario to map to the file invalid_login.scenario. All this was basically possible with existing JBehave classes, when configured the correct way (and certain functions overridden).

The Source

import org.jbehave.scenario.PropertyBasedConfiguration;
import org.jbehave.scenario.RunnableScenario;
import org.jbehave.scenario.errors.PendingErrorStrategy;
import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
import org.jbehave.scenario.parser.PatternScenarioParser;
import org.jbehave.scenario.parser.ScenarioDefiner;
import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;

/**
 * Customisation of standard JBehave {@link PropertyBasedConfiguration} to allow clearer naming of scenario files:
 * <ul>
 * <li> Usage of *.scenario file extension</li>
 * <li> Strip 'Scenario' off test class names</li>
 * <li> Load scenario files from classpath root</li>
 * </ul>
 * So a test class named <code>InvalidUsernameScenario</code> would be attempting to resolve the resource path <code>/invalid_username.scenario</code>.
 *
 * This configuration also fails on 'pending' (unimplemented) steps.
 */
public final class ScenarioConfiguration extends PropertyBasedConfiguration {
    private final ClassLoader _classLoader;

    public ScenarioConfiguration(final ClassLoader classLoader) {
        _classLoader = classLoader;
    }

    @Override
    public ScenarioDefiner forDefiningScenarios() {
        final ResourceNameResolver filenameResolver = new ResourceNameResolver(".scenario");
        filenameResolver.removeFromClassname("Scenario");
        return new ClasspathScenarioDefiner(filenameResolver, new PatternScenarioParser(this.keywords()), _classLoader);
    }

    @Override
    public PendingErrorStrategy forPendingSteps() {
        return PendingErrorStrategy.FAILING;
    }

    /**
     * Override {@link UnderscoredCamelCaseResolver} to load resources from classpath root. This means we can collect
     * scenario files in a single resource directory instead of in packages.
     */
    class ResourceNameResolver extends UnderscoredCamelCaseResolver {
        public ResourceNameResolver(final String extension) {
            super(extension);
        }

        @java.lang.Override
        protected String resolveDirectoryName(final Class<? extends RunnableScenario> scenarioClass) {
            return "";
        }
    }
}

The function forDefiningScenarios() is the important part – it sets the resolver to use the .scenario extension, but also strips out ‘Scenario’ from the class name.

Also, to force the resolver to look at the classpath root, the resolveDirectoryName() function is overridden to return an empty string.

The testcases using this Configuration object would call:

public class InvalidLoginScenario extends Scenario {
    public InvalidLoginScenario() {
        super(new ScenarioConfiguration(InvalidLoginScenario.class.getClassLoader()), new LoginScenarioSteps());
    }
}

References

Building a JStack Parser

Background

Recently, I was briefed on a situation where a main public facing java web application was going down fairly regularly, for what appeared to be an out of memory error.

After an investigation by a previous developer turned up no concrete leads, they suggested using JStack to get a profile of what the threads in the application were holding locks that could be causing the crash.

Now I’ve never worked with JStack before, but the purpose seems fairly straightforward. Trouble is, with ~500 threads in the output, analysing each one to find a common cause would be a pretty intensive task.

I set about searching for some kind of output analyser for JStack, but with no luck, I decided to write my own to give me a summary of the results.

Requirements

At least for my application, there were a lot of similar-looking stacktraces, so it made sense to group and summarise the results.

The JStack output I was provided with looked something like this:

Attaching to process ID 18526, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.5.0_14-b03
Thread t@6872: (state = BLOCKED)
- java.lang.Thread.sleep(long) @bci=-1766132960 (Interpreted frame)
- java.lang.Thread.sleep(long) @bci=0 (Interpreted frame)
- sun.net.www.http.KeepAliveCache.run() @bci=3, line=149 (Interpreted frame)
- java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)
Thread t@6871: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- java.util.TimerThread.mainLoop() @bci=201, line=509 (Compiled frame)
- java.util.TimerThread.run() @bci=1, line=462 (Interpreted frame)

What I initially wanted from my parser was to:

  • See the total number of thread states
  • Summary information for each stacktrace.

So what I need to do is extract each thread and its corresponding stacktrace to be able to process and report on it.

The Code

Firstly the main checks for a file parameter, then passes to the application instance which will check for its existence before calling a parser.

public class ParseJStack {
    public ParseJStack(final String filename) {
        File jstackFile = new File(filename);
        if (!jstackFile.exists()) {
            System.out.println("File does not exist. Exiting.");
            return;
        }
        //new Parser(jstackFile).process();
    }

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("Program requires a filename");
            System.exit(1);
        } else {
            new ParseJStack(args[0]);
        }
    }
}

For now, the call to the parser is commented out, as I’m yet to create it or determine its return type.

Test-driven

Now that I’m thinking about main functionality of the application, I’ll write testcases (JUnit 4) around the container classes JStackMeta and JStackEntry which are the thread detail and stacktrace objects respectively, and will be populated by the parser engine

JStackEntry will be a fairly simple container for a List of stack calls, and a String for its header text. From the looks of it the thread headers all follow the same pattern, so I will expect to be able to extract the state (and the id if we need to later) with a simple regex pattern.

public class JStackEntryTest {
    @Test
    public void shouldGetContentsAsNotNullWhenNullParameter() throws Exception {
        final JStackEntry stackEntry = new JStackEntry("");
        Assert.assertNotNull(stackEntry.getContents());
    }

    @Test
    public void shouldGetContents() throws Exception {
        final JStackEntry stackEntry = new JStackEntry("");
        stackEntry.append("Test Content");

        Assert.assertEquals(12, stackEntry.getContents().length());
        Assert.assertEquals("Test Content", stackEntry.getContents().toString());
    }

    @Test
    public void shouldGetEntryState() throws Exception {
        final JStackEntry stackEntry = new JStackEntry("Thread t@6872: (state = BLOCKED)");
        stackEntry.append("Test Content");

        Assert.assertEquals("BLOCKED", stackEntry.getState());
    }

    @Test
    public void shouldGetUnknownStateWhenHeaderEmpty() throws Exception {
        final JStackEntry stackEntry = new JStackEntry("");
        stackEntry.append("Test Content");

        Assert.assertEquals("UNKNOWN", stackEntry.getState());
    }
}

JStackMeta will hold the collection of JStackEntry objects, and the non-entry related meta (e.g. process id, java version info that appears at the top of the file).

public class JStackMetaTest {
    @Test
    public void testConstructorInit() throws Exception {
        Assert.assertNotNull(new JStackMeta().getHeader());
        Assert.assertNotNull(new JStackMeta().getEntries());
    }

    @Test
    public void testAppend() throws Exception {
        final JStackMeta stackMeta = new JStackMeta();
        stackMeta.append("Test Meta");
        Assert.assertEquals(9, stackMeta.getHeader().length());
    }

    @Test
    public void testAddEntry() throws Exception {
        final JStackMeta stackMeta = new JStackMeta();
        final JStackEntry stackEntry = new JStackEntry("");
        stackEntry.append("Test Entry");
        stackMeta.addEntry(stackEntry);
        Assert.assertEquals(1, stackMeta.getEntries().size());
    }
}

With those two classes set, we move back to the JStackParser which populates them. It’ll take the File handle provided by the application object, read in the contents and store them a JStackMeta and its JStackEntry objects. To test this class I created a test.jstack file (which is the same content as the example at the top of this post).

public class ParserTest {
    @Test
    public void testProcess() throws Exception {
        final URL resource = getClass().getResource("test.jstack");
        final File file = new File(resource.getFile());

        final JStackMeta stackMeta = new Parser(file).process();

        Assert.assertEquals(132, stackMeta.getHeader().length());
        Assert.assertEquals(2, stackMeta.getEntries().size());
    }
}

The actual parsing function looks like this (note that I’ve decided that it is important to keep the newlines in the stack trace to simplify the output):

    /**
     * Process the JStack output file and extract the data into a {@link JStackMeta} object.
     *
     * @return The {@link JStackMeta} object representing the JStack output.
     */
    public JStackMeta process() {
        _meta = new JStackMeta();
        try {
            FileInputStream inputStream;
            inputStream = new FileInputStream(_file);

            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));

            boolean finishedHeader = false;
            JStackEntry currentEntry = new JStackEntry("");

            String line;
            while ((line = in.readLine()) != null)
            {
                // Skip blanks
                if ("".equals(line.trim())) {
                    continue;
                }
                line += "\n";

                // Check if we're done with the header lines
                if (!finishedHeader && line.startsWith("Thread")) {
                    finishedHeader = true;
                }

                if (!finishedHeader) {
                    _meta.append(line);
                    continue;
                }

                if (line.startsWith("Thread")) {
                    currentEntry = new JStackEntry(line);
                    _meta.addEntry(currentEntry);
                } else {
                    currentEntry.append(line);
                }
            }

            in.close();
        } catch (FileNotFoundException e) {
            System.out.println("ERROR: File was not found");
        } catch (IOException e) {
            System.out.println("ERROR: A problem occurred");
            e.printStackTrace();
        }

        return _meta;
    }

Reporting

The last part of the application is a simple analysis of the JStackMeta object and reporting the statistics. As per the requirements, I want two parts to this, the totals for the different states and the single-line summary with counts.

For the purposes of a quick solution, I’m writing the output to the console. I’ll make a Report interface, just in case I get inspired and write some other implementation to report to a text or HTML file..

I’ll use two maps to keep track of the totals – one map for the status counts and one for the line summary totals. To keep the second part looking organised, I’ll use a TreeMap so that the entries remain sorted.

public interface Report {
    void buildReport(JStackMeta stackMeta);
}
public class ConsoleReport implements Report {
    public void buildReport(final JStackMeta stackMeta) {
        Map<String, Integer> stateCountMap = new HashMap<String, Integer>();
        Map<String, Integer> messageCountMap = new TreeMap<String, Integer>();  // Sorted

        // Report on results
        for (int i = 0; i < stackMeta.getEntries().size(); i++) {
            JStackEntry entry = stackMeta.getEntries().get(i);
            final String state = entry.getState();

            final Integer count;
            if (stateCountMap.containsKey(state)) {
                count = stateCountMap.get(state) + 1;
            } else {
                count = 1;
            }
            stateCountMap.put(state, count);

            final StringBuilder contents = entry.getContents();
            final String strStackEnd;
            if (contents.length() != 0) {
                strStackEnd = "(" + state + ") " + contents.substring(0, contents.indexOf("\n"));
            } else {
                strStackEnd = "(" + state + ") " + "[No stacktrace]";
            }

            final Integer countMessage;
            if (messageCountMap.containsKey(strStackEnd)) {
                countMessage = messageCountMap.get(strStackEnd) + 1;
            } else {
                countMessage = 1;
            }
            messageCountMap.put(strStackEnd, countMessage);
        }

        // State counts
        for (Map.Entry<String, Integer> entry : stateCountMap.entrySet()) {
            System.out.println(entry.getValue() + " threads at " + entry.getKey());
        }

        System.out.println("\n");

        // Message counts
        for (Map.Entry<String, Integer> entry : messageCountMap.entrySet()) {
            System.out.println(entry.getValue() + "\tthreads at " + entry.getKey());
        }
    }
}

(I may have gotten lazy here and neglected some unit test coverage- but with the report being written to console its fairly easy to eyeball bugs, right??)

With the Parser and report classes implemented, I can update the code in ParseJStack with a call to the parser and report:

...
        final JStackMeta stackMeta = new Parser(jstackFile).process();

        final Report report = new ConsoleReport();
        report.buildReport(stackMeta);
...

Finally

The end result of this analysis is being able to see an overview of the JStack results, which may give some indication of where to start looking for problems with the application.

39 threads at IN_NATIVE
503 threads at BLOCKED

1	threads at (BLOCKED)  - com.sun.appserv.util.cache.BaseCache.incrementMissCount() @bci=6, line=864 (Compiled frame; information may be imprecise)
3	threads at (BLOCKED)  - java.io.ByteArrayOutputStream.write(byte[], int, int) @bci=71, line=95 (Interpreted frame)
2	threads at (BLOCKED)  - java.io.FileInputStream.readBytes(byte[], int, int) @bci=0 (Compiled frame; information may be imprecise)
1	threads at (BLOCKED)  - java.lang.Object.hashCode() @bci=0 (Compiled frame; information may be imprecise)
4	threads at (BLOCKED)  - java.lang.Object.wait(long) @bci=-1749045981 (Interpreted frame)
195	threads at (BLOCKED)  - java.lang.Object.wait(long) @bci=-1749046076 (Interpreted frame)
    ...

As you can see we’re interested in seeing the counts for the end frames of the threads, and the state that they are in at this point.

This will at least give an opportunity to where the majority of the threads are ending up, and from this we might be able to gain some insight on what these threads are waiting on (e.g. by looking up stack traces via the byte code index in the original JStack log)

Next Steps

  • It may be of use to include a little bit more of the stacktrace in the comparison and output – I noticed that some taces would end on the frame with the same byte code index, but their full stacks would vary slightly.
  • As mentioned, it might be useful to write the report out to a file, such as a text or HTML file.

References

How to load properties files into Spring and expose to the Java classes

IMPORTANT!
This blog has moved to http://blog.brasskazoo.com!

Loading properties files in the spring configuration

The issue:

Our webapp is using a spring and hibernate backend, and both spring configuration and Java classes need to access database connection properties.

Currently there is an application.properties file and a spring applicationContext.xml, both which contain the same information for the database connection.

Ideally, there should be only one configuration file to define the properties, which is used by both spring and Java.

Spring has the ability to load properties files as part of the application configuration, for use internally. The properties can be referenced within spring configuration files using ant-style placeholders, e.g. ${app.var}.

To solve our issue though we’ll also need to provide a populated bean that can be used by our production classes.

Here’s the properties file (application.properties):

appl.name=My Web Application
appl.home=/Users/webapp/application/

# Database properties
db.driver=org.hsqldb.jdbcDriver
db.name=v8max.db
db.url=jdbc:hsqldb:file://${appl.home}/database/${db.name}
db.user=SA
db.pass=

Spring loads the properties file using a bean of the type org.springframework.beans.factory.config.PropertyPlaceholderConfigurer, and then we can reference the properties directly in the spring configuration file.

Note that we can also use placeholders within the properties file, as in the db.url above – the PropertyPlaceholderConfigurer will resolve them too!

    <!-- Load in application properties reference -->
    <bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties"/>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${db.driver}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.user}"/>
        <property name="password" value="${db.pass}"/>
    </bean>

So now we’ve removed the need to have literals in the spring config!

Exposing the spring properties bean in java

To allow our Java classes to access the properties from the same object as spring, we’ll need to extend the PropertyPlaceholderConfigurer so that we can provide a more convenient method for retrieving the properties (there is no direct method of retrieving properties!).

We can extend the spring provided class to allow us to reuse spring’s property resolver in our Java classes:

public class PropertiesUtil extends PropertyPlaceholderConfigurer {
   private static Map propertiesMap;

   @Override
   protected void processProperties(ConfigurableListableBeanFactory beanFactory,
             Properties props) throws BeansException {
        super.processProperties(beanFactory, props);

        propertiesMap = new HashMap<String, String>();
        for (Object key : props.keySet()) {
            String keyStr = key.toString();
            propertiesMap.put(keyStr, parseStringValue(props.getProperty(keyStr),
                props, new HashSet()));
        }
    }

    public static String getProperty(String name) {
        return propertiesMap.get(name);
    }
}

If we now update the applicationProperties bean to use the PropertiesUtil class, we can use the static getProperty method to access the resolved properties via the same object as the spring configuration bean.

Of course, we could run into problems if a class tries to use PropertiesUtil before the spring context has been initialised. For example if you’re registering ServletContextListeners in your web.xml before configuring spring, you’ll get a NullPointerException if one of those classes tries to use PropertiesUtil. For that reason I’ve had to declare the spring context before any context listeners.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Other listeners -->

References

  1. http://www.jdocs.com/spring/1.2.8/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html
  2. http://j2eecookbook.blogspot.com/2007/07/accessing-properties-loaded-via-spring.html