home.


Tagged: ant


Tomcat 7: Deploying a simple Servlet

Now you’ve deployed a simple JSP, you can now alter that to deploy a simple servlet.

First change the web.xml file to point to a servlet. Not the new servlet-class tag.

 <web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   version="2.4">

   <display-name>Hello, World Application</display-name>
   <description> A simple servlet </description>

   <servlet>
     <servlet-name>HelloServlet</servlet-name>
     <servlet-class>org.denevell.tomcat.Hello</servlet-class> 
   </servlet>
   <servlet-mapping>
   <servlet-name>HelloServlet</servlet-name>
     <url-pattern>/hello</url-pattern>
   </servlet-mapping> 

 </web-app>

And now create the Hello.java file in src/org/denevell/tomcat/

 public final class Hello extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
      throws IOException, ServletException {
        response.setContentType("text/plain");
        PrintWriter writer = response.getWriter();
        writer.println("Sup?");
    }
 }

We’re extending a servlet class, and overriding the doGet method that deals with HTTP GET requests. The first parameter is what’s sent to the serlvet and the second is what’s going back to the client. In it we simply set the content type, get its writer and write something to it.

We now need to update our build.xml to ensure we’re compiling this class. Note we’ve set a new property to point to your tomcat directory, added the libraries in a classpath, and created a new javac and copy task in the compile target.

 ...
    <property name="catalina.home" value="/usr/share/tomcat7" />

    <path id="compile.classpath">
      <fileset dir="${catalina.home}/bin">
        <include name="*.jar"/>
      </fileset>
      <pathelement location="${catalina.home}/lib"/>
      <fileset dir="${catalina.home}/lib">
        <include name="*.jar"/>
      </fileset>
    </path>

    <target name="compile" depends="prepare">
      <javac srcdir="${src.home}" includeantruntime="false" destdir="${build.home}/WEB-INF/classes">
        <classpath refid="compile.classpath"/>
      </javac>
      <copy todir="${build.home}/WEB-INF/classes">
        <fileset dir="${src.home}" excludes="**/*.java"/>
      </copy>
    </target>
 ...

Now you can deploy that servlet and see your new servlet at (if you’ve deployed it to hiya/ again):

 http://localhost:8080/hiya/hello
tomcat tomcat-setup ant tomcat-httpservlet java

Tomcat 7: Deploying a simple JSP

First download Tomcat7. I used this to get it setup in Debian (https://wiki.bedis.eu/debian/squeeze_tomcat7_installation until Servlet installation).

Then create a working directory for your project. Here’s the directory structure. Note we’re not using the src/ directory just as yet.

 src/
 web/
 web/WEB-INF/

In the web/ directory put a simple JSP file called hello.jsp. Note the notation for including java code.

 <%= new String("Hiya.") %>

Now create a web.xml file in your web/WEB-INF/ folder (stands for web information that will tell the servlet container about this site).

 <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   version="2.4">

   <display-name>Hello, World Application</display-name>
   <description>
     Sup?
   </description>

   <servlet>
     <servlet-name>HelloServlet</servlet-name>
   </servlet>
   <servlet-mapping>
     <servlet-name>HelloServlet</servlet-name>
     <url-pattern>/hello</url-pattern>
   </servlet-mapping>

 </web-app>

After all the schema definitions and the version information in web-app, the display-name tell your servlet container (Tomcat) the site’s name for administration purposes, and description likewise.

Then the servlet tag has a servlet-name for you to define your serlvet a name that will be used later in mapping. You’d normally define a Java class under servlet-class also, but we’re not creating Java classes in this tutorial.

Finally you set a servlet-mapping, that points via servlet-name to the name of the servlet you defined above, and maps that to a url via url-pattern, ‘/hello’ in this case.

Next you will need a build.xml file to build this via Ant.

 <project name="My Project" default="compile" basedir=".">

  <property name="build.home" value="${basedir}/build"/>
  <property name="src.home" value="${basedir}/src"/>
  <property name="web.home" value="${basedir}/web"/>

  <target name="compile" depends="prepare">
  </target>

  <target name="prepare">
    <mkdir dir="${build.home}"/>
    <mkdir dir="${build.home}/WEB-INF"/>
    <mkdir dir="${build.home}/WEB-INF/classes"/>
    <copy todir="${build.home}">
      <fileset dir="${web.home}"/>
    </copy>
  </target>

 </project>

We first set the properties for the project. Then we have a blank compile target, that would normally compile your Java classes. And this depends on a prepare target that copies all the stuff in web/, i.e. web.xml and hello.jsp, into the build directory. Run ‘ant’ to make it do this.

Then you need to deploy this. You’d normally package this up into a WAR (Web ARchive) file, but Tomcat allows you merely to copy the content of build/ into its webapps/ folder (in the location where tomcat is installed, in my case /var/lib/tomcat). You do this via:

 mkdir $YOUR_TOMCAT_HOME/webapps/hello
 cp -r build/ $YOUR_TOMCAT_HOME/webapps/hello

Then restart your tomcat installation for good measure. You new web site is available at:

 http://localhost:8080/hello/hello.jsp
tomcat tomcat-setup ant

Java Cucumber testing

Make a product directory with bin/ and lib/ directories within.

You need the cucumber-jvm (https://github.com/cucumber/cucumber-jvm) libs in the lib/ folder. You need:

* cucumber-core-1.1.1.jar  
* cucumber-html-0.2.2.jar  
* cucumber-java-1.1.1.jar  
* cucumber-junit-1.1.1.jar  
* junit-4.11.jar

I got these via Apache Ant. You can use Maven, or the Ant build script that comes with the hello world example in the cucumber-jvm repository.

Next you need to write the features file. Put this in the main directory:

 Feature: Hello World

  Scenario: Print my shopping list
    The list should be printed in alphabetical order of the item names

    Given a shopping list:
      | name  | count |
      | Milk  |     2 |
      | Cocoa |     1 |
      | Soap  |     5 |
    When I print that list
    Then it should look like:
      """
      1 Cocoa
      2 Milk
      5 Soap

      """

The lines starting Given, When and Then are parsed by Cucumber. You need to write step definitions for these. Create a file called ShoppingStepdefs.java in your main folder:

 import cucumber.api.java.en.Given;
 import cucumber.api.java.en.Then;
 import cucumber.api.java.en.When;

 import java.util.List;

 import static org.junit.Assert.assertEquals;

 public class ShoppingStepdefs {
    private StringBuilder printedList; 
    private final ShoppingList shoppingList = new ShoppingList();

The above line initialises the class we’ll be testing (to be defined later).

  public static class ShoppingItem {
      private String name;
      private Integer count;
  }

This is used for grabbing list data. See below.

  @Given("^a shopping list:$")
  public void a_shopping_list(List<ShoppingItem> items) throws Throwable {
      for (ShoppingItem item : items) {
          shoppingList.addItem(item.name, item.count);
      }
  }

This defines the Given line above, the one with ‘a shopping list’ as its text. The “:” means we’ll be taking in an object. “^” and “$” end the definition.

We take in the | Milk | 2 | in the feature file as a List as a parameter. Then in the method we go through each adding it to the shoppingList initialised earlier.

  @When("^I print that list$")
  public void I_print_that_list() throws Throwable {
      printedList = new StringBuilder();
      shoppingList.print(printedList);
  }

Then we define the ‘When’ line. This simply takes the output of the shoppingList and puts it the printedList StringBuilder as defined above.

  @Then("^it should look like:$")
  public void it_should_look_like(String expected) throws Throwable {
      assertEquals(expected, printedList.toString());
  }

Then final ‘Then’ statement takes in a string as a parameter and compares it to the output of the printedList.

 }

Now we need the ShoppingList class. Put it in the root folder:

 import java.io.IOException;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;

 public class ShoppingList {
    private SortedMap<String,Integer> items = new TreeMap<String, Integer>();

    public void addItem(String name, Integer count) {
        items.put(name, count);
    }

    public void print(Appendable out) throws IOException {
        for (Map.Entry<String, Integer> entry : items.entrySet()) {
            out.append(entry.getValue().toString()).append(" ").append(entry.getKey()).append("\n");
        }
    }
 }

Now you need a build.xml file to run the tests via ant (I’ve omitted things like clean for clarity):

 <project name="java-helloworld" basedir="." default="runcukes">

    <property name="jars" value="lib"/>

    <target name="classpath">
        <path id="classpath">
            <fileset dir="${jars}">
                <include name="**/*.jar"/>
            </fileset>
            <pathelement location="bin/classes"/>
        </path>
    </target>

    <target name="compile" depends="classpath">
        <mkdir dir="bin/classes"/>
        <javac srcdir="." destdir="bin/classes" classpathref="classpath" includeantruntime="false"/>
    </target>

The above just compiles the java files into classes and sets the classpath.

    <target name="runcukes" depends="compile">
        <mkdir dir="bin/cucumber-junit-report"/>
        <java classname="cucumber.api.cli.Main" fork="true" failonerror="false" resultproperty="cucumber.exitstatus">
            <classpath refid="classpath"/>
            <arg value="--format"/>
            <arg value="junit:bin/cucumber-junit-report/allcukes.xml"/>
            <arg value="--format"/>
            <arg value="pretty"/>
            <arg value="--format"/>
            <arg value="html:bin/cucumber-html-report"/>
            <arg value="--glue"/>
            <arg value=""/>
            <arg value="."/>
        </java>

This runs the cucumber tests via running cucumber.api.cli.Main with various arguements that point to the location of our feature file and sets various reporting and formatting features.

      <junitreport todir="bin/cucumber-junit-report">
          <fileset dir="bin/cucumber-junit-report">
              <include name="allcukes.xml"/>
          </fileset>
          <report format="frames" todir="bin/cucumber-junit-report"/>
      </junitreport>

This next part runs junit on the junit that cucumber produced, failing if we have errors. The hello-world sample project has a fail tag here, but I haven’t found it to be needed, so I’ve omitted it here.

    </target>

 </project>

Now run ‘ant’ in the directory and voila:

 runcukes:
     [java] Feature: Hello World
     [java] 
     [java]   Scenario: Print my shopping list # helloworld.feature:3
     [java]     The list should be printed in alphabetical order of the item names
     [java] 
     [java]     Given a shopping list:         # ShoppingStepdefs.a_shopping_list(List<ShoppingStepdefs$ShoppingItem>)
     [java]     When I print that list         # ShoppingStepdefs.I_print_that_list()
     [java]     Then it should look like:      # ShoppingStepdefs.it_should_look_like(String)
     [java]       """
     [java]       1 Cocoa
     [java]       2 Milk
     [java]       5 Soap
     [java] 
     [java]     Then it should look like:      # ShoppingStepdefs.it_should_look_like(String)
     [java]       """
     [java]       1 Cocoa
     [java]       2 Milk
     [java]       5 Soap
     [java] 
     [java]       """
     [java] 

You’ll see errors in this output should there be a failure.

java ant java-testing cucumber

Ant: If-else conditionals

You can create normal conditionals via:

 <condition property="property_to_create" 
   value="value_to_set_as" 
   else="if_below_isnt_true">
  <isset property="another_property" />
 </condition>

The above sets a new property ‘property_to_create’ with the value ‘value_to_set_as’ if the property ‘another_property’ exists, else ‘property_to_create’ will have the value ‘if_below_isnt_true’

ant ant-condition

Ant: Calling targets and Inheritance

You can call other targets using antcall:

 <target name="thetarget">
    <antcall target="atarget" />
    <antcall target="anothertarget" />
 </target>

You can also perform inheritance from imported build files: If you have an ant build file, build.xml, that imports another i.e.

 ...
  <import file="/dir/another_build_file.xml" />
 ...

And another_build.file.xml has a target name ‘android_rules’ and a target ‘debug’ like so:

 ...
 <project name="android_rules" default="debug">
   <target name="debug">
     ....
   </target>
   ...
 </project>
 ...

Then in your build.xml file you can inherit ‘debug’ from the other build file by referencing android_rules.debug:

 <target name="debug" extends="android_rules.debug">
   ...
 <target>

If you use android_rules.debug in antcall tasks too.

ant ant-inheritance ant-target ant-antcall

Page 1 of 4
Next