Warszawa (Warsaw)
2008-07-07 05:17:57
Warszawa is the capital of Poland. During the World War II it was razed to the ground by order of Hitler, around 85% of the buildings were destroyed. After the war the old town Starowka (see below) was reconstructed and now it's an UNESCO world heritage site. The Palace of Culture and Science, built by the soviets, is the tallest building in Poland.
Entrevistado por minube.com
2008-07-04 00:16:47
Pedro Jareńo de minube.com me ha hecho una entrevista en su parada en Los Angeles durante su vuelta al mundo, por si quieres saber alguna cosa mįs sobre mi 
minube es una web de viajes "social" con una comunidad de usuarios, muy a la web 2.0. Pedro estį dando una vuelta al mundo y blogueando desde los lugares que visita para promocionar la pįgina.
Upgrading Struts 2.0.x to 2.1.x
2008-07-02 15:47:42
Now that Struts 2.1.2 is officially out you may want to upgrade. I've found the upgrading instructions at the Struts wiki to be extremely useful, and pretty much you'll need to read the whole thing.
Two things that I've contributed to the wiki:
Ensure no dependencies in the freemarker groupId are used as the latest version used by Struts is now under the org.freeemarker groupId and you'll get classpath conflicts if you added a freemarker dependency.
In the unit tests you may get a NullPointerException as ActionContext.getContext() does not create a context on demand, I think there are better alternatives to avoid the direct use of getContext, but this snippet will fix the problem.
ConfigurationManager configurationManager = new ConfigurationManager();
configurationManager.addContainerProvider(new XWorkConfigurationProvider());
Configuration config = configurationManager.getConfiguration();
Container container = config.getContainer();
ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack();
stack.getContext().put(ActionContext.CONTAINER, container);
ActionContext.setContext(new ActionContext(stack.getContext()));
assertNotNull(ActionContext.getContext());
Poznan, Poland
2008-07-02 05:16:44
Poznan is one of the oldest cities in Poland, and the fifth in size. Poznan's cathedral is the oldest in the country, containing the tombs of the first Polish rulers.
`
New York, New York (3)
2008-06-30 05:16:33
Last batch of pictures from New York, I promise
.
Functional testing with Maven, Cargo and Selenium
2008-06-25 18:17:10
.code-keyword {
color: #000091;
background-color: inherit;
}
.code-object {
color: #910091;
background-color: inherit;
}
.code-quote {
color: #009100;
background-color: inherit;
}
.code-comment {
color: #808080;
background-color: inherit;
}
.code-xml .code-keyword {
color: inherit;
font-weight: bold;
}
.code-tag {
color: #000091;
background-color: inherit;
}
Setting up automated functional integration tests is not too hard if you have the right tools. It can take you a bit of time to setup but in the long run you'll benefit from reduced QA times, reduced risks, a more confident development team, the ability to do safe refactorings, and many more advantages.
I'm going to explain how Maven, Selenium, Cargo and JBoss 4.2 can be setup to run automatically in a continuous integration server such as Continuum customizing the server configuration as needed and deploying any webapp automatically. Every time the webapp is changed the CI server will execute the tests against the latest version ensuring you are always in a safe state.
The biggest difference with other tutorials I've found is that most of them cover just Jetty and are not updated to the latest versions of libraries and tools, so here it is my contribution.
We use profiles to enable different combination of browser/application server. By default cargo uses jetty.
| Config | Profiles |
|---|---|
| JBoss 4.2 and Firefox (default) | -Pjboss42x,firefox |
| JBoss 4.2 and Internet Explorer | -Pjboss42x,iexplore |
| Jetty and Firefox | -Pfirefox |
| Jetty and Internet Explorer | -Piexplore |
<dependencies>
<dependency>
<groupId>com.acme</groupId>
<artifactId>mywebapp</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<!-- the jdbc driver we need to copy to the appserver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.openqa.selenium.client-drivers</groupId>
<artifactId>selenium-java-client-driver</artifactId>
<version>1.0-SNAPSHOT</version> <!-- required for firefox 3 else use 1.0-beta-1 -->
<scope>test</scope>
</dependency>
</dependencies>
Ports, where to uncompress the application server,...
<properties>
<cargo.install.directory>${project.build.directory}/installs</cargo.install.directory>
<selenium.port>14444</selenium.port>
<servlet.port>18880</servlet.port>
<selenium.background>true</selenium.background>
</properties>
Copy mysql jdbc driver to the app server lib folder
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-jdbc-lib</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>mysql</includeGroupIds>
<outputDirectory>${lib.target}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Install the application server in an early phase so we can customize it with our configuration files (see profiles). Then start before integration tests and stop afterwards. Parameters are used so different profiles can use different application servers.
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>install</id>
<phase>generate-resources</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<wait>false</wait>
</configuration>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<container>
<containerId>${container.name}</containerId>
<zipUrlInstaller>
<url>${container.url}</url>
<installDir>${cargo.install.directory}/${container.name}</installDir>
</zipUrlInstaller>
<log>${project.build.directory}/logs/${container.name}.log</log>
<output>${project.build.directory}/logs/${container.name}.out</output>
<timeout>600000</timeout>
</container>
<configuration>
<!--
<home>${project.build.directory}/${container.name}conf</home>
<type>existing</type>
-->
<properties>
<cargo.servlet.port>${servlet.port}</cargo.servlet.port>
<cargo.jboss.configuration>default</cargo.jboss.configuration>
<cargo.rmi.port>1099</cargo.rmi.port>
</properties>
<deployables>
<!-- application to deploy -->
<deployable>
<groupId>com.acme</groupId>
<artifactId>mywebapp</artifactId>
<type>war</type>
<properties>
<context>acontext</context>
</properties>
</deployable>
</deployables>
</configuration>
</configuration>
</plugin>
Make surefire skip tests during test phase and run them in the integration-test phase. Pass some properties as system properties so they are accessible from the junit test case.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skip the normal tests, we'll run them in the integration-test phase -->
<skip>true</skip>
<systemProperties>
<property>
<name>browser</name>
<value>${browser}</value>
</property>
<property>
<name>servlet.port</name>
<value>${servlet.port}</value>
</property>
<property>
<name>selenium.port</name>
<value>${selenium.port}</value>
</property>
</systemProperties>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<!-- to run headless in a Unix server with a virtual framebuffer X server Xvfb
you need to call first the goal selenium:xvfb ie. "mvn clean selenium:xvfb install"
see http://mojo.codehaus.org/selenium-maven-plugin/examples/headless-with-xvfb.html -->
<executions>
<execution>
<id>start-selenium</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
</execution>
</executions>
<configuration>
<background>${selenium.background}</background>
<port>${selenium.port}</port>
<logOutput>true</logOutput>
</configuration>
</plugin>
We can configure a different profile for each application server and set some specific application server configuration.
<profiles>
<profile>
<id>jboss42x</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<container.name>jboss42x</container.name>
<container.url>http://internap.dl.sourceforge.net/sourceforge/jboss/jboss-4.2.1.GA.zip</container.url>
<jboss.version>4.2.1.GA</jboss.version>
<jboss.conf.directory>${cargo.install.directory}/${container.name}/jboss-${jboss.version}/jboss-${jboss.version}/server/default</jboss.conf.directory>
<lib.target>${jboss.conf.directory}/deploy/lib</lib.target>
<war.target>${jboss.conf.directory}/deploy</war.target>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jboss</artifactId>
<version>${jboss.version}</version>
<type>zip</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- copy to the application server directory any customized configuration files that we need -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<copy todir="${jboss.conf.directory}" overwrite="true">
<fileset dir="${basedir}/src/test/${container.name}"/>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
As with the application servers we have a profile for each browser
<profile>
<id>firefox</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<browser>*firefox</browser>
</properties>
</profile>
<profile>
<id>iexplore</id>
<properties>
<browser>*iexplore</browser>
</properties>
</profile>
<profile>
<id>otherbrowser</id>
<properties>
<browser>*custom ${browserPath}</browser>
</properties>
</profile>
Make selenium not to run in the background so we can execute tests from the IDE
<profile>
<id>dev</id>
<properties>
<selenium.background>false</selenium.background>
</properties>
</profile>
Required for Selenium dependencies
<repositories>
<repository>
<id>openqa.org</id>
<name>OpenQA Repository</name>
<url>http://archiva.openqa.org/repository/releases</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<!-- for selenium 1.0-SNAPSHOT -->
<repository>
<id>snapshots.openqa.org</id>
<name>OpenQA Sanpshots Repository</name>
<url>http://archiva.openqa.org/repository/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
In an Unix server without X running you can still run Selenium tests using Xvfb (virtual framebuffer X server) by calling selenium:xvfb provided it's properly configured.
Also you can pass the path to the browser binary if not in the PATH
mvn clean selenium:xvfb install -Dbrowser="*firefox /usr/lib64/firefox-1.5.0.12/firefox-bin"
public class SeleniumHelloWorldTest
extends TestCase
{
private DefaultSelenium selenium;
private String baseUrl;
@Override
public void setUp()
throws Exception
{
super.setUp();
String port = System.getProperty( "servlet.port" );
baseUrl = "http://localhost:" + port;
selenium = createSeleniumClient( baseUrl );
selenium.start();
}
@Override
public void tearDown()
throws Exception
{
selenium.stop();
super.tearDown();
}
protected DefaultSelenium createSeleniumClient( String url )
throws Exception
{
String browser = System.getProperty( "browser" );
String port = System.getProperty( "selenium.port" );
return new DefaultSelenium( "localhost", Integer.parseInt( port ), browser, url );
}
public void testHelloWorld()
throws Exception
{
selenium.open( baseUrl + "/mycontext/" );
assertTrue( selenium.isTextPresent( "acme" ) );
}
}
Other wiki entries and blogs
New York, New York (2)
2008-06-24 17:16:26
A lot more pictures from my trip to New York.
New York, New York
2008-05-27 10:46:41
Some pictures from last year' trip to New York
Eclipse IAM passes creation review, Maven support at Eclipse Foundation soon
2008-05-22 12:47:24
This week we have gone through the creation review for Eclipse IAM (Eclipse Integration for Apache Maven), and so we are starting with the paperwork at the Eclipse Foundation to create the project in the incubator and start moving the code from Q4E, the codebase will be donated to IAM as start point.
Development won't stop in the meantime and we don't expect any interruption for Q4E users.
Speaking at CommunityOne on Monday
2008-05-02 16:16:40
Seems that I have been volunteered to do a lightening talk at CommunityOne on Monday at the Moscone as part of the Atlassian session.
Thanks to Cenqua' Pete for offering free drinks in exchange (he hasn't realized yet the mistake he has made) and entertainment like last year (hopefully with some differences in critical parts).
See you there.