After I introduced embedded mysql for unit testing to my project, the build is taking longer now. For my local development, sometimes I want to disable the unit test:
mvn clean package -DskipTests
Note that you can even skip the compiling of test class by using
mvn clean package -Dmaven.test.skip
However, if you use cobertura for code coverage check, you would get the following error:
[ERROR] Project failed check. Total branch coverage rate of 0.0% is below 85.0%
Project failed check. Total line coverage rate of 0.0% is below 85.0%
So you need to skip cobertura as well. if you google "skip cobertura", most answers suggested using haltOnFailure. However, cobertura already provides the skip functionality:
mvn clean package -DskipTests -Dcobertura.skip
With -Dcobertura.skip, cobertura check will be skipped:
[INFO] --- cobertura-maven-plugin:2.5.2:instrument (default) @ tag-service ---
[INFO] Skipping cobertura execution
Search This Blog
Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts
Tuesday, June 11, 2013
Monday, June 10, 2013
Using embedded mysql database for unit test with maven and spring
I used H2 in memory database to unit test my DAO. However, my production database is MySQL.
Generally, H2 is compatible with MySQL. However, H2 doesn't support ENUM type yet, and my schema uses ENUM for a column definition. Inspired by this post and another, I successfully used embedded MySQL for unit test. Here is what I did:
1. Add mysql-connector-mxj dependency:
2. Create EmbeddedMysqlDatabase.java and EmbeddedMysqlDatabaseBuilder.java
3. Create spring bean datasource:
4. Run unit test with Spring:
A couple things are worth mentioning:
1. The test uses Spring annotation @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) which reload the context after every test method. It means every test method starts a new mysql instance. You may group test methods to 2 different categories, one changes data, and another not. For those methods don't change data, only need to create one instance of mysql to speed up testing.
2. If you see the following error message on Linux server:
/lib64/libc.so.6: version `GLIBC_2.7' not found (required by /tmp/test_db_2420035739165052/bin/mysqld)
You need to either downgrade mysql-connector-mxj to 5.0.11 or upgrade your linux OS. I got the above error message on CentOS 5.4 with 5.0.12, but no problem with 5.0.11. However, 5.0.11 isn't in any public maven repo, but you can download it from here and install it to your local repo, or upload to your company's repo. Using the following command to check CentOS version:
cat /etc/redhat-release
3. The code is tested on Mac and CentOS only, and can be downloaded from github
Generally, H2 is compatible with MySQL. However, H2 doesn't support ENUM type yet, and my schema uses ENUM for a column definition. Inspired by this post and another, I successfully used embedded MySQL for unit test. Here is what I did:
1. Add mysql-connector-mxj dependency:
2. Create EmbeddedMysqlDatabase.java and EmbeddedMysqlDatabaseBuilder.java
3. Create spring bean datasource:
4. Run unit test with Spring:
A couple things are worth mentioning:
1. The test uses Spring annotation @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) which reload the context after every test method. It means every test method starts a new mysql instance. You may group test methods to 2 different categories, one changes data, and another not. For those methods don't change data, only need to create one instance of mysql to speed up testing.
2. If you see the following error message on Linux server:
/lib64/libc.so.6: version `GLIBC_2.7' not found (required by /tmp/test_db_2420035739165052/bin/mysqld)
You need to either downgrade mysql-connector-mxj to 5.0.11 or upgrade your linux OS. I got the above error message on CentOS 5.4 with 5.0.12, but no problem with 5.0.11. However, 5.0.11 isn't in any public maven repo, but you can download it from here and install it to your local repo, or upload to your company's repo. Using the following command to check CentOS version:
cat /etc/redhat-release
3. The code is tested on Mac and CentOS only, and can be downloaded from github
Labels:
DAO test mysql,
embedded mysql,
maven,
mxj,
mysql,
Spring,
unit test
Friday, June 29, 2012
mvn test: LocalJobRunner.java with java.lang.OutOfMemoryError
When I run mvn test to unit test some hadoop related program, I got the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xms256m -Xmx512m</argLine>
</configuration>
</plugin>
java.lang.OutOfMemoryError: Java heap spaceI tried to set MAVEN_OPTS=-Xmx2048m, but it didn't work. After the online research, I fixed this problem by adding the following to pom:
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.<init>(MapTask.java:949)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:428)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:372)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:212)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xms256m -Xmx512m</argLine>
</configuration>
</plugin>
Labels:
Java heap space,
maven,
maven-surefire-plugin,
mvn,
OutOfMemoryError,
plugin,
test,
unit test
Thursday, June 28, 2012
maven shade plugin: Invalid signature file digest for Manifest main attributes
If you get the following error message with maven shade plugin:
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
You need to add the following to pom.xml:
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
Explanation:
The above configuration filters all files in META-INF ending with .SF, .DSA, and .RSA for all artifacts (*:*) when creating uber-jar file.
The reason java.lang.SecurityException is raised is because some dependency jar files are signed jar files. A jar file is signed by using jarsigner, which creates 2 additional files and places them in META-INF:
See jarsigner for detailed explanation of JAR Signing and Verification Tool.
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
You need to add the following to pom.xml:
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
Explanation:
The above configuration filters all files in META-INF ending with .SF, .DSA, and .RSA for all artifacts (*:*) when creating uber-jar file.
The reason java.lang.SecurityException is raised is because some dependency jar files are signed jar files. A jar file is signed by using jarsigner, which creates 2 additional files and places them in META-INF:
- a signature file, with a .SF extension, and
- a signature block file, with a .DSA, .RSA, or .EC extension.
See jarsigner for detailed explanation of JAR Signing and Verification Tool.
Sunday, June 24, 2012
Eclipse: fix plugin execution not covered by lifecycle configuration
I recently used maven-jaxb2-plugin to generate java classes based on xml schemas (xsd). I can run "mvn compile" on command line to generate java classes with the following configuration:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
However, my Eclipse shows the following error:
Plugin execution not covered by lifecycle configuration: org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.8.1:generate (execution: default, phase: generate-sources)
This error prevents Eclipse generating java source codes and adding the generated sources to the class path. In order to fix this problem, I need to install m2e connector for maven-jaxb2-plugin. I can manually install it to Eclipse with the following update site:
http://bitstrings.github.com/m2e-connectors-p2/milestones/
However, Eclipse provides a better to install it. Eclipse shows the problem with the following:
Roll the mouse over <execution>, it displays the following:
Click the link "Discover new m2e connector", and eclipse will try to find the correct connector automatically:
Eclipse found the same m2e connector. Click finish to install it. After I installed it successfully, Eclipse is happy with maven-jaxb2-plugin.
This approach can be applied to other plugins too.
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
However, my Eclipse shows the following error:
Plugin execution not covered by lifecycle configuration: org.jvnet.jaxb2.maven2:maven-jaxb2-plugin:0.8.1:generate (execution: default, phase: generate-sources)
This error prevents Eclipse generating java source codes and adding the generated sources to the class path. In order to fix this problem, I need to install m2e connector for maven-jaxb2-plugin. I can manually install it to Eclipse with the following update site:
http://bitstrings.github.com/m2e-connectors-p2/milestones/
However, Eclipse provides a better to install it. Eclipse shows the problem with the following:
Roll the mouse over <execution>, it displays the following:
Click the link "Discover new m2e connector", and eclipse will try to find the correct connector automatically:
Eclipse found the same m2e connector. Click finish to install it. After I installed it successfully, Eclipse is happy with maven-jaxb2-plugin.
This approach can be applied to other plugins too.
Saturday, May 19, 2012
cobertura-maven-plugin
Recently I created a parent pom for my team to use. All my team's projects need to inherit this parent pom. This parent pom is rather simple:
<exclude>com/zhentao/Some.class</exclude> excludes Some.class from the cobertura report.
However, this flexibility can be abused by some developers. I got an build failed notification today:
<properties>We are targeting a pretty high unit test coverage, 90% for both line and branch coverage. However, some classes don't need unit test or don't need high coverage. Then each individual project can include the following to its project pom:
<default.encoding>UTF-8</default.encoding>
<default.jdk>1.6</default.jdk>
<line.coverage.target>90</line.coverage.target>
<branch.coverage.target>90</branch.coverage.target>
</properties>
<build>
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${default.jdk}</source>
<target>${default.jdk}</target>
<encoding>${default.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${default.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8</version>
<configuration>
<encoding>${default.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.2.2</version>
</plugin>
<!-- Sonar uses these versions, below -->
<plugin>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<targetJdk>${default.jdk}</targetJdk>
<encoding>${default.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>${default.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<check>
<!-- Per-class thresholds -->
<branchRate>${branch.coverage.target}</branchRate>
<lineRate>${line.coverage.target}</lineRate>
<!-- Project-wide thresholds -->
<totalLineRate>${line.coverage.target}</totalLineRate>
<totalBranchRate>${branch.coverage.target}</totalBranchRate>
</check>
<formats>
<format>html</format>
</formats>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>clean</goal>
<goal>cobertura</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<!-- Ensure that source code is packaged and deployed for inclusion into IDEs -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<build><ignore>org.slf4j.*</ignore> ignores all log statement in the code since we don't need to test logs.
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<instrumentation>
<ignores>
<ignore>org.slf4j.*</ignore>
</ignores>
<excludes>
<exclude>com/zhentao/Some.class</exclude>
<exclude>com/zhentao/other.class</exclude>
</excludes>
</instrumentation>
</configuration>
</plugin>
</plugins>
</build>
<exclude>com/zhentao/Some.class</exclude> excludes Some.class from the cobertura report.
However, this flexibility can be abused by some developers. I got an build failed notification today:
One developer excluded all classes from testing. What a developer!11:52:52 Archiving artifacts 11:52:52 [htmlpublisher] Archiving HTML reports... 11:52:52 [htmlpublisher] Archiving at PROJECT level /target/site/cobertura to /htmlreports/Cobertura_Report 11:52:52 ERROR: Specified HTML directory '/target/site/cobertura' does not exist. 11:52:52 Build step 'Publish HTML reports' changed build result to FAILURE
Subscribe to:
Posts (Atom)


