Nov 14, 2013

Testing private methods in Java and Groovy

If you search the internet for the topic testing private methods you will find several opinions if this is good practice or not. Some people even consider it a misconception. I personally think that it is a good idea to encapsulate logic that makes only sense in the context of a single class into a private method. If the code inside of this method exceeds a certain complexity it should be tested.

In this post however I do not want to start a discussion on this topic but show how it can be done easily in Groovy and Java. Let's have a look at the following code:

public class SomeClass {
  private String methodToBeTested(String input) {
    return input.toLowerCase(); 
  } 
}

// inside of a test
SomeClass someClass = new SomeClass();
assert "foo" == someClass.methodToBeTested("Foo");

If you run this code in Groovy you may expect an Error because the test calls a private method of SomeClass. However as of Groovy 2.1.9 this is currently not the case due to a bug in Groovy:
http://jira.codehaus.org/browse/GROOVY-1875
Consequently testing private methods in Groovy currently is really simple: just do it.

However if SomeClass is a class produced by the Java compiler the test will fail with an error like this:

methodToBeTested(java.lang.String) has private access in SomeClass         someClass.methodToBeTested("Foo");

The Groovy developers are working on a fix for the issue that will hopefully make it into Groovy 3. So the Groovy code shown above is eventually not compatible with future Groovy releases.

To overcome this testing problem one can use the Java Reflection API.
The test code must be changed like this:

// inside of a test SomeClass
someClass = new SomeClass();
Method method = SomeClass.class.getDeclaredMethod("methodToBeTested", String.class)
method.setAccessible(true);
assert "foo" == method.invoke(someClass, "Foo");

Note that the reflection methods can throw several Exceptions. If the test is written in Java these must be caught or the test method must be adjusted accordingly.

Dec 1, 2010

Tracking Session Lifecycle in Grails

Web applications often need to keep track when new user sessions are created and when user sessions are terminated - either by timing out or by active invalidation.
The Java Servlet Specification defines Event Listeners for this purpose. Have a look at this article for an introduction on how to utilize these servlet technologies.

I want to explain here how to integrate HttpSessionListeners smoothly with Grails.

We start by registering a listener in the deployment descriptor - the file web.xml.
By default this file is not visible when developing with Grails since it is generated dynamically. You can get a static version by executing the following command in the application's root directory:

grails install-templates

Instead of executing this command and creating a static web.xml file we are going to choose the more modular approach of extending the web.xml generation process.

The first thing to do is to create the file _Events.groovy in the scripts directory of the application root. Note that this directory was created when executing grails create-app. The contents of _Events.groovy should look something like this:

import groovy.xml.StreamingMarkupBuilder
eventWebXmlEnd = {String tmpfile -> 
  def root = new XmlSlurper().parse(webXmlFile)
  root.appendNode {
    'listener' { 
      'listener-class' (
        'org.test.MyHttpSessionListener'
      ) 
    }
  } 
  webXmlFile.text = new StreamingMarkupBuilder().bind {
    mkp.declareNamespace(
      "": "http://java.sun.com/xml/ns/j2ee")
    mkp.yield(root) 
  }
}

This defines a closure that is called by the Grails build mechanism right after creation of web.xml. In the closure Groovy's XmlSlurper is used to parse the web.xml into a tree data structure. Xml elements for listener and listener-class are added and the tree data structure is written back using Groovy's StreamingMarkupBuilder.

The class org.test.MyHttpSessionListener is registered as event listener.
The file  src/groovy/org/test/MyHttpSessionListener.groovy contains this class. Obviously the org/test part of the path depends on the package name you want to choose. The file's contents should look like this:

package org.test

import org.codehaus.groovy.grails.commons.ApplicationHolder
import javax.servlet.http.HttpSession
import javax.servlet.http.HttpSessionEvent
import javax.servlet.http.HttpSessionListener
class MyHttpSessionListener implements HttpSessionListener {
  HttpSessionService httpSessionService
  
  // called by servlet container upon session creation
  void sessionCreated(HttpSessionEvent event) {
    HttpSession session = event.getSession()
    getHttpSessionService().sessionCreated(session)
  }

  // called by servlet container upon session destruction
  void sessionDestroyed(HttpSessionEvent event) {
    HttpSession session = event.getSession()
    getHttpSessionService().sessionDestroyed(session)
  }

  private synchronized HttpSessionService
  getHttpSessionService() {
    if (httpSessionService == null) {
      httpSessionService =
        (HttpSessionService) ApplicationHolder
        .getApplication().getMainContext()
        .getBean("httpSessionService")
    }
    return httpSessionService
  }
}

The class implements the sessionCreated and sessionDestroyed methods as defined in the HttpSessionListener interface. These methods are called by the servlet container upon session creation and destruction. However to integrate our listener with the rest of the Grails artefacts it would be nicer if conventional Grails Service methods were called on these events.

To achieve the desired Service calls we cannot utilize Spring injections in our SessionListener. We therefore manually fetch a bean called httpSessionService from the application's MainContext. This bean is a conventional Grails Service that we have to implement in a file called grails-app/services/org/test/HttpSessionService.groovy.  The file could have the following contents:

package org.test

import javax.servlet.http.HttpSession

class HttpSessionService {

  // method called upon session creation
  def sessionCreated(HttpSession session) {
    log.info("Session created: "+session.id)
  }

  //method called upon session destruction
  def sessionDestroyed(HttpSession session) {
    log.info("Session destroyed: "+session.id)
  }
}

Other services can be injected into the HttpSessionService and relevant business logic can be called from the sessionCreated and sessionDestroyed Service methods.

Aug 11, 2008

Oliver Wahlen's Blog Online

So this is my first post on Blogger.
As an IT consultant I have done several projects using Netbeans and its Visual Web JSF framework based on the Woodstock components.
I think that JSF is in general one of the best approaches to create robust web applications.

However the whole web technology sector is evolving with an enormous speed and to stay "in business" developers have to get comfortable with new technologies at an enormous rate.

I want to use this blog for two purposes:
  1. to present new technology approaches, and to help developers getting comfortable with these technologies.
  2. to share my personal technology evaluation results with others and to challenge other opinions. I think such discussions will help people to get a better level of judgement concerning state of the arte technologies. Therefore I encourage everybody to comment my posts!
And now: Happy blogging!

Netbeans Visual Web Tables with thousands of records

Maybe you have noticed that the table component in Netbeans visual
web tends to become quite slow if it has to deal with a huge amount of
records (e.g. coming from a database).
This is true even if pagination is used.

The reason is that the typical dataproviders (e.g. ObjectArrayDataProvider) on the server side require a complete fetch of all data from the database.
Based on this data they analyze the amount of records which in turn is used to operate the augmented table header and the pagination controls.
Thus the application does not only become slow (because of the sql operations) but also consumes a large amount of memory.

To overcome this problem I have created a new dataprovider called ObjectControllerDataprovider.
Like all the other dataprovider this class can directly be used in the table layout of the visual table component.
This ObjectControllerDataprovider is in turn connected an ObjectController.
In more detail the ObjectControllerDataprovider is connected to a class that is to be written manually which extends the abstract ObjectController class.
The manual written class finally contains the functionality to efficiently retrieve small pages from a database utilizing a caching window concept.

You can download a working Netbeans 6.1 example project using the new dataprovider from the following link: http://sites.google.com/site/owahlen/Home/ObjectControllerTest.tar.gz