MATLAB находит файл persistence.xml для eclipselink только в течение первых нескольких секунд - PullRequest
2 голосов
/ 14 декабря 2010

Это продолжение проблемы, описанной в Использование eclipselink в Java-коде, запускаемом из MATLAB , и аналогично проблеме, описанной в Java JPA Class для MATLAB , но принятых решенияхописанное там не полностью решило проблему.

Я пытаюсь использовать eclipselink для подключения к базе данных oracle в matlab.Из ответов в предыдущих постах я поместил код в статический classpath (в classpath.txt).Когда я это делаю, я могу использовать его, но только если я создаю EntityManager (через вызов Persistence.createEntityManager (...)) в течение первых нескольких секунд после загрузки Matlab.Если я подожду более 5 секунд после запуска Matlab, точно такой же код выдаст исключение «No Persistence обеспечивается».Я подтвердил, что когда он работает, он на самом деле использует загрузчик классов, отличный от того, который он не делает.Единственное, о чем я могу подумать, это то, что classpath инициализируется в отдельном потоке, отличном от консоли Matlab, и что, если я его быстро выполню, загрузчик классов OSGI в Matlab еще не инициализируется, поэтому он использует загрузчик классов по умолчанию.

Очевидно, что это неприемлемое решение, и, похоже, оно действительно не решило причину, по которой загрузчик классов Matlab не может найти файл persistence.xml.У кого-нибудь есть еще идеи?Может ли быть так, как я инициализирую eclipselink?Ни парень, который работал над этим кодом до меня, ни я не смогли найти способ заставить его распознавать файл persistence.xml любым способом, кроме как поместить его в папку META-INF на пути к классам.

Ответы [ 2 ]

2 голосов
/ 17 декабря 2010

Я нашел решение, которое работает, хотя я не очень доволен им. Когда PersistenceProviderResolverHolder впервые инициализируется, он создает закрытый внутренний класс DefaultPersistenceProviderResolver, который при запросе найдет файл persistence.xml в вашем каталоге META-INF. Позже, когда вы вызываете Persistence.createEntityManagerFactory (), он запрашивает для распознавателя PersistenceProviderResolverHolder, а затем запрашивает для распознавателя файл persistence.xml.

Проблема при запуске этого в Matlab заключается в том, что через некоторое время во время инициализации PersistenceProviderResolverHolder предоставляется класс Activator, который заменяет распознаватель по умолчанию. Насколько я могу судить, этот класс Activator пытается использовать OSGI для поиска любых конфигураций персистентности. Оптимально, я должен быть в состоянии настроить вещи так, чтобы он также находил файл persistence.xml, но до сих пор мне это не удавалось.

Решение, которое я придумала, состоит в том, чтобы создать собственную копию класса DefaultPersistenceProviderResolver и установить его экземпляр в качестве распознавателя в PersistenceProviderResolverHolder. Это заменит класс Activator, который был добавлен в него, и вернет его к поиску файла persistence.xml в папке META-INF. Мне действительно не нравится это делать, но это единственное решение, которое мне удалось получить за неделю работы над этим.

2 голосов
/ 14 декабря 2010

eclipselink доступен в двух вариантах:

  1. "Предназначен для использования в средах Java EE и SE." и
  2. "Пакет OSGI Zip для использования среды выполнения EclipseLink 2.1.2 в контейнере OSGi."

"Пакет OSGI" не будет работатьMATLAB JVM из-за отсутствия контейнера OSGI.Поэтому единственная банка для сред Java EE и SE будет правильным выбором.

Согласно Развертывание EclipseLink размещение persistence.xml в папке META-INF на пути к классам, похоже, является правильным.

РЕДАКТИРОВАТЬ:

Следующие строки добавляются в startup.m, тогда как ClassPathHacker.class должен находиться в /MATLAB/java/.Все три необходимые библиотеки derby.jar, eclipselink.jar, javax.persistence_2.0.1.v201006031150.jar могут быть загружены из мест, указанных в JPA 2.0, с EclipseLink Tutorial .

javaaddpath('/MATLAB/java/');
ClassPathHacker.addFile(java.lang.String('/NetBeansProjects/JpaForMatlab/dist/JpaForMatlab.jar'))
ClassPathHacker.addFile(java.lang.String('/NetBeansProjects/JpaForMatlab/lib/derby.jar'))
ClassPathHacker.addFile(java.lang.String('/NetBeansProjects/JpaForMatlab/lib/eclipselink.jar'))
ClassPathHacker.addFile(java.lang.String('/NetBeansProjects/JpaForMatlab/lib/javax.persistence_2.0.1.v201006031150.jar'))

JpaForMatlab.jar имеет следующую компоновку:

|- META-INF
   |- persistence.xml
|- jpaformatlab
   |- Main.class
   |- Todo.class

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<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"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="todos" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>jpaformatlab.Todo</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
            <property name="javax.persistence.jdbc.url"
                value="jdbc:derby:/NetBeansProjects/derby-db/simpleDb;create=true" />
            <property name="javax.persistence.jdbc.user" value="test" />
            <property name="javax.persistence.jdbc.password" value="test" />
            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.ddl-generation.output-mode" value="both" />
        </properties>
    </persistence-unit>
</persistence>

Main.java

package jpaformatlab;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class Main {

    private static final String PERSISTENCE_UNIT_NAME = "todos";
    private static EntityManagerFactory factory;

    public static void main(String[] args) {
        factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = factory.createEntityManager();
        // Read the existing entries and write to console
        Query q = em.createQuery("select t from Todo t");
        List<Todo> todoList = q.getResultList();
        for (Todo todo : todoList) {
            System.out.println(todo);
        }
        System.out.println("Size: " + todoList.size());

        // Create new todo
        em.getTransaction().begin();
        Todo todo = new Todo();
        todo.setSummary("This is a test");
        todo.setDescription("This is a test");
        em.persist(todo);
        em.getTransaction().commit();

        em.close();
    }
}

Todo.java

package jpaformatlab;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Todo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String summary;
    private String description;

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Todo [summary=" + summary + ", description=" + description
                + "]";
    }

}

Наконец, мы вызываем метод main, чтобы запустить этот простой пример из приглашения MATLAB.

>> jpaformatlab.Main.main(javaArray('java.lang.String',1))
>> Todo [summary=This is a test, description=This is a test]
...