Tag Archives: trivia

Java project structural best practices

The structure of a java project has gone through some transitions in time. Here are some conventional examples.

Basic project

Here is a simple java project created in eclipse for basic needs. Although this is lightweight and simple it offers no place to put resources.

eclipse-project/
|-- bin
`-- src

Ant web project

Here is the legacy ant project layout before maven came along. It provides a place to put resources. However the problem is that if you put stuff in WEB-INF then it is not classpath accessible and, specific to eclipse, you cannot add WEB-INF as a source folder to add it to your editor classpath because it is nested in your output folder of WEB-INF/classes/.

ant-project/
|-- src
|-- tests
`-- webapp
    `-- WEB-INF
        `-- classes

Basic maven project

This is the standard maven layout and provides clean separation of every distinct responsibility of a project structure. It is very well defined and has no classpath problems and is my favourite.

basic-maven-project/
|-- pom.xml
|-- src
|   |-- main
|   |   |-- java
|   |   |-- resources
|   |   `-- webapp
|   |       `-- WEB-INF
|   `-- test
|       |-- java
|       `-- resources
`-- target
    |-- classes
    `-- test-classes

Advanced maven project

The advanced maven project structure is offered by M2Eclipse, the eclipse plugin, and has one advantage over the previous structure. It offers different output directories for eclipse and command line. This is useful when building in editor and command line and you don’t want them to conflict, clear or overwrite each other in the output directory. This helps also with setting editors and build tools to work independently if their settings differ.

advanced-maven-project/
|-- pom.xml
|-- src
|   |-- main
|   |   |-- java
|   |   `-- resources
|   `-- test
|       |-- java
|       `-- resources
|-- target
|   |-- classes
|   `-- test-classes
`-- target-eclipse
    |-- classes
    `-- test-classes

Best practices

So what must one consider when creating a new project structure? Sometimes the use of maven is not permitted either due to a legacy environment or due to a heavy investment in ant already. That is when it becomes necessary to think in terms of concepts and the pros and cons of different structures outside of the domain of specific build tools. The following are some recommendations to follow which make life a hell of a lot easier.

  • Separate sources from tests. Yes I have seen them both together and it is a very bad idea.
  • Separate resources from the output folder. This can take the shape of a resources/ folder by itself in its simplest form. The benefit of this is that it can be classpath accessible by your editor and your build tool and is not nested within your output folder and can therefore be added as a source folder within your editor. This also thereby provides a uniform classpath based access mechanism to all its contents independent of the tool used. The build tool can then be configured to copy its contents to the output folder.
  • Optionally have separate output directories for different tools. At times for example it is necessary for eclipse and ant to operate on the same project but independently and in isolation especially when you are testing your build environment with various different tools and settings. Most of the time this is unnecessary and so optional.
  • When accessing resources from your application always use classpath based paths relative to your classpath. Spring makes this dead easy by allowing various locator patterns that also interpret wildcards (classpath:, classpath*:, file:). If you are storing your resources in their own folder and that is added to the classpath then you can access its contents by using simply a slash. The build tool or editor will then copy your resources into the output folder where the classpath based access will continue to apply whether deployed or otherwise.
  • When using components (jars) in your application containing resources such as spring context files and property files allow the application to aggregate. The component should only ever provide config and resources and never load them. It should also never access the application to load application specific content. The end-user application is where the control should lie and the components should remain subordinate and not only because the same component may be used in more than one disparate application.
  • Use Spring to your benefit. Spring provides a uniform mechanism to load resources of different kinds. Use it instead of loading resources manually. Try to resist the temptation to innovate on the classpath and associated integration and build tools. Reinventing the wheel rarely pays off in a positive way in some common ground!
  • Standardise on your editor if possible (non-essential) and if using source control check in your editor project configuration. It makes new check outs far more informative as to the project structure and classpath entries. If omitted or ignored it has be reconfigured from scratch every time.

This was a blog post on a rather simplistic and basic note. However I felt it was worth a mention at least once as there will always be legacy projects out there in need of inspiration. Classpath problems are fundamental and if they exist they tend to impact the application as a whole and its components and cause prolonged heartache. It’s worth having a clearly defined and justified strategy to begin with so that later on down the line your app can grow and change with ease.

JUnit3, JUnit4 and Spring testing tips and trivia

If you’re in a legacy environment (as I am for the moment) with only the old version of junit at your disposal the following may be useful.

JUnit3 Multiple Instantiation [#]

import junit.framework.TestCase;

public class Junit3MultipleInstancesTest extends TestCase {

    public Junit3MultipleInstancesTest() {
        System.out.println("test instance created");
    }

    public void test1() {
        System.out.println("test1");
    }

    public void test2() {
        System.out.println("test2");
    }
    
}

What would you expect the above to print? Answer below.

test instance created
test instance created
test1
test2

JUnit4 Multiple Instantiation

import org.junit.Test;

public class Junit4MultipleInstancesTest {

    public Junit4MultipleInstancesTest() {
        System.out.println("test instance created");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

}

Output:

test instance created
test1
test instance created
test2

Would you want your test class to be instantiated on every test? Are you satisfied with the justification that it is done for complete test isolation between test methods? Does this make it impossible to maintain state between test methods without resorting to static context?

JUnit3 one time setup and one time teardown

Want to declare your one-time setup and one-time teardown in one place and reuse it for all your tests? You can.

Base class
import junit.framework.TestCase;

public class Junit3TestSuperClass extends TestCase {

    protected static void setUpBeforeClass() {
        System.out.println("set up before class");
    }

    protected static void tearDownAfterClass() {
        System.out.println("tear down after class");
    }

}
Child class
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestSuite;

public class Junit3TestSubClass extends Junit3TestSuperClass {

    public static Test suite() {

        TestSuite suite = new TestSuite(Junit3TestSubClass.class);

        return new TestSetup(suite) {

            protected void setUp() {
                setUpBeforeClass();
            }

            protected void tearDown() {
                tearDownAfterClass();
            }
        };

    }

    public void test1() {
        System.out.println("test1");
    }

    public void test2() {
        System.out.println("test2");
    }

}

The subclass, when run, prints the following.

set up before class
test1
test2
tear down after class

Yes – the additional infrastructural suite() method in the subclass is nasty but then again junit3 makes no other provisions. This is made a hell of a lot nicer in juni4 with the allowance of @BeforeClass and @AfterClass annotations.

JUnit4 one time setup and one time teardown

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class Junit4Test {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("set up before class");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("tear down after class");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

}

Performance optimisation

When testing one might want to reduce overhead and run tests quickly. This may be because you have a lot of tests or because you are waiting on them repeatedly to verify that your code is working correctly as per the laws of test-driven development.

For unit tests time, overhead and waiting are not normally a problem as they are pretty succinct, quick and free of other dependencies i.e are isolated. However, integration tests need a whole other approach as they are end-to-end and often rely on environmental and infrastructual tools and at times human intervention to work satisfactorily.

Take the rather common use-case of a Spring integration test. Spring have gone out of their way to provide a fully featured test framework and numerous mock classes to make testing quick and easy. However if certain considerations are overlooked it can make your integration test suite significantly slower. Adhering to the following helps.

  • Use the Spring test framework and paradigms. Don’t reinvent the wheel. You will almost certainly end up with a more inferior solution. If there’s a quirk of your application which prevents you from using a Spring based testing architecture for your spring application sort it out. It’s often the least time consuming option and aids better long term maintainability.
  • Use the context cache. Load the context once and run many integration tests. Spring 2.0.x and 2.5.x have native support for this out of the box. However if you are loading the context manually one can still cache using the above one-time setup and teardown paradigm. If your tests are modifying the context or in Spring’s terminology dirtying the context then it has support for reloading after designated dirty actions.
  • Use test context files. In this way heavyweight beans can be replaced with lighter and simple alternatives if necessary. Mocks can be introduced and a more custom aggregation of context files can be achieved. Test contexts are not a “bad thing” – in fact I would argue that they are a “good thing” and a necessity depending on the application. Ultimately tests are not secondary – they are part of your application – if done correctly then almost half of your application. You want them to be maintainable and efficient.
  • Use stubs and mocks for when you cannot rely on your environment or for better isolation. A stub is a dummy class which implements the same theoretical interface api as the original class but does nothing. A mock is like a dynamic stub which can be told to adapt to a particular class interface and can be told what input to receive and how to react to it. Mocks can make slow end-to-end integration tests run almost instantly unless of course you really do need end-to-end testing.
  • Use default lazy initialisation/loading of spring beans so that you only load the bean dependencies of the beans you require and are testing. If certain specific beans like scheduled jobs are not referred to by any other bean and need to be eagerly loaded at context startup then explicitly mark them as eagerly loaded. This is the same mentality as in hibernate.
  • Designate different types of tests in different areas. Layer them by responsibility. Data layer tests, business layer tests, service layer tests and controller tests all have different responsibilities and should be separated. The advantages are that you can run each responsibility separately but also it hugely improves structuring and maintainability. If using a build tool or continuous integration you can also ask these tools to run specific test groups at given time intervals or to skip certain problematic or slow test groups.

Essential test attributes

Incidentally, InfoQ, had an excellent article on testing recently. Here’s what I extracted to be the key attributes of a good test from my point of view.

  • Automated
  • Environment independent (to extent possible)
  • Easy to run
  • Quick to run
  • Provides regression testing capability
  • Can be run repeatedly
  • Demonstrates use of api through example
  • Order independent

Ultimately one has to be realistic. True TDD i.e. tests before code is difficult to achieve in a commercial hard driven environment and most people don’t expect it nor expect to be doing it. However, tests should at least be written after the task is done. After all, without that, how do we know anything works at any moment in time?

Recently I’ve overheard people question what benefits junit4 and spring 2.5 test context framework provide over the old ways of doing things. My short answer would be huge benefits. If I get time I’ll do a summary post on this topic. For now here are Junit4‘s and Spring‘s official answer.