Mojarra comes with over 8000 tests, but as we explained in a previous article, building it and running those tests is not entirely trivial. It’s not that difficult though if you know the steps, but the many outdated readmes and many folders in the project can make it difficult to find these steps.
Since the previous article some things have changed, so we’ll provide an update here.
Currently the Mojarra project is in a migration status. Manfred Riem is currently working on moving the complicated and ancient ANT based tests to a more modern Maven based setup. For the moment this is a bit of an extra burden as there are now two distinct test folders. Eventually though there should be only one. Since the migration is in full swing things can also still change often. The instructions below are valid for at least JSF 2.2.5 till 2.2.7-SNAPSHOT.
We’ll first create a separate directory for our build and download a fresh version of GlassFish 4 that we’ll use for running the tests. From e.g. your home directory execute the following:
mkdir mtest cd mtest wget http://download.java.net/glassfish/4.0/release/glassfish-4.0.zip unzip glassfish-4.0.zip
Note that unlike the 2012 instructions it’s no longer needed to set an explicit password. The default “empty” password now works correctly. The readme in the project still says you need to install with a password, but this is thus no longer needed.
Next we’ll check out the Mojarra 2.2 “trunk”. Note here that the real trunk is dormant and all the action happens in a branch called “MOJARRA_2_2X_ROLLING”. Unfortunately Mojarra still uses SVN, but it is what it is. We’ll use the following commands;
svn co https://svn.java.net/svn/mojarra~svn/branches/MOJARRA_2_2X_ROLLING/ cd MOJARRA_2_2X_ROLLING cp build.properties.glassfish build.properties
We now need to edit build.properties and set the following values:
jsf.build.home=[source home] container.name=glassfishV3.1_no_cluster container.home=[glassfish home]/glassfish halt.on.failure=no
[source home] is the current directory where we just cd’ed into (e.g. /home/your_user/mtest/MOJARRA_2_2X_ROLLING), while [glassfish home] is the directory that was extracted from the archive (e.g. /home/your_user/mtest/glassfish4/).
If your OS supports all the following commands (e.g. Ubuntu does) you can also execute:
sed -i "s:<SET CURRENT DIRECTORY>:$(pwd):g" build.properties sed -i "s:container.name=glassfish:container.name=glassfishV3.1_no_cluster:g" build.properties sed -i "s:container.home=:container.home=$(readlink -f ../glassfish4/):g" build.properties
We’re now going to invoke the actual build. Unfortunately there still is a weird dependency between the main build task and the clean task, so the first time we can only execute “main” here. If the build needs to be done a subsequent time we can do “clean main” then. For now execute the following:
We can then run the ANT tests as follows:
export ANT_OPTS='-Xms512m -Xmx786m -XX:MaxPermSize=786m' ant test.with.container.refresh
Just like the previous time, there are always a number of ANT tasks that are already failing. Whether the “trunk” of Mojarra simply has failing tests all the time, or whether it’s system dependent is something we didn’t investigate. Fact is however that after some three years of periodically building Mojarra and running its tests, on various different systems (Ubuntu, Debian, OS X) we’ve never seen it happening that out of the box all tests passed. In the current (March 28, 2014) 2.2.7-SNAPSHOT branch the following tests failed out of the box;
So if you want to test the impact of your own changes, be sure to run the tests before making those changes to get an idea of which tests are already failing on your system and then simply comment them out.
The ANT tests execute rather slowly. On the 3.2Ghz/16GB/SSD machine we used they took some 20 minutes.
The maven tests are in a separate directory and contain only tests. To give those tests access to the Mojarra artifact we just build we need to install it in our local .m2 repo:
(if we use this method on a build server we may want to use separate users for each test. Otherwise parallel builds may conflict since the .m2 repo is global to the user running the tests)
We now CD into the test directory and start with executing the “clean” and “install” goals:
cd test mvn clean install
After the clean install we have to tell maven about the location of our GlassFish server. This can be done via a settings.xml file or by replacing every occurrence of “C:/Glassfish18.104.22.168” in the pom.xml that’s in the root of the folder we just cd’ed into. A command to do the latter is:
sed -i "s#C:/Glassfish22.214.171.124#$(readlink -f ../../glassfish4/)#g" pom.xml
The test directory contains several folders with tests for different situations. Since JSF 2.2 can run on both Servlet 3.0 and Servlet 3.1 containers there’s a separate Servlet 3.1 folder with tests specific to that. It’s however not clear why there still is a Servlet 3.0 folder (probably a left-over from JSF 2.0/2.1). The most important test folder is the “agnostic” one. This runs on any server and should even run with every JSF implementation (e.g. it should run on MyFaces 2.2 as well).
The following commands are used to execute them:
cd agnostic/ ../bin/test-glassfish-default.sh
The Maven tests run rather fast and should be finished in some 3 to 4 minutes. Instead of modifying the pom and invoking the .sh script we can also run Maven directly via a command like the following:
mvn -Dintegration.container.home=/home/your_user/mtest/glassfish4/ -Pintegration-failsafe,integration-glassfish-cargo clean verify
(replace “/home/your_user/mtest/glassfish4/” with the actual location of glassfish on your system)
The difference is that the script is a great deal faster. It does this by calling maven 6 times with different goals. This will cause work to be done in advance for all tests instead of for each test over and over again. The fact that this needs to be done via a script instead of directly via maven is maybe indicative of a weakness in maven. Although understanding the script is not needed for the build and running the tests, I found it interesting enough to take a deeper look at it.
The pom uses a maven plug-in for the little known cargo project. Cargo is a kind of competitor for the much wider known Arquillian. Just as its more popular peer it can start and stop a large variety of Java EE containers and deploy application archives to those. Cargo has existed for much longer than Arquillian and is still actively developed. It supports ancient servers such as Tomcat 4 and JBoss 3, as well as the very latest crop like Tomcat 8 and WildFly 8.
The 6 separate invocations are the following;
- Copy a Mojarra artifact (javax.faces.jar) from the Maven repo to the GlassFish internal modules directory (profile integration-glassfish-prepare)
- Clean the project, compile and then install all tests (as war archives) in the local Maven repo (no explicit profile)
- Start GlassFish (profile integration-glassfish-cargo, goal cargo:start)
- Deploy all previously build war archives in one go to GlassFish (profile integration-glassfish-cargo, goal cargo:redeploy)
- Run the actual tests. These will do HTTP requests via HTML Unit to the GlassFish instance that was prepared in the previous steps (profile integration-failsafe, goal verify)
- Finally stop the container again (profile integration-glassfish-cargo, goal cargo:stop)
As said previously, the project is in migration status and things still change frequently. In the 2.2.7 “trunk” an additional glassfish-cargo profile appeared that’s basically a copy of the existing integration-glassfish-cargo, but without the embedded and unused copy goal (which we’d seen above was part of the integration-glassfish-prepare profile). There’s also a new glassfish-copy-mojarra-1jar goal that’s a copy of the integration-glassfish-prepare profile with some parametrized configuration items replaced by constants, etc.
With the constant change going on documenting the build and test procedure is difficult, but hopefully the instructions presented in this article are up to date enough for the moment.