具有NetBeans,嵌入式GlassFish,JPA和MySQL数据源的Arquillian

这是一个偶然的帖子。 我一直在研究交易CDI观察者,并尝试使用嵌入式GlassFish对它进行一些集成测试。 但是令人惊讶的是,这种方法不能很好地工作,我仍在弄清楚,使用普通的嵌入式GlassFish时问题出在哪里。

同时,我转到了Arquillian 。 去年我仔细查看了Arquillian 1.0.0.Alpha4之后,是时候看看这些家伙为1.0.0决赛准备了什么。 有些东西有些变化,我很惊讶只在网上找到一些基本的例子。 这就是我开始写这篇文章的主要原因。 要获得所有这三种技术一起工作的更完整示例。

入门
首先,获取最新的NetBeans 7.1的新副本。 几周后就出来了,看起来真的很好。 如果愿意,您可以下载Java EE版本的副本,该副本随附最新的GlassFish OSS Edition 3.1.1。 安装并启动它。 还要grep MySQL Community Edition的副本并安装它。 返回NetBeans,通过新的项目向导设置新的Maven Web应用程序。 我们将其称为“ simpleweb”,并告诉它在GF 3.1.1上运行(如果尚未运行,则应在服务创建之前创建Services> Server> GlassFish实例,或者在项目设置过程中创建它)。

实施您的应用程序
即使这不是测试驱动的,我还是喜欢使用这种方法,因为我仍然相信,这是您在项目中发现的最常见的情况。 您已经准备好运行很多东西,并且正在寻找某种自动集成测试。 因此,假设您有一个非常基本的实体,我们将其称为“ com.mycompany.simpleweb.entities.AuditLog”。 您可以使用NetBeans新实体向导创建它。 实体创建过程中的第三步是提供程序和数据库设置。 定义一个新的数据源,并将其命名为“ jdbc / auditlog”。 作为连接规范,请使用MySQL J驱动程序,并且我假设您已经启动了数据库并正在运行(假设这称为Auditlog)。 测试连接并完成向导。

如果您使用向导,则将获得一些免费礼物。 除了事实,您现在在源代码树中有AuditLog实体,您还可以在src / main / resources中找到一个META-INF / persistence.xml文件,并在src / main / setup中找到一个glassfish-resources.xml。 稍后需要这样做,请记住这一点。 向您的实体添加一些其他属性。 现在,我添加“字符串帐户”。 并且不要忘记定义一个Version字段“ Timestamp timestamp”。 还有一点点命名查询来获取所有AuditLogs的列表也是很好的

@NamedQuery(name = "findAllAuditLogs",
query = "SELECT OBJECT (e) FROM AuditLog e")
 
@Version
private Timestamp timestamp;

如果使用向导,请确保检查pom.xml。 该向导会在提供的范围内添加一些eclipselink依赖关系,因此在这里应该不会有太大的不同。 接下来是添加com.mycompany.simpleweb.service.AuditRepositoryService EJB。 这应该负责AuditLog实体上的所有CRUD操作。
向其中添加一些代码以插入AuditLog:

@PersistenceContext
private EntityManager em;
 
  public void writeLog(String account) {
        AuditLog log = new AuditLog();
        log.setAccount(account);
        em.persist(log);
    }

还有更多代码来查找表中的条目总数:

public int findAll() {
        TypedQuery<AuditLog> query = em.createNamedQuery("AuditLog.findAllAuditLogs", AuditLog.class);
        return query.getResultList().size();
 
    }

目前为止就这样了。

添加基本​​测试依赖项
接下来,我们将添加一些非常基本的测试依赖项。 打开您的项目pom.xml文件,然后将Arquillian的以下部分添加到您的项目中:

<repository>
        <id>JBoss</id>
        <name>JBoss Repository</name>
        <url>https://repository.jboss.org/nexus/content/groups/public/</url>
    </repository>
<dependencymanagement>     
      
    <dependencies>
        <dependency>
            <groupid>org.jboss.arquillian</groupid>
            <artifactid>arquillian-bom</artifactid>
            <version>1.0.0.Final-SNAPSHOT</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencymanagement>
<dependencies>
     
    <dependency>
        <groupid>org.jboss.arquillian.container</groupid>
        <artifactid>arquillian-glassfish-embedded-3.1</artifactid>
        <version>1.0.0.Final-SNAPSHOT</version>
        <scope>test</scope>
    </dependency>
    <dependency>
     
        <groupid>org.jboss.arquillian.junit</groupid>
        <artifactid>arquillian-junit-container</artifactid>
        <scope>test</scope>
    </dependency>
</dependencies>

除此之外,您还需要嵌入的Glassfish依赖项。

<dependency>
    <groupid>org.glassfish.extras</groupid>
    <artifactid>glassfish-embedded-all</artifactid>
    <version>3.1</version>
    <scope>test</scope>
</dependency>

我们还需要MySQL J驱动程序:

<dependency>
    <groupid>mysql</groupid>
    <artifactid>mysql-connector-java</artifactid>
    <version>5.1.18</version>
    <scope>test</scope>
</dependency>

配置Arquillian
在所有必要的依赖关系就绪之后,我们需要进一步配置Arquillian。 这是通过arquillian.xml完成​​的,该文件必须放在src / test / resources文件夹中(您可能之前需要在NetBeans外部创建它),并且应如下所示:

<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian-1.0.xsd">
    <engine>
        <property name="deploymentExportPath">target/arquillian</property>
    </engine>
 
    <container default="true" qualifier="glassfish">
        <configuration>
            <property name="sunResourcesXml">src/main/setup/glassfish-resources.xml</property> 
        </configuration>
    </container>
</arquillian>

engine参数告诉Arquillian将测试存档的打包版本放置到target / arquillian文件夹中。 这对于解决问题非常有用。 容器限定符将测试运行程序指向由实体创建向导创建的glassfish-resources.xml。 全做完了。 我想建议的一件事是制作persistence.xml的副本,并将其放置到重命名为test-persistence.xml之类的test / resources文件夹中。 我认为最好的选择是配置测试JPA与生产性JPA有所不同。 作为一个简单的例子,我们希望在测试期间看到更多日志记录输出,因此复制的版本还应包含所需的参数。 我还想将用于测试的表生成策略更改为拖放表:

<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.logging.level.sql" value="FINEST" />
<property name="eclipselink.logging.parameters" value="true" />

让我们看一下测试。

添加一个测试用例
让我们添加一个测试。 对于NetBeans,这很容易:右键单击EJB,然后选择“工具>创建JUnit测试”。 选择JUnit 4.x,并接受名称建议“ com.mycompany.simpleweb.service.AuditRepositoryServiceTest”。 现在,您的项目有了一个新的“ Test Packages”文件夹。 如您所见,测试是错误的。 NetBeans假定您要基于嵌入式EJBContainer进行测试。 不错的猜测,但我们想在此处添加一些Arquillian。 删除EJBContainer导入并将类剥离为此:

@RunWith(Arquillian.class)
public class AuditRepositoryServiceTest {
}

现在是时候使用ShrinkWrap定义测试的部署档案了。 测试的部署存档是使用带有Arquillian的@Deployment批注的静态方法定义的。

@Deployment
    public static JavaArchive createTestArchive() {
        return ShrinkWrap.create(JavaArchive.class, "test.jar").addPackage(AuditLog.class.getPackage()).addPackage(AuditRepositoryService.class.getPackage()).addAsManifestResource(
                new ByteArrayAsset("<beans>".getBytes()),
                ArchivePaths.create("beans.xml")).addAsManifestResource(
                "test-persistence.xml",
                ArchivePaths.create("persistence.xml"));
    }

在添加了应包含的软件包之后,添加了一个空的beans.xml(现在应该足够了),并添加了test-persistence.xml作为名为persistence.xml的清单资源。 大。 最后一件事是定义测试本身。

@EJB
AuditRepositoryService repository;
 
 @Test
    public void insertLog() throws Exception {
        repository.writeLog("Markus");
        int numberOfLogs = repository.findAll();
        Assert.assertEquals(1, numberOfLogs);
 
    }

我们正在插入一个简单的测试实体,并从数据库中返回计数,该计数通过assertEquals检查。 就这样。 启动您的测试。 (右键单击AuditRepositoryServiceTest类,然后选择“测试文件(Strg + F6)。

检查发生了什么
输出窗口显示起始GlassFish的Std.out。 如果进一步检查输出,将会看到JDBC连接池和JDBC资源已创建: INFO:命令添加资源结果:PlainTextActionReporterSUCCESS描述:添加资源AdminCommandnull JDBC连接池mysql_auditlog_rootPool创建成功。 JDBC资源jdbc / auditlog已成功创建。 并部署了“测试”应用程序: 信息:WEB0671:在[/ test]处加载应用程序[test] 17.01.2012 10:12:39 org.glassfish.deployment.admin.DeployCommand执行 INFO:测试成功部署了6.461毫秒。

扫描输出确实会指向一些EclipseLink东西,但是附加的SQL日志记录似乎无效。 这是因为EclipseLink需要知道将输出指向哪个记录器。 通常,日志输出将重定向到自动发现的服务器记录器。 到目前为止,我们没有进行任何日志记录配置,仅依赖于Java Logging的默认值。 因此,让我们添加一些日志记录配置。 将一个空的logging.properties文件放入src / test / resources并向其中添加一些简单的行:

handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level =完成 将maven sure-fire插件添加到pom.xml的build部分:

<plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-surefire-plugin</artifactid>
                <version>2.11</version>
                <configuration>
                    <includes>
                        <include>com/mycompany/simpleweb/service/*</include>
                    </includes>
                    <systempropertyvariables>
                        <java.util.logging.config.file>${basedir}/src/test/resources/logging.properties</java.util.logging.config.file>
                    </systempropertyvariables>
                </configuration>
            </plugin>

如果现在执行清理和构建,则会看到所需的日志输出显示在NetBeans构建输出中。
有限:插入音频日志(ID,帐户,时间戳)值(?,?,?)
绑定=> [1,马库斯,2012-01-17 11:02:54.0] 实际上,如果您使用Strg + F6,您仍然只会看到INFO级别的消息。 要解决此问题,您需要更改NetBeans运行操作设置。 右键单击您的项目,然后选择“属性”。 选择“操作”和“测试文件”。 将以下内容作为新行添加到“设置属性”区域中:

java.util.logging.config.file = src / test / resources / logging.properties

现在,您还可以通过一次测试运行看到所需的日志级别输出。 就是这样 您可以下载完整的示例maven项目(作为ZIP文件) ,并带有提到的类,并进行一些操作。 玩得开心!

即使上面的帖子旨在成为一个更复杂的演示,事实证明,我还是错过了设置方面的一个大问题。 当您开始向实体中引入增强功能时,一切工作都很好。 仅举几例:延迟加载,更改跟踪,获取组等。 JPA提供者喜欢将此称为“增强”,并且通常将其称为“编织”。 编织是一种操作已编译Java类的字节码的技术。 EclipseLink JPA持久性提供程序使用编织来增强提到的内容的JPA实体并进行内部优化。 编织既可以在运行时加载实体时动态执行,也可以在编译时通过对Entity .class文件进行后处理来静态执行。 通常建议使用动态编织,因为它易于配置并且不需要对项目的构建过程进行任何更改。 您可能已经看到了EclipseLink的一些更好的日志输出,如下所示:

[…] –开始weaver类转换器处理类[com / mycompany / simpleweb / entities / AuditLog]。
[…] –持久化(PersistenceEntity)[com / mycompany / simpleweb / entities / AuditLog]。
[…] –编织变更跟踪(ChangeTracker)[com / mycompany / simpleweb / entities / AuditLog]。 […] –编织懒惰(间接使用ValueHolder)[com / mycompany / simpleweb / entities / AuditLog]。 […] –编织提取组(FetchGroupTracker)[com / mycompany / simpleweb / entities / AuditLog]。 […] –结束weaver类转换器处理类[com / mycompany / simpleweb / entities / AuditLog]。

Arquillian和嵌入式GlassFish的问题
想象一下,您以昨天博客中的示例为例,将简单的String account属性更改为如下所示:

@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
   private Person person;

这正是上述情况之一,您的JPA提供程序需要在执行之前对类文件进行一些增强。 如果不修改项目,将导致一些非常讨厌的异常:

异常描述:访问不存在的编织_vh_方法[_persistence_get_person_vh]时将发生NullPointerException。 未正确编织该类–对于EE部署,请检查application.xml部署描述符中的模块顺序,并验证包含持久性单元的模块是否在使用该持久性单元的任何其他模块之前。
[…]
内部异常:java.lang.NoSuchMethodException:com.mycompany.simpleweb.entities.AuditLog._persistence_get_person_vh() 映射:org.eclipse.persistence.mappings.ManyToOneMapping [person] 描述符:RelationalDescriptor(com.mycompany.simpleweb.entities.AuditLog –> [DatabaseTable(AUDITLOG)]) 在org.eclipse.persistence.exceptions.DescriptorException.noSuchMethodWhileInitializingAttributesInMethodAccessor(DescriptorException.java:1170) 在org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor.initializeAttributes(MethodAttributeAccessor.java:200) […]

表示缺少某些内容。 而这种缺失的方法是由编织过程引入的。 如果您反编译编织的实体,则可以看到JPA提供程序在抱怨什么。 这是增强型实体类的外观。 这只是编织过程引入到您的代码中的增强方法之一。

public WeavedAttributeValueHolderInterface _persistence_get_person_vh()
  {
      _persistence_initialize_person_vh();
      if(_persistence_person_vh.isCoordinatedWithProperty() || _persistence_person_vh.isNewlyWeavedValueHolder())
      {
          Person person1 = _persistence_get_person();
          if(person1 != _persistence_person_vh.getValue())
              _persistence_set_person(person1);
      }
      return _persistence_person_vh;
  }

动态与静态编织
显然,默认的动态编织不适用于上述设置。 为什么? 编织是一个被宠坏的孩子。 仅当要编织的实体类仅存在于应用程序类加载器中时,它才起作用。 嵌入式GlassFish,Arquillian和maven sure-fire-plugin的结合使这一点有点混乱,故事的结尾是,您的实体完全没有任何增强。 比较这个不错的讨论以获得更详细的解释。 如果动态波动不起作用,我们必须使用称为静态编织的后备。 静态意味着:在构建过程中对实体进行后处理。 有了Maven项目,这听起来很容易。 让我们寻找这样的东西。 您可能会发现的第一件事是StaticWeaveAntTask 。 第二件事可能是Craig的eclipselink-staticweave-maven-plugin

让我们从StaticWeaveAntTask开始。 您将必须使用maven-antrunner-plugin进行介绍。 从左到右复制课程,并进行大量的争吵以使您的课程路径牢牢掌握。 Laird Nelson在为所有3个大型JPA提供程序(EclipseLink,OpenJPA,Hibernate)提供示例配置原型方面做得很出色,您可以尝试一下。 有关正在发生的事情的详细说明可以在他的博客中找到 。 谢谢莱尔德的指点! 不要误会我的意思:这是一种有效的方法,但是我根本不喜欢它。 主要是因为它给构建带来了巨大的复杂性,并且看到了太多的项目,甚至没有管理正常Maven项目所需的技能,这对我来说根本不是解决方案。 我尝试了Craig Day完成的静态编织插件。

向simpleweb添加静态编织
因此,让我们从昨天的项目中打开pom.xml并引入新的插件:

<plugin>
    <artifactId>eclipselink-staticweave-maven-plugin</artifactId>
    <groupId>au.com.alderaan</groupId>
    <version>1.0.1</version>
         <executions>
            <execution>
                 <goals>
                   <goal>weave</goal>
                 </goals>
                 <phase>process-classes</phase>
            </execution>
          </executions>
     </plugin>

做完了 现在,您的类已经编好了,如果您通过插件配置引入一些日志记录,您实际上可以看到,实体类会发生什么。 该插件可通过repo1.maven.org获得。 我遇到的唯一问题是,对EclipseLink 2.2.0的引入依赖关系(或当然)不能通过相同的存储库获得,因此您可能需要使用正确的存储库和依赖关系为自己构建它。 您可以通过插件的Google代码页获取源代码。

不要忘记将编织属性添加到您的test-persistance.xml中:

<property name="eclipselink.weaving" value="static" />

[更新:2012年1月19日]
Craig发布了该插件的新1.0.2版本,该版本解决了EclipseLink依赖项的问题。 现在,您可以简单地包括所需的EclipseLink版本作为插件的依赖项。 还需要正确的EclipseLink Maven存储库。 具有配置的日志级别的完整示例如下所示:

<repository>
            <id>eclipselink</id>
            <name>Repository hosting the eclipselink artifacts</name>
            <url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo/</url>
        </repository>
 
[...]
  <plugin>
                <artifactId>eclipselink-staticweave-maven-plugin</artifactId>
                <groupId>au.com.alderaan</groupId>
                <version>1.0.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>weave</goal>
                        </goals>
                        <phase>process-classes</phase>
                        <configuration>
                            <logLevel>ALL</logLevel>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.eclipse.persistence</groupId>
                        <artifactId>eclipselink</artifactId>
                        <version>2.3.1</version>
                    </dependency>
                </dependencies>
            </plugin>

参考: 具有NetBeans,嵌入式GlassFish,JPA和MySQL数据源的 Arquillian 和具有NetBeans,GlassFish嵌入式,JPA和MySQL数据源的 Arquillian –来自我们JCG合作伙伴 Markus Eisele在企业软件开发和Java博客上的第二部分。


翻译自: https://www.javacodegeeks.com/2012/01/arquillian-with-netbeans-glassfish.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值