嵌入式GlassFish会忽略Maven测试资源 [英] Embedded GlassFish ignores Maven test resources
问题描述
我有几个会话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:'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\.m 2\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使用适当的持久性单元的任何提示非常感谢!当使用嵌入式Glassfish运行测试时,JPA提供程序不使用命令行上显示的类路径,而是使用执行maven-surefire-plugin目标(用于运行测试阶段)。嵌入式Glassfish将作为测试范围一部分提供的构件部署为 ScatteredArchive
。这个分散的文档通常是在 java.io.tmpdir
目录中创建的,通常名称为 gfembed< a_random_number> tmp
,除非嵌入的Glassfish配置指定了Glassfish安装根目录和Glassfish域的位置。
$ b 当嵌入的Glassfish域使用部署的分散存档准备时,通常会被复制到一个展开目录中,该目录包含应用程序所需的所有类(包括所有依赖项)。此目录通常恰好存在于
GF_EMBED_DOMAIN_HOME / applications /< application_name>
目录中。您的 src / main / resources / META-INF
和 src中的 persistence.xml
文件/ 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(道具);
context = container.getContext();
datasource =(DataSource)context.lookup(jdbc / mylog); //你也可以查找数据源,以确认你的设置是否成功。
上述 glassfish-install
目录和它的子目录 glassfish
出现在Maven项目根目录中(并且也检入到版本控制中); glassfish
目录必须包含一个目录结构 domain1 / config
来表示Glassfish域的名称域1
。该项目中的结构可以在下面的截图中看到。其他相关文件(JDBC资源适配器JAR等)可以从Glassfish安装目录中获得,但如果配置正确,这些文件通常也可以通过嵌入式Glassfish运行时放置在正确的位置。
Glassfish域配置文件的内容与嵌入式Glassfish使用的默认内容不同,除了数据源和连接池配置(在执行集成测试的我的用例中添加的相关条目已发布下面):
< domain log-root =$ {com.sun.aas.instanceRoot} / logsapplication- root =$ {com.sun.aas.instanceRoot} / applicationsversion =10.0>
< system-applications />
< applications />
<资源>
...
< property name =Uservalue =APP>< / property>
< property name =RetrieveMessageTextvalue =true>< / property>
< property name =ServerNamevalue =localhost>< / property>
< property name =SecurityMechanismvalue =4>< / property>
< property name =TraceFileAppendvalue =false>< / property>
< property name =TraceLevelvalue = - 1>< / property>
< property name =Passwordvalue =APP>< / property>
< property name =databaseNamevalue =MYDB>< / property>
< / jdbc-connection-pool>
...
< /资源>
<服务器>
< server name =serverconfig-ref =server-config>
< resource-ref ref =jdbc / __ TimerPool/>
< resource-ref ref =jdbc / __ default/>
< resource-ref ref =jdbc / mylog/>
< / server>
< /服务器>
...
...
默认的domain.xml文件可以从java.net网站下载并修改,如果您希望保持更改尽可能最小化,而不是从Glassfish安装中复制一个。
2。通过persistence.xml文件复制
可以将目标添加到Maven POM文件中,以备份和复制 persistence.xml从
src / test / resources / META-INF
到 src / main / resources / META-INF $
c $ c>,在测试
阶段之前。测试阶段完成后,原件被恢复。我不会详细讨论这个问题,因为类似的解决方案已经在一个相关的StackOverflow问题。我没有使用这种方法进行集成测试,因为我需要对 persistence.xml
中可执行的更改进行更改,如创建自定义领域。然而,由于JPA提供程序将从 target / classes $>中获取
persistence.xml
文件,因此我将它用于单元测试c $ c>而不是 target / test-classes
,尽管后者在类路径顺序中首先出现。如果您使用Hibernate作为JPA提供程序,请为 org.hibernate.ejb
记录器启用TRACE日志记录(如 Ejb3Configuration
类负责执行查找)会说服你在 test-classes
中的文件不会被拾取。
注意: 大部分答案都假设Glassfish 3.1,但可能适用于即将推出的版本还有。 I have several session beans that I have written unit tests for. I have setup Maven to include a persistence.xml in the src/main/resources/META-INF directory that refers to a local MySQL database for development purposes. I have another persistence.xml in src/test/resources/META-INF directory that refers to the embedded Derby database __default. The tests are deployed to an embedded GlassFish 3.1 container. When I run the tests however, I get the following error: jdbc/mylog is the MySQL database that the persistence unit in the main directory refers to. It is obviously ignoring the persistence unit in the test directory but I have no clue as to why. Maven is setting the classpath correctly as far as I can tell, with test-classes before classes and a peek in the actual target/test-classes/META-INF directory reveals that it copied the correct, embedded Derby, persistence unit. Any hint on how to have GlassFish use the proper persistence unit very much appreciated! Thanks! When running tests using embedded Glassfish, the JPA provider does not use the classpath displayed on the command-line, before executing the maven-surefire-plugin goal (that is used to run the test phase). Embedded Glassfish deploys the artifacts that are available as part of a test scope, as a When the embedded Glassfish domain is prepared with the deployed scattered archive, the files to be deployed are typically copied into an exploded directory that houses all the classes (including all dependencies) required by the application. This directory typically happens to be present in the You can overcome this situation in two ways: 1. Using a custom Glassfish domain configuration file You can specify a domain configuration file ( The afore-mentioned The contents of the Glassfish domain configuration file are different from the default one used by embedded Glassfish, except for the datasource and connection pool configuration (the relevant entries added in my usecase where I perform integration tests, have been posted below): The default domain.xml file can be downloaded from the java.net site, and modified, in the event you wish to keep the changes as minimal as possible, instead of copying one from a Glassfish installation. 2. Copying over the persistence.xml files One can add goals to the Maven POM file, to backup and copy the Note: Most of the answer assumes Glassfish 3.1 but may hold good for upcoming versions as well. 这篇关于嵌入式GlassFish会忽略Maven测试资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
java.lang.RuntimeException: javax.naming.NamingException: Lookup failed for 'jdbc/mylog'
[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
ScatteredArchive
. This scattered archive is typically created in the java.io.tmpdir
directory usually with the name gfembed<a_random_number>tmp
, unless the embedded Glassfish configuration specified the location of a Glassfish installation root, and a Glassfish domain.GF_EMBED_DOMAIN_HOME/applications/<application_name>
directory. The persistence.xml
files from your src/main/resources/META-INF
and src/test/resources/META-INF
directories are copied here into the <application-name>/META-INF
directory. Needless to state, the one that gets copied last, or the one that doesn't get overwritten is the one that is used by the JPA provider during the tests. This always happens to be the file in src/main/resources/META-INF
.domain.xml
) that will contain the datasource definition for jdbc/mylog
. This is what I do currently for it is very flexible and the domain configuration file can contain other configurations as well. The config file, needs to specified as part of test setup in the following way: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
directory and its sub-directory glassfish
are present in the Maven project root (and also checked into version control); the glassfish
directory must contain a directory structure of domain1/config
to represent the directory structure of the Glassfish domain of name domain1
. The structure in the project can be seen in the below screenshot. The other related files (the JDBC resource adapter JARs and the like), can be obtained from a Glassfish installation directory, but typically these might also be placed in the correct location by the embedded Glassfish runtime, if configured correctly.<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>
...
...
persistence.xml
file from src/test/resources/META-INF
to src/main/resources/META-INF
, before the test
phase. After the test phase is complete, the original is restored. I will not go into details of this, as a similar solution is already discussed in a related StackOverflow question. I did not use this approach for integration tests as I required changes to be done beyond the ones that can be carried in persistence.xml
, like creation of a custom realm. I use it for unit-tests however, due to the fact that the JPA provider will fetch the persistence.xml
file from target/classes
instead of target/test-classes
, despite the latter appearing first in the classpath order. If you use Hibernate as your JPA provider, enabling TRACE logging for the org.hibernate.ejb
logger (as the Ejb3Configuration
class is responsible for performing the lookup) would convince you that file in test-classes
will not be picked up.