【问题标题】:Spring boot - Eclipelink scanning orm.xmlSpring boot - Eclipelink 扫描 orm.xml
【发布时间】:2014-10-08 19:59:21
【问题描述】:

我正在将现有应用程序转换为 Spring Boot,当我使用创建的 jar 运行应用程序时,当它扫描并在我的实体 jar 中找到一个 orm.xml 时出现异常(作为依赖项包含在内)。

org.eclipse.persistence.exceptions.PersistenceUnitLoadingException:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: org.springframework.boot.loader.LaunchedURLClassLoader@38cdedfd
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [UAccessPersistenceUnit] failed.
Internal Exception: java.lang.RuntimeException: java.io.IOException: Unable to open root Jar file 'jar:file:everything-jar.jar'
        at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
                at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107)
                        at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
                                at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)


Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [UAccessPersistenceUnit] failed.
Internal Exception: java.lang.RuntimeException: java.io.IOException: Unable to open root Jar file 'jar:file:everything-jar.jar'
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:1954)
                at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1945)
                        at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:98)
                                at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:96)
                                        ... 46 common frames omitted
                                        Caused by: org.eclipse.persistence.exceptions.EntityManagerSetupException:
                                        Exception Description: Predeployment of PersistenceUnit [UAccessPersistenceUnit] failed.
                                        Internal Exception: java.lang.RuntimeException: java.io.IOException: Unable to open root Jar file 'jar:file:everything-jar.jar'
                                                at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:230)
                                                        ... 50 common frames omitted

这不是使用弹簧数据,我目前正在从外部属性文件构建数据源。似乎是扫描引起了问题。

这是带有 eclipselink 2.5.1 的 spring boot 1.1.5-RELEASE

everything-jar.jar 是一个弹簧靴包装的罐子。使用我的编译类、spring boot loader 和打包在 jar 中的实体。我已将依赖项标记为解包并且它可以工作,但它并不理想。

这个问题不断出现,现在如果我尝试从另一个 jar 加载 persistence.xml,它会抛出同样的异常。

【问题讨论】:

  • 我认为你的问题可能是内部异常:java.lang.RuntimeException: java.io.IOException: Unable to open root Jar file 'jar:file:everything-jar.jar' 你能给关于这个罐子的更多信息
  • 您是使用 Spring Boot 来设置实体管理器还是您自己做的事情。我建议放弃你自己的属性文件和它的加载,并使用 Spring Boot 默认的 application.properties 加载。将您正在使用的属性重命名为能够使用 spring boot 引导(即spring.datasource.* 并尝试让 Spring Boot 发挥它的魔力而不是您自己。接下来您可能还想尝试新发布的 1.1.6 版本,谁知道呢. 为了获得更多帮助,您可以发布部分配置、引导类和完整的堆栈跟踪。

标签: spring jpa eclipselink spring-boot


【解决方案1】:

经过大量调查,这里的问题似乎有两个部分。

  1. Spring Boot 加载程序支持如下所示的 url: jar:file:!/!/

  2. Eclipselink 像这样为嵌入的 orm.xml 文件生成 url jar:jar:file:!/!/

我在 Spring Boot 中进行了修复,以使其更好地打开 eclipselink URL,但为了立即修复,我们需要创建自定义 ArchiveFactoryImpl 并覆盖 createArchive 方法以在协议为 jar 时返回自定义 JarInputStreamURLArchive。

在这个自定义类中,将 get 条目覆盖为 URL 以检查具有以 jar 开头的 jar 协议的 url 并从原始文件创建一个新 URL(这从原始 url 中切断了协议部分给出我们使用 jar:url 而不是 jar:url:url

public URL getEntryAsURL(String entryPath) throws IOException {
            URL entryUrl = super.getEntryAsURL(entryPath);

            if(entryUrl == null) {
                return null;
            }

            if("jar".equals(entryUrl.getProtocol()) && entryUrl.getFile().startsWith("jar:")) {
                //cut off the jar portions
                String file = entryUrl.getFile();
                return new URL(file);
            } else {
                return entryUrl;
            }
        }

【讨论】:

    猜你喜欢
    • 2015-11-10
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多