XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Archive for the ‘Java’ Category

Patang – My new open source project

Tuesday, March 28th, 2006

Patang is a framework for testing server-side code. Patang intends to simplify writing and executing acceptance and unit integration tests for server-side code. It implements an in-container testing strategy, meaning that the tests are executed inside the container.

Patang provides the infrastructure/framework to run fit tests inside the container. What type of fit tests you write will determine which type of testing you can do with Patang.

Currently Patang works only with fitnesse. But the vision is to make it generic.

Why another framework?
Several kinds of functional and unit testing frameworks are available for testing enterprise applications. They can be broadly categorized into 3 types:

1. Unit isolation testing. State based or interaction based testing frameworks such as JUnit or Mock objects seem to fit well.

2. Unit integration testing. These tests will exercise the interactions with the container. Frameworks like Cactus, JUnitEE, etc suite this category.

3. Functional unit integration testing. Frameworks which let you test full use cases which can be composed of several requests/responses cycles. Some times these are also referred to as unit acceptance tests. HttpUnit, Fit, etc fit into this category.

Mostly on enterprise projects, three or more, different frameworks are used just to test the functionality of the code. Patang proposes to use Ward Cunningham‘s FIT framework to achieve second and third category of testing. This can be easily achieved by running FIT inside the container by having a FitServlet, which can execute the fit tests.

Advantages of this approach:

1. Reuse of tests. Usually there is an overlap between acceptance tests and integration tests. We can use pretty much same/similar fit tests for both.

2. EJB References, JNDI lookups, transaction management, container security, data sources and other container provided facilities can be used the same way in test environment as in development environment.

3. Test First Development: Helps in driving development with a failing tests. These are mostly black box tests at different layers of the architecture.

4. Easy of deployment and maintenance of test and development environments. All you need is the servlet and the fit framework running.

5. Remote debugging: It is very easy to debug your server side code by driving it through tests and stepping through the code in your favorite IDE

6. Bringing test environment much closer to production environment: In most of the enterprise web applications you have a web front end running inside a web container calling business components running in an application server. Executing FIT tests using patang, simulates the web front end and hence is much closer to the real world.

How patang works?
Patang provides a servlet which executes the fit tests inside the web container using the FitServer class. This helps us setup remote debugging on the web container and easily debug the fixture, business delegate and actual EJB code. This also helps us to avail all the EJB ref look ups and other container provided services. With the fit tests running inside the container, we can use the container?s class load and hence we do not need to maintain classpaths on .root page.

Some day Patang can become a good alternative to Cactus and JUnitEE.

For more details: http://sourceforge.net/projects/patang

Updates to FitDecorator project

Saturday, March 25th, 2006

I have added some more interesting decorators to the fitdecorator project.

The latest version of fitdecorator supports both Fit and Fitnesse.

Any feedback/suggestions are welcomed!

Automated database change management process for an Agile project

Monday, March 13th, 2006

This is an over simplified summary of my experiences, handling database changes on different agile projects.

Most of the projects I worked on, we were using ANT for our builds. So we automated our database scripts using ANT.

List of things that need to be in place for this to work:

1. Ever developer has a database instance, either on local machine or on a central server. Local machine is preferred. Properties file can be used to point to the correct database.

2. The development team is following an iterative development model. At the beginning of each iteration/sprint, someone on the team [DBA or build master or someone] creates a baseline of the database from the current database snapshot and stores it in a central place. This baseline can then be used by every developer to bring their DB instance to the baseline version.

3. Under the project directory, we create a folder called DB. This folder contains one folder per iteration/sprint. All the database scripts are added to the respective iteration/sprint folders in which they are created. The whole DB folder is checked into version control along with the code.

4. In the build.properties file, declare a property called current.iteration.number. This property is defines the current iteration or sprint number and is used by the targets in ant to get the baseline DB.

I would like to describe the different scenario that can occur on a project irrespective of whether you have a dedicated DBA or not.

Scenario 1: Developer needs a database change
Developer Activities:
1. Create a sql script [with or without DBA‘s help] as per standards in the appropriate DB folder
2. Apply script to local database using appropriate database client [Eg. Query Analyzer for MS SQL Server, Toad for Oracle, etc]
3. Test application against local database
4. Check in the script into version control

Scenario 2: Team member needs to get database changes made by others during the current iteration/sprint
Developer Activities
1. Update the source tree from version control system. This should get all the database, code and configuration changes from the version control.
2. Run the default ant target [build verification] at the project level (this will run the ‘updatedb‘ target that executes all new database scripts on the local database)

Scenario 3: Beginning of Iteration/Sprint
Activities
1. Backup the database from the build/QA server at the same time as labeling the codebase in your version control (If the team has a Build Master then it‘s that person responsibility to label the codebase and take the backup). The baseline can be checked into version control. Its optional.
2. Update the current.iteration.number in build.properties to the latest iteration/sprint number
3. Run ‘restoredb‘ ant target to get the baseline version of the database for the new sprint.

Scenario 4: Local Database is messed up
Developer Activities:
1. Update the project tree from source control to make sure you have all the latest changes.
2. Run ‘forceupdatedb‘ ant target to restore the baseline database for the current iteration/sprint and to catch up with the latest changes. [Executes the ‘restoredb‘ and ‘updatedb‘ targets]

Properties of SQL Scripts:

1. Naming convention: yyyy-mm-dd-hhmi.sql
The scripts are named based on the time of creation. The name is used to execute the scripts in the order of creation.

2. The scripts should be incremental .i.e. you should never modify an existing script.
For example, you create a new table and check in the create table script. Then you need to add a new column to this table, you should create a new alter table script. The same goes for objects that you cannot modify like stored procedures. You would create new scripts that drop the existing procedure and create the procedure again with modified code.

3. The scripts need not be re-entrant .i.e. if the same script is execute multiple times then they can fail. We use the modified selector on the FileSet element. The modified selector selects files if the return value of the configured algorithm is different from that stored in a cache. So if a file is not updated, then it does not execute the file. This means, only new scripts are executed and the old ones are executed only once.

http://ant.apache.org/manual/CoreTypes/selectors.html#modified

If you want to be sure that the scripts are executed only once, then you could create a version table in database and have the sql scripts check the version to decide if it needs to be executed. The script would insert a row into the version table if it has to be executed. This also gives us the ability to restore databases to a specific version.

All these tasks can be achieved by three simple ant targets:

1. updatedb: Executes all the new (or modified) sql scripts for current iteration/sprint against local server. It executes the scripts in the order of their creation time, based on the script‘s file name.

2. restoredb: Restores the database from the baseline version.

3. forceupdatedb: Executes all sql scripts for current sprint against local server after restoring the local database from the baseline.

To see the actual build file and sample DB folder with sample scripts click here

Note: the scripts and ant targets assume that the database is SQL Server. They can be easily modified for other Databases.
Download the DBChangeManagement.jar and rename it to DBChangeManagement.zip.

Private ANT targets

Sunday, March 12th, 2006

In ANT, the optional ‘description‘ attribute can be used to provide a one line description of any given target, which is printed by the -projecthelp commandline option. Targets without such a description are deemed internal or private and will not be listed, unless either the verbose or debug option is used.

But what if you want to create a target which cannot be executed directly? A target which is meant only for internal use by other targets and cannot or should not be executed as a standalone target.

A small and elegant trick I learnt from a colleague at ThoughtWorks is, let the target names begin with a dash, e.g., -init
[target name=“-init”].

If you try to execute this target from the command promt, it would be considered as an argument and ant will give the following error: Unknown argument: -init

Simple and handy trick when working with large build files.

Some differences between FIT and Fitnesse

Thursday, March 9th, 2006

1. Fixture.getArgsForTable(Parse table)
a. Fit: Method is at protected access level
b. Fitnesse: Method is at default access level

2. Fixture.loadFixture(String fixtureName)
a. Fit: throws InstantiationException, IllegalAccessException
b. Fitnesse: throws Throwable

3. Results page:
a. Fit: Directly adds colors to the resulting columns [Ex: for Right = #cfffcf]
b. Fitnesse: Adds different style values to the resulting columns [Ex: for Right = ‘class=“pass”‘

4. Counts: The number of exceptions and ignored can change based on the type of exception.

There are lots of other small differences which can make moving between fit and fitnesse tricky.

Agile India 2006 Conference

Friday, February 24th, 2006

ASCI is planning to organize its annual conference in Bangalore on 5th and 6th May 2006. The theme for last year‘s conference was “Introduction to Agile”. We are hoping people have spent the last year or more using and adopting to agile and would have some good insights into the methodology. This year‘s conference plans to help people share these insights and focus on more advance topics in Agile.

Currently we are looking for speakers. So if you have some this topic, please contact me.
For more details: http://agileindia.org
Mailing list: http://groups.yahoo.com/group/agileindia

Contents of MANIFEST files being cleared by WsEjbDeploy target

Sunday, February 12th, 2006

Recently on our project, we ran into a weird issue with the contents of the Manifest files being cleared out after passing the jar, containing the manifest file, to the com.ibm.websphere.ant.tasks.WsEjbDeploy task or wsejbdeploy target.

Following are the contents of the

Manifest-Version: 1.0
Class-Path: log4j.jar
fit.jar
fitdecorator.jar
junit.jar

After analyzing the issue we discovered the following regarding the format and contents of the manifest files that are expected by the webshpere‘s wsejbdeploy target
1. The manifest file should always end with a new line. No spaces or special characters are allowed on this last line. Else the contents of the manifest file will be cleared. (We had a new line, but by mistake it had a space in the beginning)
2. For the class-path, you could choose to have one jar per line or a space separated listed of jars. But if you choose the first option for readability then:
a. Each line should begin with a space followed by the jar name. Else will result in the following error
com.ibm.websphere.management.application.client.AppDeploymentException: AppDeploymentException: [null]
[exec] com.ibm.etools.j2ee.commonarchivecore.exception.DeploymentDescriptorLoadException: com.ibm.etools.j2ee.commonarchivecore.exception.DeploymentDescriptorLoadException: IWAE0022E Exception occurred loading deployment descriptor for module “XXX.jar“ in EAR file “C:\Documents and Settings\username\Local Settings\Temp\app39696.ear”
b. Each line should end with a space, else it will collapse the subsequent jars on the same line without a space in between and will result in wrong jar names

For some basic understanding of manifest files visit the following link:
http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html

First ray of hope for fitdecorator project

Tuesday, December 20th, 2005

The fitdecorator project is now listed on the 3rd party fit tools page.
http://fit.c2.com/wiki.cgi?FitTools

Currently the fitdecorators work with FIT. Action points are to make it work with FitLibrary and FitNesse.

Running Fitnesse inside the container

Tuesday, December 20th, 2005

How does fitnesse work currently?
When you click the test button on the fitnesse page, the following steps occur
1. The TestResponder class gets invoked
a. Based on the !path variable defined on the root page, it builds the classpath
b. It uses the TEST_RUNNER variable to figure out the class that needs to be invoked to run the fit tests. It defaults to fit.FitServer
c. Spawns a new thread and invokes the fit.FitServer class in a new java process with the classpath it just built. It passes 3 parameters to this class.
c1. Host on which fitnesse is running.
c2. Port on which fitnesse is running.
c3. Socket token or id, to identify
d. Declares itself as the socket listener and waits for socket connection from fit.FitServer class based on the socket token
2. Inside the FitServer class,
a. it establishes a socket connection with the fitnesse server based on the host and port given to it
b. On this socket connection, it makes a http request as follows “GET /?responder=socketCatcher&ticket=“+socketToken+“ HTTP/1.1\r\n\r\n”
c. This will help to connect back to the TestResponder class, which then returns the fit test page [html] as a string
d. It creates a parse object from this string and invokes the doTable() on a new fit fixture. Eg: newFixture().doTables(tables);
e. It then publishes the results back on the wiki page thru the TestResponder
3. The TestResponder class waits on the thread in which it invoked the FitServer class. Once the FitServer class has terminated, it does all the publishing stuff and stops.

Issues with this approach:
1. EJB Refs won't work : If you are trying to tests EJBs which are been looked up using EJB Refs, then they won‘t work. Let‘s say you are doing your EJB lookup inside your business delegate classes. In this case, you would write a fixture class which calls the business delegate, which in turn calls your EJB. But your fixture classes and business delegate classes are running in a new JVM [FitServer space] and they cannot resolve the EJB refs as they are not running inside the container [Application server space]
2. Remote debugging won't work : If your fit tests are testing some J2EE components, it is not possible to use the remote debugging options provided by the IDEs coz we have 3 different JVMs involved. [fitnesse, FitServer, Application Server]. Also you need to look at 2 different logs for trace statements. So debugging gets very tricky.
3. Difference in test and production environment : In production env, you would have a web front end running inside a web container which calls the EJBs residing inside the EJB container thru the Business Delegates. Hence you would have the EJBs being invoked from the web container and you would probably want something similar in your fit tests. You don‘t want EJBs been called directly from outside the container.
4. Managing classpath mess : Defining the classpaths on the .root page can get very cryptic and error prone. Development teams tend to waste a lot of time setting up classpath and maintaining it.
5. Setting up and maintaining another environment : If you trying to run tests from Fitnesse, then you need to configure and maintain a lot of other stuff for your enterprise app to work properly. I have seen a lot of teams struggling with properties, log files, security, etc

Solution:
We want the FitServer class to be invoked inside the web container. Then we can setup remote debugging on the web container and easily debug the fixture, business delegate and actual EJB code. This also helps us to avail all the EJB ref look ups and other container provided services.

Implementation:

1. Add the following line at the parent fit test page.
!define TEST_RUNNER {fit.FitServerServletInvoker} : This will tell fitnesse [TestResponder class] to invoke fit.FitServerServletInvoker class instead of fit.FitServer
!define COMMAND_PATTERN {java -cp %p %m http://localhost:8080/yourAppName/FitServlet} : This helps us pass the URL of the fit servlet that needs to be invoked

2. Write the fit. FitServerServletInvoker class and make sure you put it in fitnesse path. [Add it to the !path property on the root page]

3. All the fit. FitServerServletInvoker class has to do is, make an HttpURLConnection to your web container, call the appropriate Servlet on the container and pass all the arguments it got. [3 parameters: host, port and socketToken]

4. Write the Servlet which invokes the FitServer class with the parameters it‘s got. I have called the Servlet as FitServlet.

5. Add your servlet definition to the deployment descriptor of your web container [web.xml]

I have also modified this servlet to use the TestRunner class instead of the FitServer if the socket token is not present. This servlet is used to run my fit tests inside the container from directly the web browser or from the ant build file. [We run some fit tests as a part of our continuous integration build]

All the source code and related files is now open sourced. Please refer to the Patang project for details.

JNDI binding conflict issues

Monday, December 12th, 2005

Trying to deploy 2 applications [EARs] on the same application server and having JNDI binding conflict issues?

If you are using Websphere, this might help.

1. Remove all JNDI name bindings from Web and EJB modules (ibm-web-bnd.xmi and ibm-ejb-jar-bnd.xmi) from both your applications
2. Change all EJB resource reference names to match the EJB name in the DD, prefixed by ejb. For example the ejb-jar shows:

ejb-name>LoginBean /ejb-name>
home>com.xyz.abc.LoginHome /home>

The EJB reference in the Web or EJB DD using this bean should be named:
ejb/LoginBean

This is actually quite intuitive compared to setting up the JNDI names in the bindings.

3. Updated the redeploy script with the following
AdminApp.install(application, ‘[-server server1 usedefaultbindings defaultbinding.ejbjndi.prefix ‘+jndiPrefix+‘]‘)

Using the -defaultbindings and the jndiPrefix=ejb/app1 defaults the EJB JNDI names to: ejb/app1/LoginBean and the lookup works properly from web

All this appears to work nicely and prevents any non-EJB names from being prefixed (which results in JMS connection factory and/or destination lookup failures). In addition, it has the nice side-effect that we do not have to specific any EJB JNDI names as part of the applications DDs.

Another interesting thing I found was if we provide a binding file with the appropriate JNDI names defined in it,
AdminApp.install(application, ‘[-server server1 usedefaultbindings defaultbinding.ejbjndi.prefix ‘+jndiPrefix+‘]‘)
does not overwrite the JNDI names. It leaves it the way we had defined in our bnd file and everything works the way it used to work before. For modules which do not have the bnd files, they will now be deployed with the prefixed JNDI name.

Bingo!

P.S: usedefaultbindings defaultbinding = should be read as dash usedefaultbindings dash defaultbinding

    Licensed under
Creative Commons License