Wednesday, January 29, 2014

Making Ant Scripts Smarter Using Macrodef

General:


Have you struggled using Ant? Have you experienced the frustration of getting scripts to work exactly the way you want?  I have been dealing with the Ant-isms that seem to make the process of creating a build difficult to accomplish for some time now.  I have added the Apache.org ant-contrib jar file to add some intelligence but it can fall short.  Sometimes it even causes the build to run longer because of a need to create objects to handle some of the tasks that I need done.   Not wanting to create my own "addon" classes to address my issues due to current time constraints I reached the point where I felt my only solution was to write copious lines of redundant targets to address multiple tasks.  Then I found the macrodef task and my Ant scripts have now picked up considerably in the smart department.

As fair warning this blog topic is not to replace the Ant documents already in place which document the macrodef task.  My intention is only to give some basics to people needing some intelligent Ant scripts.  By introducing them to the macrodef task through a few simple examples, they may have confidence to tackle the official documentation to get more details on all the sub tasks, properties and nuances of this very useful Ant task.   To this end, only required properties and sub-tasks will be listed where a task is described.

The Basics:


A macrodef should be a child of the project task in the ant script. If enclosed inside a target task, it can only be used within that target task.

Here is the most basic example so we can start discussing some of the elements:
<macrodef name="mymacro">
    <sequence>
    </sequence>
</macrodef>
The main XML element for this is <macrodef>.  This task has only one required property: "name".   This will be the name by which you will call the macro in future targets.  We will see this more in a bit.

The macro, "mymacro" does nothing.  So, lets improve on it a bit.  Consider the following:
<macrodef name="sayhello">
    <sequential>
        <echo>Hello World! I am "sayhello" macrodef!</echo>
    </sequential>
</macrodef>
Now, to run the macro, you only need to put the following as a child of project task or in a target.:
<sayhello />
which produces:
    [echo] Hello World! I am "sayhello" macrodef!
If entered as a child of the project task, it will run every time the ant XML file is run whereas if it is in a target, it will only run when that target is run.

The macrodef task requires a nested sequential task. Any ant task can be put inside the sequential task. This is the unit of work the macrodef task will perform.

At this point, the macro still is not very useful. It would seem a waste to write all the macrodef when you could have just enclosed the echo task directly inside a target task.

So, we introduce the attribute task.  Attribute tasks are the parameters passed to the macro from the calling function with no nested tasks.  The name of each attribute is the name of the corresponding property you pass in the call.  An example will explain better:
<macrodef name="sayhello">
    <attribute name="addressee" />
    <sequential>
        <echo>Hello World! I am "sayhello" macrodef!</echo>
    </sequential>
</macrodef>
So the call to implement the macro would look like:
<sayhello addressee="Bob"/>
This has now passed the parameter addressee with a value of "Bob" to the macro.  We still have a problem because the macro does not do anything with the parameter.  Again, lets go back to the macrodef task and connect the attribute.
<macrodef name="sayhello">
    <attribute name="addressee" default="World"/>
    <sequential>
        <echo>Hello @{addressee}! I am "sayhello" macrodef!</echo>
    </sequential>
</macrodef>
As you can see there are two changes.  First, I added an optional parameter "default" to the attribute task and set the value to "World".  This is because we do not want the line to print to the console as:
    [echo] Hello @{addressee}! I am "sayhello" macrodef!
If not defined, the attribute, as does an undefined property, will not expand in the Ant processor.

Secondly, note the use of the "@{someattribute}".  It is used to expand an attribute just as ${someproperty} is used to expand a property in Ant.

Now, lets finally run the call again.  First using:
<sayhello />
We see the output still is the same as the original macro:
    [echo] Hello World! I am "sayhello" macrodef!
If we call it with the parameter "addressee", we see the glory of parameters because this:
<sayhello addressee="Bob"/>
will now display this:
    [echo] Hello Bob! I am "sayhello" macrodef!

Tuesday, January 28, 2014

Using the Java Keyword: final

So, you have been coding for some time and you happen across the occurrence of the Java keyword final. What does it mean? How does it apply to what I am doing? I thought I would give some examples of the use of the word in order to better aid in clearing up the use of this keyword.

The 'final' Class

Declaring a class final makes it so no other code can subclass it. This prevents a stable, reliable class from being changed in a way so as to break code dependent on it. This can be seen in many classes in the Java standard library such as java.lang.String and java.lang.System.

Example 1:
package com.blogspot.howdoidothatinjava;

public final class UnextendableClass {
    
}

If you were to try compiling the following:
package com.blogspot.howdoidothatinjava;

public class ExtendedClass extends UnextendableClass {
    
}

... you would get the following compiler error:
ExtendedClass.java:3: error: cannot inherit from final UnextendableClass
public class ExtendedClass extends UnextendableClass {
                                   ^

The 'final' Method

A method that is marked final cannot be overridden by any of its subclasses. Typically a method is marked final when it should no longer be changed because it behaves exactly as it is desired and no further change could improve it or if changing it would cause critical functionality to break. At times, constructors call methods and these should generally be final because a subclass could cause unexpected behavior if it were to override that method.

Example 2:
package com.blogspot.howdoidothatinjava;

public class FinalMethodClass {
    
    public void nonFinalMethod(){
        // does something can be redefined
    }
    
    public final void finalMethod(){
        // does something that shouldn't be changed
    }
}

If you tried compiling the following subclass:
package com.blogspot.howdoidothatinjava;

public class FinalMethodClassSubclass extends FinalMethodClass {
    
    public void nonFinalMethod(){
        // does something differently from super class implementation
    }
    
    public void finalMethod(){
        // this causes compiler error
    }
}

You would recieve the following error at compile time:
FinalMethodClassSubclass.java:9: error: finalMethod() in FinalMethodClassSubclass cannot override finalMethod() in Final
MethodClass
    public void finalMethod(){
                ^

The 'final' Variable

final variable is a variable that can only be initialized one time, either at declaration or in the class constructor. Any attempt to initialize the variable outside the constructor or any attempt to reassign a final variable will result in a compile error. A final variable which is declared only first and then initialized in the constructor is called a blank final.

Typically, constants in a Java program are declared static final. This is because the constant only needs to be declared once so it should be "static" and it is final because it cannot be changed. Common practice is to give constants names which are all uppercase and words are separated with underscore characters. (i.e. SECONDS_IN_MINUTE, HOURS_IN_DAY, PI, etc.)

Any mutable object declared final can be modified by any class or method referencing it.  It cannot be reassigned.  The declaration of a mutable object only makes the variable name of the object final.

Example 3:
package com.blogspot.howdoidothatinjava;

import java.util.ArrayList;
import java.util.List;

public class FinalVariableClass {
    
    private final static int SECONDS_IN_MINUTE = 60;
    private final static int MINUTES_IN_HOUR = 60;
    private final static int SECONDS_IN_HOUR;
    
    { SECONDS_IN_HOUR = SECONDS_IN_MINUTE * MINUTES_IN_HOUR; }
    
    private final List<String> finalThings = new ArrayList<String>();
    private final int int1, int2;
    private int total;
    
    public FinalVariableClass(){
        int1 = 17;
        int2 = 42;
        total = getTotal();
    }
    
    public int getTotal(){
        return int1 + int2;
    }
    
    public void setInt1(int in){
        int1 = in;
    }
    
    public void setupFinalThings(){
        String[] strings = new String[]{"ball", "cat", "tree"};
        for(String s : strings){
            finalThings.add(s);
        }
    }
}

There are several issues which will prevent the code from compiling. First, the static final SECONDS_IN_HOUR is not initialized. The attempt to initialize it in a static block failed because you cannot initialize a final variable outside of  a constructor and final static fields must be declared in the same manner as SECONDS_IN_MINUTE or MINUTES_IN_HOUR.

FinalVariableClass.java:12: error: cannot assign a value to final variable SECONDS_IN_HOUR
    { SECONDS_IN_HOUR = SECONDS_IN_MINUTE * MINUTES_IN_HOUR; }
      ^

Additionally, there is an issue with the method setInt1(int in). This method is trying to reassign the value of the variable 'in' to 'int1' which is final. The compiler promptly tells us so.

FinalVariableClass.java:29: error: cannot assign a value to final variable int1
        int1 = in;
        ^

I would like to also direct your attention to the setupFinalThings() method. This is an example of a method altering a mutable object which was declared final.  As you can see, we can add new items to the List (or we could have removed them) even though the variable finalThings is final. We can do this outside any constructor because the variable was initialized with a mutable object when it was declared. We could never reassign a new list to the variable but we can modify the list whenever and wherever we like without fear of compile-time errors.

It should be pointed out here that the method getTotal() called in the constructor would have been better declared as a final method as described previously to avoid unexpected results.

"Final"-ly

That about covers most things you would need to know about the Java final keyword. It certainly can be very useful and at times troublesome if you don't pay attention to what you are doing. In the end though, you should be sure to exercise the right to make use of this keyword for its intended purpose.

Friday, January 24, 2014

Struts Framework - Introduction to Struts

General

Struts is a framework from the Apache Software Foundation (www.apache.org) for creating J2EE applications using an MVC (model-view-controller) architecture. It is open-source software that extends the Java Servlet API and the latest evolution of this is in the Apache Struts 2 Framework which was released in February 2007. The original Struts 1.x version has reached end of life and is no longer supported by the Apache Software Foundation.  For purposes of this article, I am limiting the discussion to Struts2.

At the core, as previously mentioned is the need to create applications using the MVC architecture. Figure 1 illustrates, albeit simplistically, the MVC architecture as it is used in Struts2.

Figure 1: Simplistic Struts2 MVC Architecture

Description of Process Flow (refer to Figure 1)

  1. The HTTP servlet request is received from the interaction of the user with the JSP/HTML in their browser.
  2. The Action Mapper passes the request to one or more interceptors.
  3. The Interceptors refine and pass the requested Action to the Model.
  4. The Action then interacts with the database or some external system (possibly via MQ)
  5. The Action passes the completed action to the Result.
  6. The Result response is passed to the Template to generate the output (JSP, JSF, JasperReport, etc)
  7. The templated result is then passed in reverse order through the interceptors it arrived through as an action request.
  8. The HTTP servlet response is sent to the browser for display of the result to the User.