Java Beginner Tutorial – Downloading and Installing Tools for Java Development

This video tutorial for beginners in Java shows you how to install and configure the tools you’ll need to get started in Java development. You’ll download a Java Development Kit, JDK, version 7, and the free community edition of IntelliJ Idea. The total time for this tutorial is 15 minutes.

Tagged with: , , ,
Posted in Java Beginners

Using TestNG with Spring


Moving to TestNG From JUnit

A few weeks ago I published a Simple Introduction to Spring Unit testing using JUnit. We’ve been using JUnit quite a bit in our examples so far, but as some of you may already know, JUnit is not the only unit test framework for Java. Another framework, TestNG, offers a lot of features that JUnit lacks, such as the ability to run parameterized tests in which a given test is run against an array of different values, and the ability to break tests down into categories coupled with fine-grained configuration control over what tests to run. Indeed, the author of TestNG (“Next Generation”) very much had the limitations of JUnit in mind in writing the new framework. You can read about some of the problems with JUnit that TestNG was designed to solve on it the TestNG web site.

Of course, the choice of which technology to use is often a matter not of what’s best, but what’s most popular (especially if you’re early in your career and need to get certain key technologies added to your resume). So for my wife, who’s just beginning her technical career as a tester, I’d be inclined to recommend JUnit, whereas for myself, old fart programmer that I am, I have the luxury of picking the technology I consider better in many cases. For example, compared to IntelliJ Idea, for me Eclipse is just too painful — free or not, big market share or not. So I use IntelliJ. So if you’re playing “Dice Keyword Bingo”, stick with JUnit, otherwise do yourself a favor and take a look at TestNG. </My two cents>

Setting up the Maven Dependency for TestNG

Rather than repeat all the sample bean code from our original JUnit article, let’s focus here on the tests. The original sample code is, after all, not very interesting — it only gave us something to test. To migrate the JUnit sample, the first thing I needed to do was change the dependency section in our POM file slightly. Remove the JUnit dependency:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.8.2</version>
  <scope>test</scope>
</dependency>

Now add the dependency for TestNG:

<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.1.1</version>
  <scope>test</scope>
</dependency>

For the benefit of those of you starting from scratch, the here is the full POM file.

Simple AbstractTestNGSpringContextTests Test Examples

Next, let’s see what we need to do to use Spring’s basic TestNG testing support class, AbstractTestNGSpringContextTests. Don’t let the “Abstract” in the name scare you off here, there’s really nothing much to implement. All you need to do is add a ContextConfiguration annotation to your class and it just works. Here’s the Hello-World-simple example, which only uses the ContextConfiguration annotation to get it to compile and run.

package com.codesolid.tutorials.tests;

import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.Test;

import static org.testng.Assert.assertTrue;

@ContextConfiguration("file:src/main/resources/spring-config.xml")
public class SimpleTest extends AbstractTestNGSpringContextTests {

    @Test
    public void SomeTest() {
        assertTrue(true);
    }
}

Modifying our JUnit tests to work with TestNG was just as easy. The @RunWith annotation was no longer needed, being replaced by the fact that we’re extending AbstractTestNGSpringContextTexts. So pretty much the only migration we did involved changing JUnit imports to TestNG ones. We removed:

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

We replaced it with:

import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

Here for example is a little bit longer example, that exercises some of the test beans we’ve wired up in our application context:

package com.codesolid.tutorials.tests;

// Generally needed:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

// Application specific
import com.codesolid.tutorials.UserStory;
import com.codesolid.tutorials.User;

@ContextConfiguration("file:src/main/resources/spring-config.xml")
public class ContextTests extends AbstractTestNGSpringContextTests {

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    protected ApplicationContext ac;

    // Using ApplicationContext
    // The getBean method is the workhorse of the Spring ApplicationContext.
    // The user field in the UserStory object was set up (dependency injected)
    // by Spring:
    @Test
    public void testUserNotNull() {
        UserStory story = (UserStory) ac.getBean("userStory");
        assertNotNull(story.getUser());
    }

    // Not using ApplicationContext
    // Regular non-Spring instantiation
    // Instantiating our own UserStory, you can see that the user
    // is null.
    @Test
    public void testUserStoryNotFromContext() {
        UserStory story = new UserStory();
        assertNull(story.getUser());
    }

    // Not using ApplicationContext
    // Regular non-Spring instantiation
    // The default role if you just call the constructor
    // is "User".
    @Test
    public void testNonSpringUserDefaultRole()
    {
        User u = new User();
        assertEquals(u.getRole(), "User");
    }

    // Using ApplicationContext
    // Since Spring instantiated this according to the property
    // from spring-config.xml, it overrode the default "user"
    // role with "SuperGenius User".  (This presumably
    // is Wile E. Coyote.)
    @Test
    public void testUserRoleIsAsExpected() {
        UserStory story = (UserStory) ac.getBean("userStory");
        assertEquals(story.getUser().getRole(), "SuperGenius User");
    }
}

Getting started using the Spring TestNG support turned out to be really easy. Check our our IntelliJ project and the full source on GitHub.

Tagged with: , , , ,
Posted in Testing, JUnit, TestNG Tutorials

Spring Security – Part I: Spring Authentication and Authorization Basics


My Scandalous Confession

Before we begin with the tutorial, I am going to lay bare my soul to you. I know, most tutorials are dry and boring, and don’t include such titillating and scandalous gossip as you are about to hear. You’re welcome.

Whenever I write an article that has Part 1 in the title, I generally am doing so without even a remote business plan for a clue about how many parts I’m going to end up with. There, I’ve made my confession. Eat your heart out, St. Augustine.

In this tutorial we’re going to start digging into Spring Security in the easiest way I know how. First, spend $199 on a great Java IDE, or download it free for thirty days so you can get through however many parts this article ends up having. We’re using IntelliJ 12 Ultimate Edition to generate a starter project for this article in the next section. The cool thing is, though, once you have the starter project, you can likely follow along with the rest of the article using either the IntelliJ Idea 11 or 12 Community Edition, which is free. I’ve had good luck doing that. You can even import the POM file into Eclipse and run the project that way.

Generating a Spring Security Project

With Idea Ultimate Edition Version 12 and later, to create a Spring Security Project you simply select create a new project from the Welcome Screen:

IntelliJCreateNewProject

Next, select Spring Security and give your project a name:

SpringSecurityCreateProject


The Security Configuration Files

In the Spring security starter project, IntelliJ adds the security-related configuration to the two required places, web.xml, and the main Spring configuration file, both of which are in src\webapp\WEB-INF\.

In web.xml, we first set up a security filter name, then use that name to defining a mapping to ensure that all application URLs go through the security filter first:

    <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>

Next we turn to the main Spring configuration file, spring-config.xml, which is shown in abbreviated form below:

    <security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" secured-annotations="enabled" />

    <security:http use-expressions="true">
        <security:intercept-url pattern="/**" access="permitAll" />
        <security:form-login />
        <security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
        <security:remember-me />
        <security:session-management invalid-session-url="/">
            <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </security:session-management>
    </security:http>

    <bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>

    <security:authentication-manager>
        <security:authentication-provider>
            <security:password-encoder ref="encoder"/>
            <security:user-service>
                <!-- Password: "koala" for both -->
                <security:user name="user"
                      password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde"
                      authorities="user"/>
                <security:user name="admin"
                      password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde"
                      authorities="admin"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

First, we see a line enabling JSR-250 annotations, such as @RolesAllowed, @PermitAll, @DenyAll, which allows fine-grained, method level access control. Furthermore, the ‘use-expressions=”true”‘ clause allows us to use Spring Expression Language style security expressions in our view layer. We’ll be looking at what that allows us to do a bit further on when we discuss the view layer.

Next, the attributes ‘pre-post-annotations=”enabled”‘ and ‘secured-annotations=”enabled”‘ will be used by our controllers. These configuration elements enable a feature that is new as of Spring 3.0. Spring 3.0 introduced several new, method-level annotations beginning with @Pre and @Post. We see one of these, @PreAuthorize, used in both the UserService class and the ApplicationController classes:

    // In UserService.java:
    @PreAuthorize("hasRole('admin')")
    public Collection<? extends GrantedAuthority> getAuthorities(UserDetails userDetails) {
        return userDetails.getAuthorities();
    }

    // In ApplicationController.java:
    @PreAuthorize("hasRole('admin')")
    @RequestMapping(value = "/admin", method = RequestMethod.GET)
    public String admin(ModelMap map) {
        UserDetails userDetails =
                (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Collection<? extends GrantedAuthority> securedMessage = userService.getAuthorities(userDetails);
        map.addAttribute("userDetails", userDetails);
        map.addAttribute("userAuthorities", securedMessage);
        return "admin";
    }

In the next section of the configuration, we see a setting that is probably worth giving some thought to before you move an application into production:

  <security:http use-expressions="true">
        <security:intercept-url pattern="/**" access="permitAll" />
        ...
   </security:http>

The demo app takes the unusual approach of allowing access by default, and allowing it for certain roles. Generally it’s considered a best practice for secure applications to deny access by default, then turn it on selectively — that way when you forget a setting somewhere, you err on the side of more security, not less.

Spring’s StandardPasswordEncoder

In the next two sections of spring-config.xml, we set the password encoder our application will use to the StandardPasswordEncoder, then we configure two users with passwords generated by that encoder:

...
<security:user-service>
    <!-- Password: "koala" for both -->
    <security:user name="user"
         password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde"
         authorities="user"/>
    <security:user name="admin"
         password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde"
         authorities="admin"/>
</security:user-service>
...

The StandardPasswordEncoder is a small and quite nicely designed class that bundles everything you want a password encoder to do into a very small interface. It uses an SHA-256 hasing together with an eight byte random salt to generate a password hash that is unique each time. Although the starter application does not show this, for additional security you can add an extra secret value for your application, in which case the hash will be based on the password, the random salt, and the secret value. This is configured using basic constructor injection:

<bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
  <constructor-arg value="x9ajDR$#Qkr91">
</bean>

Getting back to the application configuration, we see that the application is configured with two users, “user” and “admin”, both with the password “koala”, which is hashed to: 4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde.

To show you a little more about how the StandardPasswordController works, I’ve added a unit test to the code that IntelliJ Idea provides. As you can guess from the code, each time the tests are run the output for each encoded string will be different, even though we are encoding the same password over and over again. Moreover, though we can verify the encoded string against the password, the password is virtually impossible to reverse engineer.

import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.security.crypto.password.StandardPasswordEncoder;

public class StandardPasswordEncoderDemo {
    @Test
    public void testCannotReproduceHashFromConfigFile() {
        StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        String password = "koala";
        String encoded = encoder.encode(password);
        String encodedFromXML = "4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde";

        // What we generated is not what's in the XML
        assertTrue(encodedFromXML != encoded);

        // But both what's in the XML and what we generated match the password.
        assertTrue(encoder.matches(password, encoded));
        assertTrue(encoder.matches(password, encodedFromXML));

        System.out.println(encoded);
   }

    @Test
    public void testAnotherRunWillAlsoYieldDifferentHashes() {
        StandardPasswordEncoder encoder = new StandardPasswordEncoder();
        String password = "koala";
        String encoded = encoder.encode(password);
        String encoded2 = encoder.encode(password);
        assertTrue(encoded2 != encoded);

        System.out.println(encoded);
        System.out.println(encoded2);
    }
}


Using Security in the View Layer – The Spring Security Tag Libraries

If we look in ApplicationController.java, we find the following method mapping:

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(ModelMap map) {
        // Additional code...
        return "index";
    }

No surprises here, the root mapping is to the traditional index page. Examining the source in src/webapp/WEB-INF/pages/index.jsp we find a good demonstration of the use of the Spring Security Tag Library. First, we import the tag library:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

We now have access to the Spring Security Expressions that we saw enabled earlier when we discussed the configuration. For example, we first check to see if the User has logged in or not, and if not, we prompt for a sign-in:

<sec:authorize access="isAnonymous()">
    <p>
        <a href="/spring_security_login">Sign In</a>
    </p>
</sec:authorize>

Using the inverse of the isAnonymousCheck, if the user is authenticated we display a welcome message and a sign-out link:

<sec:authorize access="isAuthenticated()">
    <p>Hello, ${userDetails.username}! <a href="/j_spring_security_logout">Sign Out</a></p>
</sec:authorize>

Note that for production use, there’s a bit of a bug in this code, since there’s a the user could be a user who asked to be remembered (“Remember Me”), in which case isAuthenticated would still return true even if the user were not logged in. To eliminate this possibility, use “isFullyAuthenticated” instead.

Finally, we do a check for the admin role and conditionally display a link if the signed in user has that role assigned.

<sec:authorize access="hasRole('admin')">
    <p>
        <a href="/admin">Admin page</a>
    </p>
</sec:authorize>

With that, we’ve seen a basic Spring Security starter project that illustrates how to set up a very basic authentication based on pre-configured user names and passwords. In Spring Security Part II, we’ll dig into how to handle the much more common use case of storing user authentication information in a database. We’ll also dig into customizing the log-in forms. This will serve as a starting point for a much more full featured authorization system suitable for a business to consumer or business to business web site. Later on in another tutorial we’re planning to tie this database-based authentication system with Spring OAuth, allowing users with (for example) a Google account to sign in using that account.

Tagged with: , , ,
Posted in Spring, Tutorials

Configuring Spring for Test versus Production


Spring Configuration Options

The Spring Framework is not opinionated software. Instead, Spring has a rich set of configuration options about which you can — indeed, about which you must — make up your own mind. In this tutorial we’ll discuss some of the ways you can easily configure your application to be ready for production, while still making it easy to work with your code in a test environment.

The META-INF Gospel

When you’re first getting something working, the easiest path I’ve found is to locate your properties somewhere underneath what in the standard Maven directory structure is the src\main\resources\META-INF directory. Then, to give just one example for now, you want to point to those resources as shown in the following annotation from a Unit test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/applicationContext.xml")
// class YourTestClass { ...

This will work just fine, and although I’ve seen a few spec Nazis on Stackoverflow complain that the Java JAR specification contains the gospel truth about what files are allowed in the META-INF directory, I’ll take the side of Roo and other Spring tools to preach a new gospel to you:

Generally speaking, put your configuration files in META-INF, unless you like pain.

That will get your software working, but the limitation of this approach is that once you’ve located all your configuration files in META-INF\<somewhere> to set up a single environment correctly, how do you set up different environments like those you’ll need for test, staging, and production. Though I’m sure there are a lot more ways to skin this poor cat, let’s discuss two of the more popular approaches to this problem. The first option, which we’ll discuss more briefly, is to resolve all your option file dependencies at compile time.

Configuring Spring Properties Using Multiple Modules

To use this approach, you set up a multi-module project. This approach takes advantage of the fact that WAR files can pack all the jars they need inside themselves, ready to be deployed to Tomcat or another web server. So we bundle our code and any configuration files that are common to all our target environments in the WAR file, then build a jar file for each different environment containing only environment-specific files.

What we might end up with is a directory structure that looks something like this:

root        
root/app
root/config_test
root/config_production

The app directory contains the whole structure of the application’s WAR file project. In the root directory is a pom file that builds the targets in the other directories, as shown in the following snippet:

<!-- pom.xml in root/ directory that builds the whole project -->
<modules>
   <module>app</module>
   <module>config_test</module>
   <module>config_production</module>
</modules>

The config_test and config_production files contain a src\main\resource\WEB-INF directory, whatever configuration files you need, and a pom file in the root to bundle the configuration files into a JAR. What’s important is that although the contents of the files will contain different settings, the names of the files should be the same in each configuration file we build — that way when they’re referenced from the main files in the application’s WAR files, all is well.

In turn, the WAR file in the main app depend on either the test configuration or the production configuration as desired, as shown in the snippet below. In the snippet below, we’re building for the test environment, so the production configuration is disabled.

<!-- pom.xml in root/app directory that builds the WAR file -->
<!-- Test configuration -->
<dependency>
  <groupId>com.codesolid</groupId>
  <artifactId>config_test</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

<!-- Production configuration  
<dependency>
  <groupId>com.codesolid</groupId>
  <artifactId>config_production</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>            
-->

I’ve used the multi-module approach and it works fine, but having to build three projects to configure one WAR file is a bit heavy handed. It also spreads the configuration files around more than I like. Fortunately, there’s an easier way to get this done, and that is to resolve the configuration files at run time, not at build time.

Configuring Spring Properties at Run Time Using the PropertyPlaceholderConfigurer

One powerful mechanism that Spring provides to make configuration flexible across different environments is the PropertyPlaceholderConfigurer. Since I think it’s the better approach, let’s take a look at a more detailed tutorial. The code for this is available under the PropertyPlaceholderConfigurer directory of our Github Tutorials Repository.

The structure of our PropertyPlaceholderConfigurer build is shown below:

PropertyPlaceholderConfigurer

We have a single bean under test (yes, you guessed it: TestBean), and our mission, if we choose to accept it, is to:

  1. Dynamically set up properties in our configuration files, so we can switch to new properties in production.
  2. Inject the values of those properties into the test bean. In many cases our properties would be consumed by another third-party bean, but injecting properties directly allows us to take the next step…
  3. Set up a unit test to show that we correctly injected the properties we want for the appropriate environment


Setting up PropertyPlaceholderConfigurer in the ApplicationContext

Our main “common configuration” area is in the META-INF\spring. Our global properties file and main application context file go here. Let’s look at applicationContext.xml, where the detailed comment explains what’s going on:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" />  <!-- Other namespaces omitted for brevity -->

    <!--
       The configuration below will use any application-wide properties files
       in the spring directory and make those properties available to all
       configurations (test, production, etc.).

       However, by setting the "environment" variable appropriately, we
       can use the files in either "test" or "production" (if you want staging etc.,
       simply create another directory under META-INF).

       For example, adding -Denvironment=test to the
       JVM command line will expose the properties located in META-INF/test.
       Likewise, you can set a system environment variable to do the same thing.

       The located property files are parsed and their values can
       then be used within other configuration files or in annotation-based
       configuration in the form of ${propertyKey}.

       See com.codesolid.properties.TestBean for an example of injecting these
       properties directly into a bean, and in the test directory, see
       com.codesolid.properties.tests for what the result is.
   -->

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:META-INF/spring/*.properties</value>
                <value>classpath:META-INF/${environment}/*.properties</value>
            </list>
        </property>
    </bean>

    <!-- Scan beans for annotation-based configuration -->
    <context:component-scan base-package="com.codesolid.properties" />
</beans>


Some Properties Files to Test

To have something to test, we’ve set up three simple properties files. First, we have a global “common.properties” with our humble title:

application.name=The Greatest Sample Ever

Next come two db.properties files:

test/db.properties:

# These are the values we'll use when testing.
database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/mydb
database.username=myuser
database.password=mypassword

production/db.properties:

# Different values for the production server
database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost/proddb
database.username=prod_user
database.password=DoubleSecretProbation


Injecting Properties

To keep things simple, lets inject only two of these properties. If our setup is correct and we set the environment variable “environment” to “test” we should be able to verify that we get the right application name (a global property), and the test environment value for (for example) database.username.

We inject these properties in TestBean.java:

package com.codesolid.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service(value="testBean")
public class TestBean {
    private String applicationName;
    private String databaseUser;

    // This property is set in common.properties and will be the same
    // for all environments, test, production, etc.
    @Value("${application.name}")
    public void setApplicationName(String applicationName) {
        this.applicationName = applicationName;
    }

    // In contrast, this property and other database related properties
    // are quite likely different in test and production.
    @Value("${database.username}")
    public void setDatabaseUser(String databaseUser) {
        this.databaseUser = databaseUser;
    }

    public String getDatabaseUser() {
        return databaseUser;
    }

    public String getApplicationName() {
        return applicationName;
    }
}


Testing with JUnit

As a final step, let’s make sure we’re running our test environment and our properties are injected correctly. Our JUnit test is as follows:

package com.codesolid.properties.tests;

import com.codesolid.properties.TestBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.context.ApplicationContext;


import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/applicationContext.xml")
public class ContextTests {

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private ApplicationContext ac;

    /* Verify that we've correctly injected a property from the Spring directory
    (in this case, the common.properties file).  Property files in this
    directory define properties that can be used in all environments. */

    @Test
    public void testApplicationName() {
        String expected = "The Greatest Sample Ever";
        TestBean test = (TestBean) ac.getBean("testBean");
        String actual = test.getApplicationName();
        assertEquals(actual, expected);
    }

    /* Verify that we've correctly injected a property from the test directory's
    db.properties. Property files in the test directory only apply to the test
    environment and can be overridden in the production directory (for example). */

    @Test
    public void testDatabaseConfiguredCorrectly() {
        String expected = "myuser";
        TestBean test = (TestBean) ac.getBean("testBean");
        String actual = test.getDatabaseUser();
        assertEquals(actual, expected);
    }

Working with the PropertyPlaceholderConfigurer class lets you easily configure your WAR file for production, test, and any other environments you need — and with that out of the way, you can now get busy writing your application. Enjoy!

Tagged with: , , , ,
Posted in Spring, Tutorials

A Simple Hibernate, MySQL, and JUnit Tutorial


Getting Started With Hibernate and MySQL

In this tutorial, we’re once again going to use JUnit as a learning tool for exploring various Java technologies — in this case Hibernate. We’ll be configuring Hibernate to run with MySQL in a way that works both in a standalone application or in a Spring or other web application. Along the way we’ll also be setting up Log4J logging for hibernate. We’ll work on a small generics class that — although it doesn’t really do much more than wrap a few Hibernate functions — will allow us to demonstrate and test out the basic CRUD operations — Create, Read, Update, and Delete.

As usual, you can download the complete project files for IntelliJ Idea from our Tutorials Repository on Github. This tutorial is located in the HibernateGeneric directory. If you’re using Eclipse, check out our Eclipse instructions.


Configuring MySQL

This tutorial assumes you have mysql installed and can log in as root. If you don’t have MySQL on your system, you should start here and work through the instructions appropriate to your environment. Go into the mysql monitor (i.e., the mysql command line client). To do this, run:

<PathToMySQLBin>\mysql.exe –user=root –password=YourRootPassword

(If you haven’t set a mysql root password, you should — if you haven’t, you can simply use the command:

<PathToMySQLBin>\mysql.exe –user=root

Once you’re connected in the mysql client, use the source command to run the dbsetup.sql script located in the database directory of the tutorial, for example:

source database\dbsetup.sql

CREATE DATABASE tutorials;
USE tutorials;
GRANT ALL ON tutorials.* TO 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
commit;
FLUSH privileges;

Of course, the user name and password given in this script are pretty brain-dead and certainly not secure so probably want to change them. If you do, that’s fine, you’ll just need to make one other change, in the hibernate configuration file. Let’s look at that next:


Configuring Hibernate

The hibernate configuration file is the file hibernate.cfg.xml in the root of the resources directory (i.e., at src/main/resources). As you can see, we’ve configured the JDBC driver directly in this file. If you changed the user name or password in the dbsetup.sql script, you need to make the corresponding chagnes to the “connection.username” and / or “connection.password” properties below.

You might also experiment with setting the show_sql and use_sql_comments to true, especially if you run into problems. For now they are turned off to keep the test run output a little bit cleaner.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/tutorials</property>
        <property name="connection.username">myuser</property>
        <property name="connection.password">mypassword</property>

        <!-- JDBC connection pool (use the built-in connection pool) -->
        <property name="connection.pool_size">1</property>

        <!--
            SQL dialect
            There are other mysql dialects avaialable IF you run INTO trouble WITH this one.
            The FULL list IS:
                MySQL5Dialect
                MySQL5InnoDBDialect
                MySQLDialect
                MySQLInnoDBDialect
                MySQLMyISAMDialect
            See http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/dialect/package-summary.html
        -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Change these values to true to echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
        <property name="use_sql_comments">false</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <!-- This is the entity class that we'll be testing. -->
        <mapping class="com.codesolid.tutorials.model.entities.Actor"/>

    </session-factory>
</hibernate-configuration>

I won’t post the log4j configuration here. Hibernate issues a warning if logging is not enabled, so I have configured Hibernate to use the log file, “log4j.log” in the root of the project directory. The configuration file for log4j is at src/main/resources/log4j.xml.


Minimizing Setup Time

As with any process that initially connects to a database, initializing Hibernate sessions takes a fair amount of time, and is not something you want to be doing over and over again in your tests. In the case of Hibernate, creating the SessionFactory object takes even more time, adding up to about 1.4 seconds on a laptop, or about .8 seconds on a faster machine. We don’t want to be running that for every test class. (To be sure, in the kind of one-class suite we’re running in this tutorial, it wouldn’t make a difference, but one of the purposes of these tutorials is to give you steal-able code that you can use in larger projects. What we want is to initialize the SessionFactory only once.

The Hibernate tutorial that comes with the Hibernate docs gives us a part of the solution, the HibernateUtil class, which exists for the sole purpose of ensuring a one time initialization of a SessionFactory, which it then caches as a static object. I’ve used this class pretty much verbatim in the current tutorial, changing only the package name.

// This file is adapted with only minor changes from the original in the hibernate
// tutorial, http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/tutorial.html.
package com.codesolid.tutorials.model.dal;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}

OK, so we have a class where we can cache our SessionFactory, but the question remains — how should we wire that up to our JUnit tests? Since JUnit 4.9, we can use the @ClassRule annotation to set up a test suite with before and after methods that will run before and after all the classes in the suite have run. This allows for the initialization of expensive resoures once before all the tests in the suite are run.

The following listing shows the RuleSuite test suite, which builds with the rest of the tests in the src\test\java\code\codesolid\tests directory:

package com.codesolid.tests;

import com.codesolid.tutorials.model.dal.HibernateUtil;
import org.apache.log4j.Level;
import org.apache.log4j.xml.Log4jEntityResolver;
import org.junit.ClassRule;
import org.junit.rules.ExternalResource;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.apache.log4j.Logger;

@RunWith( Suite.class )
@Suite.SuiteClasses( {
        TestStorage.class
        /* , Add more test classes here separated by commas*/
} )
public class RuleSuite{

    static HibernateUtil util;

    // This is a static field.  Per the ClassRule documentation,
    // to use a ClassRule we need a field that is "public, static,
    // and a subtype of of TestRule."
    // See http://junit.czweb.org/apidocs/org/junit/ClassRule.html
    @ClassRule
    public static ExternalResource testRule = new ExternalResource(){
        @Override
        protected void before() throws Throwable{
            Logger.getLogger("com.codesolid.tests").log(Level.DEBUG, "Inside RuleSuite::ExternalResource::before.");
            util = new HibernateUtil();
        };

        @Override
        protected void after(){
            // Nothing to do here in this case.
            Logger.getLogger("com.codesolid.tests").log(Level.DEBUG, "Inside RuleSuite::ExternalResource::after.");
        };
    };
}

I’ve added some logging methods so you can see that the before and after methods are run only once at the start and end of the suite.


A Simple Hibernate Entity

In order to have an entity to save, I created an “Actor” entity. This represents a user in the system, but I’ve named the class “Actor” to avoid any potential conflict with the SQL keyword by the same name. I am using Hibernate annotations to define the entity.

@Table allows us to name the table.
@Entity marks the class as representing a Hibernate Entity, that is to say, an object that Hibernate can save to and load from the database.

For the Id primary key field, we use the following Hibernate annotations to mark the field as the primary key and to auto-increment the field for each new record:

@Id
@GeneratedValue(generator=”increment”)
@GenericGenerator(name=”increment”, strategy = “increment”)

Finally, we used the column annotation to explicitly set the field name for the Role property to “user_role”:

@Column(name=”user_role”)

/**
 * Class Actor
 * Description:  A user of the system, the subject of a user story.  We use
 *               actor instead of user as table name to avoid any conflict
 *               with the database concept of user
 */

package com.codesolid.tutorials.model.entities;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;

@Table( name = "ACTORS" )
@Entity
public class Actor {
    public static final String DEFAULT_ROLE = "Standard User";

    public Actor() {
        setRole(Actor.DEFAULT_ROLE);
    }

    private Long id;
    private String role;

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    @Column(name="user_role")
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}

The final step to making the Entity work is one that’s easy to forget, but as we saw when we discussed the hibernate.cfg.xml file, make sure you include a mapping to the entity class, as we show again below:

<!-- This is the entity class that we'll be testing. -->
<mapping class="com.codesolid.tutorials.model.entities.Actor"/>


A Hibernate Generic Entity Storage Class

While working with Hibernate enitities, it struck me that many of the basic operations one might do with an entity could be captured well in a generic class, which is what we’ll be using to test here. As you can see below, each of the methods was pretty much a wrapper around a single Hibernate session call — with the exception of BeginTransaction, which combines getting the session from the session factory and starting the transaction.

package com.codesolid.tutorials.model.dal;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Storage <T > {

    public static SessionFactory getSessionFactory() {
        return HibernateUtil.getSessionFactory();
    }

    private T entity;
    private Session session;

    public void beginTransaction() {
        session = Storage.getSessionFactory().getCurrentSession();
        session.beginTransaction();
    }

    public void commit () {
        session.getTransaction().commit();
    }

    public Storage(T entity) {
        this.entity = entity;
    }

    public void update(T entity) {
        session.update(entity);
    }

    public Long insert(T entity) {
        return (Long) session.save(entity);
    }

    public void delete(T entity) {
        session.delete(entity);
    }

    // This call will issue a warning about the unchecked cast,
    // but we know the value returned will be of the right type because
    // we specify the entity (T) class in the call.
    //
    // Note that "get" will return a null if no value with this id fails
    @SuppressWarnings (value="unchecked")
    public T getById(Long id) {
        return (T) session.get(entity.getClass(), id);        
    }
}

Taken together, this class and the unit tests I wrote for it were a good way to discover a couple of interesting Hibernate gotchas. The first Hibernate mine that I steped on was that objects are no longer usable outside the context of a transaction. Before my testing uncovered this, my original implementation of getById was called loadById, and the implementation and test looked something like this:

  // Implementation  
    public T getById(Long id) {
        storage.beginTransaction();
        T obj = (T) session.load(entity.getClass(), id);
        session.getTransaction().commit();
        return obj;
    }

   // Test code:
   // ...
   Actor actor  = storage.getById(id);
   assertEquals(actor.getRole(), "Some Role");

This seemed like a safe approach (albeit not an efficient one since each call is wrapped in a transaction). As it turns out, because Hibernate uses lazy initialization, the object returned from getById needed to still have the transaction active. As a result, I got the following exception:

org.hibernate.LazyInitializationException: could not initialize proxy – no Session

This caused me to push the transaction management out to the client, so I exposed beginTransaction and commit methods on my storage class.

At that point, the code and test looked like:

// Implmentation
public T getById(Long id) {
    return (T) session.load(entity.getClass(), id);
}

// Test code
storage.beginTransaction();
Actor actor  = storage.getById(id);
assertEquals(actor.getRole(), "Some Role");
storage.commit();

The second interesting Hibernate quirk that I ran into was in trying to test my delete method. Originally I wrote the test by deleting an object and then checking for the ObjectNotFoundException when I called loadById in an effort to reload the deleted object. The first time I ran it, that test passed, but a few minutes later it failed. It turns out that loadById may or may not return an ObjectNotFoundException, or it may instead return a “proxy object”, though I admit I have a bit of a hard time following the architectural genius behind the decision to return a proxy to an object that doesn’t exist yet — or in this case, doesn’t exist any more. At that time I researched it and found that getById has the more reasonable behavior of reliably returning a for objects that don’t exist, so the test and the code evolved accordingly.


The JUnit Test


With that, the final form of the JUnit test is below. Even though I’m showing it last, in reality the process was more test-first, going back and forth between the tests, the configuration, and the classes under development.

package com.codesolid.tests;

import com.codesolid.tutorials.model.entities.*;
import com.codesolid.tutorials.model.dal.Storage;
import org.junit.Test;
import static org.junit.Assert.*;

public class TestStorage {

    @Test
    public void testWrite() {
        // Just a write, verify id set
        Actor user = new Actor();
        Storage<Actor> storage = new Storage<Actor>(user);
        storage.beginTransaction();
        user.setRole("SuperUser");
        assertNull(user.getId());
        storage.insert(user);
        assertNotNull(user.getId());
        storage.commit();
    }

    @Test
    public void testWriteAndRead() {

        // This time write and read back
        String overRideRole = "SuperUser";

        // Write
        Actor actor = new Actor();
        Storage<Actor> storage = new Storage<Actor>(actor);
        storage.beginTransaction();
        actor.setRole(overRideRole);
        assertNull(actor.getId());
        storage.insert(actor);
        assertNotNull(actor.getId());
        Long id = actor.getId();
        storage.commit();

        // Read and verify
        Actor actor2  = new Actor();
        assertEquals(actor2.getRole(), Actor.DEFAULT_ROLE);
        storage = new Storage<Actor>(actor2);
        storage.beginTransaction();
        actor2 = storage.getById(id);
        assertEquals(actor2.getRole(), overRideRole);
        storage.commit();
    }


    @Test
    public void testUpdate() {

        String overRideRole = "SuperUser";
        String newOverrideRole = "GUEST";

        // Insert an actor
        Actor actor = new Actor();
        Storage<Actor> storage = new Storage<Actor>(actor);
        storage.beginTransaction();
        actor.setRole(overRideRole);
        assertNull(actor.getId());
        storage.insert(actor);
        assertNotNull(actor.getId());
        Long id = actor.getId();
        storage.commit();

        // Read it back
        Actor actor2  = new Actor();
        assertEquals(actor2.getRole(), Actor.DEFAULT_ROLE);
        storage.beginTransaction();
        actor2 = storage.getById(id);
        assertEquals(actor2.getRole(), overRideRole);

        // Update it
        actor2.setRole(newOverrideRole);
        storage.update(actor2);
        storage.commit();

        // Read it again and verify update
        storage.beginTransaction();
        Actor actor3  = storage.getById(id);
        assertEquals(actor3.getRole(), newOverrideRole);
        storage.commit();
    }

    @Test
    public void testDelete() {

        Actor actor = new Actor();
        Storage<Actor> storage = new Storage<Actor>(actor);

        // Write
        storage.beginTransaction();
        storage.insert(actor);
        Long id = actor.getId();
        storage.commit();

        // Delete it now
        assert(actor.getId() > 0);
        storage.beginTransaction();
        storage.delete(actor);
        storage.commit();

        // Now we can't read it back, as expected
        storage.beginTransaction();
        Actor actor2 = storage.getById(id);
        assertNull(actor2);
        storage.commit();
    }
}
Tagged with: , , , , ,
Posted in Testing, JUnit, TestNG Tutorials, Tutorials

How to Run the CodeSolid Tutorials in Eclipse

If you’ve taken a look at the Github Repository for the CodeSolid tutorials, you may have noticed that the project files all use IntelliJ Idea.  I use the Ultimate Edition (currently Version 12) for most of my development, but recently I promised to look into using these project files in Eclipse.  I had a feeling it would work since I have sourced the Maven project — i.e., the POM files, those named pom.xml in the root of each tutorial — but being the good test infected developer that I am, I try not to take “that should work” for granted.

Well, the good news in this case is that not only should it work, but it actually does.  I have tested it out on the Spring Tool Suite version 3.2, as well as on a more vanilla version of Eclipse (Indigo — version 3.7).  Because we’re importing Maven files, Maven is resolving the dependencies — meaning the Spring Tutorial works even without the Spring Tool Suite.  (How cool is that — it’s magic!)  To run the projects, start by right clicking on any empty space in the Package Explorer window, as shown below.


EclipseImport

 

From the menu, select Import.  In the Import dialog box, you want to select Maven, then Existing Maven Project, as shown below:

EclipseImport2

If you then navigate to the root of the tutorials directory, you can select which tutorials you want to import.  I’m writing this article when there are only two tutorials available — you’ll likely see more projects available.  Select the project(s) you want, click finish, and you’re done!  You can now run the tutorials in Eclipse.  Enjoy!

EclipseImport3

Tagged with: , , , , ,
Posted in Tutorials