使用嵌入式Glassfish運行測試時,在執行maven-surefire插件目標(用於運行測試階段)之前,JPA提供程序不使用命令行上顯示的類路徑。嵌入式Glassfish部署可作爲測試範圍一部分的工件,如ScatteredArchive
。除非嵌入的Glassfish配置指定了Glassfish安裝根目錄和Glassfish域的位置,否則通常會在名稱爲gfembed<a_random_number>tmp
的java.io.tmpdir
目錄中創建這種分散的存檔。
當嵌入式Glassfish的域與部署散射歸檔製備,要部署的文件通常被複制到容納所有應用程序所需的類(包括所有的依賴關係)的分解目錄。該目錄通常恰好存在於GF_EMBED_DOMAIN_HOME/applications/<application_name>
目錄中。您的src/main/resources/META-INF
和src/test/resources/META-INF
目錄中的persistence.xml
文件在此處被複制到<application-name>/META-INF
目錄中。不用說,最後被複制的那個,或者沒有被覆蓋的那個是JPA提供程序在測試期間使用的那個。這總是碰巧是src/main/resources/META-INF
中的文件。
可以克服這種情況,有兩種方式:
1.使用自定義的Glassfish域配置文件
你可以指定一個域配置文件(domain.xml
)將包含數據源定義爲jdbc/mylog
。這是我目前所做的,因爲它非常靈活,並且域配置文件也可以包含其他配置。該配置文件,需要指定爲通過以下方式測試裝置的一部分:
Map<String, Object> props = new HashMap<String, Object>();
props.put("org.glassfish.ejb.embedded.glassfish.installation.root", "./glassfish-install/glassfish");
container = EJBContainer.createEJBContainer(props);
context = container.getContext();
datasource = (DataSource) context.lookup("jdbc/mylog"); //You can lookup the datasource too, to confirm that your setup is successful.
前面提到的glassfish-install
目錄及其子目錄glassfish
存在於Maven項目根(也簽入到版本控制); glassfish
目錄必須包含domain1/config
的目錄結構,以表示名稱爲domain1
的Glassfish域的目錄結構。該項目中的結構可以在下面的截圖中看到。其他相關文件(JDBC資源適配器JAR等)可以從Glassfish安裝目錄中獲得,但是如果配置正確,這些文件通常也可以通過嵌入的Glassfish運行時放置在正確的位置。
Glassfish的域配置文件的內容是從默認的嵌入式Glassfish的使用不同,除了數據源和連接池配置(在我的用例中添加相關項,我進行集成測試,已經貼在下面):
<domain log-root="${com.sun.aas.instanceRoot}/logs" application-root="${com.sun.aas.instanceRoot}/applications" version="10.0">
<system-applications/>
<applications/>
<resources>
<jdbc-resource pool-name="MyPool" jndi-name="jdbc/mylog"/>
...
<jdbc-connection-pool driver-classname="" datasource-classname="org.apache.derby.jdbc.ClientDataSource" res-type="javax.sql.DataSource" description="" name="MyPool" ping="true">
<property name="User" value="APP"></property>
<property name="RetrieveMessageText" value="true"></property>
<property name="CreateDatabase" value="true"></property>
<property name="ServerName" value="localhost"></property>
<property name="Ssl" value="off"></property>
<property name="SecurityMechanism" value="4"></property>
<property name="TraceFileAppend" value="false"></property>
<property name="TraceLevel" value="-1"></property>
<property name="PortNumber" value="1527"></property>
<property name="LoginTimeout" value="0"></property>
<property name="Password" value="APP"></property>
<property name="databaseName" value="MYDB"></property>
</jdbc-connection-pool>
...
</resources>
<servers>
<server name="server" config-ref="server-config">
<resource-ref ref="jdbc/__TimerPool"/>
<resource-ref ref="jdbc/__default"/>
<resource-ref ref="jdbc/mylog"/>
</server>
</servers>
...
...
的default domain.xml file can be downloaded from the java.net site和修改,你想保留的變化儘可能小,而不是複製一個從GlassFish安裝的事件。
2.複製過的persistence.xml文件
可以添加目標,Maven的POM文件,備份和persistence.xml
文件複製從src/test/resources/META-INF
到src/main/resources/META-INF
,在test
階段之前。測試階段完成後,原件被恢復。我不會詳細討論這個問題,因爲在a related StackOverflow question中已經討論過類似的解決方案。我沒有使用這種方法進行集成測試,因爲我需要對persistence.xml
進行修改,比如創建自定義領域。然而,我將它用於單元測試,因爲JPA提供程序將從target/classes
而不是target/test-classes
獲取persistence.xml
文件,儘管後者首先出現在類路徑順序中。如果您使用Hibernate作爲您的JPA提供程序,則爲org.hibernate.ejb
記錄器啓用TRACE日誌記錄(因爲Ejb3Configuration
類負責執行查找)將使您確信test-classes
中的文件不會被拾取。
注:
大多數的回答假設Glassfish的3.1,但可以把握好爲即將來臨的版本。
我在不同的arquitecture條件下有類似的問題,骯髒的解決方案是合併成一個persistence.xml這兩個persistente單位,生產和測試。 –