Search code examples
springhibernateunit-testingjpahibernate-entitymanager

Spring + Hibernate + Maven NullPointerException


I thought it was a good idea to add some testing to my project, but during the process I somehow managed to get the real deal broken.

I am using Spring MVC with JPA (Hibernate). The entityManager cannot be loaded properly anymore:

INFO - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3aa1e2da: defining beans [dataSource,org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,signatureBlobService,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,validator,emf,org.springframework.security.filterChains,org.springframework.security.filterChainProxy,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.userDetailsServiceFactory,org.springframework.security.web.DefaultSecurityFilterChain#0,org.springframework.security.provisioning.InMemoryUserDetailsManager#0,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager]; root of factory hierarchy
INFO - Hibernate Validator 4.2.0.Final
INFO - Building JPA container EntityManagerFactory for persistence unit 'default'
INFO - HCANN000001: Hibernate Commons Annotations {4.0.1.Final}
INFO - HHH000412: Hibernate Core {4.1.4.Final}
INFO - HHH000206: hibernate.properties not found
INFO - HHH000021: Bytecode provider name : javassist
INFO - HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
INFO - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3aa1e2da: defining beans [dataSource,org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,signatureBlobService,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,validator,emf,org.springframework.security.filterChains,org.springframework.security.filterChainProxy,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.userDetailsServiceFactory,org.springframework.security.web.DefaultSecurityFilterChain#0,org.springframework.security.provisioning.InMemoryUserDetailsManager#0,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager]; root of factory hierarchy
ERROR - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'emf' defined in ServletContext resource [/WEB-INF/spring/root-context.xml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: error trying to scan <jar-file>: file:/Users/XXX/Documents/Coding/Webapps/.metadata/.plugins/org.eclipse.wst.server.core/tmp2/wtpwebapps/XXX/WEB-INF/classes/
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.RuntimeException: error trying to scan <jar-file>: file:/Users/david/Documents/Coding/Webapps/.metadata/.plugins/org.eclipse.wst.server.core/tmp2/wtpwebapps/payworkssign/WEB-INF/classes/
    at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:855)
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:597)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    ... 22 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at javassist.bytecode.AnnotationsAttribute.getAnnotations(AnnotationsAttribute.java:230)
    at javassist.bytecode.AnnotationsAttribute.getAnnotation(AnnotationsAttribute.java:184)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(AbstractJarVisitor.java:256)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(AbstractJarVisitor.java:212)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisitor.java:173)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:126)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.getClassNamesInTree(ExplodedJarVisitor.java:134)
    at org.hibernate.ejb.packaging.ExplodedJarVisitor.doProcessElements(ExplodedJarVisitor.java:92)
    at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:149)
    at org.hibernate.ejb.packaging.NativeScanner.getFilesInJar(NativeScanner.java:192)
    at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:504)
    at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:852)
    ... 28 more
Caused by: java.lang.NullPointerException
    at javassist.bytecode.ConstPool.getUtf8Info(ConstPool.java:616)
    at javassist.bytecode.annotation.Annotation.addMemberValue(Annotation.java:205)
    at javassist.bytecode.annotation.Annotation.addMemberValue(Annotation.java:185)
    at javassist.bytecode.AnnotationsAttribute$Parser.memberValuePair(AnnotationsAttribute.java:625)
    at javassist.bytecode.AnnotationsAttribute$Walker.memberValuePair(AnnotationsAttribute.java:355)
    at javassist.bytecode.AnnotationsAttribute$Walker.annotation(AnnotationsAttribute.java:348)
    at javassist.bytecode.AnnotationsAttribute$Parser.annotation(AnnotationsAttribute.java:620)
    at javassist.bytecode.AnnotationsAttribute$Walker.annotation(AnnotationsAttribute.java:343)
    at javassist.bytecode.AnnotationsAttribute$Parser.annotationArray(AnnotationsAttribute.java:610)
    at javassist.bytecode.AnnotationsAttribute$Walker.annotationArray(AnnotationsAttribute.java:330)
    at javassist.bytecode.AnnotationsAttribute$Walker.annotationArray(AnnotationsAttribute.java:325)
    at javassist.bytecode.AnnotationsAttribute$Parser.parseAnnotations(AnnotationsAttribute.java:588)
    at javassist.bytecode.AnnotationsAttribute.getAnnotations(AnnotationsAttribute.java:227)
    ... 42 more

When running

mvn test

Everything runs through. There I use an embedded H2 database Removing the test related things (dependencies etc.) did not solve the problem.

Javassist is responsible for annotations in this case, if I understood correctly. My problem is I have no idea where to continue looking. Is it really a UTF8 issue? And why is it trying to scan the /classes directory while thinking it is a jar file?

A list of what else could be somehow related to the problem:

  1. I played around a bit with the project configuration in eclipse (added for maven, wst). I did remove this configuration again to try if it makes a difference. I also used mvn package war:war to deploy the application on a local tomcat. The same error occurs here. Again mvn test works fine

  2. I updated hibernate-validator and hibernate-entitymanager to the newest version. However, downgrading again left the issue present.

Some other infos that might be necessary to locate the problem:

The relevant part of my root-context.xml

<!-- Enable JPA Support -->
<!-- Enable Annotation driven declaration -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Define transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="packagesToScan" value="com.payworksmobile.dev.jpa"/>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.max_fetch_depth">3</prop>
            <prop key="hibernate.jdbc.fetch_size">50</prop>
            <prop key="hibernate.jdbc.batch_size">10</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

Solution

  • After trying many things before posting this question, I actually just stumbled upon the solution:

    I found two classes from my test cases in my WEB-INF/classes folder. These to classes where actually the configuration classes for my tests. After deleting them everything runs like a charm. I found those classes in there after extracting my war file and looking for leftovers from my tests.

    Why did this happen? (This is me just guessing) When creating a new test folder in eclipse, it took me some time to modify my pom.xml to treat this folder as a <testSourceDirectory>. Eclipse built the project in between, copying the class files from my test configuration classes to WEB-INF/classes. This somehow messed with Spring and Hibernate. My learning: Check that only the relevant classes get copied into the war file and WEB-INF/classes does not contain any leftovers.