Lau*_*ens 5 java jpa glassfish java-ee maven
我有几个会话bean,我已经编写了单元测试.我已经设置Maven在src/main/resources/META-INF目录中包含一个persistence.xml,该目录引用本地MySQL数据库用于开发目的.我在src/test/resources/META-INF目录中有另一个persistence.xml,它引用了嵌入式Derby数据库__default.测试部署到嵌入式GlassFish 3.1容器中.
但是,当我运行测试时,我收到以下错误:
java.lang.RuntimeException: javax.naming.NamingException: Lookup failed for 'jdbc/mylog'
Run Code Online (Sandbox Code Playgroud)
jdbc/mylog是主目录中的持久性单元引用的MySQL数据库.它显然忽略了测试目录中的持久性单元,但我不知道为什么.
据我所知,Maven正确地设置类路径,在类之前使用测试类,在实际目标/测试类/ META-INF目录中查看它显示它复制了正确的嵌入式Derby持久性单元.
[DEBUG] Test Classpath :
[DEBUG] C:\Users\Laurens\Documents\Projects\Mylog\target\test-classes
[DEBUG] C:\Users\Laurens\Documents\Projects\Mylog\target\classes
[DEBUG] C:\Users\Laurens\.m2\repository\org\eclipse\persistence\eclipselink\2.2.0\eclipselink-2.2.0.jar
[DEBUG] C:\Users\Laurens\.m2\repository\org\eclipse\persistence\javax.persistence\2.0.3\javax.persistence-2.0.3.jar
[DEBUG] C:\Users\Laurens\.m2\repository\org\eclipse\persistence\org.eclipse.persistence.jpa.modelgen.processor\2.2.0\org.eclipse.persistence.jpa.modelgen.processor-2.2.0.jar
[DEBUG] C:\Users\Laurens\.m2\repository\org\glassfish\extras\glassfish-embedded-all\3.1\glassfish-embedded-all-3.1.jar
[DEBUG] C:\Users\Laurens\.m2\repository\javax\javaee-web-api\6.0\javaee-web-api-6.0.jar
[DEBUG] C:\Users\Laurens\.m2\repository\junit\junit\4.8.1\junit-4.8.1.jar
Run Code Online (Sandbox Code Playgroud)
关于如何让GlassFish使用正确的持久性单元的任何暗示非常感谢!谢谢!
Vin*_*lds 11
使用嵌入式Glassfish运行测试时,JPA提供程序在执行maven-surefire-plugin目标(用于运行测试阶段)之前不使用命令行上显示的类路径.嵌入式Glassfish将可用作测试范围一部分的工件部署为ScatteredArchive
.除非嵌入式Glassfish配置指定了Glassfish安装根目录和Glassfish域,否则java.io.tmpdir
通常会在目录中创建通常使用名称的分散存档gfembed<a_random_number>tmp
.
使用部署的分散存档准备嵌入式Glassfish域时,通常会将要部署的文件复制到一个展开的目录中,该目录包含应用程序所需的所有类(包括所有依赖项).该目录通常恰好存在于GF_EMBED_DOMAIN_HOME/applications/<application_name>
目录中.persistence.xml
您src/main/resources/META-INF
和src/test/resources/META-INF
目录中的文件将复制到<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.
Run Code Online (Sandbox Code Playgroud)
上述glassfish-install
目录及其子目录glassfish
存在于Maven项目根目录中(并且还检入版本控制); 该glassfish
目录必须包含一个目录结构,domain1/config
以表示Glassfish域名的目录结构domain1
.项目中的结构可以在下面的屏幕截图中看到.其他相关文件(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>
...
...
Run Code Online (Sandbox Code Playgroud)
该默认domain.xml文件可以从java.net网站上下载,并修改,在事件你想保留的变化尽可能小,而不是从GlassFish安装复制一个.
2.复制persistence.xml文件
可以添加目标,Maven的POM文件,备份和拷贝persistence.xml
文件从src/test/resources/META-INF
到src/main/resources/META-INF
,在之前test
的阶段.测试阶段完成后,原始文件将恢复.我不会详细讨论这个问题,因为类似的解决方案已在相关的StackOverflow问题中讨论过.我没有使用这种方法进行集成测试,因为我需要进行更改,而不是可以进行的更改persistence.xml
,例如创建自定义领域.我将它用于单元测试,但是,由于JPA提供程序将persistence.xml
从而target/classes
不是获取文件target/test-classes
,尽管后者在类路径顺序中首先出现.如果您使用Hibernate作为JPA提供程序,则为org.hibernate.ejb
记录器启用TRACE日志记录(因为Ejb3Configuration
类负责执行查找)将说服您test-classes
不会接收文件.
注意:
大部分答案都假定为Glassfish 3.1,但也可能适用于即将推出的版本.
归档时间: |
|
查看次数: |
4195 次 |
最近记录: |