重复生成的类gradle输出(build/…)与intellij输出(out/…)

重复生成的类gradle输出(build/…)与intellij输出(out/…),gradle,intellij-idea,lombok,Gradle,Intellij Idea,Lombok,我将intellij(2019.1.1)用于JavaGradle(5.4.1)项目,将lombok(1.18.6)用于自动生成代码。Intellij将生成的源代码放在out/production/classes/generated/…下,gradle将它们放在build/generated/sources/… ext { // path to Gradle generated main sources directory gradleGeneratedMainSourcesDir

我将intellij(2019.1.1)用于JavaGradle(5.4.1)项目,将lombok(1.18.6)用于自动生成代码。Intellij将生成的源代码放在
out/production/classes/generated/…
下,gradle将它们放在
build/generated/sources/…

ext {
    // path to Gradle generated main sources directory
    gradleGeneratedMainSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/main/"
    // path to Gradle generated test sources directory
    gradleGeneratedTestSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/test/"
    // path to IDEA generated sources directory
    ideaGeneratedSourcesDir = "$projectDir/out/production/classes/generated"        
}

idea {
    module {
        // exclude main & test sources generated by Gradle from project source directories
        excludeDirs += file(gradleGeneratedMainSourcesDir)
        excludeDirs += file(gradleGeneratedTestSourcesDir)

        // include generated sources directory managed by IDEA
        sourceDirs += file(ideaGeneratedSourcesDir)
        generatedSourceDirs += file(ideaGeneratedSourcesDir)
    }
}
这很好,我喜欢intellij将自己的构建工件与gradles分开,但是,intellij在运行项目时似乎会同时查看两个目录,并且会抱怨生成的重复类。 将intellij与gradle和自动生成源一起使用的最佳实践是什么?你是否:

  • 告诉intellij将输出到与gradle相同的目录(此 如果intellij之外的进程更新,可能会导致异常行为 生成中的文件/)
  • 告诉intellij使用执行所有任务 gradle(我听说这比intellij的品牌慢)
  • 告诉intellij 简单地忽略“build”目录(您是如何做到这一点的?以及 为什么intellij知道它的输出时还关心“build/ 到“out/”)
  • 更新:为了澄清情况,问题不在于lombok自动生成的代码,而在于hibernate jpamodelgen。问题仍然是一样的(重复生成的源代码),但我想澄清的是,这是由jpamodelgen生成的源代码,而不是lombok生成的源代码

    更新2:我尝试了以下配置,试图告诉intellij生成的源所在的位置,并告诉intellij忽略生成目录。遗憾的是,这不起作用(在生成的源文件上仍然会出现重复的类错误)

    更新3: 尝试了M.Riccuiti的建议,删除了build/、out/、.idea/、.gradle/,并重新导入了gradle项目,但intellij仍在build/目录中看到生成的源代码


    我在之前的评论中提出的解决方案在IDEA 2018.3.x中运行良好,但在升级到IDEA 2019.1后,我再次遇到了这个重复类异常

    下面是使用Gradle 5.x(用5.4测试)和IDEA 2019.1实现此功能的有效解决方案,以实现您的解决方案#3,我认为这是最佳选择(不要混合使用Gradle和IDEA生成的输出目录,也不要将IDEA操作委托给Gradle)

    关键点是使用
    idea.module
    扩展中的
    excludeDirs
    属性,使idea忽略由Gradle在
    build/generated/sources/…

    ext {
        // path to Gradle generated main sources directory
        gradleGeneratedMainSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/main/"
        // path to Gradle generated test sources directory
        gradleGeneratedTestSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/test/"
        // path to IDEA generated sources directory
        ideaGeneratedSourcesDir = "$projectDir/out/production/classes/generated"        
    }
    
    idea {
        module {
            // exclude main & test sources generated by Gradle from project source directories
            excludeDirs += file(gradleGeneratedMainSourcesDir)
            excludeDirs += file(gradleGeneratedTestSourcesDir)
    
            // include generated sources directory managed by IDEA
            sourceDirs += file(ideaGeneratedSourcesDir)
            generatedSourceDirs += file(ideaGeneratedSourcesDir)
        }
    }
    

    请参见此处基于此配置的完整示例项目:

    这里是一种最终对我有效的方法。诀窍是要注意,当gradle生成类时,它会将它们放入:

    build\generated\sources\annotationProcessor\java\main\com...
    
    但是intellij将生产源目录设置为“已生成”。在这种情况下,源将转到:

    build\generated\sources\annotationProcessor\java\main\generated\com...
    
    如果您首先使用gradle编译,然后使用idea,那么您将获得这两个版本,这将导致问题


    要解决此问题,请将intellij注释处理器“生产源目录”和“测试源目录”配置中的“生成的”和“生成的测试”替换为“/”。这将使gradle和intellij在同一目录中生成源,并根据需要相互覆盖。还要确保“存储生成的源相对于”设置为“模块内容根目录”,并重新生成应用程序以清除任何其他源

    您可以输入IntelliJ设置(首选项):

    首选项|构建、执行、部署|构建工具| Gradle | Runner

    然后勾选复选框将IDE构建/运行操作委托给Gradle


    最后,您将再次进行清理和构建。问题将得到解决。

    我在“复制类”(为QueryDSL和MapStruct注释插件生成的类)中遇到了同样的问题在我从Gradle 4.10迁移到Gradle 5.x之后:在Gradle 5.x之前,IDEA在
    /out
    下为生成的类使用另一个目标目录,奇怪的是这些类没有被检测到重复。。您是否使用Gradle IDEA插件来配置IDEA项目?您是否在IDEA中启用了“委托生成/测试生成工具”选项?我可以通过正确配置
    IDEA.module.generatedSourceDirs
    IDEA.module.sourceDirs
    属性来解决此问题,将值设置为
    out/production/classes/generated/
    @M.Ricciuti我没有启用委托构建/测试构建工具(这是我列表中的选项2),因为我听说它可能会更慢。我将研究通过idea插件设置SourceDir。@Andrey这似乎是一种恶意行为/错误。。我甚至不能用我自己的github项目重现这个问题=>我创建了一个新的更简单的项目,以便重现:请参阅。请参阅自述文件,了解复制步骤!填充了“请跟随”。我尝试了一下,但它不起作用。Intellij将$buildDir/generated/sources/annotationProcessor/java/main/视为源目录,即使它位于排除的目录中。如果我检查intellij中的模块,它会将此目录列为排除目录,但它也会将其列在源目录下。我觉得这是一种操作顺序,intellij更喜欢源目录而不是排除目录。我建议您在手动删除.IDEA/、.gradle/、/out和/build目录后,将项目完全重新导入IDEA。然后,首先使用Gradle(来自IDEA Gradle工具)进行构建,并检查
    $buildDir/generated/sources/annotationProcessor/java/main
    在项目目录树中是否未标记为“generated source”dir。只有在这之后,才能使项目按想法进行。希望这能有所帮助。@M.Ricciuti很抱歉“攻击”你,但在一个大项目中,我们也有很多问题,无法找到生成的元模型,这些模型确实是由jpamodelgen制造的。我注意到我们的项目正在“build/generated/sources”下添加一个“generated”目录