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

Cannot instantiate DocumentBuilderFactory in JDK 5

Saturday, December 30th, 2006

Few months back I moved to JDK 5. After this move, recently, I tried running some Acceptance tests using an old fitnesse.jar, which was compiled using JDK 1.4. And guess what? I get the following exception :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
javax.xml.parsers.FactoryConfigurationError:
Provider com.sun.org.apache.xerces.internal.jaxp.
DocumentBuilderFactoryImpl could not be instantiated: java.lang.NullPointerException
[java] at javax.xml.parsers.DocumentBuilderFactory.newInstance
(DocumentBuilderFactory.java:104)
[java] at fitnesse.util.XmlUtil.<clinit>
[java] at fitnesse.wiki.WikiPageProperties.loadFromXmlStream
[java] at fitnesse.wiki.FileSystemPage.attemptToReadPropertiesFile
[java] at fitnesse.wiki.FileSystemPage.loadAttributes
[java] at fitnesse.wiki.FileSystemPage.makePageData
[java] at fitnesse.wiki.CachingPage.getData
[java] at fitnesse.responders.run.FitClientResponder.readyToSend
[java] at fitnesse.responders.run.PuppetResponse.readyToSend
[java] at fitnesse.FitNesseExpediter.sendResponse
[java] at fitnesse.FitNesseExpediter.start
[java] at fitnesse.FitNesseServer.serve
[java] at fitnesse.FitNesseServer.serve
[java] at fitnesse.socketservice.SocketService$ServerRunner.run
[java] at java.lang.Thread.run(Thread.java:595)

If I use JDK 1.4, everything works fine. But there seems to be some backward compatibility issues with JDK 1.5.

After trying different things for a while, I came across a site that stated that “The J2SE 1.4 platform included the ‘Crimson‘ reference implementation for JAXP 1.1. The J2SE 5 platform includes a reference implementation for JAXP 1.3 based on the Apache ‘Xerces‘ library.”

In JDK 1.4, xerces and xalan are embedded in the JDK. In JDK 1.5 too, but the packages are under com/sun (so com.sun.org.apache….).

So you would think all this should be transparent to developers. But no.

To verify the above statement, I opened up the DocumentBuilderFactory in JDK 1.5 and I found

1
2
3
4
5
6
7
8
9
10
11
12
public static DocumentBuilderFactory newInstance() {
try {
return (DocumentBuilderFactory) FactoryFinder.find(
/* The default property name according to the JAXP spec */
"javax.xml.parsers.DocumentBuilderFactory",
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.
DocumentBuilderFactoryImpl");
} catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError(e.getException(),
e.getMessage());
}

}
while the JDK 1.4‘s DocumentBuilderFactory class had:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static DocumentBuilderFactory newInstance()
throws FactoryConfigurationError
{
try {
return (DocumentBuilderFactory) FactoryFinder.find(
/* The default property name according to the JAXP spec */
"javax.xml.parsers.DocumentBuilderFactory",
/* The fallback implementation class name */
"org.apache.crimson.jaxp.
DocumentBuilderFactoryImpl");
} catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError (e.getException(),
e.getMessage());
}
}

After all this research I still don‘t know what is the exact problem. But I have a solution.

Solution: Luckily adding the xerces.jar to the classpath solved the problem.

Would appreciate if someone would let me know the answer.

Beta version of Lattu released

Monday, December 11th, 2006

I just released the first beta version of Lattu.

Lattu is a framework for testing Eclipse RCP Applications. It can run both Unit and Functional tests. Essentially, it is an Eclipse Plugin which provides Fitnesse extension to run unit and acceptance tests. It uses JUnit for unit testing and Abbot for GUI tests.

More details: http://lattu.sourceforge.net

Date aware FitLibrary Fixtures

Thursday, November 23rd, 2006

Having problems parsing Dates in your fit/fitnesse tests?

Here is a simple way to fix date parsing problem using FitLibrary.

Fit Page

|set date format as|MM/dd/yyyy|

|date|
|11/23/2006|

|set date format as|dd-MMM-yyyy|

|date|
|23-Nov-2006|

Fixture Class

1
2
3
4
5
6
<br />
public void setDateFormatAs(String format) {<br />
ValueAdapter.registerParseDelegate(java.sql.Date.class, new SimpleDateFormat(format));<br />
ValueAdapter.registerParseDelegate(java.util.Date.class, new SimpleDateFormat(format));<br />
}</p>
	<p>

How this works?
The ValueAdapter class holds a static HashMap called PARSE_DELEGATES which contains all the ParseDelegators. The ParseDelegator‘s job is to implement a parse method which take a String and returns the Object of your Data Type. You can register the Data Type and its respective ParseDelegator using the registerParseDelegate() method.

In this case, my ParseDelegator is SimpleDateFormat which has the following method

1
2
3
4
5
6
7
8
9
10
<br />
public Date parse(String source) throws ParseException{<br />
ParsePosition pos = new ParsePosition(0);<br />
Date result = parse(source, pos);<br />
if (pos.index == 0)<br />
throw new ParseException("Unparseable date: " + source ,<br />
pos.errorIndex);<br />
return result;<br />
}</p>
	<p>

All that matters is the following method signature:
public Date parse(String source){

You can use the same mechanism to parse any object of choice.

WebSphere Deployment Descriptor Load Exception

Thursday, August 24th, 2006

Getting the following error message while deploying an application in Websphere?

com.ibm.etools.j2ee.commonarchivecore.exception.
DeploymentDescriptorLoadException: IWAE0022E Exception occurred loading deployment descriptor

Context:
Check your web.xml.
If you are using the following XSD as the DOCTYPE of your web.xml http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
Then you might want to check your servlet tag to make sure they match the Servlet 2.4 specification.

For example, the following servlet causes the above exception when it tries to deploy the app.

1
2
3
4
5
6
7
8
9
10
<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;sampleservlet&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;ABCClass&lt;/servlet-class&gt;<br />
&lt;init-param&gt;<br />
&lt;param-name&gt;ABCParamName&lt;/param-name&gt;<br />
&lt;param-value&gt;ABCParamValue&lt;/param-value&gt;<br />
&lt;description&gt;some desc&lt;/description&gt;<br />
&lt;/init-param&gt;<br />
&lt;/servlet&gt;<br />

Surprising this works perfectly fine if your web.xml is using http://java.sun.com/dtd/web-app_2_3.dtd as the DOCTYPE

Solution:
Removing the

1
2
<br />
&lt;description&gt;some desc&lt;/description&gt;<br />

tag from

1
2
<br />
&lt;init-param&gt;<br />

tag fixes the problem.

Another problem with DTDs:
If you are using DTD, the order of the tag elements within the web.xml must follow the order reflected in the DTD. Else you will get similar exception message. The order of the tags in web.xml is very important when using DTD. But it should not matter if you are using XSD.

If you open the DTD, it would list the order of the tags in there.
For example, web-app_2_3.dtd specifies the following order that the tags must have in order for the document to be considered a valid XML document:

1
2
<br />
&lt;!ELEMENT web-app (icon?, display-name?, description?, distributable?, context-param*, filter*, filter-mapping*, listener*, servlet*, servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?, error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*, login-config?, security-role*, env-entry*, ejb-ref*, ejb-local-ref*)&gt;<br />

Hence

1
2
<br />
&lt;ejb-ref&gt;<br />

tag element must be before

1
2
<br />
&lt;ejb-local-ref&gt;<br />

tag.

Selenium Presentation at Agile 2006 conference

Tuesday, August 1st, 2006

Recently I co-presented with Alex Ruiz on Agile User Interface Development at the Agile 2006 conference. Alex presented on Abbot and I gave a demo on Selenium.

The objective of my talk was to show:

  1. How to write acceptance tests for Web UIs? The focus was on driving UI development from a functional stand-point using acceptance tests.
  2. How to quickly build regression/functional tests for an application with existing UI [legacy code] using Selenium?
  3. Last but not the least, to introduce Selenium

For the demo, I used VQWiki as my test application. The wiki is a simple yet powerful application to demonstrate some of the core selenium and acceptance testing fundas. Coz of this, the Wiki turned out to be an interesting application for the demo. I had tests in Selenium core and Selenium remote control. This was sufficient to show the power of Selenium. Finally when I recorded a test scenario using Selenium IDE, the audience went gaga over Selenium.

I‘m hoping to upload the tutorial soon. Till then you can have a look at the presentation here.

Is Fitnesse ready for enterprise use?

Monday, July 24th, 2006

I think Fitnesse can be a very handy tool. I appreciate Object Mentor‘s contributions. But there are certain features which are not supported by Fitnesse. These small things can be very painful on projects. I think a part of the reason is, lack of feedback from people using it. I hope this blog can be perceived as feedback.

An initial list of complains from people about Fitnesse:

  1. Lack of version control compatibility. This issue can be quite limiting if you are using a version control system which has pessimistic locking [makes all checked in files to read-only].
  2. Crazy wiki syntax
  3. Search sucks big time
  4. Lack of support for integration with Ant and similar tools
  5. Continuous Integration servers do not have a built in mechanism to display Fitnesse results. For Ex: CruiseControl does not have a style sheet to display Fitnesse results.
  6. Fitnesse cannot execute tests inside an application/web server. By default Fitnesse spins of a new process called FitServer, which runs all the tests. In this setup it is not possible to debug your fixtures and application code.
  7. Lack of standard out-of-box Fixtures which let you deal with databases. I know about JdbcFixtures. But it is crazy to expect people who write fit tests to know SQL. It is also crazy to mention all the DB connection properties on every single fit document [test].
  8. Lack of patterns /anti-patterns around Fitnesse. Ex: Should we use statics to share data between fixtures? How to design Fixtures [to inherit or not to inherit]? Etc.

Following is the list of work around we found:

  1. Version control compatibility: Fitnesse is pretty extensible. It lets you add plugins by adding new responders. So we added a plugin which lets one checkout files from ClearCase. Now users can click on the ckeckout menu item and easy checkout files from the fitnesse page. This can be easily extended to other version control systems. Please note that we have not added checkin facility. The rationale behind it is, we have FitnesseRoot under the project directory. So once the developer has done all the changes and are ready to checkin, they find checkouts at the project level and checkins all the files, including the content.txt and properties.xml file. This is great coz it lets developers do atomic checkins.
    Hopefully I can add support for different Version controls and contribute it back to Fitnesse or spawn another open source project.
  2. There is not much we can do about the wiki syntax except reading the MarkupLanguageReference. There are lot of good tricks and tips.
  3. Right now we are using Google Desktop to search our wiki pages. In future, I plan to write a plugin for FitNesse to make use of the Lucene Search Engine.
  4. We are able to run all our fit tests thru add by using the following target.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    <br />
    &lt;target name="fitNesseTest" description="Run FitNesse acceptance tests." if="project.fitnesse.tests"&gt;<br />
    &lt;echo&gt;About to run fitnesse server&lt;/echo&gt;<br />
    &lt;property name="fitnesse.port" value="8090" /&gt;<br />
    &lt;parallel&gt;<br />
    &lt;daemons&gt;<br />
    &lt;java classname="fitnesse.FitNesse" classpath="${fitnesse.root}/fitnesse.jar"&gt;<br />
    &lt;arg value="-p" /&gt;<br />
    &lt;arg value="${fitnesse.port}" /&gt;<br />
    &lt;arg value="-e" /&gt;<br />
    &lt;arg value="0" /&gt;<br />
    &lt;arg value="-d" /&gt;<br />
    &lt;arg value="${fitnesse.root.location}" /&gt;<br />
    &lt;/java&gt;<br />
    &lt;/daemons&gt;<br />
    &lt;sequential&gt;<br />
    &lt;echo&gt;sleeping for 3 seconds to let FitNesse server start&lt;/echo&gt;<br />
    &lt;sleep seconds="3" /&gt;<br />
    &lt;echo&gt;running fit tests from ${fitnesse.location}&lt;/echo&gt;<br />
    &lt;echo&gt;Running fit tests at "${project.smoke.tests.suite.page}"&lt;/echo&gt;<br />
    &lt;java classname="fitnesse.runner.TestRunner" classpath="${fitnesse.root}/fitnesse.jar " fork="true" jvm="${java.home}/bin/java.exe" dir="${fitnesse.location}" resultproperty="fit.test.failures"&gt;<br />
    &lt;classpath&gt;<br />
    &lt;!-- you can add classpath here. Not required if you are using standard fitnesse--&gt;<br />
    &lt;/classpath&gt;<br />
    &lt;arg value="-debug"/&gt;<br />
    &lt;arg value="-nopath"/&gt;<br />
    &lt;arg value="-html" /&gt;<br />
    &lt;arg value="${fitnesse.output.html.file.location}" /&gt;<br />
    &lt;!-- optional --&gt;<br />
    &lt;arg value="-xml" /&gt;<br />
    &lt;arg value="${fitnesse.output.xml.file.location}" /&gt;<br />
    &lt;!-- end of optional --&gt;<br />
    &lt;arg value="${fitnesse.host.address}" /&gt;&lt;!-- usually localhost --&gt;<br />
    &lt;arg value="${fitnesse.port}" /&gt;<br />
    &lt;arg value="${project.smoke.tests.suite.page}" /&gt;&lt;!-- Ex: FronPage.projectName --&gt;<br />
    &lt;/java&gt;<br />
    &lt;echo&gt;Finished FIT tests: ${fit.test.failures} failures/exceptions&lt;/echo&gt;<br />
    &lt;fail message="FIT test failures/exceptions: ${fit.test.failures}"&gt;<br />
    &lt;condition&gt;<br />
    &lt;not&gt;<br />
    &lt;equals arg1="${fit.test.failures}" arg2="0" /&gt;<br />
    &lt;/not&gt;<br />
    &lt;/condition&gt;<br />
    &lt;/fail&gt;<br />
    &lt;/sequential&gt;<br />
    &lt;/parallel&gt;<br />
    &lt;/target&gt;<br />

    It would be great to have build-in ant task which an do this.

  5. There are some simple things you can do to integrate Fitnesse with Continuous integration server like CruiseControl. For more details: Integrating Fitnesse with CruiseControl
  6. I have an open source project called Patang, which lets you run Fit and Fitnesse tests inside the application/web server. For more details: Patang on SourceForge and Running Fitnesse inside the container
  7. We have developed a list of standard fixtures which help you insert data into the database tables, clean it up based on ids, etc. It uses properties file to read all the database connection parameters. It also hides any SQL from the user. I‘ll shortly blog about these fixtures. May be it deserves another small open source project.
  8. Am planning to expand the Patterns on the Fitnesse website.

After reading this blog, you might get a feeling that I‘m crazy about spawning new open source projects. That‘s not true. There is a reason behind me making that decision.

New release of FIT Decorator out

Sunday, July 23rd, 2006

I just released a new version of FIT Decorator. The latest version supports a build-in Fitnesse wiki for you to see the examples.
In addition to this, all the time based fit decorators have been updated to display the actual time taken.

Fit Decorator has also been ported to Python by Jens Engel. We have not yet released this, but you can have an early glimpse from the source repository.

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

Hot deploy in Tomcat

Saturday, June 24th, 2006

Over the last couple of days I was wondering how to hot deploy webapps in Tomcat? After trying all possible search queries in Google I gave up. But I knew for sure that it was possible to hot deploy webapps in Tomcat, as I had done it before.

I started playing with Sysdeo Eclipse Tomcat Launcher plugin. This plugin had an option to make the context reloadable. It actually updates the server.xml under the tomcat/conf dir. This is how I figured out how to make this work for any webapp.

Just add the following line to the server.xml

1
2
<br />
&lt;Context path="/yourContext" reloadable="true" docBase="rootFolderOfYourApp" /&gt;<br />

Now I don‘t have to stop and start tomcat for a small change in a class file to reflect.

Patang now supports Fit and FitNesse

Saturday, April 15th, 2006

Recently I released the beta 0.2 version on Patang. In this release I added support to run plain Fit tests inside the container [web container]. So now, you can run your fit tests inside the container. It does not matter if you are using plain Fit or FitNesse.

Setup for Fit:
1. Add the fit.FitServlet definition to the deployment descriptor of your web container [web.xml]. An example is available under the docs/web.xml in the release file.

2. Add the absolute path to the directory containing fit tests and the results directory as init-params to the servlet.

3. Deploy the patang-fit.jar file to you web app by putting patang-fit.jar and fit.jar under the WEB-INF/lib folder.

4. If you plan to call your fit tests during your continuous integration build, use the fit.ServletInvoker class, which communicates with the fit.FitServlet in the web container. This servlet can be used to run your fit tests inside the container directly from the web browser or from the ant build file. An example of this is available under the docs/build.xml in the release file.

More details:
http://sourceforge.net/projects/patang

Fit as a replacement for JUnitEE and Cactus (in container testing frameworks)?

Friday, April 14th, 2006

My current project is a J2EE project which uses JDOs for persistence. Off late there has been a huge emphasis on running our unit and unit integration tests inside the app container. With lack of IoC and DI, the code does behave different inside the container and outside the container. Given this as the reality of the world which we cannot change, how do we test drive our code?

So we started of by using JUnitEE for running unit tests inside the container and FitNesse for acceptance tests at the service level. FitNesse does not run inside the container. Hence remote debugging, EJB refs and other container provided facilities could not be used. So I started a new open source project called Patang which gives you the infrastructure to run Fit/FitNesse inside the container through a FitServlet.

Now we had JUnitEE tests testing individual layers of our services, while FitNesse test doing more of what we call end to end service test. We found the following problems with this approach:
1. There seemed like a lot of duplication of test coverage and test data in these 2 types of tests.
2. JUnitEE is as bad as FitNesse tests in terms of quick feedback. In both the cases we need to redeploy our code to the container to test it.
3. Any refactoring meant changes in 2 places. So maintaining the tests became a costly affair.

Because of these problems, we started just writing fit tests and driving our development using FitNesse tests. It seems to be working fine so far.

I feel this approach gives us the following advantages:
1. Fit is pretty good to express the intent. It helps to clearly express what needs to be done. What are the inputs and what are the outputs.
2. It is very good in separating setup data from the actual test itself. So it‘s much easier to understand.
3. We are using just one tool for in container testing and hence decrease learning curve for new team members.
4. Much less test maintenances. It‘s all in one place.
5. Our tests cater to a broader audience. It‘s no more just a developer tool. Our testers can take these fit tests and enhance them with different scenarios. This helps them to keep pace with development. And sometimes drive development to some extent.
6. xJunit is not very good at setting the context and providing explanation to the tests. With Fit we can make our tests more like stories and hence bring them closer to our acceptance tests.

Side effects of this approach:
1. It is much harder to refactor your code, because now you have the fit test and its associated fit fixture. When we rename a method/class or change a method signature, the fit fixture gets refactored by the IDE. But the fit test can be difficult to refactor. It can be even more difficult to maintain them if the test pages are not inside the project structure.
2. The feedback cycle is longer. But same as any in container testing framework.
3. Writing and maintaining the fit pages is a very difficult task. It can get very cryptic. There is no decent IDE to do this. [May be my next open source project]

Some myths associated with this approach:
1. We are moving tests away from the code. I don‘t think so. The fixtures are still organized in the same way we organize our tests.
2. More maintenance. Much better than applying changes in 3 different places. [JUnitEE and then acceptance tests]
3. No IDE support. One can easily use the FitRunner class to run fit tests from the IDE.
4. Cannot be made a part of the build process. Patang project provides you with a ServletInvoker class which can run all your fit tests inside the container and publish the results.

This seems to be working fine for us so far. In the end that‘s what it boils down to.

    Licensed under
Creative Commons License