Archive for the ‘Tutorial’ Category

Articles

Hadoop – HDFS – Extra

In Hadoop,Tutorial on 25/02/2012 by pier0w

This extra hadoop setup is for those of you who are a little bit more adventurous. It requires some very small edits to the hadoop startup scripts, so if you would rather just run a vanilla hadoop install then don’t bother reading the rest of this extra tutorial.

The goal of this tutorial is to have hadoop running in what some would consider a slightly cleaner way. That is it will run without having to rely on ssh.

To do this first run through the previous hadoop hdfs tutorial, but leave out anything to do with ssh and also don’t edit the conf/hadoop-env.sh. Having the JAVA_HOME variable set in the conf/hadoop-env.sh file is only required when hadoop executes remote commands through ssh.

The only part our of hadoop cluster that requires ssh by default is the Namenode, so we will be editing the files on this server only.

Now since we have not set the JAVA_HOME variable in the conf/hadoop-env.sh file it will need to be set as a global environment variable for the server. On Ubuntu server this can be done by exporting the environment variables in a Java specific scrip in the /etc/profile.d/ directory.


#> sudo vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export JDK_HOME=/usr/lib/jvm/java-6-openjdk
~
~

Once that is setup the first hadoop file to edit is bin/hadoop-daemon.sh, this script uses rsync to make sure that the hadoop files are on the server it is about to start. The reason it does this is so that you can have a central server that can start up multiple Namenodes on remote servers that don’t actually have to have hadoop installed on them.

We are going to edit line 119 in this file and remove the text -e ssh which forces rsync to run through ssh.


#> vim /opt/hadoop/bin/hadoop-daemon.sh
...
    if [ "$HADOOP_MASTER" != "" ]; then
      echo rsync from $HADOOP_MASTER
      rsync -a --delete --exclude=.svn --exclude='logs/*' --exclude='contrib/hod/logs/*' $HADOOP_MASTER/ "$HADOOP_HOME"
    fi
...

Next we are going to edit the bin/start-dfs.sh and bin/stop-dfs.sh scripts and make it so that the Secondary Namenode is started up in the same way as the primary Namenode.


#> vim /opt/hadoop/bin/start-dfs.sh
...
# start dfs daemons
# start namenode after datanodes, to minimize time namenode is up w/o data
# note: datanodes will log connection errors until namenode starts
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode $nameStartOpt
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start secondarynamenode
~
~


#> vim /opt/hadoop/bin/stop-dfs.sh
...
. "$bin"/hadoop-config.sh

"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR stop namenode
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR stop datanode
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR stop secondarynamenode
~
~

Lastly we will remove any domain names from the conf/slaves file, even localhost. This stops hadoop from trying to start a Datanode up on the Namenode server.


#> vim /opt/hadoop/conf/slaves
~
~

And that’s it, you should now be able to start a Namenode on the server without having to have any special ssh setup.

Advertisements

Articles

Hadoop – HDFS

In Hadoop,Tutorial on 23/02/2012 by pier0w

So you want to have a go at playing with hadoop, but are a little apprehensive because it just looks so complicated and hard to setup. Well DON’T BE! It’s super easy and I’ll show this by first demonstrating below the simple setup for a fully working HDFS cluster.

To get started lets first explain the HDFS structure. It’s a very simple master slave architecture. There is a master, the Namenode, that manages all the slaves, the Datanodes. See the super duper diagram bellow:


            Namenode
       ________|_______
      |                |
Datanode One     Datanode Two

The Namenode manages the distribution of the data within HDFS and the Databodes just store the data. That is HDFS put very very simply. As you can see it doesn’t provide the best redundancy because of the single point of failure. Though, there is a Secondary Namenode that can be used in a time of emergency, but the way to do that is WAY out of the scope of this tutorial. HDFS may not have the most resilient architecture, but it is at least easy to understand.

So how does one set one’s self up the HDFS? Well very easily actually…

Step One: Create a Namenode
To do this get your self a server, an Ubuntu Server VM will do nicely. Make sure the VM is running within a host only network so that it can talk to your host machine and the Datanode VM’s.

When using unix it is always best practice to create a user for the task at hand so lets create a hadoop user and use that from now on. Super users are dangeresque.


#> sudo useradd -m -G users -s /bin/bash hadoop
#> sudo passwd hadoop
# Set the password to what every you like.
#> su - hadoop

Now make sure that the server is running an ssh server. A good way to do this is to login to local host.


#> ssh localhost

If that doesn’t succeed then install the ssh server.


#> sudo apt-get install openssh-server

Now hadoop uses ssh to run it’s commands even when they are on the local machine, because of this you have to make sure that you can automatically ssh into localhost without the need for a password. To do this create an ssh key and add it to you .ssh/authorized_keys2 file.


#> ssh-keygen
# Just press ENTER for all the input request.
#> cat .ssh/id_rsa.pub >> .ssh/authorized_keys2

That’s it, you should now be able to ssh to localhost without having to type in your password.

The next thing to do is make sure your server has a static ip address. So set the IP of the host only network interface to be a static IP within the host only network.


#> sudo vim /etc/network/interfaces
...
# Host Only Network
auto eth0
iface eth0 inet static
        address 192.168.69.201
        netmask 255.255.255.0
        network 192.168.69.0
        broadcast 192.168.69.255
~
~

#> sudo /etc/init.d/networking restart
#> ifconfig
eth0      Link encap:Ethernet HWaddr 00:00:00:00:00:00
          inet addr:192.168.69.201 Bcast:192.168.69.255 Mask:255.255.255.0
...

Lastly hadoop is written in Java so this will need to be installed on the server. It seems that it is only possible now to install the OpenJDK on Ubuntu but this is ok because hadoop runs fine on that JVM.


#> sudo apt-get install openjdk-6-jdk

Now that the server is all ready extract the hadoop tarball somewhere onto the filesystem. /opt/ is as good a place as any. Then do all the configuration that is required for a working Namenode. That is, edit two files.

First edit the conf/core-site.xml file and set the fs.default.name property to be the ip address that you gave the server with a port of your choosing. 9000 seems to be a good default. You’d think that you’d be able to just set the fs.default.name property to be localhost, but unfortunately this does not work. I’m guessing it is because the server will only accept requests for the provided URI and nothing but the local machine can carry out a request to localhost.


#> vim /opt/hadoop/conf/core-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
        <property>
                <name>fs.default.name</name>
                <value>hdfs://192.168.69.201:9000</value>
        </property>
</configuration>
~
~

Then lastly edit the conf/hadoop-env.sh file and uncomment and set the JAVA_HOME variable to the directory that contains the JDK files. On Ubuntu Server this is the /usr/lib/jvm/java-6-openjdk/ directory.


#> vim /opt/hadoop/conf/hadoop-env.sh
...
# The only required environment variable is JAVA_HOME. All others are
# optional. When running a distributed configuration it is best to
# set JAVA_HOME in this file, so that it is correctly defined on
# remote nodes.

# The java implementation to use. Required.
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk

# Extra Java CLASSPATH elements. Optional.
# export HADOOP_CLASSPATH=
...

And that’s it, you can now start a perfectly running Namenode.


#> /opt/hadoop/bin/hadoop namenode -format # The Namenode must be formatted before it can start up.
#> /opt/hadoop/bin/start-dfs.sh

To check that it is running, browse to the Namenodes ip address on port 50070 e.g. http://192.168.69.201:50070
This will take you to the Namenodes monitoring page.

Step Two: Create a Datanode

The preliminary setup of a Datanode VM is very simple, you just have create the hadoop user and switch into it. Leave the Host only network interface as DHCP, the Datanodes do not require static ip addresses, also below you will see why it is actually really good if their ip addresses are allocated dynamically.

Now extract the same hadoop tarball that you used on the name node into the /opt/ directory on the Datanode. Now all you have to do is configure the Datanodes conf/core-site.xml file with the exact same configuration as the Namenode. By exact I mean character for character, to the point where if you wanted to you could just copy the Namenodes conf/core-site.xml file over the top of the newly extracted one on the Datanode. This now means that the Datanode is configured to be aware of the Namenode.

So I know what you’re now thinking “Hold on a minute there. How does the Datanode know to act as a slave if it has the exact same configuration as the Namenode?”. Well it does because we start it in a completely different way to the Namenode. Where the name node is started with the bin/start-dfs.sh script we are going to start the Datanode with the bin/hadoop-daemon.sh. As follows:


#> /opt/hadoop/bin/hadoop-daemon.sh --config /opt/hadoop/conf start datanode

That’s it your new Datanode should now be up and running. You can confirm this by refreshing the Namenodes monitoring page and you should now see that the Live Nodes number has increased from 0 to 1.

Note: The Datanode could take a little while to register to the name node, you can check on it’s progress in the logs/hadoop-hadoop-datanode-*.log file.

So as you can see all and all setting up hadoop is a very easy process. You can now add extra Datanodes to you hearts content by simply cloning and your first Datanode and starting it up. Since you have left the Host only network interface as DHCP each Datanode will automatically have it’s own unique ip address.

You may also notice if you have read the hadoop documentation that I don’t mention anything about the conf/slaves file. This is because I think that a hadoop cluster should be configured in an extendible way from the beginning so I have shown you how to start a Datanode so that it registers itself with an existing hadoop cluster. Instead of listing the Datanodes within the Namenodes conf/slaves file and having the Namenode start the Datanodes for you.

Articles

Spring Tutorial Two (Spring MCV)

In Tutorial on 13/02/2011 by pier0w

This next Spring tutorial is going to look at Spring MVC. This is Springs implementation of the Model View Controller architecture, with it you can configure your Model layer, configure the View template you wish to use, and create very simple and concise Controllers.

Now just like all Java web application frameworks Spring MVC must be wrapped up within a WAR file and run from within a Java web container. A web container can just be thought of as an environment that provides all the required boilerplate to allow the easy creation of web applications. It will automatically handle the creation of a thread pool to handle any requests, create sessions so that you can keep state across a users time on your web app, and lots of other great stuff.

There are quite a lot of Java web containers out there, there is Tomcat, Jetty, Glassfish, and JBoss just to name a few.

The one we are going to use is Jetty, this is a Java web app container that can be embedded within an application. It is not the only one of course, Tomcat can also be embedded, but Jetty was specifically created for this purpose.

This tutorial is going to build on the previous Spring tutorial, so open that within Intellij IDEA.

Since we are working with the project from the first tutorial lets make a tag to preserve the code in it’s current state. To do this navigate to the projects directory and type the following command.

#> git tag -a tutorial_one -m "A tag taken at the end of the first Spring tutorial."

You can check to make sure that tag was created with this command.

#> git tag -l -n1

The -l tells git to list the tags and the -n1 tells git to display one line of the tags message. You can use a higher number to display more lines.

The first thing we will do is add the Jetty maven dependency to our pom file, so open the file and add the dependency to the <dependencies> tag.

...
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.aggregate</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>7.1.4.v20100610</version>
        </dependency>
    </dependencies>
...

Now lets remove pretty much all of the code we wrote in the first tutorial because it won’t be of any use to us in this new tutorial. Delete the context file in the resources directory, the MyClassOne, MyClassTwo, and MyHolder classes, all the code from within the MainTest leaving the shell of the test method, the toStuff method from within the Main class as well as all the code within the main method. Once that is done commit the changes into git.

package org.project;

public class Main {

    public static void main(String[] args) {
    }
}
package org.project;

import org.junit.Test;

public class MainTest {

    @Test
    public void testDoStuff() throws Exception {
    }
}

If you wish to get the old code back you can just checkout the tag.

#> git checkout tutorial_one

Note that when you commit changes to the tag they will not actually be saved if you then move off the tag. To save your changes you will have to create a branch from the tag with the git branch method.

If you wish to then get back to the code we just committed then us this command.

#> git checkout master

Now that we are back looking at our new code lets see if we can’t start up a Jetty server in preparation for our Spring code. First create an instance of a Jetty Server class, start the server, then join the server to the main thread so that the main thread doesn’t just exit right after starting the server.

package org.project;

import org.eclipse.jetty.server.Server;

public class Main {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080); // Create a server instance that listens on port 8080.
        server.start(); // Start the server.
        server.join(); // Join the main thread to the server so that the main thread doesn't exit.
    }
}

Pro tip: Only copy the code from within the main method and past it into yours. Then use ALT-ENTER to get Intellij IDEA to import the jetty Server class for you. The start and join method calls will now be underlined in red so click within the code of one of them and in a moment a small red light build should show up off to the left. Click on it and select the Add Exception(s) to Method Signature option. This will make the main method throw the correct exception for the methods.

You can now run the main method and see the server start up. Though it is a rather useless application server because there is nothing running within it.

To get Jetty to run something he have to give it a Handler. It is possible to either create your own handler or use one of the pre-made handlers that Jetty provides. Since we are making a web application that will be running Spring MVC we will be using Jetty’s WebAppContext handler. To instantiate this handler you need to give it the path to where your web application configuration files will be and also the context of your web application. A context is simply some text that comes after the domain name of the web app where all of the web apps pages will fall under. So if a web app is found at the following URL.

http://localhost:8080/myapp/index.html

Then the context would be myapp and all the wep apps pages like index.html will be found under that context.

So lets instantiate a WebAppContext handler and give it the path webapp and the context / which means there actually will not be a context.

To get the proper path to the webapp directory we will need to get the resource URL and then get the external form from that. This is because we are running within the environment of a JAR file, so it is unfortunately not as simple as giving it the name of the directory.

We will also need to tell Jetty not to extract the web apps directory, this is again because we running the project from within a JAR environment.

package org.project;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;

import java.net.URL;

public class Main {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080); // Create a server instance that listens on port 8080.

        URL webAppURL = server.getClass().getClassLoader().getResource("webapp"); // Find the webapp dir from within the JAR.

        String webAppPath = webAppURL.toExternalForm(); // Then get it's actual path string.

        WebAppContext webAppContext = new WebAppContext(webAppPath, "/"); // The config dir will be in resources/webapp.
        webAppContext.setExtractWAR(false); // Make sure not to extract the web app directory because we will run this in a JAR file.

        server.setHandler(webAppContext); // Add the WebAppContext handler to the Jetty server.

        server.start(); // Start the server.
        server.join(); // Join the main thread to the server so that the main thread doesn't exit.
    }
}

You can now try and run the Jetty server again but as you might expect it will crash, this is because we haven’t created the webapp directory under the resources directory. Also we haven’t created the web.xml file that is required by the WebAppContext handler.

Lets do both of those things now, first create the webapp directory under the resources directory, then create another directory under that called WEB-INF, lastly under that directory create an empty file called web.xml. In the end you should have a path to the web.xml file as follows.

src/main/resources/webapp/WEB-INF/web.xml

Now past the following into the web.xml file.

<web-app id="WebApp_9" version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="   http://java.sun.com/xml/ns/javaee
                                http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>Spring Tutorial Two</display-name>
</web-app>

Now run the main method again and Jetty should start up happily.

It is also a good idea to add a thread pool to Jetty, this will make it run a lot more efficiently and faster. We will start up a queued thread pool with a minimum of 10 threads and a maximum of 50 threads.

package org.project;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;

import java.net.URL;

public class Main {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080); // Create a server instance that listens on port 8080.

        URL webAppURL = server.getClass().getClassLoader().getResource("webapp"); // Find the webapp dir from within the JAR.

        String webAppPath = webAppURL.toExternalForm(); // Then get it's actual path string.

        WebAppContext webAppContext = new WebAppContext(webAppPath, "/"); // The config dir will be in resources/webapp.
        webAppContext.setExtractWAR(false); // Make sure not to extract the web app directory because we will run this in a JAR file.

        server.setHandler(webAppContext); // Add the WebAppContext handler to the Jetty server.

        QueuedThreadPool threadPool = new QueuedThreadPool(); // Instantiate the thread pool.
        threadPool.setMinThreads(10); // Set the minimum threads to 10.
        threadPool.setMaxThreads(50); // Set the maximum threads to 50.

        server.setThreadPool(threadPool); // Add the thread pool to the Jetty server.

        server.start(); // Start the server.
        server.join(); // Join the main thread to the server so that the main thread doesn't exit.
    }
}

Right, so now the programmatical configuration of the Jetty server is complete. All the rest of our configuration will be done within the web.xml file.

The web.xml is where we will configure our Spring context. Remember in the first tutorial we started the Spring context within the main method. This time by configuring the Spring context object within the web.xml file we will get the web app container to start it.

Now to return a successful response to an HTTP request a Java Web Application Container needs to contain a Servlet. Servlets are J2EE classes that contain all the logic to handle request for a given URL pattern. That is all you will ever need to know about them because no one ever manually programs Servlets any more and all we will be doing is configuring the Spring context so that it behaves like a Servlet.

So as always when starting a Spring project the first thing we need to do is create a XML context configuration file and place it in the resources directory.

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
</beans>

Now that we have the context file we need to configure the Spring context class. We will use is the Spring DispatcherServlet class which configures the Spring context and wraps it in a J2EE Servlet. We will need to add the Spring MVC dependency to the pom file so that we have access the DispatcherServlet class and all the other classes within the Spring MVC module.

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.aggregate</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>7.1.4.v20100610</version>
        </dependency>
    </dependencies>

To correctly configure this class we need to give it a name, the full name of the DispatcherServlet class, the path to the context file, and lastly the order in which it should be started. For our project we will want it to be the very first thing the web container starts.

<web-app id="WebApp_9" version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="   http://java.sun.com/xml/ns/javaee
                                http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>Spring Tutorial Two</display-name>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:context.xml</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

We can now run the main method again and we should see the Jetty server start as well as the Spring framework.

It is now possible to start actually writing some code for a very simple Spring MVC web app. The first place to start is the Model or the M in MVC. The model is the data layer of the application, we shall make our model exceptionally simple, it will just be a class that contains some data. So lets create a Model class.

package org.project.model;

import java.util.Date;
import java.util.List;

public class Model {

    private String name;
    private Date date;
    private List data;
    private String message;

    public Model() {
    }

    public Model(String name, Date date, List data, String message) {
        this.name = name;
        this.date = date;
        this.data = data;
        this.message = message;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List getData() {
        return data;
    }

    public void setData(List data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

And now lets wire it up within the Spring context file.

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">

    <bean id="model" class="org.project.model.Model">
        <property name="name" value="Model"/>
        <property name="date">
            <bean class="java.util.Date"/>
        </property>
        <property name="data">
            <list>
                <bean class="java.lang.Integer"><constructor-arg value="1"/></bean>
                <bean class="java.lang.Integer"><constructor-arg value="2"/></bean>
                <bean class="java.lang.Integer"><constructor-arg value="3"/></bean>
                <bean class="java.lang.Integer"><constructor-arg value="4"/></bean>
            </list>
        </property>
        <property name="message" value="Message from the model."/>
    </bean>
</beans>

Now that we have a model lets configure our view, the V in MVC. The view is the framework that we will use to present the data from our model to the user, this is generally done with HTML. We will use Freemarker as our view, so lets first add it’s dependency to our pom file.

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty.aggregate</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>7.1.4.v20100610</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.16</version>
        </dependency>
    </dependencies>

Now that we have access to the Freemarker classes we can configure it in the Spring context file. There are two classes that need to be configured, the first is the FreeMarkerConfigurer class, here we set the path to the Freemarker files. The next class is the FreeMarkerViewResolver which is the class that will actually parse the Freemarker files. We will configure this so that it doesn’t cache the pages, so that it knows what files are our Freemarker files, enable the Spring extensions, and lastly set the Freemarker resolver to always be the first resolver that is picked by Spring when it tries to resolve a view.

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">

    <bean id="model" class="org.project.model.Model">
        <property name="name" value="Model"/>
        <property name="date">
            <bean class="java.util.Date"/>
        </property>
        <property name="data">
            <list>
                <bean class="java.lang.Integer">
                    <constructor-arg value="1"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="2"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="3"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="4"/>
                </bean>
            </list>
        </property>
        <property name="message" value="Message from the model."/>
    </bean>

    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/pages/"/>
    </bean>

    <bean id="freemarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="false"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".ftl"/>
        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="order" value="0"/>
    </bean>

</beans>

Now that our view framework is configured we can create a simple view page. This page will display the name and message properties of the model class. This class will be passed to the view by the controller which we will write next. To created the page first create the pages directory under the WEB-INF directory. This is where we said the Freemarker files would be when we configured the FreeMarkerConfigurer above. Then create a file called view.ftl and passed the following HTML into it.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Spring Tutorial Two</title>
</head>
<body>
    <h1>${model.name}</h1>
    <p>${model.message}</p>
</body>
</html>

The ${model.name} and ${model.message} within the page are the very small snippets of Freemarker that we are going to use in this tutorial. It is this syntax that is used to access a domain class and it’s properties. A domain class is a class that has been placed into the domain of a view by the controller. We will see how this is done soon.

Now that the view file is created we can move onto the controller, the C in MVC. A controller is a class to simply take data classes from the model and sends them into the view. This is usually done by the controller calling on a service layer that abstracts away any logic and decouples the Controllers and Views from the Model layer, but for simplicities sake we are just going to pass the Model class straight into the controller.

The annotations we are going to use are:
@Controller – This is used to annotate a class to mark it as a Spring Controller.
@RequestMapping – This is used to annotate a class or method to map them to a specific request URL pattern. When the annotation is used on a class it is usually used to map a common context that all the methods in that class will then fall under. Though it is also possible to map a class to a URL pattern then just have a method that handles all the GET request for that class. Other wise methods can have their own unique request URL patterns mapped to them.
@Resource – This annotation is another way of telling Spring to inject a class, the difference between this and @Autowired is that with this annotation you can specify the name of the bean you would like to inject.

So after those explanations here is the controller.

package org.project.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.project.model.Model;

import javax.annotation.Resource;

@Controller
@RequestMapping(value = "/model")
public class ModelController {

    @Resource(name = "model")
    private Model model;

    @RequestMapping(value = "/view")
    public String view(ModelMap modelMap) {

        modelMap.addAttribute("model", model);

        return "view";
    }
}

For this controller we have used the combination of providing a request mapping for the class and the method. This means that Spring with route all request that begin with /model to the ModelController class, then it will finally route the complete pattern /model/view to the view method within that class.

We have given the method a ModelMap argument. Any ModelMap argument that you give to a request method will automatically be injected by Spring with the responses ModelMap. The ModelMap is a map that is forwarded by Spring to the view. So any classes you place into this map will become domain classes in the view. That is why we are placing the Model object into this map. It can get a bit confusing that the word Model is used by Spring to label classes that will be passed to the view, since this is also the name for the data layer of an application that uses the MVC pattern. This is also Spring MVC we are talking about so you would have thought they might have seen how that could be confusing, but oh well…

The last thing to explain about this controller is that the request method is returning a static String "view". If Spring sees that your request method returns a String it will assume that that String will be that name of a view file that it should use to render the response. It is possible to have your request methods return far more complicated things but that is outside the scope of this tutorial. So with that in mind you can see that Spring will select out view.ftl file to render the response.

Now the very last thing we have to do is to tell Spring were our controller is. This is done in the same way that we told it how to find the HyHolder class at the end of the last tutorial.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="model" class="org.project.model.Model">
        <property name="name" value="Model"/>
        <property name="date">
            <bean class="java.util.Date"/>
        </property>
        <property name="data">
            <list>
                <bean class="java.lang.Integer">
                    <constructor-arg value="1"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="2"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="3"/>
                </bean>
                <bean class="java.lang.Integer">
                    <constructor-arg value="4"/>
                </bean>
            </list>
        </property>
        <property name="message" value="Message from the model."/>
    </bean>

    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/pages/"/>
    </bean>

    <bean id="freemarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="false"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".ftl"/>
        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="order" value="0"/>
    </bean>

    <context:component-scan base-package="org.project.controllers"/>
</beans>

With that complete we can finally run our web application and the simple view we created should be able to be seen at the following URL displaying the data that we configured in the model.

http://localhost:8080/model/view

Articles

Maven New Project Tutorial

In Maven,Tutorial on 12/02/2011 by pier0w

Maven is a Java build tool that not only compiles your project and automatically runs all it’s tests it also provides a really good directory structure and handles the retrieval of any JAR dependencies your project might have. Also as you might have guessed it builds your project in a way that it is then able to be used as a maven dependency it’s self.

This tutorial is only going to describe the very basic process of creating a new maven project. So lets begin.

Creating a maven project is as simple as running the following command.

#> mvn archetype:generate
...
365: remote -> wicket-scala-archetype (-)
366: remote -> wikbook.archetype (-)
367: remote -> circumflex-archetype (-)
368: remote -> javg-minimal-archetype (-)
Choose a number: 99:

Pro tip: If you get an error like the following saying that maven can’t find the archetype plugin this means that your repository is set to download a version of the plugin that is too new for the repository that you are using.
[INFO] Unable to find resource 'org.apache.maven.plugins:maven-archetype-plugin:maven-plugin:2.0-alpha-6' in repository central (http://repo1.maven.org/maven2)

To fix this you will need to open up the .m2/repository/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata-central.xml file and edit the <latest> and <release> tags. Place the value of one of the <version> tags within them that is a couple version down from the what is in there. It’s also a good idea to just stay away from alpha versions so maybe take the highest version that isn’t alpha. Your maven-metadata-central.xml file will then look as follows.

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-archetype-plugin</artifactId>
  <versioning>
    <latest>2.0</latest>
    <release>2.0</release>
    <versions>
      <version>1.0-alpha-3</version>
      <version>1.0-alpha-4</version>
      <version>1.0-alpha-7</version>
      <version>2.0-alpha-1</version>
      <version>2.0-alpha-2</version>
      <version>2.0-alpha-3</version>
      <version>2.0-alpha-4</version>
      <version>2.0-alpha-5</version>
      <version>2.0</version>
    </versions>
    <lastUpdated>20101028011818</lastUpdated>
  </versioning>
</metadata>

This technique can also be used to fix any other plugins that might not download.

The mvn archetype:generate command will kick off a process to allow you to easily generate a maven project. You’ll be displayed with a list of around 300 – 400 custom maven projects that provide you with good starting points for different situations and frameworks, read through them, you might find a good starting point for your project, otherwise just select the default option (99: remote -> maven-archetype-quickstart) by pressing ENTER.

367: remote -> circumflex-archetype (-)
368: remote -> javg-minimal-archetype (-)
Choose a number: 99: 
Choose version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6:

Next you will be asked which version of the template you would like to use, select the latest by pressing ENTER again.

Now you need to select how you want to name your project by giving the group id (namespace), artifactId (name), version, and package name (generally but not always the same as your given groupId) of your project. Fill these in with what ever you feel is apropriate.

5: 1.0
6: 1.1
Choose a number: 6: 
Define value for property 'groupId': : org.project 
Define value for property 'artifactId': : project
Define value for property 'version': 1.0-SNAPSHOT: 1.0
Define value for property 'package': org.project: #Press ENTER to select the groupId as the package name by default
Confirm properties configuration:
groupId: org.project
artifactId: project
version: 1.0
package: org.project
Y: #Press ENTER to confirm

You will now have a brand new maven project.

#> ls -R project/
project/:
pom.xml  src

project/src:
main  test

project/src/main:
java

project/src/main/java:
org

project/src/main/java/org:
project

project/src/main/java/org/project:
App.java

project/src/test:
java

project/src/test/java:
org

project/src/test/java/org:
project

project/src/test/java/org/project:
AppTest.java

That is it you can now begin developing within the maven project. To build and run tests use the following command.
#> mvn clean install

If the build command finishes successfully maven will place a copy of the JAR file it has built from your project into your local maven repository (the place where maven keeps all of your dependencies). This means that any classes from your project will be accessible from any other local maven projects as long as you add your project as a dependency. Your should remember though that your local build JAR’s only ever get updated after a successful run of mvn install so if you make a change in one project and want it to be seen by your other projects you will have to run a build.

Articles

Spring Tutorial One (Old)

In Spring,Tutorial on 06/02/2011 by pier0w

Right so… what is Spring? Well the Spring About page has a good description of what it does but not how it does it or how you can does stuff with it. My self, I see Spring as a container that initialises and sticks all your classes together. This is handy because it means you don’t have to bother writing factory classes or singletons because Spring will start up a single instance of each class then propagate those single instances throughout any classes that require them. So you could almost think of Spring as duct tape for Java.

Springs main goal is to provide a paradigm called Inversion of Control or IoC. The wikipedia explanation is ok but it doesn’t really give you any idea about how this relates to Spring. Springs version of IoC can be easily summed up with the term Dependency Injection. Now coming from a unix background and being quite used to the dependency resolution of package managers, when I first heard that term I instantly thought Spring must be dynamically pulling down all the dependant libraries you have used and injecting them into your class path and maybe even dynamically adding the imports at compile time. This is of course not the case at all, but oddly is pretty much exactly what Maven does except for adding the imports, that’s what your IDE is for. Springs dependency injection refers to the dynamic injection of a classes properties during the start up of an application.

So say we have the following classes:

public class MyClassOne {

        private Integer one;

        // All classes that are to be used within Spring MUST have a default constructor.
        // This is so that Spring can instantiate the class before injecting the properties.
        public MyClassOne () {
        }

        public MyClassOne (Integer one) {
                this.one = one;
        }

        public Integer getOne() {
                return one;
        }

        public void setOne(Integer one) {
                this.one = one;
        }
}
public class MyClassTwo {

        private Integer two;

        // All classes that are to be used within Spring MUST have a default constructor.
        // This is so that Spring can instantiate the class before injecting the properties.
        public MyClassTwo () {
        }

        public MyClassTwo (Integer two) {
                this.two = two;
        }

        public Integer getTwo() {
                return two;
        }

        public void setTwo(Integer two) {
                this.two = two;
        }
}
public class MyHolder {

        private MyClassOne one;
        private MyClassTwo two;

        // All classes that are to be used within Spring MUST have a default constructor.
        // This is so that Spring can instantiate the class before injecting the properties.
        public MyHolder() {
        }

        public MyHolder(MyClassOne one, MyClassTwo two) {
                this.one = one;
                this.two = two;
        }

        public MyClassOne getMyClassOne() {
                return one;
        }

        public void setMyClassOne(MyClassOne one) {
                this.one = one;
        }

        public MyClassTwo getMyClassTwo() {
                return two;
        }

        public void setMyClassTwo(MyClassTwo two) {
                this.two = two;
        }

}

Spring would handle these classes by first instantiate MyClassOne and then MyClassTwo, Spring might even set an Integer value for both classes. The two new instances would then be used to create an instance of MyHolder, this would be done by injecting the instance of MyClassOne into the property named one and then injecting the instance of MyClassTwo into the property named two.

For my example I have only used concrete classes, it should also be noted that it is of course possible for Spring to inject a property with any object that can be cast into the properties type. So a property could just have the type of an interface which is great because your code then becomes a lot more generic since you don’t ever have to care about the implementation of your properties, you can let Spring decide on the best implementation for you.

Spring can do the injection in three different ways. First it can be told to instantiate the MyHolder class using the constructor that contains the arguments one and two and place the new MyClassOne and MyClassTwo instances in the correct slots. If this method is used the MyHolder class would not require a default constructor.
Secondly Spring could instantiate an empty MyHolder class then use the setter and getter methods to populate the one and two properties.
Lastly through the use of annotations Spring could then use reflection to directly access and set the values for the one and two properties.

If the last method is used it is actually possible to create classes that look like they would be impossible to use. For example it would be quite valid for the MyHolder classes code to be as follows:

public class MyHolder {

        @Autowired // Spring annotation that will be explained later.
        private MyClassOne one;

        @Autowired
        private MyClassTwo two;
}

It now looks like there is no way to set the properties in the MyHolder class but Spring can do this quite happily. It also looks rather clean and wizz bang nifty. Personally I don’t like using Spring like this because it tightly couples your cope to the Spring framework which I guess in reality is fine because you’ll rewrite your application before you’ll actually ever move away from Spring. But I personally think it is bad practice, if you wish to use Spring in this way I would still make sure to add all the getters and setters at the very least. I my self also add the property constructor as well.

So that is what the very basic core of Spring does, though there are now quite a lot of extra modules that make up the core Spring echo system that provide far more functionality including, web interface security, data validation, data base transacting and even more.

For this initial tutorial we will only be looking at the different types of dependency injection and how to start the Spring container outside of a J2EE container, which is the most common place to use Spring. The next tutorial will look at how to use Spring with the J2EE containers Tomcat and Jetty.

Before starting this tutorial we need to make sure we have all the right equipment.

First the build tool we will be using is Maven, so make sure to have this installed and that you are connected to the internet. Though odds are if you are reading this you should have the second half of that done. Installing maven is very simple so I won’t be discussing how to do it here. We will just be using the default maven config so no extra configuration is required.

Secondly the SCM we will be using is git. Again this just has to be installed and working, there is no need for any extra configuration, we won’t even be using a remote repository so that doesn’t even have to be set up.

Lastly the IDE I will be using for these examples will be Intellij IDEA. I am going to use the free Community Edition.

Once your environment is set up we can begin.

First generate your self a maven project by running the following command.

#> mvn archetype:generate
...
365: remote -> wicket-scala-archetype (-)
366: remote -> wikbook.archetype (-)
367: remote -> circumflex-archetype (-)
368: remote -> javg-minimal-archetype (-)
Choose a number: 99:

This will kick off a process to allow you to easily generate a maven project. You’ll be displayed with a list of around 300 – 400 custom maven projects that provide you with good starting points for different situations and frameworks, if there was a nice independent Spring template I would tell you to use it now, but as of writing this there isn’t one so just choose the default option (99: remote -> maven-archetype-quickstart) by pressing ENTER.

367: remote -> circumflex-archetype (-)
368: remote -> javg-minimal-archetype (-)
Choose a number: 99: 
Choose version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6:

Next you will be asked which version of the template you would like to use, select the latest by pressing ENTER again.

Now you need to select how you want to name your project by giving the group id (namespace), artifactId (name), version, and package name (generally but not always the same as your given groupId) of your project. Fill these in with the same values as I have shown below.

5: 1.0
6: 1.1
Choose a number: 6: 
Define value for property 'groupId': : uk.co.bbc.spring 
Define value for property 'artifactId': : spring
Define value for property 'version': 1.0-SNAPSHOT: 1.0
Define value for property 'package': uk.co.bbc.spring: #Press ENTER to select the groupId as the package name by default
Confirm properties configuration:
groupId: uk.co.bbc.spring
artifactId: spring
version: 1.0
package: uk.co.bbc.spring
Y: #Press ENTER to confirm

You will now have a brand new maven project.

#> ls -R spring
spring:
pom.xml  src

spring/src:
main  test

spring/src/main:
java

spring/src/main/java:
uk

spring/src/main/java/uk:
co

spring/src/main/java/uk/co:
bbc

spring/src/main/java/uk/co/bbc:
spring

spring/src/main/java/uk/co/bbc/spring:
App.java

spring/src/test:
java

spring/src/test/java:
uk

spring/src/test/java/uk:
co

spring/src/test/java/uk/co:
bbc

spring/src/test/java/uk/co/bbc:
spring

spring/src/test/java/uk/co/bbc/spring:
AppTest.java

Ok so next we need get git to start tracking the changes on the project so move into the projects directory and run the git init command.

#> cd spring/
#> git init
Initialized empty Git repository in /some/dir/projects/spring/.git/

Now we can check to see what git has found in our project with the git status command.

#> git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	pom.xml
#	src/
nothing added to commit but untracked files present (use "git add" to track)

It has found the maven pom file and the source directory for our project lets tell git to start tracking these by adding them to the repository and then carrying out our first commit.

#> git add pom.xml src/
#> git status # Just running git status again to check what files have been added.
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached ..." to unstage)
#
#	new file:   pom.xml
#	new file:   src/main/java/uk/co/bbc/spring/App.java
#	new file:   src/test/java/uk/co/bbc/spring/AppTest.java
# 
#> git commit -m "First commit." # Our first commit. Ignore the warnings, you can do what it says to stop git complaining if you like.
[master (root-commit) 4100aeb] First commit.
 Committer: Some One 
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

If the identity used for this commit is wrong, you can fix it with:

    git commit --amend --author='Your Name '

 3 files changed, 76 insertions(+), 0 deletions(-)
 create mode 100644 pom.xml
 create mode 100644 src/main/java/uk/co/bbc/spring/App.java
 create mode 100644 src/test/java/uk/co/bbc/spring/AppTest.java

Git is now tracking all of our files so it is time to open the project in our IDE. If you are using Intellij IDEA select File->Open Project... then find the spring directory select it and click the OK button. Once the project is open click on the Project tab in the top left hand corner and you will see the project structure and all it’s files.
Intellij will create some of it’s own project files within the spring directory, we do not want git to track these so to tell git to ignore them create a file called .gitignore within the spring directory and enter the following into it.

# Ignore intellij IDEA project files.
*.iml
*.ipr
*.iws

# Ignore the maven temporary build directory.
target/

Notice we are also going to ignore the maven build directory. Once that file is created add it to git and commit.

#> git add .gitignore
#> git commit -m "Created .gitignore file to stop tracking IDE project files and maven build directory."

You can now tell Intellij to recheck the git status by selecting Version Control->Refresh File Status. You will now see that the project files are no longer being tracked.

Now lets create our main class that we will use to run this project. Right click on the uk.co.bbc.spring package under the java directory and select New->Java Class and give the class the name Main. If you are asked whether you would like to add the new file to git tick the box to tell Intellij to stop asking and then click Yes.
We now have an empty main class, lets give it a method called doStuff so we have something to test.

package uk.co.bbc.spring;

public class Main {

    public String doStuff() {
        return "Do Stuff.";
    }
}

You will now notice something odd, Intellij doesn’t seem to recognise the Java String class. This doesn’t seem right since that is part of the Java core library. The reason for this is that you have to tell Intellij which Java compiler it should use on your code. To do this place the cursor inside the word String that is the return type of the method. After a few moments you should see a red light bulb appear to the left of the word public. Now hover the cursor over the red light buld and click on the drop down arrow that appears and select the Setup JDK option, then click the Configure... button. Next click the small + button at the top left of the Configure SDK window, then select the JSDK option. Intellij should now be showing you the home directory of you JDK, select it and click OK, then click ok in the Configure SDK window, then finally click OK in the Select Project SDK window. Your Java compiler should now be setup.

The next thing to do will be to create a test class for Main. But before we do that we should update two things within our maven pom file.

First is the Java Compiler version, by default this is set to 1.4 which is far too old so we are going to upgrade it to 1.6 by adding the following to the root of the pom file.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerVersion>1.6</compilerVersion>
                    <fork>true</fork>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

Pro tip: Press CTRL-ALT-L to format any code including XML.

Then we are going to update the JUnit verion to 4.7 by changing the version tag within the dependency.

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

Pro tip: Delete the number inside the version tag then press CTRL-SPACE to get a list of all the versions that are available for any maven dependency. This will work in most of the tags within the maven pom file so you could also use it to find all the artefacts within the junit group.

After editing the pom file Intellij will pop out a small message at the top of the code window asking to import the new changes from the pom file, click the Import Changes link in this pop out to tell Intellij to process the changes. Now that we have finished editing the pom file lets commit the changes by right clicking on the code and then selecting Git->Commit File..., this will pop up the commit changes window. The first thing to do here is to untick the Perform code analyses for affected file tick box. This will speed up your commits and also stop you getting bugged by Intellij. Then write your commit message into the Commit text area and click Commit.

Now click back into the Main class’s code and make sure the cursor is somewhere within the code for the class, clicking in it’s name is good then press CTRL-SHIFT-T to start the process of generating a JUnit test class. Click on the Creat New Test... option then make sure to select the JUnit4 radio button at the top of the Create Test window, also tick the doStuff method to generate a test method, then click ok.
We now have a test class so lets right a pointless test to make sure that the doStuff method is returning the correct string. For this we will need to statically import the junit assert methods.

package uk.co.bbc.spring;

import org.junit.Test;

import static junit.framework.Assert.*;

public class MainTest {
    
    // Test strings and other variables should be set up as constants so that they 
    // can be easily modified and used across multiple tests.    
    private static final String DO_STUFF = "Do Stuff.";

    @Test
    public void testDoStuff() throws Exception {
        Main main = new Main();

        // Assert that the method is returning the correct value.
        assertEquals("test do stuff method's return string", DO_STUFF, main.doStuff());
    }
}

To run the test right click on the method name and select Run "testDoStuff()".

Now that we have a new class and it’s corresponding test class we can safely delete the generated AppTest and App classes, in that order so that Intellij’s safe delete doesn’t complain. Once that is done it would also be a good idea to commit the new Main files to git. From now on I’m going to leave the commiting up to you.

At this point we should now have a very simple and completely useless maven project. You can test to see if it will build with the following command.

#> mvn clean install

You should get a pointless yet successful build. Lets take this one step further by making a pointless yet executable project by creating a main method within the main class that outputs the string from the doStuff method.

package uk.co.bbc.spring;

public class Main {

    public static void main(String[] args) {
        Main main = new Main();

        System.out.println(main.doStuff());
    }

    public String doStuff() {
        return "Do Stuff.";
    }
}

Pro tip: Type psvm inside the class and press the TAB key, this will automatically generate a main method. Also then type sout within the main method and press TAB, this will generate System.out.println().

We can now execute our class, try it by right clicking on the main method or the class in the Project pain and select Run "Main.main()". Similar to how you previously ran the test.

Ok so far for a Spring tutorial there is very little about Spring so lets fix that.
To be able to use Spring in our project we are going to need to add it as a dependency within our pom file.

   <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.0.3.RELEASE</version>
        </dependency>
    </dependencies>

We have added the spring-context module which will give us access to the Spring context which is where Spring stores all of it’s instantiated objects.

Now that we have access to all the classes we can start up the Spring container, so to do this we first have to create a context (config) file for the container to use on startup.
To create the context file first create a directory called resources in the directory called main within the project, then create a file called context.xml and place the following inside it. The resources directory within a maven project is where all config and “resource” files should be placed.

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
</beans>

You now have an empty context file that can be used to start up a Spring container. So lets start it up, to do that we have to instantiate the ClassPathXmlApplicationContext class and give it the path to the context file as an argument.

package uk.co.bbc.spring;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("context.xml");

        Main main = new Main();

        System.out.println(main.doStuff());
    }

    public String doStuff() {
        return "Do Stuff.";
    }
}

Run the main class again and you should get some Spring output, but not much else. Now as I mentioned before Spring’s main feature is Dependency Injection, so lets inject some classes.

Before we can inject anything we need something to inject, so lets create the same classes that were mentioned at the start of this tutorial. MyClassOne, MyClassTwo, and MyHolder.

Once these classes have been created you can use Spring to inject and instantiate them by adding bean definitions to the context file. For the two my classes we are going to us property injection then for the holder we are going to use constructor injection.

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">

    <bean id="myClassOne" class="uk.co.bbc.spring.MyClassOne">
        <property name="one" value="1"/>
    </bean>

    <bean id="myClassTwo" class="uk.co.bbc.spring.MyClassTwo">
        <property name="two" value="2"/>
    </bean>

    <bean id="myHolder" class="uk.co.bbc.spring.MyHolder">
        <constructor-arg name="one" ref="myClassOne"/>
        <constructor-arg name="two" ref="myClassTwo"/>
    </bean>
</beans>

Now lets access the new beans from the Spring context with the following code.

package uk.co.bbc.spring;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        Main main = new Main();

        System.out.println(main.doStuff());

        AbstractApplicationContext context = new ClassPathXmlApplicationContext("context.xml");

        // Retrieve MyClassOne using just the id. Casting required because no type set.
        MyClassOne one = (MyClassOne) context.getBean("myClassOne");

        // Retrieve MyClassTwo using the id and type. No cast required.
        MyClassTwo two = context.getBean("myClassTwo", MyClassTwo.class);

        System.out.println("Spring instantiated MyClassOne one value: " + one.getOne());
        System.out.println("Spring instantiated MyClassTwo two value: " + two.getTwo());

        // Retrieve MyHolder with just the type because there is only ever one instance instantiated.
        MyHolder holder = context.getBean(MyHolder.class);

        System.out.println("Spring instantiated MyHolder one value: " + holder.getOne().getOne());
        System.out.println("Spring instantiated MyHolder two value: " + holder.getTwo().getTwo());
    }

    public String doStuff() {
        return "Do Stuff.";
    }
}

Now if we run the application we should get output similar to the following.

Do Stuff.
06-Feb-2011 19:44:27 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1815859: startup date [Sun Feb 06 19:44:27 GMT 2011]; root of context hierarchy
06-Feb-2011 19:44:27 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [context.xml]
06-Feb-2011 19:44:27 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d2fc36: defining beans [myClassOne,myClassTwo,myHolder]; root of factory hierarchy
Spring instantiated MyClassOne one value: 1
Spring instantiated MyClassTwo two value: 2
Spring instantiated MyHolder one value: 1
Spring instantiated MyHolder two value: 2

The Spring project now actually does something interesting, it instantiates and injects some beans then retrieves and displays their content.

Lastly lets do some injection with Spring annotations. First we need to update the context file so that Spring knows where to look for the annotated classes. To do this add the spring context XSD to the context file to enable access to the context tags then add the component scan tag to scan for any annotated classes under the uk.co.bbc.spring package. Lastly comment out the wiring of the holder object in the context file.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="myClassOne" class="uk.co.bbc.spring.MyClassOne">
        <property name="one" value="1"/>
    </bean>

    <bean id="myClassTwo" class="uk.co.bbc.spring.MyClassTwo">
        <property name="two" value="2"/>
    </bean>

    <context:component-scan base-package="uk.co.bbc.spring"/>

    <!--<bean id="myHolder" class="uk.co.bbc.spring.MyHolder">-->
    <!--<constructor-arg name="one" ref="myClassOne"/>-->
    <!--<constructor-arg name="two" ref="myClassTwo"/>-->
    <!--</bean>-->

</beans>

Now we need to add the right annotations to the MyHolder class. FIrst we annotate the class with the org.springframework.stereotype.Component annotation. This tells Spring that this class should be instantiated and injected. Then we annotate the properties with org.springframework.beans.factory.annotation.Autowired, this tells Spring that the properties should be populated with beans in the context that match their type. It is also possible to just annotate the property constructor and then Spring will instantiate the class in the same way that it did with the previous context file configuration.

package uk.co.bbc.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyHolder {

    @Autowired
    private MyClassOne one;

    @Autowired
    private MyClassTwo two;

    public MyHolder() {
    }

    public MyHolder(MyClassOne one, MyClassTwo two) {
        this.one = one;
        this.two = two;
    }

    public MyClassOne getOne() {
        return one;
    }

    public void setOne(MyClassOne one) {
        this.one = one;
    }

    public MyClassTwo getTwo() {
        return two;
    }

    public void setTwo(MyClassTwo two) {
        this.two = two;
    }
}

And there you have it the end of the first Spring tutorial, where you have learned a little about what Spring does, how it does it, and the different ways to does things with it.