Spring Boot IllegalStateException ArchiveDescriptor重用;可以多次处理网址吗?

时间:2014-10-24 08:49:52

标签: java eclipse spring hibernate spring-boot

我正在使用hibernate运行spring boot应用程序,但是遇到了一些问题。

注意:如果我直接在eclipse中运行应用程序,一切正常。 但是,如果我使用spring-boot插件将其打包为jar并运行Jar我会收到以下错误

使用hibernate-core版本:4.3.6

java.lang.reflect.InvocationTargetException
        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.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
        at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fakeEntityManagerFactory' defined in class path resource [com/my/package/fake/lib/fakeContext.x
ml]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: ArchiveDescriptor reused; can URLs be processed multiple times?
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:975)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:752)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
        at com.my.package.fake.app.boot.FakeAppBooter.main(FakeAppBooter.java:16)
        ... 6 more
Caused by: java.lang.IllegalStateException: ArchiveDescriptor reused; can URLs be processed multiple times?
        at org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl.validateReuse(AbstractScannerImpl.java:223)
        at org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl.buildArchiveDescriptor(AbstractScannerImpl.java:102)
        at org.hibernate.jpa.boot.scan.spi.AbstractScannerImpl.scan(AbstractScannerImpl.java:63)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.scan(EntityManagerFactoryBuilderImpl.java:723)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:219)
        at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:51)
        at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:182)
        at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:177)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
        ... 21 more

使用hibernate-core版本:4.2.15

java.lang.reflect.InvocationTargetException
        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.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
        at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fakeEntityManagerFactory' defined in class path resource [com/my/package/fake/lib/fakeContext.x
ml]: Invocation of init method failed; nested exception is java.lang.RuntimeException: error trying to scan <jar-file>: file:/C:/dev/trees/ix-platform/FakesSpringBoot/providers/providers/fake/app/targ
et/__fake.jar
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:975)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:752)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
        at com.my.package.fake.app.boot.FakeAppBooter.main(FakeAppBooter.java:16)
        ... 6 more
Caused by: java.lang.RuntimeException: error trying to scan <jar-file>: file:/C:/dev/trees/ix-platform/FakesSpringBoot/providers/providers/fake/app/target/__fake.jar
        at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:864)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:600)
        at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:75)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
        ... 21 more
Caused by: org.hibernate.AssertionFailure: Cannot read files twice on NativeScanner
        at org.hibernate.ejb.packaging.NativeScanner.getFilesInJar(NativeScanner.java:168)
        at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:506)
        at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:861)
        ... 27 more

提出问题的bean是:

<bean id="fakeEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    depends-on="fakeJpaProperties,fakeDataSource">
    <property name="persistenceUnitName" value="fake" />
    <property name="persistenceUnitManager">
        <bean class="com.my.package.lib.persistence.MergingUnitManager">
            <property name="persistenceXmlLocations">
                <list>
                    <value>classpath*:META-INF/fake/persistence.xml</value>
                </list>
            </property>
        </bean>
    </property>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false" />
        </bean>
    </property>
</bean>

装载两次的罐子显然是我正在运行的主罐子。

关于这个问题可能出现在哪里的任何想法?

补充说明:

正在加载的persistence.xml的唯一内容是:<persistence-unit name="fake" />

1 个答案:

答案 0 :(得分:0)

为Spring 3.2和多个持久化上下文实现MergingPersistenceUnitManager技巧as described here时,我注意到Spring无法处理persistenceUnitRootURL最终在jarFile中的事实。

ArrayList<URL> combinedNewURLs = new ArrayList<>();
combinedNewURLs.addAll(newPU.getJarFileUrls());
combinedNewURLs.add(newPU.getPersistenceUnitRootUrl());
if (!combinedNewURLs.contains(oldPU.getPersistenceUnitRootUrl())){
    // Root url of existing persistenceunit not known in the 
    // new one, add it as jar url.
    newPU.addJarFileUrl(oldPU.getPersistenceUnitRootUrl());
}

这解决了“ArchiveDescriptor used”问题。不确定是否会引起其他问题。