Почему я не могу загрузить файл persistence.xml из приложения OSGi / RCP / EclipseLink? - PullRequest
4 голосов
/ 10 августа 2011

Мы создаем приложение RCP с использованием EclipseLink, которое развернуто в комплекте OSGi. Когда мы запускаем приложение в eclipse, оно отлично работает, после развертывания в linux оно работает хорошо, но когда мы разворачиваем его под windows, оно вылетает.

Исключение происходит в следующем коде:

Map<String, Object> connectionProperties = new HashMap<String, Object>();
connectionProperties.put(PersistenceUnitProperties.CLASSLOADER, 
        this.getClass().getClassLoader());
PersistenceProvider pp = new PersistenceProvider();
entityManagerFactory = pp.createEntityManagerFactory(
        "persistence_unit", connectionProperties);

PersistenceProvider из пакета org.eclipse.persistence.jpa.osgi, Свойства соединения

После запуска этого кода мы получаем org.eclipse.persistence.exceptions.PersistenceUnitLoadingException, вызванное java.net.MalformedURLException. Много отладок позже, я могу сказать, что OSGi определенно находит этот файл persistence.xml (ранее у нас был файл persistence.xml, расположенный в неправильном каталоге, и у нас было другое исключение, говоря, что не было никакого пакета, который определил этот модуль персистенции), он может легко получить это (проверено, вручную загружая и читая это). Мне кажется, что PersistenceUnitProcessor не может загрузить нужный архив в методе findPersistenceArchives (кажется, что он возвращает один архив после нахождения файла META-INF / persistence.xml, но этот архив пуст).

Я нашел что-то похожее по ссылке http://www.eclipse.org/forums/index.php/mv/msg/218408/693584/#msg_693584. Хотя это не совсем то же самое, но охватывает eclipse и eclipseLink, но это не применимо в нашем проекте.

Я считаю, что отладка глубже в библиотеках бессмысленна, и ошибка должна быть либо в конфигурации экспорта продукта, либо в нашем коде какая-то ошибка.

Обе системы (Windows XP и Ubuntu 11.04) используют одно и то же Eclipse 3.7 с одинаковыми добавленными пакетами, обе имеют Java 1.6u26, EclipseLink 2.3.0

Есть идеи?

EDIT:

Просто чтобы убедиться, что это не что-то еще, что мы могли испортить в нашем проекте (поскольку он сейчас довольно большой), я сделал новый чистый проект, выполнив следующие шаги:

  • Создан новый проект плагина с шаблоном Hello RCP и конфигурацией продукта.
  • Создан файл META-INF / persistence.xml в пакете src со следующим содержимым:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <class>DummyEntity</class>
        <properties>
            <property name="javax.persistence.jdbc.url"
                value= database-url />
            <property name="javax.persistence.jdbc.user" value= database-user />
            <property name="javax.persistence.jdbc.password" value= database-password />
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />  
        </properties>
    </persistence-unit>
    </persistence>  
    
  • Создан класс DummyEntity.

  • добавлено в файл manifest.mf:

    Import-Package: javax.persistence;jpa="2.0";version="2.0.3",
     org.eclipse.persistence.config;version="2.3.0.v20110604-r9504",
     org.eclipse.persistence.jpa;version="2.3.0.v20110604-r9504",
     org.eclipse.persistence.jpa.osgi;version="2.3.0.v20110604-r9504"
    JPA-PersistenceUnits: pu
    
  • добавлены необходимые зависимости в конфигурации продукта, сделана DummyEntity сущностью JPA

  • добавлен код для Activator.start:

    import javax.persistence.EntityManagerFactory;
    import org.eclipse.persistence.config.PersistenceUnitProperties;
    import org.eclipse.persistence.jpa.osgi.PersistenceProvider;
    
    ...
    
    Map<String, Object> connectionProperties = new HashMap<String, Object>();
    connectionProperties.put(PersistenceUnitProperties.CLASSLOADER, this
            .getClass().getClassLoader());
    
    try {
        EntityManagerFactory emf = new PersistenceProvider()
                .createEntityManagerFactory("pu", connectionProperties);
    
        log("Connection established");
    } catch (Exception e) {
                 // here some code to log the exception stack trace
    }
    
  • экспортировано в красивый исполняемый пакет.

Хотя из-за затмения он работает гладко, запущенный развернутый пакет вернул следующее:

    EXCEPTION
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException : 
    Exception Description: An exception was thrown while trying to load persistence unit at url: bundleresource://34.fwk2279771
    Internal Exception: Exception [EclipseLink-30004] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
    Exception Description: An exception was thrown while processing persistence.xml from URL: bundleresource://34.fwk2279771
    Internal Exception: java.net.MalformedURLException
    TRACE:
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionLoadingFromUrl(PersistenceUnitLoadingException.java:99)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:538)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException : 
    Exception Description: An exception was thrown while processing persistence.xml from URL: bundleresource://34.fwk2279771
    Internal Exception: java.net.MalformedURLException
    TRACE:
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(PersistenceUnitLoadingException.java:117)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:579)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:536)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

    java.net.MalformedURLException : null
    TRACE:
    java.net.URL.<init>(Unknown Source)
    java.net.URL.<init>(Unknown Source)
    java.net.URL.<init>(Unknown Source)
    com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
    com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:577)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:536)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

У нас тоже была эта проблема.

Короче говоря, решение для нас состояло в том, чтобы создать подкласс ArchiveFactoryImpl (который принадлежит jpa), переопределить метод isJarInputStream, поэтому он всегда возвращает false (измените, если хотите выполнить более сложную проверку ..)

Затем зарегистрируйте этот подкласс системным свойством:

System.setProperty(SystemProperties.ARCHIVE_FACTORY, OurArchiveFactoryImpl.class.getName());

Обычный ArchiveFactoryImpl # isJarInputStream, похоже, реагирует иначе, начиная с затмения 3.7 (кто-нибудь может подтвердить это ??). В этом методе выполняется небольшая хитрость, чтобы «проверить», является ли данный URL-адрес действительно JarInputStream. Похоже, что затмение 3.7 имеет несколько иной способ разрешения URL, в результате чего isJarInputStream возвращает true.

1 голос
/ 11 августа 2011

Ответ на эту проблему (как и в случае с несколькими похожими проблемами, обнаруженными в Интернете) был перенесен в Hibernate.

Мое мнение таково, что PersistenceProvider из EclipseLink плохо работает с протоколом пакетов ресурсов.В любом случае переключение на Hibernate PersistenceProvider работало как чудо.

Могу добавить, что эта миграция была довольно безболезненной, основная проблема, с которой мы столкнулись, была повторное присоединение отсоединенных сущностей с объединениями ленивого типа (На самом деле эта проблема все еще нас беспокоит, сейчас мы реализовали небольшой обходной путь, но вернемся к нему).

...