Archive for the ‘Java’ Category

Intro to Web Services and REST in JAVA

Wednesday, October 28th, 2009
Presentation given to Texas A&M CPSC 438 (Distributed Objects Programming) Students on 10/28/2009

Presentation given to Texas A&M CPSC 438 (Distributed Objects Programming) Students on 10/28/2009

Introduction:

From a technical standpoint, building a Web Service is not entirely difficult, but it’s not a task that should be taken lightly either. Given the vast use of Web Services in the Enterprise environment, on a recent trip to Texas A&M University, I was able to speak to students (courtesy of Dr. Salih Yurttas) about Web Services and REST in JAVA.

Demo Applications:

As part of the presentation linked above, several demonstrations were given including overviews of the following projects and technologies.

  • metroSOAP
    We create a simple java object (POJO) representing a saying about Texas and it’s author. Using the Hibernate framework, we create a mapping to a mysql table for this object as well as a data access object for accessing the objects. Creating a service class, and it’s implementation, we annotate the service as necessary to produce a RPC based SOAP Web Service Web Application that is factored into a war file for deployment on a Java Web App server such as Apache Tomcat.
  • jerseyRest
    Using the same POJO, Hibernate mapping, and DAO as the previous project, we expose a resource and annotate it as necessary to produce a RESTful Web Service.

Optional Resources:

These resources are indirectly used in the demonstration of the above projects and may be necessary to recreate the given scenarios.

  • soapUI project

    Project files for SOAP UI. Import as necessary.
  • database table
    A collection of famous texas quotes returned by our service calls. May be imported into a mysql table.

Required Software:

A collection of software to build and deploy our example applications.

Optional Software:

Additional resources to test and access the Web Services in a meaningful way. I am also including references to tools that once added to SOAP UI will allow for JAVA client code generation.

License:

This article, along with any associated source code and files, is licensed under Apache License, Version 2.0

About the Author:

Dustin Talk is a consultant at Credera. He graduated from Texas A&M University with his Masters of Computer Science, B.S. in Computer Science, and a minor in Business. Throughout his academic career he developed applications using Java and .Net technologies. While in school, he worked for The Department of Statistics as a Network Administrator. He has interned for Anheuser-Busch Inc. as a Systems Engineer developing in .Net and working with industrial software.

The Grinder - Load Testing Web Applications

Tuesday, October 13th, 2009

I ended up using The Grinder load tester for work recently and found it to be remarkably lightweight and easy to use. The Grinder is a free, Java open source load testing framework that uses Jython scripts for running the load tests. Jython is interesting in itself — it’s a Java implementation of Python that is compiled to bytecode and runs on a JVM and also allows you to access the Java libraries using the Python syntax.

But for the purposes of this post, I’m going to give a quick rundown of how The Grinder works, how to set it up, and then how to use the TCPProxy to generate Jython test scripts for the purposes of load testing web applications.

The Players

There are essentially 4 main components to The Grinder.

  1. Agents - You’ll typically have a single agent on each load injector machine, which will start a configured number of worker processes. If the agents can connect to the console, they’ll wait for a signal to start before passing off a local grinder.properties file to the worker processes.
  2. Workers - Workers, as you would imagine, do the work. That is, they actually execute the load test scripts. The grinder.properties file that is passed to the worker by the agent defines, among other things, the script that the worker will execute against the target, how many threads the worker will spawn, and how many times each one of those threads will execute the script.
  3. Console - This is a GUI that can be used to control the agents, and also displays the collected statistics that are reported back from the workers.
  4. TCPProxy - The TCPProxy is interposed between your browser and the target server, and can be used to generate scripts by recording the activity of your browser, which can subsequently be executed by the worker processes. This is really handy for generating load tests that simulate user interaction with a web application

Installing The Grinder

This part is incredibly easy.

  1. Download the Grinder at SourceForge.net. You’ll need to at least have J2SE 1.4 on your machine to run The Grinder 3.
  2. Unzip it.
  3. You might want to create a few scripts for setting the environment variables and starting The Grinder for your own convenience. These are for Windows.

setGrinderEnv.cmd
[code lang="dos"]
set GRINDERPATH=C:\grinder-3.2
set GRINDERPROPERTIES=C:\grinder-3.2\examples\grinder.properties
set CLASSPATH=%GRINDERPATH%\lib\grinder.jar;
set JAVA_HOME=C:\Program Files\Java\j2re1.4.2_15
PATH=%JAVA_HOME%\bin;%PATH%
[/code]

startAgent.cmd
[code lang="dos"]
call C:\grinder-3.2\setGrinderEnv.cmd
echo %CLASSPATH%
java -cp %CLASSPATH% net.grinder.Grinder %GRINDERPROPERTIES%
[/code]

startConsole.cmd
[code lang="dos"]
call C:\grinder-3.2\setGrinderEnv.cmd
java -cp %CLASSPATH% net.grinder.Console
[/code]

startProxy.cmd
[code lang="dos"]
call C:\grinder-3.2\setGrinderEnv.cmd
java -cp %CLASSPATH% net.grinder.TCPProxy -console -http > grinder.py
[/code]

Recording Scripts With TCPProxy

To create a test script with the TCPProxy, you’ll need to configure your browser to point to the TCPProxy so that it can record your actions.

Configure the Browser
The first thing that you’ll need to do is to configure your web browser to use the TCPProxy as the HTTP proxy. The steps required to do this will be different depending on the browser that you’re using. I’m using Mozilla/Firefox 3.0, so I selected:

1.  Tools  -> Options -> Advanced  Settings.
2.  I then configured the HTTP Proxy to point to localhost:8001 (TCPProxy default listener port).

Record the Script
With your browser pointed to the TCPProxy use the shortcut you created in the previous section to start the proxy. Let’s take a quick look at the options specified on startup.

[code lang="dos"]
java -cp %CLASSPATH% net.grinder.TCPProxy -console -http > grinder.py
[/code]

console - displays the console below, which can be used to add comments during the recording process and to shut the TCPProxy down cleanly.
http - Adds the request/response filters to produce a script readable by The Grinder’s HTTP plugin.
grinder.py - The script will be output locally to a file named grinder.py. You can rename this or relocate where it will be created if you like.

Of course, there are many more startup options I won’t cover now, but which you can check out here.

Once the proxy has started, the TCPProxy console should appear.  The TCPProxy will record all of the requests, and time between requests, that your browser makes until you press the stop button. You can add ad-hoc comments throughout the process if you wish.

Here are some snippets from a script created by starting the TCPProxy and going to Credera.com.

connectionDefaults.defaultHeaders = \
( NVPair('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.12) Gecko/2009070611 Firefox/3.0.12'),
NVPair('Accept-Encoding', 'gzip,deflate'),
NVPair('Accept-Language', 'en-us,en;q=0.5'),
NVPair('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7'), )

headers0= \
( NVPair('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'), )

headers1= \
( NVPair('Accept', 'text/css,*/*;q=0.1'),
NVPair('Referer', 'http://www.credera.com/default.html'), )
...
...
...
url0 = 'http://www.credera.com:80'
url1 = 'http://www.google-analytics.com:80'

Headers and urls are defined once at the top of the script.

request101 = HTTPRequest(url=url0, headers=headers0)
request101 = Test(101, 'GET /').wrap(request101)

request102 = HTTPRequest(url=url0, headers=headers0)
request102 = Test(102, 'GET Default.aspx').wrap(request102)

request103 = HTTPRequest(url=url0, headers=headers0)
request103 = Test(103, 'GET default.html').wrap(request103)
...
...
...

An HTTPRequest is created for each request and wrapped in a Test object.

class TestRunner:
"""A TestRunner instance is created for each worker thread."""
...
...
...
def __call__(self):
"""This method is called for every run performed by the worker thread."""
self.page1()      # GET / (requests 101-112)

grinder.sleep(234)
self.page2()      # GET WebResource.axd (request 201)

grinder.sleep(31)
self.page3()      # GET WebResource.axd (requests 301-303)

grinder.sleep(63)
self.page4()      # GET ga.js (request 401)

grinder.sleep(47)
self.page5()      # GET CrederaButterfly_v4.swf (request 501)

grinder.sleep(109)
self.page6()      # GET __utm.gif (request 601)

A TestRunner instance is created for each worker process thread and executes the _call_ method a predetermined amount of times, or indefinitely, depending on the configuration (set in grinder.properties).

A few things of note:

  • You can see that the sleep method is incorporated into the script to simulate user “think time”.
  • The value passed to sleep is the mean value of a pseudo normal distribution. So actual sleep times will vary slightly when the script is played back.
  • Requests are executed serially by a single worker thread. This differs slightly from how a browser will function in that the browser can spawn multiple parallel threads to make simultaneous requests.

Configuring Script Playback

Before executing your generated test script, you’ll want to configure a few properties on the grinder.properties file located at <installation directory>/examples/ by default. We’ll just look at the most basic properties to get you started. You’ll have a properties file for each agent process.

grinder.script - This is the name of the script you will execute (e.g. grinder.py). The value is relative to the directory in which the property file resides.
grinder.processes - This is the number of workers that the agent will start
grinder.threads - This is the number of threads each worker will spawn. Each thread will execute the script.
grinder.runs - This is the number of times each worker thread will run the script. If this is set to 0, the script will run indefinitely until stopped by the console.

So you might have something like the following in your grinder.properties file:
[code lang="dos"]
grinder.script = grinder.py
grinder.processes = 1
grinder.threads = 10
grinder.runs = 50
[/code]
If you’re running your agent on a different machine than the console, you’ll also need to configure those properties that allow the agent to contact the console - grinder.consoleHost and grinder.consolePort. The default port for the console is 6372.

Script Playback

Put your grinder.py script in a location where the properties file can read it. We defined grinder.py above as being in the same directory as the grinder.properties file, so put your script in the
<installation directory>/examples/ directory. Then:

1. Start the Grinder console using startConsole.cmd.
2. Start the agents using startAgent.bat.

If you click on the Processes tab of the console, you should see your agent(s) have connected.  After detecting the console, the agents will wait for a signal to start. Just click the start button in the upper left corner of the console to have the agents kick the worker processes off.

While the workers are running the test scripts, you can click on the Results tab to see the response times for the various requests. These statistics are also presented in graphical form — as you would probably guess — on the Graphs tab. You can later export these statistics to an Excel file for analysis if need be.

That, in a nutshell, is how you can use The Grinder’s TCPProxy to very easily generate load test scripts to simulate user interaction with your web application.

Why Did I Want a JSON View Resolver?

Friday, September 11th, 2009

In my previous post, I documented a scenario that I encountered while setting up a JSON view resolver in a Spring MVC project.  Let me take a step back and explain my motivations for why I wanted a JSON view resolver.

In any Spring MVC application, Controller classes are responsible for processing some data, then returning a ModelAndView .  Typically views eventually return HTML either directly from a JSP or through a templating framework like Tiles.  However, custom views  can provide output such as Excel or PDF files.  In my case, I wanted an easy way to return a JSON response from certain Controller methods that would be called from an Ajax request.

HTML is a perfectly valid response to an Ajax request; often the Javascript processes an HTML response and then inserts the HTML into a page.  But occasionally JSON makes more sense, like when a page simply needs to know something about what is going on back on the server without displaying anything to the user(for example, whether the user has a valid session that has not timed out).  JSON is the native format of Javascript, so it is a convenient way to return a response to a Javascript client.

I found a great project called Spring Json View that offers all the features of Spring MVC like validation, exception handling, and error handling and automatically converts the Model to a JSON object.  It was probably a bit more than I needed for what I was trying to accomplish, but I was working on an internal company project and one of our secondary goals was to build skills and identify patterns that would be useful on future projects.  So I tested it out for this simple scenario, and I expect that this pattern could be useful on future projects.

Check out the configuration snippets from my previous post to see how I integrated Spring Json View into Spring MVC.

Also, here’s a quick example of how a controller method can use it:

@RequestMapping(method = RequestMethod.GET)
public ModelAndView isLoggedIn(ModelMap model) {
model.addAttribute("loggedIn",
!SecurityContextHolder.getContext().getAuthentication().getName().equals("guest"));
return new ModelAndView("jsonView", model);
}

Integrating PHP and Java

Friday, September 11th, 2009

As part of an upcoming project, I have been doing some research and coding trying to understand some of the various methods of integrating Java into a PHP environment. We can categorize the methods into three basic areas: The use of Web Services, utilizing a VM Bridge, and Direct Calling. We also take a look at another alternative, which is running PHP in a Java Environment. I will briefly describe the features of each method, giving those looking for such tools some insight as to what may best fit their application.

Web Services

Since there are many various forms of web services, I have focused my research on two commonly accepted methods.

SOAP (have a working prototype available)

  • Uses direct calls of Java functions via Java web service from within PHP
  • Can maintain independent Java & PHP environments
  • Uses Apache AXIS / AXIS 2 framework, but can be adapted for other web service platforms
  • SOAP is built into PHP5, but there are popular third party modules for older versions of PHP
  • Have the ability to use normal Java classes then auto-generate the service and a client with JUnit tests from within Eclipse JEE
  • Features an optional online management interface in AXIS2 to disable, enable, or monitor services as needed
  • Java RESTful Web Service with Jersey using JSON passing (have a working prototype available)
  • Can maintain independent Java & PHP environments
  • Requires more coding on the PHP side with independent requests to individual methods and handling JSON objects
  • JSON is built into PHP5 but may require third party libraries for older versions
  • Requires more coding on Java side with annotations and passing JSON objects; not plain Java objects
  • There are many libraries available for RESTful Service in Java, Jersey is only used as a reference
  • Is the slowest tested method due to slow http requests in PHP (1/5 second per call)
  • Can be optimized if only a single http request is required per page

VM Bridge. A bridge uses “continuation passing” to invoke procedures/methods from each environment maintaining their individual properties.

php-java-bridge.sourceforge.net (have a working prototype available)

  • Can maintain independent Java & PHP environments
  • Much faster than methods implemented above. (In my tests: 2-3x that of SOAP, 10x that of rest services with multiple requests) (Authors claim: 50x improvement over SOAP/XML-RPC)
  • Uses a VM Bridge XML Network Protocol behind the scenes to communicate with remote or local JVM running a Java app, or Java servlet
  • Have the ability to program regular Java classes
  • Can directly call Java functions in PHP (Works with apache or IIS)
  • Listed as the only free alternative to Web Services/XML-RPC
  • http://php-Java-bridge.sourceforge.net/pjb/index.php

Zend Platform PHP Java Bridge

  • Similar to the above product but a commercial package bundled as part of the Zend Platform.
  • Offers a similar API as the above product.
  • http://www.zend.com/en/products/platform/product-comparison/Java-bridge

Direct Calling

By far the simplest method for using Java in PHP, it can load java classes directly and call its methods. This is not without its drawbacks however.

Direct Java calling within PHP5

  • This is an experimental feature of PHP5
  • Authors say to use at own risk
  • http://us.php.net/manual/en/intro.Java.php

Running PHP in a Java Environment. The methods described below attempt to emulate a specific PHP version entirely in Java. This has the potential of being very fast and easy, however may not meet integration requirements.

Caucho Resin J2EE Application Server with PHP Integration

  • Runs PHP scripts fast (claim a 6x improvement in speed over apache with PHP)
  • The entire PHP implementation is built in Java
  • Not entirely all features of PHP have been implemented, may have issues with multi-threading
  • Requires only one server and environment
  • Have the ability to use regular Java classes
  • May have to adapt current PHP code for a Java environment
  • Is a good way to transition developers from PHP to Java
  • http://www.caucho.com/resin-3.0/quercus/

Tomcat PHP Java Servlet SAPI

  • Enables the entire PHP processor to be run as a servlet
  • PHP has a habit of changing the working directory and may not be able to load any classes from the relative CLASSPATH
  • Requires only one server and environment
  • Have the ability to use regular Java classes
  • PHP version 5 is not currently supported
  • May have to adapt current PHP code for a Java environment
  • http://us.php.net/manual/en/Java.servlet.php

For more information on any of the above methodologies or to request sample code, please don’t hesitate to contact me at: dtalk@credera.com

Pro Flex on Spring by APress

Friday, July 17th, 2009

I wanted to announce that a book that I was the technical reviewer for has been published. It’s called Pro Flex on Spring and published by APress. It shows some of the best practices that have been developed for accessing Spring framework application from Flex.

Compiling Flex without Flex Builder

Friday, July 17th, 2009

Flex builder is a great tool that I highly recommend. Using it provides great features such as design preview and debugging. You can get a free 30 day evaluation of it at Adobe’s website.

There are times, however, that you might find yourself in need of compiling a Flex application and you don’t have access to the Flex Builder (for example if your trial expired but you need that last build). It is very easy to use Ant to build your Flex Application.

Besides Ant you need the Flex SDK. If you have installed the Flex Builder then the SDK was installed in C:\Program Files\Adobe\Flex Builder 3\sdks\3.0.0 for windows, unless you changed the default installation directory. If you download the SDK separately then the default installation directory is C:\Program Files\Adobe\flex_sdk_3.

Adobe provides the Ant build tasks in the SDK. They are located in ant/lib/flexTasks.jar from the SDK installation directory.  You can use the Flex tasks with the following xml in your Ant build script:

<!-- FLEX_HOME is normally installed at C:\Program Files\Adobe\flex_sdk_3-->
<property name="FLEX_HOME" value="C:\Program Files\Adobe\Flex Builder 3\sdks\3.0.0\"/>
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}\ant\lib\flexTasks.jar "/>

This provides several Flex specific tags such as mxmlc, compc and html-wrapper.  You can find detailed documentation in the Flex 3 Livedocs.  Below you’ll find an example of an Ant build script that compiles a Flex application.
<?xml version="1.0" encoding="utf-8"?>
<project name="TestFlexNonBuilder" basedir=".">
<!-- FLEX_HOME is normally installed at C:\Program Files\Adobe\flex_sdk_3-->
<property name="FLEX_HOME" value="C:\Program Files\Adobe\Flex Builder 3\sdks\3.0.0\"/>
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}\ant\lib\flexTasks.jar "/>
<property name="APP_ROOT" value="src"/>
<property name="OUTPUT_DIR" value="WebContent" />
<property name="APP_NAME" value="TestFlexNonBuilder" />
<target name="init">
<delete dir="${OUTPUT_DIR}" />
<mkdir dir="${OUTPUT_DIR}" />
</target>
<target name="wrapper">
<html-wrapper
title="Test Flex App without Builder"
file="index .html"
height="300"
width="400"
bgcolor="red"
application="app"
swf="${APP_NAME}"
version-major="9"
version-minor="0"
version-revision="0"
history="true"
template="express-installation"
output="${OUTPUT_DIR}"/>
</target>
<target name="main" depends="init,wrapper">
<mxmlc file="${APP_ROOT}/${APP_NAME}.mxml"
output="${OUTPUT_DIR}/${APP_NAME}.swf"
keep-generated-actionscript="true">
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<!-- Access to all SWC files in the project libs directory. -->
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
<include name="../bundles/{locale}" />
</compiler.library-path>
</mxmlc>
</target>
<!-- Perform a clean build -->
<target name="clean">
<delete dir="${APP_ROOT}/generated"/>
<delete>
<fileset dir="${OUTPUT_DIR}" includes="${APP_NAME}.swf"/>
</delete>
</target>
</project>

You can find more valuable information like this including how to connect your Flex applications to Spring in the book that I did a technical review for called Pro Flex on Spring, published by APress.

Spring MVC Custom Property Editors

Thursday, January 22nd, 2009

From my experience, one of the initially frustrating things in Spring MVC was figuring out how to use a Property Editor correctly.

The idea is simple. You want to be able to convert back and forth between Java objects and their String representations. For example, let’s say you are making an internal website for a company and you want to display a list of employees. You want to be able to select an employee from the drop-down list, submit a form, and do some operation on the selected employee. Property Editors allow you to convert between your Employee objects and their String representations in the list. Spring has a number of built-in Property Editors, but for an Employee object, we will have to create a custom Property Editor to make this conversion. I found the official Spring documentation on this subject to be good, but a bit confusing on this subject.

Using Spring MVC with annotations, there are five concepts that will work together to achieve our desired goal.

1. There is an Employee object with this structure:

public class Employee {
private Long employeeID;
private String name;
} 

2. In the controller, we want to get a list of Employee objects and create a Model Attribute for use in the drop-down on the JSP:

@ModelAttribute("employees")
public List initEmployees()   {
return employeeDAO.getEmployees();
}

3. In the JSP, we want to be able to populate a drop-down list with the Employee objects and perform an operation on one of them. The drop-down on the JSP looks like this:

<form:select path="employee">
<form:options items="${employees}" itemValue="employeeID" itemLabel="name" />
</form:select>

4. Next we create the custom Property Editor. The setAsText(String) method overrides the default implementation in the PropertyEditorSupport class and will read in the selected employeeID from the drop-down list and convert it back to the appropriate Employee object.

public class EmployeeNamePropertyEditor extends PropertyEditorSupport {
EmployeeDAO employeeDAO;

public EmployeeNamePropertyEditor(EmployeeDAO employeeDAO)   {
this.employeeDAO = employeeDAO;
}

public void setAsText(String text)   {
Employee employee = new Employee();
employee = employeeDAO.getEmployee(Long.parseLong(text));
setValue(employee);
}
} 

5. The last change is in the controller class. We need to register this Property Editor and associate it with the Employee object in every controller where we will need to make the conversion.

@InitBinder
public void initBinder(WebDataBinder binder)    {
binder.registerCustomEditor(Employee.class, new EmployeeNamePropertyEditor(employeeDAO));
} 

After completing these steps, you should be able to properly configure a Property Editor for use with any Object that you like.

Chaining Spring View Resolvers

Friday, December 12th, 2008

Take this example of chaining view resolvers:

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="/WEB-INF/views.xml"/>
<property name="order" value="1"/>
</bean>

And this views.xml:

<beans><bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView"/></beans>

This should evaluate each view through the XmlViewResolver, then default back to the UrlBasedViewResolver if the XmlViewResolver does not find a view.

Now, let’s say we have the following tiles definition:

<definition name="forecastOverviewReport" extends=".mainTemplate" >
 <put-attribute name="pageHeader" value="Forecast Overview"/>
 <put-attribute name="body" value="/WEB-INF/jsp/forecastOverviewReport.jsp"/>
</definition>

Looks pretty good.

Now, what if we, by coincidence, have this bean definition?

<bean id="forecastOverviewReport" class="com.credera.forecasting.reporting.ForecastOverviewReport">
<property name="employeeDAO" ref="employeeDAO"/>
</bean>

Uh oh. The XmlViewResolver will find the bean definition above (even though it’s not in the views.xml which was explicitly specified!), and give you this lovely error:

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'forecastOverviewReport' must be of type [org.springframework.web.servlet.View], but was actually of type [com.credera.forecasting.reporting.ForecastOverviewReport]

But without the XmlViewResolver, this would have been perfectly fine. So, if you are chaining in an XmlViewResolver, make sure none of your tiles definition names are the same as any bean definition ids.

The Quickest Way to Get a Robust Java Application Running

Friday, December 12th, 2008

When developing an open source Java based web application there is frequently a great deal of work involved just to get your environment up and running. First of all the tools need to be selected, based on your requirements and preferences. At a minimum a robust website will require a place to store data (likely a database). Next, decisions will need to be made in regards to development frameworks followed by persistence layer, testing, and logging tools.

All of these choices can lead decision makers to software solutions that require fewer configurations. Previously PHP might have been chosen over a java/jsp solution. That trend has started to shift to Ruby on Rails in recent years.

In order to promote Java based web development to clients or for in house projects, the setup and configuration needs to streamlined and automated. Once this can be accomplished it will allow development to start sooner.

A few months ago I stumbled on a great open source project which provides an excellent solution for just these problems. The project named AppFuse, was started by Matt Raible. It follows a convention over configuration philosophy. In order to get a project up and running a few decisions are made (ie: database, framework, persistence layer). This project then relies on a myriad of open source projects that complement each other well. Most of these projects are heavily used in the Java world and some are the de facto standard.

For some insight on setting up a project with AppFuse please visit the Quick Start Guide. Below is a synopsis of how to get started.

  1. Required Downloads
    • Java (obviously)
    • Maven
    • Database (like MySQL)
    • Eclipse, IDEA, or NetBeans
  2. Follow the configuration settings
  3. Install optional tools
  4. Create a project
    • Run a maven command mvn archetype:create (followed by archetype parameters)
  5. Run your application Customize your application (Introduce business logic)

After step 5 above, the website is fully operational with a role based security layer that allows for user management and user self registration. At this point the website is operational quicker than a Ruby on Rails app. The customization still takes longer than Ruby on Rails scaffolding, but the conventions are provided and keep the development time closer.

The tool that speeds up most of the environment setup is Maven. AppFuse has just started utilizing Maven as of the 2.0 release. If you are unfamiliar with this tool it is well worth checking out the Maven Site. I would liken it to Ant on steroids.

The following is a list of technologies utilized in an AppFuse project.

Apache Commons

Junit

JMock

Spring

Struts

Hiberate/iBatis/JPA

Canoo Webtest

Displaytag

OpenSymphony

Jetty

JSF/Struts/SpringMVC…

Annotations

Cargo

Even if there are different tools and projects that you would like to use on your projects, AppFuse provides ideas for a blueprint by which all projects can be developed. Simply by setting up Maven properly and developing a set of convenience classes and tag libraries, projects can be set up quickly with little configuration. This allows most of the development time to be spent on building the business logic, thus increasing developer productivity.