2010-12-13 14 views
2

これはUsing eclipselink in Java code run from MATLABに記載されている問題の続きで、Java JPA Class for MATLABに記載されている問題と似ていますが、解決済みの解決策では問題は完全に解決されていません。MATLABはeclipselinkのpersistence.xmlを最初の数秒以内に見つけます

eclipselinkを使用して、matlabのOracleデータベースに接続しようとしています。前の記事の回答から、静的クラスパス(classpath.txt内)にコードを配置しました。私がこれを行うとき、私はそれを使用することができますが、私はEntityManagerを作成する場合のみ(Persistence.createEntityManager(...)への呼び出しを介して)matlabのロード後最初の数秒以内に。 Matlabを起動してから5秒以上待つと、まったく同じコードで「持続性なし」例外が発生します。私はそれが動作する時、実際にはそうでない時とは異なるクラスローダーを使用していることを確認しました。私が考えることができるのは、クラスパスがMatlabコンソールとは別のスレッドで初期化されていて、すぐに実行すると、MatlabのOSGIクラスローダーは初期化されていないため、デフォルトのJavaクラスローダーが使用されることです。

これは明らかに許容できる解決策ではなく、Matlabクラスローダーがpersistence.xmlを見つけることができない理由を実際には解決していないようです。誰か他のアイデアはありますか? eclipselinkをどのように初期化しているのでしょうか?私の前にこのコードで作業した人でも、クラスパスのMETA-INFフォルダに入れるのではなく、persistence.xmlを認識させる方法を見つけ出すことはできませんでした。

答えて

2

私はそれに非常に満足していませんが、解決策が見つかりました。 PersistenceProviderResolverHolderを最初に初期化すると、DefaultPersistenceProviderResolverというプライベート内部クラスが構築されます。このクラスは、META-INFディレクトリにpersistence.xmlがあるかどうかを尋ねられます。その後、Persistence.createEntityManagerFactory()を呼び出すと、PersistenceProviderResolverHolderにリゾルバを問い合わせて、リゾルバにpersistence.xmlを見つけるように依頼します。

これをMatlabで実行すると、初期化中にPersistenceProviderResolverHolderにデフォルトのリゾルバを置き換えるActivatorクラスが与えられることがあります。私が知る限りでは、このActivatorクラスはOSGIを使用して永続構成を探します。最適には、persistence.xmlも見つけられるように設定できるはずですが、これまで私はこれまで失敗していました。

私が思い描いた解決策は、DefaultPersistenceProviderResolverクラスの独自のコピーを作成し、そのインスタンスをPersistenceProviderResolverHolderのリゾルバとして設定することです。これは、入れられたActivatorクラスを置き換え、META-INFフォルダ内のpersistence.xmlを探すためにそれを返します。私は本当にこれをやりたいとは思わないが、それは私がこれに取り組んで1週間で働くことができた唯一の解決策である。

2

eclipselinkは2種類で利用可能です:

  1. の "Java EEとSE環境での使用を対象としています。"および
  2. 「OSGi Bundle Zipは、OSGiコンテナでEclipseLink 2.1.2ランタイムを使用します。」

"OSGIバンドル"が欠落によりOSGIコンテナにMATLAB JVM上で実行されません。したがって、Java EEおよびSE環境用の単一のjarが適切な選択肢になります。

Deploying EclipseLinkによると、persistence.xmlをクラスパスのMETA-INFフォルダに置くと正しいと思われます。

編集:

次の行が/MATLAB/java/に存在する必要がありClassPathHacker.class一方startup.mに添加されます。 3つの必要なライブラリderby.jar,eclipselink.jar,javax.persistence_2.0.1.v201006031150.jarは、JPA 2.0 with EclipseLink Tutorialで指定された場所からダウンロードできます。

|- 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:

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は、次のレイアウトを有しています。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 
       + "]"; 
    } 

} 

最後に、我々は、MATLABプロンプトから、この単純な例を実行するためにmainメソッドを呼び出します。

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

OSGIバンドルを使用しようとしましたが、「バンドル15の未解決の制約:package;(package = org.xml.sax.ext)」の行に沿ってIPLで数多くの例外があります。私はこれらのパッケージが提供されるはずの場所を追跡し、それらは基本的なJavaであるように見えます。彼らはクラスパス上にありますが、Matlabによってエクスポートされていないようです。どのようにこれらの依存関係を幸せにするためのアイデアですか? – Sam

+1

@Sam:MATLABは "OSGI Bundle"で動作しません。 「Java EEおよびSE環境」には単一のjarファイルを使用する必要があります。 – zellus

+0

@zellus:ありがとうございました、それは私に働きかけようとする手間の束を節約します。残念ながら、Matlabの起動時に直ちに行うのでなければ、classloaderにpersistence.xmlを認識させることができないのと同じ状況に陥ります。 – Sam

関連する問題