JavaRanch Newsletter Articles in this issue :
StrutsThomas Paul Printable Version
AntThomas Paul Printable Version
Cindy's Segment - a Whimsical View of the WorldCindy Glass Printable Version
You said "Certification"?Valentin Crettaz Printable Version
Cattle Drive UpdateJason Adam
Pauline McNamara
Printable Version
Book Review of the MonthCindy Glass
Madhav Lakkapragada
Printable Version
March GiveawaysCarl Trusiak Printable Version
March NewsCarl Trusiak Printable Version

Struts

By Thomas Paul

Why we need a controller architecture

There are two basic architectures for JavaServer Pages (JSP) development. The first is a page-centric design that allows requests to be made directly to a JSP. The problem with this approach is that it will lead to JSPs with excessive embedded Java code.

The second, a Model-View-Controller (MVC) architecture variant often called Model 2, is a controller design that uses servlets to handle requests and JSPs to handle presentation. This allows for easy separation of function. Although this is an improvement over the pure JSP model, this design is not without problems. If we code a separate controller servlet for each page, we can end up with dozens of almost identical servlets. If we code a single controller servlet, we end up with a monolithic class with a huge if/else statement that can be difficult to maintain. What's needed to solve this problem is a controller architecture that can handle the repetitive details while still remaining flexible and easy to maintain.


Figure: Model 2 architecture

What is Struts?


Struts is an open source application framework that provides a flexible and easy to use controller architecture. The nature of the framework helps to promote a Model 2 application architecture with clear separation of functionality. Struts includes a controller servlet, JSP custom tag libraries, and utility classes.

Struts is being developed as part of the Jakarta project, sponsored by the Apache Software Foundation. Since it is an open source project, it can be downloaded from http://jakarta.apache.org/struts and used for free.

In this article I will explain the installation of Struts and discuss some of the basic functionality that it provides. For purposes of this discussion, I will be working with Struts installed in Tomcat running on a Win32 platform. To demonstrate some of the functionality of Struts we will code a simple logon function.

The Struts Architecture


Struts provides the controller that will serve as the entry point for all requests into our application. The controller determines which Java class will handle a particular request by referring to an XML file that contains mappings of URL paths to Java classes. For a class to be usable by the Struts controller it must extend the Struts Action class. Struts will call the perform( ) method of the Action object passing it the Servlet request and response objects as well as some Struts objects which we will discuss in more detail later.

In addition, Struts can also be used to run a form pre-processor to do simple form validation. This is controlled through the same XML file. We will also discuss this topic.

Struts also has custom JSP tag libraries that can simplify JSP programming. Besides special functionality used in Struts programming, custom tags can provide commonly used functionality such as iterating through a collection. Since the Apache Project includes the development of common custom tag libraries, the Struts tag libraries may change in the future.

Installing Struts


The installation of Struts is a relatively simple process. We will first create a directory structure in our Tomcat installation that will allow us to create our test application. (In this example we are assuming that Tomcat has been isntalled to a directory named c:\tomcat.) Under the webapps directory in the tomcat installation directory, create a struts directory. Under that directory create two directories, jsp and WEB-INF. The jsp directory will be used to hold the JSPs we create for our application. Under the WEB-INF directory create two directories, classes and lib. The lib directory will hold the struts.jar file. The classes directory will be used to hold all the Java classes that we code. Under the classes directory, create a directory named test. Under the test directory, create a directory called struts.

Now download the struts installation file. This is available as either a zip or tar file from the Struts homepage. Uncompress the file. There are 20 files in this zip file but you do not need them all for your installation. Extract all the files ending in .tld (there should be six of them) and copy them into the struts/WEB-INF directory. Extract the struts.jar file and copy it into the struts/WEB-INF/lib directory. It must be installed in the each application's lib directory. Note this warning from the Struts installation document:

WARNING - Do NOT add struts.jar to the classpath of your Servlet container in an attempt to avoid placing it in the /WEB-INF/lib directory of each individual web app! Doing so will cause problems with ClassNotFoundException exceptions.

So let me reiterate: You must place the struts.jar file in the "struts\WEB-INF\lib" directory. If you don't your application will not work correctly. You will probably see this error: org.apache.jasper.JasperException: Missing message for key title.login or you may see other errors.

You can also copy the struts.jar into the jre\lib\ext directory since you will need it to do compiles of programs using Struts. You should also add the servlet.jar file to that directory if you haven't already done it. You can find the servlet.jar file in the c:\tomcat\common\lib directory.

Once this has been completed, your directory structure and installed files (ignoring the other tomcat directories) should look something like this:

Figure: Directory structure of a Struts installation in Tomcat

web.xml File


There are two XML files that we, as Struts developers, will need to maintain. The first is the web.xml file for our application. This file is stored in the application WEB-INF directory. An example web.xml file is shown in Listing 1.

The first section of this file identifies the Struts controller class, ActionServlet and provides parameters for this class. The "application" parameter identifies a properties file that contains error messages used by the application. The "config" parameter identifies the Struts configuration file (more on this later).

The second section of the web.xml file tells Tomcat when to invoked the ActionServlet. In our example, ActionServlet will be invoked whenever a URL ending with ".do" is found. For example, http://127.0.0.1/struts/login.do will invoke the ActionServlet.

The final section identifies the Struts tag libraries.

Struts Configuration File


Listing 2 shows a simple struts-config.xml file that is passed as a parameter to the ActionServlet. It should be placed in the same directory as the web.xml file. The struts-config.xml file can have several sections. The first section we will look at is the <action-mappings> section. <action> tells Struts which class to invoke from the ActionServlet. Only the "path" and "type" are required entries. The "type" tells Struts which Action class to invoke when a URL with the model of the "path" is found. From the example in Listing 2, the URL http://127.0.0.1/struts/login.do will cause the ActionServlet to run a method in the class "LoginAction".

The other tag inside the <action> tag is the <forward> tag. This tag gives a way to identify which JSP should be given control by the Action class without coding it inside the class itself.

The Action Class


In order for a class to be entered in the <action-mappings> section and to be invoked by ActionServlet, it must extend the class org.apache.struts.action.Action (see Listing 3). The ActionServlet will execute the perform( ) method of the Action object. The perform method looks like this:


	public ActionForward perform(ActionMapping mapping, ActionForm form,
		HttpServletRequest request, HttpServletResponse response)
		throws java.io.IOException, javax.servlet.ServletException

The ActionMapping and ActionForm objects will contain information found in the struts-config.xml <action-mappings> and <form-beans> sections. The HttpServletRequest and HttpServletResponse objects are from the servlet.

The perform( ) method must return an ActionForward object which will tell the ActionServlet which JSP gets control. You can either:

  1. create an ActionForward object giving the constructor a String representing the name of the JSP to invoke: return new ActionForward("MainMenu.jsp");
  2. use the ActionMapping object passed into the perform method to get the JSP from the <forward> tag found in the struts-config.xml file: return mapping.findForward("valid");


We will use the method 2 since it will make it easier to change the JSP without changing the Java class.

Listing 3 is a simple Action class. It instantiates a validation bean which validates that the user has rights to the system. In real life this might connect to a database using JDBC or connect to an LDAP server using JNDI or make calls to an EJB servers. If the user does not have rights the bean returns an ActionError object. The LoginAction class then routes the request to the correct JSP based on what the validation bean returns.

If you wish to run this example, follow these steps:

  1. Create the LoginBean.java file (Listing 6) and compile it. Notice that the bean has a get and set method for each field that the JSPs will need.
  2. Copy the class file to c:\tomcat\webapps\struts\WEB-INF\classes\test\struts
  3. Create the LoginAction.java file (Listing 3) and compile it.
  4. Copy the class file to c:\tomcat\webapps\struts\WEB-INF\classes\test\struts
  5. Create the LoginForm.java file (Listing 4) and compile it.
  6. Copy the class file to c:\tomcat\webapps\struts\WEB-INF\classes\test\struts
  7. Create the LoginView.jsp file (Listing 7)
  8. Copy this file to c:\tomcat\webapps\struts\jsp
  9. Create the MainMenu.jsp file (Listing 8)
  10. Copy this file to c:\tomcat\webapps\struts\jsp
  11. Create the web.xml file (Listing 1)
  12. Copy this file to c:\tomcat\webapps\struts\WEB-INF
  13. Create the struts-config.xml file (Listing 2a)
  14. Copy this file to c:\tomcat\webapps\struts\WEB-INF
  15. Create the MessageResources.properties (Listing 5). This file contains the text to be displayed on the labels and buttons in the form providing us with a simple way to internationalize our form. Use for this purpose is optional.
  16. Copy this file to c:\tomcat\webapps\struts\WEB-INF\classes\test\struts
  17. Start Tomcat
  18. Enter http://127.0.0.1:8080/struts/jsp/LoginView.jsp in your browser and you should see a screen similar to figure 1.
  19. Enter a user id of "admin" and a password of "admin" and you should see a screen similar to figure 2.

Breaking Down the Action Class


Let's look at the main code of the perform( ) method:

First, we create our bean to validate the login information and make that bean available to our JSPs. We then pass the HttpServletRequest object to the validation bean so that it can extract the fields it needs to validate.


		LoginBean lb = new LoginBean( );
		request.setAttribute("LoginBean", lb);
		lb.setParameters(request);

We then call the validation bean to validate the information from the form returning to us an ActionErrors object. ActionErrors is a collection object that can hold ActionError objects. In a moment we will see why we use ActionErrors to report errors. We then add the ActionErrors object to the HttpServletRequest object to make it available to our JSPs. The key we use (Action.ERROR_KEY) is a standard key for ActionErrors objects in Struts.


		ActionErrors ae = lb.validate( );
		request.setAttribute(Action.ERROR_KEY, ae);

Finally, we look at the ActionErrors object that was returned to us and if it is null or empty (either of these can signify no errors in Struts) we forward to the main menu JSP. If the ActionErrors object contains an ActionError, we pass control to the Login JSP.


		if (ae == null || ae.size( ) == 0) {
			return mapping.findForward("valid");
		} else {
			return mapping.findForward("invalid");
		}

Why use ActionErrors?


If the LoginBean finds an invalid login was attempted, it executes the following code:


	ActionErrors ae = new ActionErrors( );
	ae.add("userId", new ActionError("error.invalid.login"));
	return ae;

First it creates an ActionErrors object to hold the ActionError object it is about to create. Next, it creates the ActionError object passing a String to the constructor. The String is a key from the MessageResources.properties file (Listing 5). Then it adds the ActionError object to the ActionErrors collection giving it a String representing which particular field is causing the problem.

But why go to all this trouble to create ActionError objects in the first place? The reason has to do with the JSP. If we look at the LoginView.jsp we find this line:


<html:errors />

This tag will extract the information from the ActionErrors object and display all the errors neatly on the form (see Figure 3). The tag will use standard keys from the MessageResources file to display a header and footer around the error mesages. See the errors.header, errors.footer and error.invalid.login from the MessageResources.properties (Listing 5).


You can also use <html:errors property="userId" /> to display a particular message based on the key used when it was added to the ActionErrors object. This is useful if you want to display the message next to the field causing the error.

JSP Tags


If you look at LoginView.jsp, you will see that there are numerous references to the Struts tag libraries. For example:

	<struts:message key="heading.login" />
	<html:form action="/login">
	<html:text property="userId" size="10" />
	<html:password property="passWord" size="10" />
	<html:submit>
		<bean:message key="button.submit" />
	</html:submit>

Each of these can simplify the use of Struts, the writing of your JSP, and the internationalization of your application.

struts:message will replace this tag with the matching text found in the MessageResources file. This can simplify internationalization issues.

html:form will define the form tag with the listed action. The action is specified by using the path from the struts-config.xml file. It will be replaced with the correct form (/login.do) before it is sent to the client. The html:form tag will also populate the input fields with the current property values from the bean associated with this form.

html:text and html:password will create either a text field or password field and populate it with the specified property from the bean associated with this form.

html:submit will generate a submit button for the form. We can use a struts:message inside the html:submit tag in order to specify the label on the button.

There are tags within Struts that allow you to create radio buttons, check boxes, and other form objects.

The ActionForm class


We have seen how the Struts architecture works and developed a simple Struts application. The one major piece we have not looked at is the ActionForm class which provides a simple way to do basic form validation.

In most applications there are some basic validations that need to be done on data from a form. This may include insuring that required fields are entered, that dates are in a valid format, that numeric fields contain numerics, etc. Struts provides a simple mechanism using form beans to provide this level of validation. Form beans (any class that extends ActionForm) should not connect to a database or provide complex validations.

Form beans will be given control by Struts before the Action class. If the form bean determines that the form is invalid it should return an ActionErrors object containing an ActionError object for each error found. Struts will then return the input JSP back to the user with the errors displayed on the form. The Action class will not be invoked unless an empty ActionErrors object or a null is returned.

Listing 4 displays a sample form bean. A form bean must extend ActionForm and should have a get and set method for each field on the form. Struts will run the validate( ) method of the form bean. The validate( ) method looks like this:

public ActionErrors validate(ActionMapping mapping,
		HttpServletRequest request) {

	ActionErrors ae = new ActionErrors( );

	if (userId == null || userId.equals("")) {
		ae.add("userId", new ActionError("error.no.userId"));
	}

	if (passWord == null || passWord.equals("")) {
  		ae.add("passWord", new ActionError("error.no.passWord"));
	}

	return ae;
}

The code itself is fairly simple and should be familiar from the LoginBean.

To activate this form bean we need to add a few entries to the struts-config.xml file. Listing 2a shows the revised file. First we need to add a defintion for the bean itself:

  <form-beans>
  	<form-bean name="login" type="test.struts.LoginForm" />
  </form-beans>


Next we turn on validation for the login and define the input form. The input form is used by Struts to determine which JSP to give control to when the form bean returns ActionErrors:

  <action
    	path="/login"
    	type="test.struts.LoginAction"
    	name="login"
    	input="/jsp/LoginView.jsp"
    	validate="true">

	    <forward name="valid" path="/jsp/MainMenu.jsp" />
	    <forward name="invalid" path="/jsp/LoginView.jsp" />
	</action>

Now whenever the login is attempted, LoginForm will run and validate that the required fields are entered before control is passed LoginAction. If the fields are not entered then the form will be redisplayed and LoginAction will not run. Figure 3 shows the output of a failed login attempt.


Figure: MVC architecture with example classes

Wrapping It Up

That is a brief look at the basics of Struts. There is much more to Struts and the custom tag libraries contain a lot more functionality than we have touched upon in this article. I recommend that anyone doing servlet/JSP/EJB development take a look at Struts. Even if you choose not to use it, I think it will give you some good ideas about the proper way to build a Model 2 architecture.

Meanwhile, Struts development continues. The Struts custom tag libraries are being merged with the JSP Standard Tag Library (JSTL). Struts for Transforming XML with XSL (stxx) is available. To keep up-to-date with what is going on in Struts and to find out how others are using Struts, you can subscribe to the STRUTS-USER mailing list.


Return to Top

Ant

What is Ant?

By Thomas Paul

Ant is a Java based build tool developed as part of the Apache Jakarta project. It can be downloaded from the Ant home site: http://jakarta.apache.org/ant. Unlike make files, which are operating system specific, Ant is designed to be as cross platform as Java. Ant uses Java classes and XML scripts to provide an automated way to build applications and to be available on every Java compatible platform.

Ant (which stands for Another Neat Tool) was originally developed by James Duncan Davidson as part of the Tomcat project. Ant was developed specifically to simplify the process of building Tomcat. When Tomcat was donated to the Apache project, Ant went with it. It was soon realized that Ant was very useful and could be used in any project and became a separate Apache development effort. The current release of Ant is 1.4.1 (as of February, 2002).

What Ant can do

Ant is a build tool. But Ant will allow you to do much more than just build your code. Ant functionality includes:

  1. extract source from a version control system
  2. create directories
  3. delete directories
  4. compile code
  5. generate javadoc
  6. jar files
  7. copy files
  8. generate e-mail
  9. ftp files
  10. execute SQL statements
  11. run unit test
  12. or any other function that you might need!

Ant is fully expandable. It is open so that new functions can be added by simply writing a new Java class.

The easiest way to explain Ant is with an example so we will look at a typical build and deploy script and then we will look at some code to create our own function.

Installing Ant

Ant is simple enough to install. First, download the binaries from the Apache Ant web site. If you intend on writing your own Ant classes, you can download the source as it can be a useful guide to writing Ant classes. Next, extract the files from the Ant zip file. Update your classpath to point to the ant.jar file which is found in the ant/lib directory. According to the Ant installation documentation:

     Note: Do not install Ant's ant.jar file into the lib/ext directory of the JDK/JRE. 
     Ant is an application, whilst the extension directory is intended for JDK extensions. 
     In particular there are security restrictions on the classes which may be loaded by 
     an extension.

Next, add the bin directory to your path. Set the ANT_HOME environment variable to the directory where you installed Ant.

If everything is working, you should be able to type Ant at your command line prompt and get this response:

c:\>Ant
Buildfile: build.xml does not exist!
Build failed

Note: If you are running WinXP and are having problems getting Ant to run, you should download the latest nightly build and not the current release version of Ant.

A Build Script

Ant requires the use of a build script to tell Ant what to do. The default name of the script is build.xml but you can use any name you want. Let?s take a look at a typical build script.

<?xml version="1.0"?>
<project name="aag" default="compile" basedir=".">

Every Ant build file contains one project. The attributes on the project tag are the name of the project, the default target to run when no target is specified on the command line, and the base directory to use when locating files. Ant works best when relative directories are used. Here we are creating a project called ?aag?. The target named ?compile? will run as the default (more on targets in a moment), and the base directory to locate directories and files is the directory where this build file is located.

<!-- ===================================== -->
<!--         Global properties             -->
<!-- ===================================== -->

<property name="name" value="aag" />
<property name="build" value="${basedir}/build" />
<property name="baselib" value=?/jdk/jre/lib" />
<property name="dist" value="${basedir}/dist" />
<property name="source" value="${basedir}/source" />
<property name="docs" value="${basedir}/docs" />
<property name="api" value="${docs}/api" />
<property name="tomcat" value="/tomcat/webapps/aag/WEB-INF/lib" />
<property name="tomcat-jar" value="/tomcat/webapps/aag/jar" />

Ant allows the use of properties to save values. In this section we create a series of properties that will represent the various directories we will be using in our script. In this way, if we want to change a directory we can change it in the property list and we won?t need to find each place in our script that we used that directory. Whenever Ant sees ${AName} it will replace this with the associated property named AName. So value="${basedir}/build" becomes value="./build"since basedir was defined in the project tag. value="${docs}/api" will become value="./docs/api".

The Target Tag

<!--===================================== -->
<!--            Init                      -->
<!--===================================== -->
<target name="init" >
     <tstamp />
     <mkdir dir="${build}" />
     <mkdir dir="${api}" />
     <mkdir dir="${dist}" />
</target>

The section above is a target tag. Targets can be specified on the command line when executing Ant and Ant will then execute the specified target. All commands within the target tag are executed in the order specified.

Within the init target, we first initialize our timestamp. tstamp will initialize three properties which can be used within the build script. The DSTAMP property is in the format "yyyymmdd", TSTAMP is in the format "hhmm", and TODAY is in the format "month day year". These properties could be used, for example, to generate unique file names.

The next commands will create the directories required to compile and jar our application.

Compiling our code

<!-- ===================================== -->
<!-- Compile -->
<!-- ===================================== -->
<target name="compile" depends="init" >
     <javac srcdir="${source}" destdir="${build}"
        <classpath>
          <pathelement location="${baselib}/mysql_uncomp.jar" />
          <pathelement location="="${baselib}/struts.jar" />
        </classpath>
     </javac>
</target>

The next target is named compile and has the init target as a dependency. This means that if compile is specified as the target of a Ant run, the init target will automatically run first. The compile itself if fairly simple. Ant will compile each of the java files found in the source directory and place the class files in the destination directory. Ant will automatically place the class files in the correct structure based on their package. It will also skip compiling any java file that has already been compiled and has not been changed but only if the source files are in a directory structure exactly matching the package structure. Notice that the classpath to use for the compile can be specified with separate pathelement tags. It is recommended that the classpath be specified within the compile tag so that your compile doesn?t rely on the classpath being specified correctly outside of Ant.

Generating JavaDoc

<!-- ===================================== -->
<!--           JavaDoc                     -->
<!-- ===================================== -->
<target name="javadoc" depends="compile" >
     <javadoc sourcepath="${source}"
         destdir="${api}"
         packagenames="com.aag.*" />
</target>

The next target is javadoc which is dependent on the successful completion of the compile target. Since the compile target is dependant on the init target, specifying javadoc on the command line will cause init , compile , and javadoc all to run. The javadoc tag will cause JavaDoc to be generated for all classes in all packages that start with com.aag that are in the sourcepath . The JavaDoc will be placed in the destdir . In this example, packages such as com.aag.io , com.aag.database , and com.aag.database.pool will all have JavaDoc generated.

The Jar Tag

<!-- ===================================== -->
<!-- Jar and Copy -->
<!-- ===================================== -->
<target name="jar" depends="javadoc" >
	<jar jarfile="${dist}/${name}.jar" >
		<fileset dir="${build}" />
		<fileset dir="${docs}" />
	</jar>
	<copy todir="${tomcat}" file="${dist}/${name}.jar" />
</target>

The next target is named jar and depends upon the successful completion of the javadoc target. The jar tag will create a jar file. The name of the jar file is controlled by the jarfile attribute. The files that are included in the jar file are specified by separate fileset tags. The copy tag will copy the jar file into the tomcat webapps directory.

Cleaning Up

<!-- ===================================== -->
<!-- Remove build directories -->
<!-- ===================================== -->
<target name="clean" >
	<delete dir="${build}" />
	<delete dir="${docs}" />
	<delete dir="${dist}" />
</target>

</project>

The final target is named clean and since it has no other target dependent on it, will only run if specified on the command line. The delete tag will delete the specified directory.

The build script is terminated with a final </project> tag.

Running the Script

Here is the possible output if we ran this script from the command line with ?ant jar?:

>ant jar
Buildfile: build.xml
init:
[mkdir] Created dir: C:\JavaProjects\AntTest\build
[mkdir] Created dir: C:\JavaProjects\AntTest\docs\api
[mkdir] Created dir: C:\JavaProjects\AntTest\dist
compile:
[javac] Compiling 12 source files to C:\JavaProjects\AntTest\build
javadoc:
[javadoc] Generating Javadoc
[javadoc] Javadoc execution
[javadoc] Loading source files for package com.aag.io...
[javadoc] Loading source files for package com.aag.database...
[javadoc] Loading source files for package com.aag.database.pool...
[javadoc] Constructing Javadoc information...
[javadoc] Building tree for all the packages and classes...
[javadoc] Building index for all the packages and classes...
[javadoc] Building index for all classes...
jar:
[jar] Building jar: C:\JavaProjects\AntTest\dist\aag.jar
[copy] Copying 1 file to C:\jakarta-tomcat-4.0.1\webapps\aag\WEB-INF\lib
BUILD SUCCESSFUL
Total time: 6 seconds

Ant first created our target directories, then compiled our source, generated the JavaDoc, put everything into a jar file, and then copied the jar file to our Tomcat installation.

Now we can clean up our directories by running ?ant clean?:

>ant clean
Buildfile: build.xml
clean:
[delete] Deleting directory C:\JavaProjects\AntTest\build
[delete] Deleting directory C:\JavaProjects\AntTest\docs
[delete] Deleting directory C:\JavaProjects\AntTest\dist
BUILD SUCCESSFUL
Total time: 0 seconds

Creating our own tasks

Ant comes with a rich collection of tasks, some of which we have discussed. There are additional optional tasks available at the Ant home page. If none of these tasks meet your needs, Ant allows you to write your own tasks.

Writing your own task is not very complicated. What if we want to send the jar file that we just created to one of our staff members who works from home. We don?t want to send this jar file in the clear since it contains our top secret development work. We need to create a new task that can take a file, encrypt it, and then put it into a directory where our developer can find it. The Java class to perform this function is Listing 1.

The process starts by creating a java class that extends org.apache.tools.ant.Task. The class must have a default constructor. We need to create a setter method for each attribute we intend on adding to our tag. Finally, we need to create an execute( ) method that does all the work.

public void setKeyFile(String keyFile) {
	this.keyFile = keyFile;
}
public void setInputFile(String inputFile) {
	this.inputFile = inputFile;
}
public void setOutputFile(String outputFile) {
	this.outputFile = outputFile;
}

Each of these setter methods relates to an attribute on our tag:

<crypto keyFile="key.ser"
	inputFile="${dist}/${name}.jar"
	outputFile="${dist}/${name}.secret.jar" />

When the execute( ) method runs it will have access to all the attributes that were specified within the crypto tag.

The execute( ) method must be declared to throw org.apache.tools.ant.BuildException. No other exceptions can be thrown. The constructor for BuildException allows for the wrapping of other excpetions:

} catch (Exception e) {
	throw new BuildException("Problem with cipher", e);
}

The only thing left to do is to specify in the build script the actual name of the Java class. This is done with a taskdef tag which is normally specified in the section with our global variables.

<taskdef name="crypto" classname="com.tom.ant.Crypto" />

The complete script is specified in Listing 2.

The Future of Ant

Ant development continues and Ant 2.0 is currently being developed. It is expected that build files developed in Ant 1.4 will not work in Ant 2.0.

That wraps up our brief look at Ant. If this article has interested you in Ant, you should visit the Ant home page and look at the documentation. Ant contains many more features than what we have seen in this article. I hope that this has given you a flavor for the capabilities of Ant and the simplicity of using Ant to build applications. If you are interested in Ant, I recommend that you sign up for the Ant user list available here: http://jakarta.apache.org/site/mail2.html.


Return to Top
Cindy's Segment - a Whimsical View of the World

Segment 1:
Lifestyles of the Rich and Object-Oriented
Or -
Not all Variables are created Equal

Imagine a world where all is clean and bright. Suddenly a call to glory goes out and in response, into this world comes a Mighty Class. As all good Classes do, the first thing that happens is that a ClassFile Castle is built to protect the good subjects of the class.

Now, this ClassFile Castle is built with a certain amount of storage space, of course. There is space in the Castle for class variable storage, where the Elite Static Variables can store their primitives or references. And there is space in the courtyard for literals to mill around and pool together.

There is a Castle Library where special information about related kingdoms is kept.

In addition, there is an area just outside the Castle, set aside for the Parliament, affectionately known as the Method Area. This area is a reserved place for all Royal decrees to be kept. Of course in JVMLand, the only behaviors that are allowed are those documented by royal decree. There are regular method decrees that dictate the behavior of the objects, and then there are the powerful Static decrees (also known as Static methods) that speak of things that only the Mighty Class can do.

Being a good and kind ruler, the Mighty Class allows his subject members to build Object Homes in the suburbs, outside of the Castle. The suburbs are called "The Heap". As each new object comes into being, a Home on The Heap is built, and these homes also have a certain amount of storage. So as to be fair, each and every home under the rule of this Mighty Class has exactly the SAME amount of storage, where each objects member variables can keep their primitives and references. The member variables in each Object Home is often called the objects fields, but I would call them storage closets.

And so the subjects were happy in their Object Homes, with plenty of space to hold their member variables and all of their behaviors dictated in the Method Area. And they have at their disposal all the resources of the ClassFile Castle.

But there is a dirty little secret going on in JVMLand. - - - Not All variables are created equal.

Sure, there are Elite Static variables being kept in the Castle, knowing that the Castle will probably last as long as all JVMLand. Yes, there are member variables snug in their Object homes, secure in the knowledge that as long as the Object Home is never completely abandoned, there will be a place for that member variable to live. But what no one ever talks about, what is whispered behind closed doors, is what happens in the Method Area.

When a Method is invoked, be it by one of the objects or by the Class itself, there are variables that are created automatically, on the fly. These poor creatures are never given a proper home. They are just assigned a slot on the stack, like a slave in a ship, where they toil away for the brief moment that their method is being executed, and then POOF!! They are tossed away like so much bit trash.

Oh the tragedy of it all! To have such a short existence, and to be treated with such distain. To be insulted by being called "Local Yokel"! To never have a classload or construction party, and so no one trusts you unless you are initialized right at the moment of your birth. What did they do to deserve that?

Not only is it bad enough that you know that you die as soon as your Method dies, but so often your scope of influence does not even last THAT long. If you happened to be a variable that is created in a block of code inside that Method, when the block is over, you are treated as though you were practically invisible. NO ONE knows that you are still there!!!!

Heck, if you are so unlucky as to be created in the initialization section of a For loop, when all the loops of that For stuff is over, your scope is over, you just sit around waiting for the end. Heaven forbid you should be created INSIDE one of the loops of a For loop, then your scope is only as long as the ONE loop.

Even your NAME is disposable. Heck, they figure that if you have no scope of influence, then they can't see you, and they can't get confused about who they are talking about, so what the heck, just use the same name over again. Bah!! No respect at all.

There is only one revenge that is sometimes available to the local variable. (Whisper this now) If they happen to have the same name as one of those high falutin' member or class variables or a parameter, during their short existence, they get to be "IT". If someone uses that name, it is the LOCAL variable that gets noticed. They get to over-shadow those big-shots with the stable life-styles.

And you know what, I think that they DESERVE IT.

So next time that you are thinking about how convenient it is to have Member Variables, remember the lowly Local Variable, and feel his pain.

Copyright ? 2002-2004. Cindy Glass. All rights reserved.
Graphics by Pauline McNamara and Stephanie Grasson
Next month - "When relatives move in" - or "Surviving your sub-classes"

Return to Top

You said "Certification"?

by Valentin Crettaz.

This article aims at guiding you towards the Java 2 Programmer Certification (SCJP2), although some of the information provided here may apply to other certifications as well. I also would like to provoke some kind of reaction. I'd like you to ask yourself some questions about your actual Java level. Is the latter sufficiently high for getting further or do you need to study more?
To get those questions answered, I'll first explain what a certification really is. Next, I will talk a bit about what advantages a certification can bring. I then enumerate some misconceptions that may arise when people are talking about certifications. After that, I will investigate the dos and don'ts, that is, tips to follow and traps to avoid. Finally, since the main purpose of this article is not to describe in detail every step you should follow to get certified, but to spare you some time by helping you to avoid going the wrong direction, I won't give a detailed speech about preparation tips or where to find mock exams, but I will merely give you some pointers on the web where you can find some outstanding resources.

What is a certification?

To get the ball rolling, let's have a look at the first paragraph on the Sun Education web site:

This certification is for programmers experienced in using the basic syntax and structure of the Java[tm] programming language.
Well, this sentence says it all: a certification is for programmers who already have a good experience in programming with Java and are willing to go further under the hood investigate the intricacies of the language.
A Java certification --and all certifications in general-- should not be seen as a way of learning a field from scratch. It is more geared towards the improvement of one's already-acquired knowledge. With that paper hanging on the wall of the living room, one might be taken more seriously when talking about Java issues or when applying for a programmer position. Some will say, "it's just a paper anyway". I would answer that this paper actually makes a difference. It's difficult to assess one's knowledge of Java (or any other knowledge for that matter), but getting certified brings you one step closer to credibility. There is a difference between saying "I know Java" and actually knowing Java ("I know Java". "Yeah, me too, 'been on vacation there! Beautiful, isn't it?"). I think you got my point.

The Fine Print

Recent discussions (Is Certification really worth it ? and Opinions on SCJP2 test) posted respectively in the Programmer Certification Study and the Programmer Certification Results forums kept my attention. What one can conclude after reading those discussions is that, apparently, some people want to get certified just for fun or to improve their Java knowledge. It also seems that some people think certification is not worth a penny. Everyone's thoughts are legitimate, of course, I won't argue with that. However, I assume that if you keep reading you believe in the value of a certification.

What is a Certification good for?

As mentioned in the previous paragraph, this question has been the topic of many debates. There is an everlasting tirade about how good multiple-choices exams can assess one's knowledge. One party argues that a certification doesn't prove anything while the other party claims that a certification helps evaluate one's know-how. Well, both are right and wrong at the same time. To answer this question, be aware that there are different ways of certifying people. Let's take a peek at the Java example since this is what Javaranch is all about. The Sun Education Center delivers 4 different certifications relating to the Java Language:

  • The Sun Certified Programmer for the Java 2 Platform (SCJP2);
  • The Sun Certified Web Component Developer for the J2EE Platform (SCWCD);
  • The Sun Certified Developer for the Java 2 Platform (SCJD);
  • The Sun Certified Enterprise Architect for the J2EE Platform (SCEA).
The first and the second are so-called multiple-choices exams. They require you to have basic knowledge of the Java Language, to know what it is composed of and how to use its basic building blocks to produce correct Java code. All you need after that is experience on the field, which when acquired, leads you to the next more serious certifications briefly presented below. As you may already know, there is no right way to code. There are almost always many solutions. This is exactly what the next certifications are all about.
The third and the fourth are somewhat harder; they not only require you to think but to think efficiently. You are given a work assignment to fulfill and then you have to face a Java expert and defend your design choices. Questions you might expect during the follow-up exam could be: What are the advantages of using this class instead of that one? What are the consequences of using it over another?
Now, it's clear that certifications like the first or the second less accurately assess one's knowledge since it is a matter of learning. More or less, everyone is capable of learning. However, certifications like the third and the fourth do require some outstanding knowledge of the field since you cannot possibly get certified by guessing the answers or by counting on chance.
This being said, it is obvious that both parties have legitimate beliefs. SCJP and SCWCD are more commonly aimed at because (let's face the truth) they are easier, after all, if you have a good memory and you are good at remembering things you can be a SCJP (or SCWCD for that matter). Assuming what precedes, the first party gets the credit in saying that such an exam doesn't prove much.
Their arguments don't hold, however, against SCJD and SCEA because it would take a miracle for somebody counting on chance or on her ability to remember things to get certified.

Well, to sum up, there will always be people who disagree and that's better that way. Otherwise how would the world evolve? Debates have ever been sources of evolution. No debates, no evolution. Let's just conclude this paragraph by saying that if you are willing to seek for certification, go for it, don't care about what people are going to say about it, the bottom line is YOU want to get certified (or your manager says so). BUT, pay attention to what follows!

Some Misconceptions

The certification path can be applied to many fields of study. Apparently, some people still don't make a difference between a respectable cook and a "grand chef". If you want to learn cooking then you take cooking 101 and learn the basics of cooking. How to boil water to make macaroni? How to melt some cheese to get macaroni and cheese? Then, when you are sick of macaroni and cheese and want to become somewhat more experienced in cooking, you can take advanced cooking lessons where you are going to learn how to make yummy gravies to pour on your 1/2 lb steak or how to make a good stuffed Thanksgiving turkey.
Ever tried to build a house by beginning with the roof? No need to be a PhD to figure out that the house doesn't stay upright long.
Well, the same applies to Java. First, you take Java 101 to learn the basics of the language, and then, only then, you can get further.
That's right, one step after another.
Focusing on SCJP, it is not a way of learning Java at all but more a way of improving what you already know of Java and learning some basic coding techniques that will make you stand ahead of the herd of wannabes. Again, if you try to become a SCJP without knowing the basics of Java, either you fail right away or you might get into trouble once hired and staring helplessly at your computer screen. That's the harsh truth but it needs to be said, emphasized and not be left untold.
Take the certification seriously and don't look at it as some banal professional or academic experience. Moreover, don't seek for certification because a friend of yours told you so or because you want to fancy up your resume with a, well, nice logo. Instead, you should have a profound attraction to the Java Technology itself and also want to promote it.

If you are asking yourself questions such as "What language does the word 'overloading' come from?" or "What is a subclass?", then you probably should hit the books because you are not ready. To pretend being eligible for SCJP, you should at least be comfortable with basic object-oriented concepts on which the Java Language relies, that is you should be able to answer questions like "what is an object?", "what is a class?", "what is inheritance?", etc. If you don't know how to deduce the output of a given code, then you don't know how to read code and you need more practice.
Now, if you don't know why String literals are not garbage collected or why wrapper classes (Integer, Double,...) in the package java.lang are immutable, don't worry because those are advanced topics which you will learn during your certification study.

Another thing I've seen way too much is the ever-present advice "You can count on x% chance during the exam". Two words: forget it! Let's be somewhat realistic here. If you are counting on chance to help you, you are an unreliable person and way off the line. It is true, though, that chance may help but no one should partly rely on it to get certified (the same advice holds for any other kinds of exams).

A further issue is that apparently some people are complaining about the memorizing requirements that the certification study involves. Let's face some facts:

  1. the act of memorizing has never killed anybody;
  2. we all have a brain and we won't even use half of it by the time of our death, so capacity is not an issue either;
  3. And last but not least, time is money and everybody knows that the access time to a human brain is way smaller than the time it takes to open a browser and search the API; the more you know the faster it goes (your manager will be happy), it's that easy. It doesn't mean that you have to know everything by heart, it just means that what is required to memorize for the certification exam are signatures of methods and constructors which are members of heavily used classes.
    Anyway, if you claim to be an experienced Java programmer then you probably wouldn't even complain about this memorizing requirement since you most surely already know what is required to know. The ones who complain are people who need some more learning and are not ready for getting certified yet (If you have arguments against what I just wrote, I'd be happy to hear them).
It doesn't hurt to learn more than required either, just to gain some technical culture.

If you think you satisfy the requirements stated above, then you may safely follow the certification trail further.

Dos and Don'ts

I won't describe any specific method to follow for getting certified, you should build up your own. Everybody is different; hence, everybody works according to a different method.

The first and most important thing is: DON'T SCHEDULE YOUR EXAM BEFORE YOU KNOW YOU ARE READY!!!. That's pure nonsense. How can you know that you'll be ready by the date you have chosen? What you will end up doing is getting more and more stressed because you think you might not finish in time. Stress is bad; it only leads you away from your original goal. Now, you are asking yourself, "how can I know that I'm ready?". Good question! I'll answer that by the end of this article; just keep reading.

The next important thing to do is to organize yourself properly. That means:

  • Be consistent. Don't learn 10 hours a day during 5 days and then nothing during 5 days and then again 8 hours a day during 2 weeks. Define right from the beginning, the daily time you will spend on the task. You may be able to adjust that duration after a while. If you are not able to spend the same amount of time everyday (because of whatever reason), then you should at least do a little something just to stay in touch with the study.
  • Don't overdo it. There is no need to work days and nights without taking some rest. All this will achieve is to increase your stress level and we already know that this is not good. If you are studying full-time for SCJP you shouldn't work more than 8-9 hours a day. Past that time, you will still be able to work, no questions about it, but your learning capacity will be diminished. The symptoms may be that you remember having read something but you can't recall what it was about or what it taught you.
  • Prioritize and schedule. Read several times the objectives list and underline the topics which you feel you are already comfortable with in green and the one you feel you need to work on in red. The final goal is to make all objectives appear in green, that's simple. Assign each objective a weight. The higher the weight, the less you already know and master about the objective. Prioritize the higher-weighed objectives first, because those are the ones that may require more time for you to assimilate. Define a period in your schedule during which you will spend time on them.
  • Get some resources. It is important to get several complementary resources, like books, mock exams, forum archives, and articles. Everything that might be of help to you during your preparation. Also, always compare resources against each other whenever you have a doubt about something. It may well be the case that sometimes a book says something and another says exactly the opposite. Be absolutely sure of what you learn. You can always post a question if you are still in doubt after several comparisons.
  • Review. Reserve enough time before the exam to review the objectives and eliminate remaining weaknesses.
Once you have made yourself a nice organized schedule, you can begin the festivities. From now on, no more political talks, I promise. Let's get down to work.

Resources

The first thing to feed into your browser's location field is the following address: http://www.javaranch.com/maha/index.html. This web site has been created by Maha Anna (short for Mahalakshmi Annadurai), an Indian Electronics and Communication Engineer who got certified during the year 2000. She thought that sharing her own certification experience on a website would be a great idea, which it is. She enumerates very good preparations tips, lists a great deal of mock exams and resources as well as interesting discussions which happened at Javaranch. So, I strongly recommend you to point your browser to that web site and benefit from it. Next, I will just elaborate some of the tips she gave.

The next thing to do --which should already be done-- is to get the Java 2 SDK Standard Edition (J2SE) so that you may create your own pieces of code. I'd get the latest stable version which is, as of this writing, 1.3.1, but version 1.2 is fine too. Lots of coding practice is the key to mastering the language. Never underestimate that.I guess I will never manage to emphasize this point enough. Every time you encounter a blurry concept, write some code, compile it, run it, change some statements, re-compile it, re-run it, twist it, re-compile it, and so on until you get the point. You won't always get to the point quickly, though, since some topics are rather difficult. If such a situation arises, that's the moment to point your browser to the Programmer Certification Study forum at Javaranch and ask your buddies for some piece of advice. But, by all means, DO NOT post a piece of code without even trying to compile and run it first. That's pure laziness. Questions like: "what is the output of this code?", or "will this code compile and run?" should be banished. I have noticed lately that an ever-growing number of people in the SCJP forum are aware of that too, and are simply answering a nice and killing "first try, then ask".
Seriously, the practice requirement is very important. The equation is simple: the more you code, the more comfortable you are in analyzing Java code and the faster you are going to spot bugs.

The inseparable companion of the Java programmer is the Java Application Programming Interface (API) documentation. A well-organized documentation containing thorough information about all packages, classes, methods and fields released with the J2SE. It's not something you read sequentially but it is more like a dictionary. Use it. Answers to questions like: "what does the String's method concat() do?" or "which methods are declared in class Thread?" can be found in the API. Time is precious, so stop wasting yours (and other's!) and browse those marvelous API first.
Anyway, if you satisfy the requirements I stated above, you most probably already know all that. You may not know about the Java Language Specification, though, which I'll talk about next.

The Java Language Specification (JLS) is the "best" technical Java reference. On the book's web site, it says:

The book provides complete, accurate, and detailed coverage of the syntax and semantics of the Java programming language. It describes all aspects of the language, including the semantics of all types, statements, and expressions, as well as threads and binary compatibility.
.
Wondering how a switch construct works? how forward references are managed? how class instances are created? and much more. The JLS provides accurate and thorough explanations on all basic foundations of the Java Language. Undoubtedly, THE reference. Be well aware, though, that the JLS contains some cryptic parts which heavily rely on mathematical definitions. So if you are not used to have mathematical books as bedtime readings you may want to either get used to it or look for a more understandable reference presented next. Moreover, the JLS only handles the java.lang package and does not spend time on specific Java packages, like java.awt, java.util or java.io. To get information about the later, you are better off consulting specific books on the topic, the Java tutorial, or books expressly dedicated to the certification which you can find at the Javaranch Bunkhouse.

To briefly conclude, if you want your certification to be worthy, you have to prepare yourself accordingly. Cheating is for weak people and it is not of much help anyway. Work seriously and try to write as much code as you can, this is the only way to learn Java rapidly and efficiently. If you believe in the value of your certification, focus and don't listen to troublemakers. Put all your energy in your study and you'll see that it is worth it.

Written by Valentin Crettaz.
Reviewed by Marilyn deQueiroz, Jane Griscti and Dave Vick.


Return to Top
Movin' them doggies on the Cattle Drive

It's where you come to learn Java, and just like the cattle drivers of the old west, you're expected to pull your weight along the way.

The Cattle Drive forum is where the drivers get together to complain, uh rather, discuss their assignments and encourage each other. Thanks to the enthusiastic initiative of Johannes de Jong, you can keep track of your progress on the drive with the Assignment Log. If you're tough enough to get through the nitpicking, you'll see your name on the Graduation Log.

And a shiny spur goes to...
I'm happier than a pig in slop to announce our latest graduates!  Christie Xu and Terence Doyle drove their way through OOP and is now moseyin' on over to Servlets. Newcomer Sam Tilley rode hard and made it through Java Fundamentals, time to lasso them objects in OOP!

Great job y'all!

Back from being out on the range...
Angela Poynton joined her fellow drivers out on the range after a long snooze in the bunkhouse. Welcome back Angela!

Saddle sore...
Daniel Olsen and Jason Adam are itchin' to get out of the JDBC saddle.  Hang in there, graduation is just around the corner!

Nitpicking is hard work too...
Let's all raise a toast of sarsaparilla to Marilyn deQueiroz and newbie picker Jason Adam for pickin' at them nits.  It's hard work keeping them all them drivers in line!

Tips for the Trail…...
Are you one of the many who got that famous nitpick:  "100 concatenations - any room for optimization here?"  Loops are a powerful tool, but can get messy real quick, especially when it comes to performing operations.  Try to think of ways you can move an operation - or its result - out of the loop.  This will help in optimizing the resources needed by your program!

Written by Jason Adam and Pauline McNamara


Return to Top
Book Review of the Month

Java Tools for Extreme Programming
by Richard Hightower, Nicholas Lesiecki
You can happily ignore the main title of this book. Sure there's a nod toward extreme programming, but that's not what this book is really all about. This book is a fine introduction to a whole bunch of really useful tools to boost your Java and especially J2EE programming. And all the tools can be downloaded, source code and all, for free! There are too many tools to list here, but they include the best-of-breed Ant build system, JUnit, HTTPUnit, ServletUnit and Cactus test frameworks, load and performance analysers and some great libraries for interacting with other servers.

Two major test cases are carried through the book to show the benefits of each approach. Each tool covered gets at least a chapter of tutorial, and some of the major ones also get an appendix of API and configuration information.

This book was almost too useful to review. It's been open on my desk from almost the minute I got it and has greatly improved many aspects of my development process. If you want to get up to speed quickly and practically on a load of useful, powerful, tools - get this book. Everyone I've shown it to has wanted their own copy ...

(Frank Carver - Sheriff, February 2002)
More info at Amazon.com || More info at Amazon.co.uk

Chosen by Cindy Glass and Madhav Lakkapragada

Return to Top
February Giveaways

Starting Date Book Author(s) Publisher JavaRanch Forum
Mar 5
Convergent Architecture: Building Model-Driven J2EE Systems with UML (OMG Press)
Richard G. Hubert Wiley Publishing OO, Patterns, UML and Refactoring
Mar 12
Java Tools for Extreme Programming: Mastering Open Source Tools Including Ant, JUnit, and Cactus
Richard Hightower
Nicholas Lesiecki
Wiley Publishing Jakarta Projects
Mar 19
WebSphere@Whiz - IBM WebSphere Certification (Test 488) Simulator
Pradeep Chopra Whizlabs IBM/Websphere
Mar 26
Beginning Java 2 JDK 1.4
Ivor Horton Wrox Press Java in General (beginner)

For more information on JavaRanch's Giveaways see Book Promotion Page.

Return to Top
March News

JavaRanch has added a new forum to better assist people in their hunt for information.
  • Object Oriented Scripting - OO Scripting Languages, Python, Jython, Ruby, jRuby etc. and the Use of BSF

    As always JavaRanch is dedicated to providing you with the best source of information on Java Programming and Engineering.


    Return to Top
  • Managing Editor: Carl Trusiak

    Comments or suggestions for JavaRanch's NewsLetter can be sent to the NewsLetter Staff
    For advertising opportunities contact NewsLetter Advertising Staff