質問

I'm trying to get Broadleaf Commerce running in a simple JUnit unit test, as a proof of concept to see if I can do basic shopping cart operations, such as adding to cart, updating quantities, and placing an order - without a UI.

The idea to see if I can use a completely different UI with Broadleaf as the backend.

So far, this has been a bit rough to get working (just to get the spring context up and running at all). I'm using Gradle to build my project. The configuration looks as follows:

Test Class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
    "MyTest.xml",
})
public class BltMainTest {

@Test
public void test() {
    System.out.println("THIS IS A TEST");
}

}

MyTest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       ">

<import resource="classpath:bl-framework-applicationContext-persistence.xml"/>
<import resource="classpath:bl-framework-applicationContext-entity.xml"/>
<import resource="classpath:bl-framework-applicationContext-workflow.xml"/>
<import resource="classpath:bl-framework-applicationContext.xml"/>
<import resource="classpath:bl-profile-applicationContext.xml"/>
<import resource="classpath:bl-profile-applicationContext-entity.xml"/>
<import resource="classpath:bl-profile-applicationContext-persistence.xml"/>

</beans>

build.gradle excerpts (had to do a bit of a hack to get ehcache to work against Maven Central, not totally sure why):

...
dependencies {
...
 compile 'net.sf.ehcache:ehcache-core:2.6.0'

 compile('org.broadleafcommerce:broadleaf-framework:1.6.1-GA') {
     exclude module: 'ehcache-terracotta'
     exclude module: 'ehcache'
 }
 compile('org.broadleafcommerce:broadleaf-profile:1.6.1-GA') {
     exclude module: 'ehcache-terracotta'
     exclude module: 'ehcache'
 }
...
}

The stack trace I get is rather long, but the bottom most (and I believe relevant) portion is this:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'blEntityManagerFactorySecureInfo' defined in class path resource [bl-framework-applicationContext-persistence.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
    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.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:99)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findNamedEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:511)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:493)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:657)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:630)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:339)
    ... 55 more
Caused by: java.lang.NullPointerException
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:527)
    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)
    ... 69 more

From looking at the class it seems that there is a persistence unit that is not being specified - but I'm not sure where to look to rectify that.

On top of that - the error changes when I change the sequence of the Spring import lines in my config.xml file.

Perhaps I'm approaching this the wrong way, but I'm assuming I should be able to get this working by including the default Broadleaf Spring XMLs in the right sequence - but I've tried a number of them and no dice (some same error, some different, all bad).

Any ideas on how to get this to work?

役に立ちましたか?

解決

After digging into this a bit more I did get this working. A few specific things were required:

  1. The stack trace in the original post was caused by the blPersistenceUnitManager bean being defined in two different Spring context files (not sure how these are being merged in a normal Broadleaf setup), one was overriding the other. The solution was to define one after importing everything that combines the configuration so reads from each of the persistence units needed.
  2. I had to explicitly use the 3.6.8.Final Hibernate libraries instead of the latest 4.x (some odd error about not being able to figure out what to do with a Map typed column)
  3. The blPasswordEncoder bean had to be defined
  4. NOTE: The blCacheManager bean in the example below was required to get around an issue with EHCache: http://jira.broadleafcommerce.org/browse/BLC-599

Here's the guts of the Spring context that finally worked:

<import resource="classpath:bl-common-applicationContext.xml"/>

<import resource="classpath:bl-framework-applicationContext.xml"/>
<import resource="classpath:bl-profile-applicationContext.xml"/>

<import resource="classpath:bl-framework-applicationContext-workflow.xml"/>

<import resource="classpath:bl-framework-applicationContext-persistence.xml"/>
<import resource="classpath:bl-profile-applicationContext-persistence.xml"/>

<import resource="classpath:bl-framework-applicationContext-entity.xml"/>
<import resource="classpath:bl-profile-applicationContext-entity.xml"/>

<bean id="blCacheManager" class="org.broadleafcommerce.common.extensibility.cache.ehcache.MergeEhCacheManagerFactoryBean">
    <property name="shared" value="true"/>
</bean>

<bean id="blPersistenceUnitManager" class="org.broadleafcommerce.common.extensibility.jpa.MergePersistenceUnitManager">
    <property name="persistenceXmlLocations">
        <list>
            <value>classpath*:/META-INF/persistence-common.xml</value>
            <value>classpath*:/META-INF/persistence-framework.xml</value>
            <value>classpath*:/META-INF/persistence-profile.xml</value>
        </list>
    </property>
</bean>

<bean id="blPasswordEncoder" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"/>

That got me to the point where the unit test builds, runs, the Hibernate environment fires up and I can @Resource() stuff, etc. Not sure how functional it all is yet, but I figured I'd post the answer to this question since I got that far.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top