我有几个会话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'
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
关于如何让GlassFish使用正确的持久性单元的任何暗示非常感谢!谢谢!
3 回答
使用嵌入式Glassfish运行测试时,JPA提供程序在执行maven-surefire-plugin目标(用于运行测试阶段)之前不使用命令行上显示的类路径 . Embedded Glassfish将可用作测试范围一部分的工件部署为
ScatteredArchive
. 此分散存档通常在java.io.tmpdir
目录中创建,通常名称为gfembed<a_random_number>tmp
,除非嵌入式Glassfish配置指定了Glassfish安装根目录和Glassfish域 .使用部署的分散存档准备嵌入式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. Using a custom Glassfish domain configuration file
您可以指定包含
jdbc/mylog
的数据源定义的域配置文件(domain.xml
) . 这是我目前所做的非常灵活,域配置文件也可以包含其他配置 . 配置文件需要以下列方式指定为测试设置的一部分:上述
glassfish-install
目录及其子目录glassfish
存在于Maven项目根目录中(并且还检入版本控制);glassfish
目录必须包含domain1/config
的目录结构,以表示名称为domain1
的Glassfish域的目录结构 . 项目中的结构可以在下面的屏幕截图中看到 . 其他相关文件(JDBC资源适配器JAR等)可以从Glassfish安装目录中获取,但如果配置正确,通常这些文件也可能由嵌入式Glassfish运行时放置在正确的位置 .Glassfish域配置文件的内容与嵌入式Glassfish使用的默认值不同,除了数据源和连接池配置(在我的用例中添加的相关条目,我执行集成测试,已在下面发布):
default domain.xml file can be downloaded from the java.net site,并且在您希望尽可能减少更改的情况下进行修改,而不是从Glassfish安装中复制一个 .
2. Copying over the persistence.xml files
可以在
test
阶段之前将目标添加到Maven POM文件,以便将persistence.xml
文件从src/test/resources/META-INF
备份并复制到src/main/resources/META-INF
. 测试阶段完成后,原始文件将恢复 . 我不会详细讨论这个问题,因为类似的解决方案已在a related StackOverflow question中讨论过 . 我没有使用这种方法进行集成测试,因为我需要在persistence.xml
之外进行更改,就像创建自定义领域一样 . 我使用它进行单元测试,但是,由于JPA提供程序将从target/classes
而不是target/test-classes
获取persistence.xml
文件,尽管后者在类路径顺序中首先出现 . 如果您使用Hibernate作为JPA提供程序,请启用TRACE记录org.hibernate.ejb
Logger (因为Ejb3Configuration
类负责执行查找)会说服您test-classes
中的文件不会被记录 .Note:
大部分答案都假定为Glassfish 3.1,但也可能适用于即将推出的版本 .
通过“嵌入式玻璃鱼容器”,你的意思是为你运行玻璃鱼的maven插件吗? maven插件的类路径是不同的,并且管理方式与maven测试类路径不同 . 您可能需要使用不同的类路径 .
这个答案可能听起来很愚蠢但我正在寻找一种让我从日食中运行这些测试的方法
Run As
- >JUnit Test
. 这就是我的方式:我只是将test / persistence.xml复制到classes / persistence.xml . 这有效 .