Hibernate - java.lang.NoClassDefFoundError

Implement a web service using the Hiberate layer for persistence. Works great, no errors. However, when I write unit test to access Dao, this meeting occurs when I get an instance of ServiceRegistry:

ServiceRegistry sr = new ServiceRegistryBuilder().applySettings( configuration.getProperties()).buildServiceRegistry(); 

Full stack trace:

 java.util.ServiceConfigurationError: org.hibernate.integrator.spi.Integrator: Provider org.jadira.usertype.dateandtime.joda.integrator.UserTypeJodaTimeHibernateIntegrator could not be instantiated: java.lang.NoClassDefFoundError: org/jadira/usertype/dateandtime/shared/spi/AbstractVersionableUserType at java.util.ServiceLoader.fail(ServiceLoader.java:224) at java.util.ServiceLoader.access$100(ServiceLoader.java:181) at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:377) at java.util.ServiceLoader$1.next(ServiceLoader.java:445) at org.hibernate.service.classloading.internal.ClassLoaderServiceImpl.loadJavaServices(ClassLoaderServiceImpl.java:236) at org.hibernate.integrator.internal.IntegratorServiceImpl.<init>(IntegratorServiceImpl.java:53) at org.hibernate.service.internal.BootstrapServiceRegistryImpl.<init>(BootstrapServiceRegistryImpl.java:80) at org.hibernate.service.internal.BootstrapServiceRegistryImpl.<init>(BootstrapServiceRegistryImpl.java:57) at org.hibernate.service.ServiceRegistryBuilder.<init>(ServiceRegistryBuilder.java:76) at com.dg.dao.SessionConfig.getSession(SessionConfig.java:26) at com.dg.dao.CustomerHibernate.doGetSingleById(CustomerHibernate.java:210) at com.dg.dao.CustomerHibernate.getCustomerByID(CustomerHibernate.java:44) at com.dg.dao.test.CustomerDaoTest.testCustomerDao(CustomerDaoTest.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.NoClassDefFoundError: org/jadira/usertype/dateandtime/shared/spi/AbstractVersionableUserType 

I checked that the class does not exist in pathpath. To fix this, I need to get an older version of usertype.spi.

The question is why it is trying to use the old class file for unit testing, but it works absolutely fine when the service starts in the container? Has anyone seen this problem before?

+4
source share
1 answer

I realized that this problem is caused by a collision between the following dependencies:

 <dependency> <groupId>org.jadira.usertype</groupId> <artifactId>usertype.jodatime</artifactId> <version>2.0.1</version> </dependency> 

and

 <dependency> <groupId>org.jadira.usertype</groupId> <artifactId>usertype.core</artifactId> <version>3.1.0.CR6</version> </dependency> 

The problem arises, in particular, because both packages contain the PersistentDateTime class (although there are many other duplicate classes). Both instances of PersistentDateTime extend a class called AbstractVersionableUserType. The only base classes here are in different packages. Thus, hibernate loads these types dynamically, using reflection when creating a ServiceRegistry. The reason he is bombing junit is because hibernate is trying to load the PersistentDateTime class from the usertype.jodatime package, and the actual class that needs to be loaded comes from the usertype.core package. It works in the container simply because another classloader is used.

In any case, when removing usertype.jodatime dependencies, everything works well.

+5
source

Source: https://habr.com/ru/post/1483684/


All Articles