如何从Gradle启用Eclipselink的静态编织

时间:2014-04-10 19:54:15

标签: java ant gradle eclipselink

我想从Gradle为我的JPA课程启用Eclipselink的静态编织。 Eclipselink文档解释了如何在Ant任务中执行此操作:

<target name="define.task" description="New task definition for EclipseLink static weaving"/>

<taskdef name="weave" classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeaveAntTask"/>
</target>
<target name="weaving" description="perform weaving" depends="define.task">
    <weave  source="c:\myjar.jar"
            target="c:\wovenmyjar.jar"
            persistenceinfo="c:\myjar-containing-persistenceinfo.jar">
        <classpath>
            <pathelement path="c:\myjar-dependent.jar"/>
        </classpath>

    </weave>
</target>

现在我有两个问题:

1。我如何翻译&#39;这是Gradle方法吗? 我已尝试过此操作(基于http://www.gradle.org/docs/current/userguide/ant.html#N1143F上的文档):

task eclipseWeave << {
    ant.taskdef(name: "weave",
                classname: "org.eclipse.persistence.tools.weaving.jpa.StaticWeaveAntTask",
                classpath: configurations.compile.asPath)

    ant.weave(source: relativePath(compileJava.destinationDir),
              target: relativePath(compileJava.destinationDir),
              persistenceinfo: relativePath(processResources.destinationDir) {
    }
}

但问题是类路径似乎不能在ant.weave(..)内工作。编织过程在消息输出后中止:

Execution failed for task ':eclipseWeave'.
> java.lang.NoClassDefFoundError: some/class/from/my/dependencies

类路径设置适用于ant.taskdef(..),因为StaticWeaveAntTask位于我的依赖项中。如何将其应用于ant.weave(..)本身?

2。如何将其集成到我的构建中,以便在每个compileJava步骤后自动执行?

2 个答案:

答案 0 :(得分:8)

我知道这是一个老问题,但是基于OP对&#34; gradle&#34;的评论。这样做的方式,我想我会分享我们的方法。我们正在使用JavaExec任务和各种可用的配置对象。

由于编织是在classes目录中完成的(在构建JAR之前),最终只需要构建一个jar而不是两个。由于我们的罐子很大,这对我们很重要。

task performJPAWeaving(type: JavaExec, dependsOn: "compileJava"){
  inputs.dir compileJava.destinationDir
  outputs.dir compileJava.destinationDir
  main "org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
  args  "-persistenceinfo",
   "src/main/resources",
   compileJava.destinationDir.getAbsolutePath(),
   compileJava.destinationDir.getAbsolutePath()
   classpath = configurations.compile
}

tasks.withType(Jar){
  dependsOn "performJPAWeaving"
}

答案 1 :(得分:1)

问题描述

我有一个类似的问题,并且想分享基于前一篇文章的解决方案。解决了以下问题:

  • 在编织之前处理 persistence.xml 并替换标记。
  • 找到此已知的EclipseLink Weaver bug的解决方法,该方法可防止将Weavers -persistenceunit 标志与Gradle一起使用。
  • 自动发现实体类,而不是在 persistence.xml 中列出它们。

步骤1:处理persistence.xml

首先,应将占位符 @datasourceName @ 替换为实际值。这是通过在您的build.gradle文件中插入以下代码来实现的:

import org.apache.tools.ant.filters.ReplaceTokens

ext {
    dsName = 'MyDataSourceName'
    puName = 'MyPuName'
}

processResources {
    filter(ReplaceTokens, tokens: [
        datasourceName: dsName,
        persistenceUnitName: puName
    ])
}

以下代码显示了(简化的) src / main / resources / META-INF / persistence.xml 文件:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="@datasourceName@" transaction-type="JTA">
        <jta-data source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=@datasourceName@)</jta-data-source>

    <!-- Necessary to let EclipseLink/Weaver discover local classes without listing them in this file,
        see http://www.eclipse.org/eclipselink/documentation/2.7/concepts/app_dev001.htm#BGBHFFAG-->
    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
        <!-- Tell the application container that our classes are already woven,
            see https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving-->
        <property name="eclipselink.weaving" value="static" />
    </properties>
</persistence-unit>

重要的是要提到,必须将标志 exclude-unlisted-classes 设置为 false 才能使EclipseLink Weaver发现 带注释的实体类自动。还请确保将属性“ eclipselink.weaving ”设置为“ 静态”,以告知您 在应用程序运行时,实体类已经被编织,不需要动态增强。如果您使用OSGi,请记住要导入 所有必需的EclipseLink软件包都放入包含编织类的捆绑软件中。

执行 processResources 任务后,生成的文件 build / resources / main / META-INF / persistence.xml 如下所示(请注意持久性单元名称):

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="MyPuName" transaction-type="JTA">
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=MyDataSourceName)</jta-data-source>

    <!-- Necessary to let EclipseLink/Weaver discover local classes without listing them in this file, 
      see http://www.eclipse.org/eclipselink/documentation/2.7/concepts/app_dev001.htm#BGBHFFAG -->
    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
        <!-- Tell the application container that our classes are already woven,
            see, https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving-->
        <property name="eclipselink.weaving" value="static" />
    </properties>
</persistence-unit>

步骤2:复制生成的persistence.xml

接下来,我们添加一个新的 Copy 任务,该任务会将已处理的资源复制到 compileJava 任务的输出目录中。这是必要的 在Weavers类路径上具有所有必需的工件(可解决错误https://bugs.eclipse.org/bugs/show_bug.cgi?id=295031)。加 将以下任务添加到您的 build.gradle 文件:

task copyResourcesToClassesOutputDir(type: Copy, dependsOn: processResources) {
    from processResources.destinationDir
    into compileJava.destinationDir
}

步骤3:编织您的实体类

为了增强您的类,有必要适当配置您的构建。将以下内容添加到您的 build.gradle 中。已经声明了单独的类路径配置,因为不需要在普通的编译类路径中包含EclipseLink类。

configurations {
    providedApi
}

dependencies {
    providedApi 'org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.2'
    providedApi 'org.eclipse.persistence:javax.persistence:2.2.0'
}

task performJPAWeaving(type: JavaExec) {
    main "org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
    args "-loglevel",
        "FINE",
        compileJava.destinationDir.absolutePath,
        compileJava.destinationDir.absolutePath

    classpath (configurations.compile, configurations.providedApi)

    dependsOn compileJava
    dependsOn copyResourcesToClassesOutputDir
}

// Do always weave the classes before a JAR is created
tasks.withType(Jar) {
    dependsOn "performJPAWeaving"
}

就是这样!如果现在运行任何 Jar 任务,则在将实体类打包到Jar文件中之前,它们会得到增强。