Recently I ran into a problem.
My team has been tasked with writing a library to help with automated testing within the client’s organization. Great. Since the team’s who are going to use our code use Maven, it was only fitting for us to release our library as a simple Maven artifact into the corporate Maven repository and let them pull it down from there. Everything was going smoothly until we actually tried to get someone to use it. Evidently since the project team’s are deploying their code to WebSphere 6.0, they are using Java 1.4. Our testing library uses TestNG and required Java 5. Crap.
Since only the tests required Java 5 and they weren’t going to be deployed this shouldn’t be an issue in theory. The problem came in the form of Maven. Our initial plan was to have the project team testers fully integrate their UATs into the project’s build, placing their tests along side any other unit/integration tests the team could muster. The developer and build servers had Java 5 installed, so the only real trick was convincing Maven to compile and execute the tests using Java 5, but compile and package the product code using Java 1.4.
** A good friend and coworked pointed out that we should make sure that the “code” tests area compiled and run in the same VM version as the production code to make sure we didn’ thave any compatiblity issues and I totally agreed. Luckily, by the time he pointed this out, I had found my ultimate solution. **
Idea #1: Configure the Maven compiler plugin to use Java 5. Simple, and effective. Too effictive. This will change the settings for both the compiler:compile and the compiler:test-compile goals. No go.
<plugin> <groupId>org.apache.maven.plugins</groupId></pre> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>
Idea #2: Somehow set test-compile specific properties for Maven, allowing the normal compile goal to function as it had and the test-compile to use Java 5. This might have worked except for two things. 1) We would have had the issue that our unit tests were no longer compiled the same as our code and 2) I could never get it to work. Despite seeing what appeared to be test-compile specific source and target properties here and here … I could never get it to work. No Go.
Idea #3: Find a way to do what I did in Idea #1, but ONLY for the test-compile goal. This one seemed straightforward but it took quite a bit of surfing to finally find an example of how it might be done. A great Codehaus.org article included an exact example of what I needed to do prompted by the exact same issue. The solution used different execution profiles for the compiler plugin to achieve what I wanted. And since I the default settings were fine for the normal code compile, my configuration was even simpler. Works (except for the unit tests in Java 5 issue).
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <executions> <execution> <id>java-1.5-compile</id> <phase>process-test-sources</phase> <goals> <goal>testCompile</goal> </goals> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </execution> </executions> </plugin>
Idea #4 (What I ended up doing): Create totally separate module to be the home for UATs. After I solved my problem with Idea #3 and a few other unrelated issues crept up I decided something needed to change. I wanted to tests integrated with the rest of their code so that anyone on the team could/would actually write and run the tests. The final solution was to move the UATs out of the main development project and into their own. The client’s development teams had already decided on a multi-module Maven project aproach already and this seemed like a natual evolution. We created a separte UAT’s Maven module which along with the main code project and some other misc sub-modules were rolled up under one parent pom.xml for the project. Under the scheme I could use Idea #1 to set the compilation source and target for the UATs project to 1.5 across the board without worrying about screwing up the compilation of the main project or its unit tests. Done.