FitNesse and Perforce

Perforce is a pessimistic locking version control system(all checked-in files are read only). FitNesse requires the files are open for edit while you make changes. It's a pain when you see "no permission" error until you save you changes, especially for QA folks who just transferred from manual testing to automated testing.

To solve this issue, we added a link in the FitNesse website, which allows them to make all the FitNesse "open for edit":

1. Implement Responder class(let's name it P4EditResponder) in FitNesse, and include it in Fitnesse classpath. And the code can be as simple as one line:
Runtime.exec("p4 edit //FITNESSE_ROOT/...");

2. Add plugins.properties in the FitNesse working directory, including the following item:
Responders=p4edit:P4EditResponder

3. Now you can use it in your FitNesse page:
[[Open For Edit][?responder=p4edit]]

4. Done! It's simple like that.

Check out http://fitnesse.org/FitNesse.PluginUsage if you still have issue.

I still have some issues with FitNesse and Perforce, any help is appreciated:

1. How to add a directory recursively into Perforce using windows command line? I would like to add another link on FitNesse page to allow QA folks to add new files into Perforce and checkin all the changes.

2. How does Perforce ignore works? I would like to ignore FitNesse version control and not checking in the zip files generated by FitNesse version control. Or just disable version control when FitNesse generates a new page.

Google was caught by stealing Sohu Pinyin dictionary

Several days ago, I talked about the new Google Pinyin. Unfortunately, the latest news says that Google stole Sohu's Chinese dictionary: http://www.chinadaily.com.cn/bizchina/2007-04/11/content_847897.htm

Google just released Pinyin Input method

Google just released its Chinese input method: http://tools.google.com/pinyin. It works very similar to Ziguang input(紫光). As always, you will not be disappointed by Google. As a big google fan, I'll say bye-bye to 紫光.

个人感觉Google还能火很长一段时间。昨天刚刚发布的Google Pinyin,今天在mitbbs上就已经被炒得十分火爆了。 Google就靠这些简单实用的小软件培养了一批铁杆的Google迷,想想它的市场会有多大。

Hibernate Exception - Simultaneously Fetch Multiple Bags

Today I bumped into the following Hibernate exception:


javax.persistence.PersistenceException: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:217)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:114)
........
What's the problem? Because I have multiple one-to-many mappings in my hibernate object, and all of them require EAGER loading.

Check out this link: http://jroller.com/page/eyallupu?entry=hibernate_exception_simultaneously_fetch_multiple, it shows you three ways to fix the issue.

ThoughtWorks is hiring...

Thoughtworks is hiring in US right now. If you want to work with cool and smart people, check it out: http://www.thoughtworks.com/jobs/United-States-Job-Openings.html

How to display an image within a JSP from Database

I'm using Spring/Struts2/Hibernate in my current project. We have a requirement to upload an image into database, then display that image on the website within a jsp page. We wrote a servlet to stream out the image from database, but there is no way to test the code outside of the web container.

Then I tried to find a way to inject the Spring beans into the Servlet. Fortunately, Spring provides FrameworkServlet: Base servlet for servlets within the web framework. Allows integration with an application context, in a JavaBean-based overall solution. By extending FrameworkServlet, I could load Spring WebApplicationContext by setting "contextConfigLocation" parameter in web.xml.

This above solution made my code much simpler. Unfortunately, I still could not test the code outside of the web container, since it's so difficult to setup WebApplicationContext from a unit test. In the end, I had to do some tradeoff, by overwriting the initFrameworkServlet() method in FrameworkServlet, I could unit test the rest of the code but this method.

public class ImageStreamServlet extends FrameworkServlet {

private MyService myService;

protected void setMySerivce(MySerivce myService) {
this.myService= myService;
}

@Override
protected void doService(HttpServletRequest request,
HttpServletResponse response) throws Exception {

String id = request.getParameter("id");
MyObject myObject = MyService.findById(Long.parseLong(id));
if (myObject != null) {
response.reset();
response.setContentType(myObject.getImageType());
IOUtils.write(myObject .getImageData(), response
.getOutputStream());

}

/**
* This method is not covered by test...
*/
protected void initFrameworkServlet() throws ServletException {
super.initFrameworkServlet();
myService = (MyService ) getWebApplicationContext()
.getBean("myService ");
}

}


Basically, MyService can be mocked out in my test now:)

First Impression of Ruby

This week, I attended a company internal ruby/rails training.

Here is some thoughts after the training:

Technically:
1. Ruby on rails uses convention over configuration. The only so called configuration file is "routes.rb". Feeling the pain of adding/modifying 5+ files to create one web page in Tapestry/Spring/Hibernate application, "convention over configuration" is definitely a no-brainer.
2. Ruby class is never final. You can override/overwrite a method on the fly.
3. Implementing a "filter" in Ruby on Rails is simple comparing to Java Servlet Filters. It's plain ruby code, and can be easily tested.

Future:
Ruby/rails requires high quality developers. If you don't have developers following TDD and other agile principles, the project can easily be screwed up. So consulting companies with high quaility developers can easily get high rate for the work.

Consulting companies always try to chase the latest and greatest technology to achieve their financial goals. But with strong typed language like Java or .Net, consulting rate went down quickly after a lot of "regular" developers moved over. But Ruby itself has raised the bar, those companies who have chased ruby/rails should be able to charge the high rate for a longer period of time comparing to java/.net.

On the other hand, due to the above reason, I don't think Ruby/Rails can compete the market with Java/.Net in the near future.

Questions:
1. How is the general performance of the ruby application?
2. How does Ruby on Rails work with legacy code/database?
3. When will the Ruby open source continuous integration server available?
4. For people used to strong typed language, what's the easiest way to switch over?
5. Ajax and RoR?

Timeout in CruiseControl

In my Cruisecontrol setup, I need to make an ant call to ruby scripts. Originally, I setup CruiseControl timeout in AntBuilder, somehow it could not kill ruby process. CruiseControl will wait till the end of ruby process, and show timeout error in the report.

I started looking at Ant exec task timeout, which I expect the process times out after 5 hours, but the build always times out within one minute.

What's wrong?

Don't laugh at me. Cruisecontrol AntBuilder use seconds to measure timeout, but Ant Exec task uses milliseconds!

How to start Organizational Transformation

In big companies, how to start working on Agile Organizational Transformation? Starting from selected projects is a good idea. Picking various projects is extremely important. You may want to pick projects to cover different business domains, platform, programming languages, etc.

Organic Java Developers?

Today at lunch time, we went to SF ferry building farmer's market to get some coffee. Everything in the market had a marker "organic", and the price was crazily expensive. Paulo, one of my colleagues, said, we should name ourselves organic java developers. We use open source tools, cage free:)

Sure, you could not be called organic java developers several months ago, because Java itself was not open source yet. Now you can:)

Ruby on rails for startups?

Ruby on rails is one of the hottest buzz words at this moment. Comparing R/R to the current J2EE and .Net. I would like to raise a question about the performance and scalability, since I have not found any industrial data yet.

Until the performance/scalability is proved, I treat R/R as a great tool for startup companies. Startup companies should be able to dive into their prototype quickly and raise the money based on the prototype. But what they are going to do next...is a secret:)

CruiseControl setup for multiple projects/releases

I tried to set up CruiseControl to handle multiple releases among different projects. All the projects share the same build scripts (which is a whole build project, sounds odd, ah?).


My original plan for the file structure was:

___CruiseControl (cc installation)

|__projects___ config.xml

|___webapps

|___trunk

|___release1

|___release2___build

|___project1_quick

|___project1_nightly

|___project2_quick___checkout

|___target

|___logs

|___artifacts


With this file structure, everything related to the project is under one directory tree. If you want to remove an obsolete project from cc, you don't have to delete files from multiple places.

But I hit a road blocker when I tried to set up logs and artifacts. There is no way to archive the above goal if I don't modify CC source code. I could make the build without any problem, but the reporting system crashes. Since CC index page will look for projects under default logs directory. After considering the design carefully, I think it makes sense for CC to setup this way, since it will avoid another setup to tell cc the available projects.


Now I will change projects directory setup to a flat file structure like what I did at other clients:

___CruiseControl (cc installation)

|__projects___ config.xml

|___webapps

|___checkout

| |___trunk-build

| |___release1-build

| |___release2-build

| |___trunk-project1-quick

| |___release-project1-nightly

|| ...

|___target (the same as checkout)

|___logs (the same as checkout)

|___artifacts (the same as checkout)


But I'm still wondering if there is a better way to remove obsolete projects/release branches easily.

OOPSLA 2006

Last week, I attended the OOPSLA 2006 at Portland, OR. For the last several years, I tried several times to register for this conference. Every time, my registration was canceled due to different reasons. Finally, I made it in 2006:)

In general, it's a great conference with great hot topics, like AOP (Aspect oriented programming), MDD (Model driven design). On the other hand, I was a bit disappointed because it's more academic than industrial oriented. There was no talks about "Web2.0" during the whole conference. After more than 6 years of work in various industries, I'm more concerned about the actual usage than academic research.

There was an interesting talking: The Geography of Programming. But it's just the start of the search. I'm curious to see more search result coming out.

Leaving Instiki, joining Trac

Recently, I helped a team to solve their wiki problem. They were using a Ruby wiki named Instiki 0.10. The wiki stopped creating snapshot after one server power outage. In the end, it took 40 minutes to restart the wiki.

Firstly, I upgraded Instiki to the latest version which is using database. But several unexpected problems happened afterwards:

  1. We got segmentation error from time to time, and Instiki automatically shuts down. The error comes from sqlite driver.
  2. Server runs out of memory several times a day, and Instiki automatically shuts down.
  3. The performance of the page is unbearble. It takes 30 seconds to do a search with around 1000 pages.
After doing some research, we decided to move away from Instiki. Trac was picked as our new Wiki. Luckly, in Instiki, we could export all your pages into textile files. With the help from Simon, my colleague, I created a simple textile to trac wiki converter using Perl. It will look through the input directory for all the files with .textile extension, convert them into trac format, and dump the new files into specified directory. Then we used "trac-admin wiki load" command to load these pages into your trac wiki. Bingo!

The script was not perfect. I had to manually change several pages manually. At least, it's a good start. If anybody wants to get the script, feel free to shoot me an email.

Ruby Intellij Plugin

I tried to install Ruby plugin for Intellij today. There is no distribution available, so I had to get the source code from subversion repository and built the distribution file myself.

I could not create any new project in Intellij after the plugin was installed. Uninstalling the plugin fixed the problem. I guess I would wait for the next release.