Upgrading Twitter

Posted by Martin Homik | Posted in WebApp | Posted on 19-03-2009


There is a nice post by Gojko Adzic about a talk he attended. The talk was given by Evan Weaver about experience with upgrading twitter.  It is quite interesting to know how sites having huge traffic solve performance problems.

German Web2.0 Paper Magazin

Posted by Martin Homik | Posted in Java, WebApp | Posted on 05-09-2008


Yesterday I went to town to get the new Java magazine. While I was at the store, I thought I could also try a new magazine. In that moment I realized that customers have many options to get A Linux or a Mac magazine which is a change when I payed attention to the fact the last time (a few years ago).  But actually, I searched for a magazine on Web2.0 or JavaScript. Both are fields I am diving into right now. Though I know many sources on the Net, I was surprised to see, or more accurately not to see, any magazine that covers this topic.

Can you recommend any magazine?

Struts2 URL Tag

Posted by Martin Homik | Posted in Java, WebApp | Posted on 26-08-2008


I use the Struts2 URL tag all the time to expand relative paths with the current context. I also use it to address images. I have not proven it, but today, I got the hint that an image to which an argument is appended, will be loaded each time the page is displayed. To prevent appending of additional parameters, use the includeParams attribute and set the value to none. Below is an example for a dynamically created URL.

  1. <s:url value="%{‘images/flags/’+locale+’.png’}" includeParams="none" id="localeURL"></s:url>

Debugging Maven projects with Eclipse

Posted by Martin Homik | Posted in Java, WebApp | Posted on 31-07-2008


Debugging Maven projects with Eclipse or any other IDE on Windows is not trivial. In the beginning. But once you know the mechansim, it’s simple. I googled and found a few helpful pages. Look here. Here are my experiences.

Maven supports two debug modes: the Generic and the Surefire. If you want to debug maven itself, one of maven’s plugins, or a maven project, use the Generic Approach. If you want to debug a test in your project launched by surefire, use the Surefire Approach.

Surefire Approach.

  • Create a new Java Project and call it “Maven Debug”. This Project will never have any source code in it, it is just a shell for attaching the debugger.
  • Create a debug configuration: Run -> Debug Configurations and then right click on Remote Java Application and select New launch configuration. Call it “Maven Surefire”.
  •  On the Connect tab click the Browse button and select the “Maven Debug” project.
  • Set connection properties to localhost and port 5005. This is the port on which Surefire waits for the debugger.
  • The connection type is Standard (Socket Attach)
  • On the Source tab add all projects that have any Maven source that you want to debug.

Now let’s do the actual debugging.

  • Select break points in the code you’re are going to run. Note, you cn select only code in your test classes. It won’t work on classes outside the test phase.
  • In your command line, append the following switch to your maven command: -Dmaven.surefire.debug. For example, to debug the tests run by the maven lifecycle install do mvn install -Dmaven.surefire.debug
  • Wait for maven to pause its execution and display the message: Listening for transport dt_socket at address: 5005
  • Attach the debugger to the running maven by selecting the “Maven Surefire” debug configuration created above. Your debugger should stop at your breakpoint.

Generic Approach.

  • Follow the instructions, presented here. The only instructions that worked for me. They are very similar to the Surefire Approach.
  • Note: use Maven 2.0.8 or higher. The, you don’t need to write your own maven debug script. It’ll be sufficient to use the shipped mvnDebug script.

OSGI and Spring

Posted by Martin Homik | Posted in Java, WebApp | Posted on 11-06-2008


There is a great presentation on OSGi and Spring at Parleys by Adrian Colyer and Costin Leau. They give a great introduction into OSGi and Spring and explain how to integrate both frameworks.

If you ask what are the benefits of going OSGi with Spring, read Adrian’s article Why should I care about OSGi anyway? 

How to test HTML code with dbunit

Posted by Martin Homik | Posted in Java, WebApp | Posted on 22-04-2008


As you know, I am working with AppFuse, and one important part of AppFuse is testing. To do that, you need sample data which is imported into the database. The dbunit sample data specifications says, that you can use any parsed character data as value but it does not say how to add html snippets into the database. To do that, you have to escape html entities. Below is an example for a body value element of table storing blog posts:

  1. <value description="body">
  2. &amp;lt;p align="justify"&amp;gt;London is the largest urban area and capital of England and the United Kingdom. &amp;lt;p&amp;gt;
  3. </value>

How to display html snippets in Struts2

Posted by Martin Homik | Posted in Java, WebApp | Posted on 22-04-2008


The second problem, I solved today, was to display html snippets in Struts. These snippets were stored in a POJO. If you use the usual Struts property element for displaying data, it will escape html code. Hence, you have to turn off escaping:

  1. <s:property escape="false" value="body"></s:property>

Automatic time-stamping of persisted data

Posted by Martin Homik | Posted in Java, WebApp | Posted on 08-04-2008


In my scenario, I want to know when a persisted object has been modified. This information should be stored in the database. There are a few approaches to do that.

  • In the database — I’ve read this suggestion somewhere that you can set a trigger. However, not all databases support this feature. Moreover, database independence is crucial. Setting a trigger as Java Annotation or property would be more convenient.
  • AOP — Write a Spring aspect that intercepts calls to Hibernate/Database and add the current time-stamp to the appropriate field.
  • JPA @Version — This was a promising approach. Unfortunately, edited objects were not updated but newly inserted. See a description here.
  • JPA Listeners – by implementing JPA listeners and using @PrePersist annotations this would be the most convenient and elegant way to implement the requirement. For some reason, entity listeners don’t work with AppFuse/Hibernate. Speculations point to Hibernate not supporting this feature.
  • Hibernate Interceptor – Similar to an aspect, one could implement a Hibernate Interceptor. However this approach bind the application to a specific Persistence Framework and prevents other persistency options in future. While this is a nice decision, one has to bear in mind that JPA is a small subset of features provided by each persistence framework. Hibernate is by far much more expressive than JPA and offers much more support than other frameworks. I fear that in the future, I will decide in favour of Hibernate as it offers much more support.
  • Manual — probably the worst solution is to leave the developer in full control. That is, he has to care that a timestamp is added and modified whenever an object is edited. This approach error-prone as changing the modified time-stamp can be forgotten. Morever, there can be a delay between setting the modified time-stamp and the actual persist action to the database.

The only option left is to give Spring AOP a shot. Let’s go!

Search with SQL

Posted by Martin Homik | Posted in Java, WebApp | Posted on 07-04-2008


Today I came across a wonderful Hibernate extension called Hibernate Search. If you have ever developed a web application with Hibernate which offered search, then you might have experiences the painful text search implementation with SQL/HQL. The truth is, SQL does not address the problem of text search in a way as we are accustomed to from Google Search. Just writing generic queries using like expressions with wildcards does not fulfil performance requirements.

This problem is actually addressed by Lucene. However, in a web application were the domain model is a key part of the business logic, Lucene is not easy to integrate. Problem such as structural mismatch, synchronization mismatch, and retrieval mismatch have to be solved. To bridge the gap and to provide the best things from both worlds, Lucene is now integrated into Hibernate. Search queries can be issued against the database or against Lucene in a transparant way. Search performance increases a lot and the developer has a very comfortable way to state queries and to provide results.

Bug in Maven Surefire Plugin

Posted by Martin Homik | Posted in Java, WebApp | Posted on 26-03-2008


On March 18 i tuned on my Laptop in the office ran a Maven build command on my project and it suddenly stopped with exceptions that pointed to Spring’s Beanfactory which was unable to load a bunch of beans. This was strange, because the evening before everything passed my JUnit tests. What happened?

I consulted AppFuse’s User group and found a thread which described my problem. Unfortunately, no good solution has been proposed. The author pointed to a Jira Issue in which a work around is described, but well, it’s not a good solution. A few other guys joined in the discussion, but none was able to solve the problem.

Today morning, I digged a bit deeper in it. I recalled March 18. One thing you have to know about Maven is, that by default, prior to compiling, it checks for new jar versions every day and downloads them. So I looked into my local m2 repository and found out that Maven downloaded the latest surefire plugin. I went to its web site and found a Jira bug report describing exactly the problem. However, the problem is still unresolved. But now that I know which version of the plugin caused the problem, I told my Maven project description not to use it and to use a previous version instead. Just add the follwing snippet to your build plugins section:

  1. <plugin>
  2.    <groupId>org.apache.maven.plugins</groupId>
  3.    <artifactId>maven-surefire-plugin</artifactId>
  4.    <version>2.3</version>
  5. </plugin>

Guess what, it solved my problem. And that makes my day. :-)