从单个源文件夹中抓取多个罐子

vit*_*dze 34 java jar gradle

至于现在,我们有一个名为单个源文件夹的项目结构src,其中包含三个模块的源代码.我想做的是:

1)编译源代码.使用sourceSets定义可以轻松完成此操作:

sourceSets {
    main {
        java {
            srcDir 'src'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2)将编译结果放入三个罐子里.我通过三个'jar'类型的任务来做这件事:

我现在通过三个单独的任务来做这件事:

问题是,server.jar应该包含不包含在所有类client.jarutil.jar.在ant build脚本中,我们使用differenceant task 来解决这个问题.如何在gradle中完成(我目前的方法不起作用)?

也许我的方法是完全错误的.请指教.

PS至于现在我们不能改变项目源代码文件夹结构.

vit*_*dze 30

我将在这里发布我的工作解决方案作为答案(我在gradle的论坛上有一个提示).

gradle中的范围非常奇怪:)我认为每个任务定义都会创建一个"Task"类的对象,在这种特殊情况下类似于"JarTask".然后我可以从build.gradle脚本的任何地方访问该类的任何属性.但是,我找到了唯一可以看到模式的地方,这些模式包含在jar文件中 - 在from任务块内.所以我现在的工作解决方案是:

1)定义项目级集合以包含要排除的模式 server.jar

2)排除任务from块中的所有模式serverJar.

请参阅下面的最终版本

sourceSets {  
    main {  
        java {  
            srcDir 'src'  
        }  
    }  
} 

// holds classes included into client.jar and util.jar, so they are to be excluded from server.jar
ext.serverExcludes = []

// util.jar
task utilJar(type: Jar) {  
    from(sourceSets.main.output) {  
        include "my/util/package/**" 
        project.ext.serverExcludes.addAll(includes)
    }  
}

// client.jar
task clientJar(type: Jar) {  
    from(sourceSets.main.output) {  
        include "my/client/package/**"
        project.ext.serverExcludes.addAll(includes)
    }  
}

// server.jar
task serverJar(type: Jar) {  
    from(sourceSets.main.output) {  
        exclude project.ext.serverExcludes
    }  
}
Run Code Online (Sandbox Code Playgroud)

  • 这很棒,但是如何引用其他项目中单独的“.jar”文件 - 例如,如何将“client.jar”拉入另一个子项目? (2认同)

Grz*_*Żur 23

我认为这种做法是错误的.我建议制作一个包含3个子项目的项目.

project
- util
- server (depends on util)
- client (depends on util)
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因你不能改变类结构使用这种构建文件:

settings.gradle

include 'util', 'client', 'server'
Run Code Online (Sandbox Code Playgroud)

的build.gradle

subprojects {
    apply plugin: 'java'
}

project(':util') {
    sourceSets {
        main {
            java {
                srcDir '../src'
                include 'util/**'
            }
        }
    }
}

project(':server') {
    sourceSets {
        main {
            java {
                srcDir '../src'
                include 'server/**'
            }
        }
    }
    dependencies {
        compile project(':util')
    }
}

project(':client') {
    sourceSets {
        main {
            java {
                srcDir '../src'
                include 'client/**'
            }
        }
    }
    dependencies {
        compile project(':util')
    }
}
Run Code Online (Sandbox Code Playgroud)

您仍然需要子项目的目录,但源可以在您想要的位置.

当你跑步时,gradle assemble你将拥有3个带有独立课程的罐子.这个解决方案的优点是我们制作了一个具有正确依赖关系的正确Gradle多模块项目,而不仅仅是构建jar的任务.

请阅读多项目构建.

  • @vitalidze 我提出的解决方案是不改变目录结构。额外的空目录是否有问题?你有依赖循环吗? (2认同)
  • 我反对这一点,因为在某些情况下,您需要一个项目来生成多个工件,而这正是 OP 所寻求的。 (2认同)