EQUIP2 WebApp: Configuring and Building

Chris Greenhalgh, 2007-01-29; last updated 2007-10-24

Introduction

This document describes how to configure and compile an EQUIP2-based web application, such as the provided minimal or tutorial examples.

See also:

Getting EQUIP2 WebApp & dependencies

EQUIP2 webapp is in the EQUIP sourceforge CVS accessible as:

CVSROOT: :pserver:anonymous@equip.cvs.sourceforge.net:/cvsroot/equip
Module: equip2webapp

It is licensed under the (so-called) new or modified BSD Open Source license.

EQUIP2 itself is in the same repository in the module 'equip2'. The dependencies are in the same repository in the module 'dependencies'.

Snapshots should be available from the project download page.

Pre-requisites

Download and install/unpack the dependencies from the dependencies module (see previous section). The default installation expects these to be in the directory ../dependencies/lib (as configured in build.properties).

Alternatively you may assemble the dependencies directly (e.g. if you require more recent versions):

Java SDK 1.5+ and Apache Ant are required.

In addition you may require Apache Xalan, although in theory the XSL support in Java 1.5+ should be sufficient (but we have had occasional problems).

In addition, to run the scripting examples in the tutorial web application you also need to have:

You will also need a J2EE servlet (2.4) container such as Jetty or Tomcat (see EQUIP2_WebApp_Deploying.html) and a database (see below).

Configuring

The following file(s) typically require modification to suit the local installation/use:

build.xml

To change the name of the WAR (and default web context path) change:
<property value="equip2minimalwebapp" name="webappname"/>
If additional database classes are required (to be generated), then add the appropriate bean/helper/database mapping generation operations to the generate target:
	<target name="generate" depends="init,xalan_check,equip2tools_check" unless="generated.uptodate">
<mkdir dir="${generated}/equip2/db"/>

<!-- e.g. -->
<!-- <java fork="true" classname="equip2.tools.j2se.xsltTransform" failonerror="true">
<classpath refid="classpath_tools"/>
<arg value="${equip2home}/etc/bean2java.xsl"/>
<arg value="etc/lovecity.db.Bond.xml"/>
<arg value="${generated}/lovecity/db/Bond.java"/>
<arg value="${equip2home}/etc/bean2javahelper.xsl"/>
<arg value="etc/lovecity.db.Bond.xml"/>
<arg value="${generated}/lovecity/db/Bond_helper.java"/>
<arg value="${equip2home}/etc/bean2hibernatehbm.xsl"/>
<arg value="etc/lovecity.db.Bond.xml"/>
<arg value="${generated}/lovecity/db/Bond.hbm.xml"/>
</java> -->

If additional dependencies are introduced (e.g. JDBC drivers, other libraries) then these must be included:

etc/hibernate.cfg.xml

Using HSQLDB
HSQLDB is a pure java database which is very convenient to use as an in-process file-backed database. This is the default (now) for EQUIP2. The following extract from the configuration in hibernate.cfg.xml configures the persistent dataspace to use HSQLDB and in particular the file(s) hsql_test_db.*:
       <!-- HSQLDB in-process database - simple/testing/development -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:file:hsql_test_db</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

Note that the username & password are standard HSQLDB defaults for an in-process database.

The nice thing about this is that no separate install is required. However, HSQLDB may be less durable than mySQL in the presence of some failures. It is also unclear how well its performance scales to larger dataspaces.

Change the Hibernate database driver configuration to refect the database name/file to be used with the deployed web application:
        <property name="connection.url">jdbc:hsqldb:file:hsql_equip2minimal_db</property>
Using mySQL

mySQL is a popular freely-available database. It requires a separate download and install. It also requires that the database to be used be explicitly created within the (logically shared) mySQL database server.

You will need to set the database URL, username, password, driver and dialect configuration, e.g:

	<!-- mysql - production -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///equip2</property>
<property name="connection.username">equip2</property>
<property name="connection.password">equip2</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

You will require the MySQL Java connector, currently version 3.1.12 (i.e. mysql-connector-java-3.1.12-bin.jar) in the dependencies directory or lib/ and update build.xml accordingly (see above).

Using another database
If you are using a different Database (not in-process HSQLDB or mySQL) then also change the username, password, driver and dialect configuration (see Hibernate documentation for dialect information), e.g.:
        <property name="connection.url">jdbc:mysql:///equip2minimal</property>
        <property name="connection.username">equip2minimal</property>
        <property name="connection.password">equip2minimalpw</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

You will also need to copy the appropriate JDBC driver JAR(s) to the dependencies directory or lib/, and update build.xml accordingly (see above).

Persistent classes

If you have added/changed the classes to be persistet by Hibernate (i.e. to be stored in the persistent EQUIP2 dataspace), then update the mappings sections accordingly:

        <mapping resource="equip2/spring/db/NextID.hbm.xml"/>
        <!-- persistent class mappings... -->

webapp/WEB-INF/web.xml

Edit <display-name> and <description> to reflect the name and description of the your web application.

If you will have more than one EQUIP2 web application in the same Servlet container then you will need to change the webAppRootKey parameter name used by Log4j:

 <context-param>
    <param-name>webAppRootKey</param-name>
   <param-value>equip2webapp.root</param-value>
 </context-param>

This file also needs to be changed if you:

webapp/WEB-INF/log4j.properties

Edit the Log4j output file path:
log4j.appender.logfile.File=${equip2webapp.root}/WEB-INF/webapp.log
The equip2webapp.root property is configured in web.xml, and must be unique between all web applications in a single Servlet container (e.g. Tomcat instance) - you'll need to change it if you have more than one EQUIP2 web app in the same container!

webapp/WEB-INF/applicationContext.xml

This specifies the global Spring configuration for the web application, e.g. creating the persistent dataspace. You need to edit this to configure the dataspace logging:
  <!-- dataspace logger -->
  <bean id="dataspaceLogger" class="equip2.core.logging.j2se.SimpleFileDataspaceLogger">
    <!-- String dirname, String prefix, String suffix,
    boolean checkpointFlag, int encoding (1=Hessian, 2=XML), Hashtable headerMetadata -->
   <!-- windows or jetty -->  <constructor-arg><value>logs</value></constructor-arg>
   <!-- tomcat on linux <constructor-arg><value>/usr/local/logs/</value></constructor-arg> -->
    <constructor-arg><value>equip2webapp-dataspace-log-</value></constructor-arg>
    <constructor-arg><value>.equip2log.hessian</value></constructor-arg>
    <constructor-arg><value>true</value></constructor-arg>
    <constructor-arg><value>1</value></constructor-arg>
    <constructor-arg><map><entry key="application" value="equip2minimalwebapp"/></map></constructor-arg>
  </bean>

Note that the web application will not start up successfully if the logging directory does not exist.

If you add more database classes and want the forms to generate IDs automatically then you will need to configure the equip2.spring.DbGenericIDAllocator with suitable entries:

   <!-- ID allocation common thing -->
  <bean id="dbIdAllocator" class="equip2.spring.DbGenericIDAllocator">
    <property name="dataspace"><ref bean="dataspace"/></property>
    <!-- map of classname to IDAllocationBean, describing how the ID
         property (if any) should be allocated using the IDAllocator. -->
    <property name="idAllocations">
      <map>
    <!--  e.g. --> <entry key="lovecity.db.Agent">
      <bean class="equip2.spring.IDAllocationBean">
        <property name="fixedPrefix" value="A"/>
      </bean>
    </entry>
     </map>
    </property>
  </bean>

You will also edit this file to add more application-scoped objects to the application.

webapp/WEB-INF/db-servlet.xml

If you are defining your own data type (you should be), and want to specify a default package name for use with forms then change the defaultPackageName properties accordingly (there are several in the file):
   <property name="defaultPackageName"><value>equip2.spring.db</value></property>
If you have database objects with properties that contain IDs of other objects but do not have property names of the form '[otherClassName]ID' then you will need to declare this to the generic view controller for pull-down choosers to work for add/update:
  <bean id="genViewController" class="equip2.spring.DbGenericController">
   ...
    <!-- properties which hold an ID of an instance of another class which
         do not conform to simple heuristic check <class>ID or ...<class>ID -->
    <property name="linkedObjectProperties">
      <map>
        <!--  e.g. <entry key="home_cityID" value="lovecity.db.City"/> -->
      </map>
    </property>
  </bean>
If you want to use the CSV bulk dump/upload function then you can optionally specify the order of columns in the CSV file (classPropertiesInOrder) and/or the explanatory text output with each column (classPropertiesDescriptions) by configuring the DbViewController:
  <bean id="dbViewController" class="equip2.spring.DbViewController"> 
    ...
    <!-- map class name - > Array of String (property name) -->
    <property name="classPropertiesInOrder">
      <map>
        <!-- e.g. <entry key="lovecity.db.City"><list><value>ID</value></list></entry>  -->
      </map>
    </property>
    <!-- map class name - > map of property name - > description -->
    <property name="classPropertyDescriptions">
      <map>
        <!--  e.g.<entry key="lovecity.db.City">
          <map>
            <entry key="ID" value="Database internal ID"/>
          </map>
        </entry> -->
      </map>
    </property>
  </bean>

See also EQUIP2_WebApp_Defining_the_Dataspace.html for more detail of database forms interface configuration options if you have added new data classes.

Building

Obtain all depdencies and edit ../build.properties to reflect the installed locations of the dependencies. (tomcathome is used only for local deployment - see EQUIP2_WebApp_Deploying.html).

NOTE: if you are using a different version of the external dependencies (Spring, Hibernate, database etc.) then you may need to change the classpath(s) in build.xml, especially classpath_hibernate, and the filesets in the webapp target to use/copy the current versions of requires JARs.

Build the WAR file:

> ant war

Testing

To run any JUnit tests (configured in the build.xml 'test' target - see EQUIP2_WebApp_Unit_Testing.html) do:

> ant test

Now deploy and test the web application.

Changes

2007-01-29
2007-02-02
2007-02-06
2007-10-24
2007-10-25