Gradle 使用PlayFramework+;埃宾和格拉德尔

Gradle 使用PlayFramework+;埃宾和格拉德尔,gradle,playframework,ebean,Gradle,Playframework,Ebean,我正在尝试使用编译/打包一个使用Ebean的Play 2.3.x应用程序 在编译和打包过程中,一切都很正常,但当我运行应用程序时,会出现众所周知的错误 Entity type class SomeEntity is not an enhanced entity bean. Subclassing is not longer supported in Ebean 那么,我怎样才能让Gradle在编译期间运行增强器呢?我就是这样做的。我正在使用play 2.4,但应该可以为您工作 首先在buil

我正在尝试使用编译/打包一个使用Ebean的Play 2.3.x应用程序

在编译和打包过程中,一切都很正常,但当我运行应用程序时,会出现众所周知的错误

Entity type class SomeEntity is not an enhanced entity bean. 
Subclassing is not longer supported in Ebean

那么,我怎样才能让Gradle在编译期间运行增强器呢?

我就是这样做的。我正在使用play 2.4,但应该可以为您工作

首先在build.gradle中添加一个配置,如下所示-

configurations {
    enhance
}
接下来,添加对ebeanorm代理的依赖项,如下所示:

dependencies {
    enhance group: 'org.avaje.ebeanorm', name: 'avaje-ebeanorm-agent', version: '4.5.3'
}
dependencies {
    play 'org.avaje:avaje-agentloader:2.1.2'
    play "org.avaje.ebeanorm:avaje-ebeanorm-agent:4.5.3"
}
确保build.gradle中具有所需的播放依赖项,如下所示:

dependencies {
    enhance group: 'org.avaje.ebeanorm', name: 'avaje-ebeanorm-agent', version: '4.5.3'
}
dependencies {
    play 'org.avaje:avaje-agentloader:2.1.2'
    play "org.avaje.ebeanorm:avaje-ebeanorm-agent:4.5.3"
}
最后,在编译任务执行后添加以下内容以进行增强:

model {
    components {
        play {
            binaries.all{binary ->
                tasks.withType(PlatformScalaCompile) {
                    doLast {
                        ant.taskdef(name: 'ebean', classname: 'com.avaje.ebean.enhance.ant.AntEnhanceTask', classpath: project.configurations.enhance.asPath)
                        ant.ebean(classSource: "${project.buildDir}/playBinary/classes", packages: 'models.package.name', transformArgs: 'debug=1')

                    }
                }
            }
        }
    }

@koolrich,我尝试过这个解决方案,当它没有编译时,我继续前进,直到后来才发现唯一的问题是dbmodels/*预期路径,而我的路径不同

起初,关于增强功能的术语看起来很神奇,令人困惑,以下内容帮助我了解了正在发生的事情:
本质上,增强是添加更多的方法和属性来处理持久性。

我将Play 2.5.2(Java)项目从sbt转换为gradle,面临同样的问题,然后尝试使用@koolrich给出的解决方案。但效果并不理想。一切正常,但它无法为关系对象返回数据(为关系对象返回null)。然后比较sbt和gradle生成的增强字节码,找出增量。然后了解该剧如何增强字节码。分三步播放增强字节码

  • 它为字段生成getter和setter,如果它们还没有到位,则由play增强插件(play.core.enhancers.PropertiesEnhancer.generateAccessors)完成
  • 它重写直接访问字段的类以使用访问器,并由play增强插件(play.core.enhancers.PropertiesEnhancer.rewriteAccess)完成
  • 如果使用Ebean,Ebean增强器将应用于通过application.conf(Ebean增强插件)配置的类
EAX示例:

Employee employee=Employee.find.byId(1);
Company company=employee.company;

After Step 1&2, this will be converted to

Company company=employee.getCompany();

With Employee#getCompany() being something like

@PropertiesEnhancer.GeneratedAccessor
public Company getCompany(){
return this.company;
}

After step 3, the getter will be modified to be something like

@PropertiesEnhancer.GeneratedAccessor
public Company getCompany(){
return _ebean_get_company();
}

protected Company _ebean_get_company() {
  this._ebean_intercept.preGetter("company");
  return this.company;
}
因此,将sbt转换为gradle,您必须执行这三个步骤,因为gradle play插件不支持这三个步骤。对于步骤3,ebean有可以使用的增强类(ant任务)(由@koolrich给出的解决方案),对于步骤1和2,我编写了另一个增强ant任务,它添加访问器并重写访问。下面是gradle.build文件的外观

configurations {
    enhance
    playEnhance
}

dependencies {
    enhance "org.avaje.ebeanorm:avaje-ebeanorm-agent:4.9.1"
    playEnhance 'com.typesafe.play:play-enhancer:1.1.0'
}

model {
    components {
        play {
            binaries.all{binary ->
                tasks.withType(PlatformScalaCompile) {
                    doLast {
                        ant.taskdef(name: "playenhancetask", classname:"com.xxx.gradlehelper.PlayGradleEnhancherTask", classpath:"${project.buildDir}/playBinary/classes/:${project.configurations.playEnhance.asPath}")
                        ant.playenhancetask(classSource: "${project.buildDir}/playBinary/classes", packages: 'com.xxx.xxx.*', classpath:"${project.configurations.play.asPath}")
                        ant.taskdef(name: 'ebean', classname: 'com.avaje.ebean.enhance.ant.AntEnhanceTask', classpath: project.configurations.enhance.asPath)
                        ant.ebean(classSource: "${project.buildDir}/playBinary/classes", packages: 'com.xxx.xxx.xxx.*', transformArgs: 'debug=1')
                    }
                }
            }
        }
    }
}

dependencies {
    play 'org.avaje:avaje-agentloader:2.1.2'
    play 'org.avaje.ebeanorm:avaje-ebeanorm:6.18.1'
    play 'com.typesafe.play:play-ebean_2.11:3.0.0'
    play 'com.typesafe.play:play-enhancer:1.1.0'
    play "org.avaje.ebeanorm:avaje-ebeanorm-agent:4.9.1"
    play group: 'org.apache.ant', name: 'ant', version: '1.8.2'
}
这是我的ant任务PlayGradleEnhancherTask.java

package com.xxx.gradlehelper;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import play.core.enhancers.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class PlayGradleEnhancherTask extends Task {

    String classpath;  
    String classSource;
    String transformArgs;
    String packages;
    public String getClasspath() {
        return classpath;
    }  
    public void setClasspath(String classpath) {
        this.classpath = classpath;
    }    
    public void setClassSource(String source) {
        this.classSource = source;
    }   
    public void setTransformArgs(String transformArgs) {
        this.transformArgs = transformArgs;
    }

    public void setPackages(String packages) {
        this.packages = packages;
    }  
    public void execute() {
        if (packages == null) {
            throw new BuildException("No message set.");
        }
        log("classSource: " + classSource + ", packages: " + packages + "\n classPath: "+ classpath);

        String dir = packages.trim().replace('.', '/');
        dir = dir.substring(0, dir.length() - 1);

        String dirPath = classSource + "/" + dir;
        File d = new File(dirPath);
        if (!d.exists()) {
            throw new RuntimeException("File not found " + dirPath + "  currentDir:" + new File(".").getAbsolutePath());
        }

        Path path = Paths.get(dirPath);
        List<File> fileNames = new ArrayList();
        List<File> files = getFiles(fileNames, path);

        //generate property accessor
        generateAccessors(files);

        //rewrite access
        rewriteAccess(files);
    }

    private void rewriteAccess(List<File> files) {
        for (File file: files) {
            try{
                 PropertiesEnhancer.rewriteAccess(classSource+":"+classpath,file);
            }catch (Exception e){
                String fileName = file == null ? "null" : file.getName() +",  e: "+ e.getMessage();
                System.err.println("Could not enhance[rewriteAccess]:"+fileName);
            }
        }
    }
    private void generateAccessors(List<File> files) {
        for (File file: files) {
            try{
                PropertiesEnhancer.generateAccessors(classSource+":"+classpath,file);
            }catch (Exception e){
                e.printStackTrace();
                String fileName = file == null ? "null" : file.getName();
                System.err.println("Could not enhance[generateAccessors]: "+fileName);
            }
        }
    }

    private List<File> getFiles(List<File> files, Path dir) {
        try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
            for (Path path : stream) {
                if(path.toFile().isDirectory()) {
                    getFiles(files, path);
                } else {
                    File file = path.toFile();
                    if(!file.getName().startsWith("Reverse")&& file.getName().endsWith(".class")) {
                        files.add(file);
                    }
                }
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
        return files;
    }
}
package com.xxx.gradlehelper;
导入org.apache.tools.ant.BuildException;
导入org.apache.tools.ant.Task;
导入play.core.enhancers.*;
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.DirectoryStream;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.path;
导入java.util.ArrayList;
导入java.util.List;
公共类PlayGradleEnhancherTask扩展任务{
字符串类路径;
字符串类源;
字符串转换参数;
字符串包;
公共字符串getClasspath(){
返回类路径;
}  
公共void setClasspath(字符串类路径){
this.classpath=classpath;
}    
公共void setClassSource(字符串源){
this.classSource=source;
}   
公共void setTransformArgs(字符串transformArgs){
this.transformArgs=transformArgs;
}
公共void setPackages(字符串包){
这个。包=包;
}  
public void execute(){
if(packages==null){
抛出新的BuildException(“无消息集”);
}
日志(“类源:“+classSource+”,包:“+packages+”\n类路径:“+classPath”);
String dir=packages.trim().replace('.','/');
dir=dir.substring(0,dir.length()-1);
字符串dirPath=classSource+“/”+dir;
文件d=新文件(dirPath);
如果(!d.exists()){
抛出新的运行时异常(“未找到文件”+dirPath+“currentDir:+new File(“.”).getAbsolutePath());
}
Path=Path.get(dirPath);
列表文件名=新的ArrayList();
列表文件=获取文件(文件名、路径);
//生成属性访问器
GenerateAccessor(文件);
//重写访问
重写访问(文件);
}
私有访问(列表文件){
用于(文件:文件){
试一试{
重写访问(classSource+“:”+类路径,文件);
}捕获(例外e){
字符串fileName=file==null?“null”:file.getName()+”,e:+e.getMessage();
System.err.println(“无法增强[rewriteAccess]:”+文件名);
}
}
}
专用void生成器访问器(列表文件){
用于(文件:文件){
试一试{
generateAccessors(classSource+“:”+类路径,文件);
}捕获(例外e){
e、 printStackTrace();
字符串fileName=file==null?“null”:file.getName();
System.err.println(“无法增强[generateAccessors]:”+文件名);
}
}
}
私有列表getFiles(列表文件,路径目录){
try(DirectoryStream=Files.newDirectoryStream(dir)){
用于(路径:流){
if(path.toFile().isDirectory()){
获取文件(文件、路径);
}否则{
File File=path.toFile();
如果(!file.getName().startsWith(“Reverse”)和&file.getName().endsWith(“.class”)){
文件。添加(文件);
}
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
归还文件;
}
}

您好,我正在将播放2.5.2从sbt转换为gradle。您的解决方案对我很有效,一个问题是,它没有返回关系对象。我指的是包含