PersistenceException issue with Cobertura and the hibernate3-maven-plugin

I have been using the hibernate3-maven-plugin for some time with a good deal of success in unit testing my data access layers through dbunit. I always separate my data access into a separate module, called data-services, for many reasons. Mostly so I can separate my testing to just database integration testing, and not unit testing in the test phase of maven.

First, I create the hibernate3-maven-plugin declaration:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<components>
<component>
<name>hbm2hbmxml</name>
<outputDirectory>target/classes</outputDirectory>
</component>
</components>
<componentProperties>
<implementation>jpaconfiguration</implementation>
<persistenceunit>ApplicationEntityManager</persistenceunit>
<drop>true</drop>
<skip>${maven.test.skip}</skip>
&lt;propertyfile&gt;<em><strong>src/test/resources/database.properties</strong></em>&lt;/propertyfile&gt;
&lt;/componentProperties&gt;
&lt;/configuration&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;hbm2ddl&lt;/id&gt;
<strong>&lt;phase&gt;process-test-resources&lt;/phase&gt;</strong>
&lt;goals&gt;
&lt;goal&gt;hbm2ddl&lt;/goal&gt;
&lt;/goals&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.h2database&lt;/groupId&gt;
&lt;artifactId&gt;h2&lt;/artifactId&gt;
&lt;version&gt;${h2.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/plugin&gt;

Notice the hbm2ddl execution phase is set to <phase>process-test-resources</phase> which is when the ddl is created.

My  database.properties to seed a file based H2 Database:

hibernate.connection.username=sa
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.url=<strong>jdbc:h2:file:target/h2/testdb;REFERENTIAL_INTEGRITY=FALSE</strong>
hibernate.connection.driver_class=org.h2.Driver

I also wanted all my tests to run in the integration-test phase, not the test phase
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
...
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;surefire-unittest&lt;/id&gt;
&lt;phase&gt;test&lt;/phase&gt;
&lt;configuration&gt;
&lt;excludes&gt;
&lt;exclude&gt;**/*Test.java&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;includes&gt;
<strong>&lt;include&gt;none&lt;/include&gt;</strong>
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;execution&gt;
&lt;id&gt;surefire-it&lt;/id&gt;
&lt;phase&gt;integration-test&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;test&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;excludes&gt;
&lt;exclude&gt;none&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;includes&gt;
<strong>&lt;include&gt;**/*Test.java&lt;/include&gt;</strong>
&lt;/includes&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;

When I execute my normal “mvn clean verify -e“, I get the following trace:
[myproject] DEBUG [main] Ejb3Configuration.configure(312) | Processing PersistenceUnitInfo [
name: <strong>ApplicationEntityManager</strong>
persistence provider classname: null
classloader: sun.misc.Launcher$AppClassLoader@11b86e7
Temporary classloader: org.springframework.instrument.classloading.SimpleThrowawayClassLoader@11db6bb
excludeUnlistedClasses: false
JTA datasource: null
Non JTA datasource: org.apache.commons.dbcp.BasicDataSource@1c7e2da
Transaction type: RESOURCE_LOCAL
PU root URL: file:/C:/opt/projects/grd/trunk/data-services/target/classes/

I plan on creating another post to detail my JUnit and TestNG DBUnit testing. For this post, I really just want to focus on the error in the hibernate3-maven-plugin.

I have 21 tests run successfully:

<em>Results :
<strong>Tests run: 21, Failures: 0, Errors: 0, Skipped: 0</strong></em>

What I then wanted to do was integrate Cobertura Code Coverage into this module.

I first added just a generic plugin delcaration:

&lt;plugin&gt;
&lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
&lt;artifactId&gt;cobertura-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;instrumentation&gt;
&lt;ignores&gt;
&lt;ignore&gt;com.baselogic.ignore.*&lt;/ignore&gt;
&lt;/ignores&gt;
&lt;excludes&gt;
&lt;exclude&gt;com/baselogic/**/*Test.class&lt;/exclude&gt;
&lt;/excludes&gt;
&lt;/instrumentation&gt;
&lt;check&gt;
&lt;branchRate&gt;85&lt;/branchRate&gt;
&lt;lineRate&gt;85&lt;/lineRate&gt;
&lt;haltOnFailure&gt;true&lt;/haltOnFailure&gt;
&lt;/check&gt;
&lt;/configuration&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;goals&gt;
&lt;goal&gt;clean&lt;/goal&gt;
&lt;!--&lt;goal&gt;check&lt;/goal&gt;--&gt;
&lt;/goals&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;net.sourceforge.cobertura&lt;/groupId&gt;
&lt;artifactId&gt;cobertura&lt;/artifactId&gt;
&lt;version&gt;1.9rc1&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/plugin&gt;

Notice I commented out the <goal>check</goal> as I did not want to fail the build, I wanted to allow lower numbers so I could generate the site documentation with these numbers.

When I run “mvn site -e“, I get this error trying creating the ApplicationEntityManager stating a class or package was not found:

[INFO] [hibernate3:hbm2ddl {execution: hbm2ddl}]
...
[myproject] DEBUG [main] Ejb3Configuration.configure(209) | Look up for persistence unit: ApplicationEntityManager
[myproject] DEBUG [main] DTDEntityResolver.resolveEntity(64) | trying to resolve system-id [http://java.sun.com/xml/ns/p
ersistence/persistence_1_0.xsd]
[myproject] DEBUG [main] EJB3DTDEntityResolver.resolveEntity(49) | recognized EJB3 ORM namespace; attempting to resolve
on classpath under org/hibernate/ejb
[myproject] DEBUG [main] EJB3DTDEntityResolver.resolveEntity(58) | located [http://java.sun.com/xml/ns/persistence/persi
stence_1_0.xsd] in classpath
[myproject] DEBUG [main] Ejb3Configuration.getDetectedArtifacts(562) | Detect class: true; detect hbm: true
[myproject] DEBUG [main] AbstractJarVisitor.unqualify(116) | Searching mapped entities in jar/par: file:/C:/opt/projects
/grd/trunk/data-services/target/generated-classes/cobertura/
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.BaseDao
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.jpa.BaseDaoJpaImpl$1
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.jpa.BaseDaoJpaImpl
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: <strong>com.baselogic.domain.IdentifiedObject</strong>
[myproject] DEBUG [main] AbstractJarVisitor.executeJavaElementFilter(213) | Java element filter matched for com.baselogi
c.domain.IdentifiedObject
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.domain.User
[myproject] DEBUG [main] AbstractJarVisitor.executeJavaElementFilter(213) | Java element filter matched for com.baselogi
c.domain.User
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.domain.UserNotFoundException
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.service.impl.UserManagerImpl
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.service.UserManager
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.fedex.ground.configuration.DataSourceFactor
y
[myproject] DEBUG [main] Ejb3Configuration.getDetectedArtifacts(562) | Detect class: true; detect hbm: true
[myproject] DEBUG [main] Ejb3Configuration.configure(158) | Creating Factory: ApplicationEntityManager
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] [PersistenceUnit: ApplicationEntityManager] class or package not found
<strong>com.baselogic.domain.IdentifiedObject</strong>
[INFO] ------------------------------------------------------------------------
[INFO] Trace
javax.persistence.PersistenceException: [PersistenceUnit: ApplicationEntityManager] class or package not found
        at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1093)
        at org.hibernate.ejb.Ejb3Configuration.addClassesToSessionFactory(Ejb3Configuration.java:871)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:758)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:191)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:253)
        at org.codehaus.mojo.hibernate3.configuration.JPAComponentConfiguration.createConfiguration(JPAComponentConfigur
ation.java:28)
        at org.codehaus.mojo.hibernate3.configuration.AbstractComponentConfiguration.getConfiguration(AbstractComponentC
onfiguration.java:51)
        at org.codehaus.mojo.hibernate3.exporter.Hbm2DDLExporterMojo.doExecute(Hbm2DDLExporterMojo.java:87)
        at org.codehaus.mojo.hibernate3.HibernateExporterMojo.execute(HibernateExporterMojo.java:152)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:453)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:559)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:50
0)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.forkProjectLifecycle(DefaultLifecycleExecutor.java:925)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.forkLifecycle(DefaultLifecycleExecutor.java:768)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:550)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:50
0)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:479)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.jav
a:331)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:292)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:301)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
        at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
        at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: java.lang.ClassNotFoundException: com.baselogic.domain.IdentifiedObject
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(RealmClassLoader.java:195)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:255)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:274)
        at org.codehaus.classworlds.RealmClassLoader.loadClass(RealmClassLoader.java:214)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:135)
        at org.hibernate.ejb.Ejb3Configuration.classForName(Ejb3Configuration.java:1009)
        at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1081)
        ... 30 more

I first started looking for the missing class file. I found 2. One in ~target/classes/**/IdentifiedObject.class and another one in ~target/cobertura/**/IdentifiedObject.class. The class was not missing, but it appeared that the hibernate3 plugin was not finding the correct classpath when running these tests instrumented with Cobertura. Remember, the tests run without Cobertura.

I wanted to test to make sure Cobertura was running all, so in the above plugin deplaration, Iuncommented the <goal>check</goal> section and re-ran “mvn clean verify -e” to find that Cobertura was indeed running successfully, and failing the build:

[INFO] [cobertura:check {execution: default}]
Cobertura: Loaded information on 11 classes.
...
Project failed check. Total branch coverage rate of 55.8% is below 85.0%
Project failed check. Total line coverage rate of 74.6% is below 85.0%
...
[INFO] Coverage check failed. See messages above.
[INFO] ------------------------------------------------------------------------

This tells me that Cobertura is instrumenting my DBUnit code, and my tests are running against my H2 file database, but there is not enough code coverage for my checked limits. This at least verifies that Cobertura works.

After quite a bit of trial and error, I tried to change the phase in which the hibernate3 plugin was getting executed. I changed from <phase>process-test-resources</phase> and moved the execute further down the lifecycle to <phase>package</phase>. Now, when I can “mvn site -e“, I generate my site documentation successfully, as well as get my Cobertura report

coverage-report_1237231414894

So now, I wanted to see the effect this change would have on my normal build life cycle, so I re-ran “mvn clean verify -e“. I was faced with more frustration, as now, my plugin was not running in the correct life cycle and all my dbunit test inserts where failing:

<em>[myproject] DEBUG [main] AbstractHibernateTest.prepareDataSet(101) | Invoked prepareDataSet()
prepareSettings called
<strong>org.dbunit.dataset.NoSuchTableException: app_user</strong>
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:279)</em>

I have seen this error before and knew that my database was not created by the hibernate3 plugin. I decided to add a property to switch which phase the plugin would get executed. I added a default property <hibernate3.execute.phase>process-test-resources</hibernate3.execute.phase> to my pom’s <properties>… section.

I then changed the hibernate3-maven-plugin phase from <phase>package</phase> to <phase>${hibernate3.execute.phase}</phase>

Now I needed to create a new profile jsut to switch this phased execution for my site:

&lt;profile&gt;
<strong>&lt;id&gt;lazy-hibernate3&lt;/id&gt;</strong>
&lt;properties&gt;<strong>&lt;hibernate3.execute.phase&gt;package&lt;/hibernate3.execute.phase&gt;</strong>&lt;/properties&gt;
&lt;/profile&gt;

Now I could easily use “mvn site -Plazy-hibernate3 -e” to lazily execute my hibernate3-maven-plugin

VN:F [1.9.1_1087]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.1_1087]
Rating: 0 (from 0 votes)
  • Share/Bookmark

This entry was posted on Monday, March 16th, 2009 at 11:54 am and is filed under Apache Maven, Consulting, Java-JavaEE-J2EE, Test Driven Development (TDD), Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.