Dev Environment Setup

This are the notes I have taken while setting up my Eclipse environment to run a Smartweb application. Feel free to comment!

Environment Details:

Checking out the source code

The first thing to do is to check out the existing codebase in your Eclipse workspace as a starting point.

sebastien@kilkenny:~/workspace$ svn checkout https://smartweb.svn.sourceforge.net/svnroot/smartweb/trunk smartweb

Once you've checked out the project, the subdirectories under smartweb should look as follows:

core
The Core of the Smartweb framework.
test
The test library used throughout the whole Smartweb application.
modules
The different modules which can be used in a project (cf. http://smartweb.sourceforge.net/modules.html)
template
A project template which can be used as a startup point in a project.
example
An example!

Setting up your Eclipse project

(I'm assuming you're running Eclipse for Java EE developers together with the JBoss Tools plugin)

The first thing to do is to import the different modules that you are likely to use during your project. To do this, go into File > Import… > Existing Projects into Workspace. Select the smartweb folder in your workspace; all the subprojects should appear as projects.

projects.png

Click Finish and the projects get imported into Eclipse.

You then have to resolve the dependencies between projects manually…

Method 1: Use the Template

Create mysmartweb project by copying the template project:

sebastien@kilkenny:~/workspace$ cp -R smartweb/template/eclipse mysmartweb

Import that new project into Eclipse as previously, and you're ready to go!

That new project is structured as follows:

src
The source folder
test
Unit tests
res
Resources
web
JSP, css, images, etc.

Method 2: Maven Archetype

Create the project with a Maven Archetype.

mvn archetype:create  -DarchetypeGroupId=org.apache.struts \ 
                      -DarchetypeArtifactId=struts-archetype-blank \
                      -DarchetypeVersion=1.3.5-SNAPSHOT \
                      -DgroupId=com.example \
                      -DpackageName=com.example.myproject \ 
                      -DartifactId=myproject \
                      -DremoteRepositories=http://people.apache.org/maven-snapshot-repository

Open the pom.xml, and edit as follows:
- remove the following:

<plugin>
             <groupId>org.codehaus.cargo</groupId>
             <artifactId>cargo-maven2-plugin</artifactId>
             <configuration>
                <container>
                   <containerId>tomcat5x</containerId>
                   <home>c:/java/apache-tomcat-5.5.17</home>
                   <log>target/tomcat5x.log</log>
                   <output>target/tomcat5x.out</output>
                </container>
                <configuration>
                   <home>target/tomcat5x</home>
                </configuration>
             </configuration>
          </plugin>

- Add the following:

<plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <wtpversion>1.5</wtpversion>
                </configuration>
            </plugin>

- Replace the dependencies with the following:

<dependency>
         <groupId>org.apache.struts</groupId>
         <artifactId>struts-core</artifactId>
         <version>1.3.8</version>
      </dependency>
      <dependency>
         <groupId>org.apache.struts</groupId>
         <artifactId>struts-taglib</artifactId>
         <version>1.3.8</version>
      </dependency>
    <dependency>
      <groupId>net.smartlab.web</groupId>
      <artifactId>smartweb</artifactId>
      <version>1.2.5-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>net.smartlab.web</groupId>
      <artifactId>smartweb-auth</artifactId>
      <version>0.8.1-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
      <scope>compile</scope>
    </dependency>
   <dependency>
      <groupId>displaytag</groupId>
      <artifactId>displaytag</artifactId>
      <version>1.1.1</version>
      <scope>compile</scope>
    </dependency>
      <dependency>
         <groupId>org.apache.struts</groupId>
         <artifactId>struts-el</artifactId>
         <version>1.3.8</version>
      </dependency>
      <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
           <version>1.0.4</version>
       </dependency>
       <dependency>
           <groupId>taglibs</groupId>
           <artifactId>standard</artifactId>
           <version>1.0.4</version>
       </dependency>
    <dependency>
      <groupId>commons-digester</groupId>
      <artifactId>commons-digester</artifactId>
      <version>1.8</version>
    </dependency>
    <dependency>
      <groupId>commons-validator</groupId>
      <artifactId>commons-validator</artifactId>
      <version>1.3.1</version>
      <exclusions>
        <exclusion>
          <artifactId>xml-apis</artifactId>
          <groupId>xml-apis</groupId>
        </exclusion>
      </exclusions>
    </dependency>

Obviously, you have to make sure that the Smartweb libraries have been installed into your local Maven repository.

- Run mvn install, then mvn eclipse:eclipse
- File > Import… > Existing Projects into Workspace
- import myproject
- Import myproject into the Web Development perspective as a Struts project.
- Open src/main/webapp/WEB-INF/web.xml, and the following between display-name and the Struts servlet definition:

<!-- ========================================================== Filters -->

 <filter>
  <filter-name>auth</filter-name>
  <filter-class>net.smartlab.web.auth.ActionFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>auth</filter-name>
  <url-pattern>*.do</url-pattern>
 </filter-mapping>

 <!-- ======================================================== Listeners --> 

 <listener>
  <listener-class>net.smartlab.web.auth.SessionListener</listener-class>
 </listener>

 <!-- ========================================================= Servlets -->
 <!-- Standard Action Servlet Configuration -->

- Change the Action Servlet from org.apache.struts.ActionServlet to net.smartlab.web.ActionServlet and add the following init-param to it:

<init-param>
   <param-name>config/auth</param-name>
   <param-value>/WEB-INF/struts-auth.xml</param-value>
  </init-param>

- Replace welcome file with the following:

<welcome-file-list>
    <welcome-file>index.do</welcome-file>
  </welcome-file-list>

- Remove DTD from web.xml, and instead redefine the web-app tag as follows to use Servlet 2.4 / JSP 2.0 (and use EL expression like in auth):

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

- In the Struts Config file, add the following:

<message-resources parameter="net.smartlab.web.messages" />
    <message-resources key="auth" parameter="net.smartlab.web.auth.messages" />
    <message-resources key="app" parameter="messages" />

and delete

<message-resources parameter="MessageResources" />. You can also delete MessageResources.properties

- Add the following action:

<action path="/index" forward="/index.jsp" />

Enabling the auth module

- Copy security.xml from the auth module into src/main/resources/META-INF (I've tried to make sure it was being copied in target/myproject/META-INF, but it was not working, so I had to make sure it was being copied into target/myproject/WEB-INF/classes/META-INF/, which sucks.)

- Copy smartweb.jar.hcf into src/main/resources/META-INF (same story as above).
- Copy auth JSPs in src/main/webapp/auth
- Copy smartweb-auth.tld into src/main/webapp/WEB-INF
- Copy auth images in src/main/webapp/images
- Copy forms-auth.xml and struts-auth.xml into src/main/webapp/WEB-INF
- Create authException.jsp in src/main/webapp/auth
- Copy resources bundles from both core and auth into src/main/resources (you'll have to recreate the net/smartlab/web(/auth) tree)
- Create message.properties in src/main/resources, and add the following properties:

welcome-on=Welcome to
    application.name=MySmartweb
    application.version=1.0

- Add the following in src/main/resources/net/smartlab/web/messages.properties:

# -- welcome --
    welcome.title=Struts Blank Application
    welcome.heading=Welcome!
    welcome.message=To get started on your own application, edit the skeleton configuration files as needed, build with "mvn install", and you are on your way!

- Run mvn package in the "auth" module folder; this creates the etc/sql/mysql.sql file to execute. Create the database schema in MySQL by executing these queries.
- Open src/main/resources/META-INF/smartweb.jar.hcf and edit the parameters to use your local MySQL database.
- Right click on project, Run As, Open Run Dialog… Edit Arguments, VM Arguments. Add the following on a new line:

"-Dsmartweb.factory.strategy=net.smartlab.web.config.TomcatConfigurationStrategy"

- mvn install, then Publish into your WTP Tomcat Server. Start.
- Try to log on:

http://localhost:8080/myproject/auth/loginPage.do

You should get a login page.

- Insert a user in the user table.

Core stuff

- Copy core pages to src/main/webapp, and images into src/main/webapp/images
- Copy core index.jsp from web/ into src/main/webapp
- Copy core smartweb.tld into src/main/webapp/WEB-INF

- Display the following page:

http://localhost:8080/myproject/index.do

and you should get the Smartweb welcome page.

Issues I had to tackle in the process

- In TomcatConfigurationStrategy, the method getSessionFactory was modified as follows:

public SessionFactory getSessionFactory(BusinessObjectFactory bof) {
        synchronized (BusinessObjectFactory.class) {
            String archive = Domain.getLastArchiveName(bof.getClass());
            URL file = Domain.getResource(bof.getClass(), new String[] {"/META-INF/" + archive + ".hcf",
                    "/META-INF/smartweb.jar.hcf"});
            try {
                if (!factories.containsKey(file.toString())) {
                    // Session factory not found in cache
                    logger.warn("getSessionFactory() - configure hibernate without JNDI");
                    SessionFactory factory = new Configuration().configure(file).buildSessionFactory();
                    factories.put(file.toString(), factory);
                }
                return (SessionFactory)factories.get(file.toString());
            } catch (Exception e) {
                logger.error("getSessionFactory() - error", e);
                return null;
            }
        }
    }

to acommodate the fact that URL is not comparable.

- Create an authException.jsp file, as it is required by the auth module when authentication error,
- Change redirect="true" into redirect="false" in Struts config to avoid errors about
missing resource bundles.
- Change DTD in struts-auth.xml
- Change taglib references in Core base.jsp file to:

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>

to be consistent with auth, but also to avoid to have to copy Struts TLD in the projects.
- Create standalone message.properties as indicated above.
- When running Core index.jsp, get the following error:

org.apache.jasper.JasperException: /index.jsp(3,0) /context.jsp(3,6) /auth/login.jsp(4,65) The prefix html specified in this tag directive has been previously used by an action in file /header.jsp line 52.
    org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
    org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
    org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:88)

I removed the taglib definitions from login.jsp in auth, and moved them to base.jsp (core). I then deleted the existing Struts taglib definitions in base.jsp. I also removed DTD declaration and html:html tag, as this is a JSP fragment included in another JSP (and it was breaking XHTML std).
- security.png is nowhere to be found.
- Core pages are not internationalized, and there are some bits of Italian in there! ;-)

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.