如何使用gradle编译单个java文件?

I S*_*son 13 java gradle

(更新:感谢Peter N的评论.)

我有一个包含多个类的java包,因此包含文件.但是我最初只想编译其中一个文件,以便我可以使用它来更新包中的其他类.它是其他类的工厂,因此依赖于它们 - 即.它引用了它们.

我一直在尝试使用JavaCompile gradle任务来执行此操作.因此,我已经阅读了JavaCompile的文档,并试图搜索示例,但似乎没有什么.我甚至在gradle论坛发帖,但到目前为止进展缓慢.

我可以使用ant javac任务使用ant脚本轻松完成所需的操作.但是我想在gradle中完成它(并且不使用ant.javac方法 - 如果我必须这样做,我将只使用ant).

我创建了一个示例案例,在一个包中只有两个类的两个源文件.

这两个文件都在一个名为some.pkg的包中,因此我们有以下目录结构:

  • \的build.gradle
  • \ SRC \主\ java的\一些\ PKG\ClassOne.java
  • \ SRC \主\ java的\一些\ PKG\ClassTwo.java

ClassOne:

package some.pkg;

import some.pkg.*;

public class ClassOne {
    public void doStuff() {
    }
}
Run Code Online (Sandbox Code Playgroud)

ClassTwo:

package some.pkg;

import some.pkg.*;

public class ClassTwo {
    public void ClassTwo() {
        ClassOne cone = new ClassOne();
        cone.doStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,ClassTwo(我们想要独立编译的类)取决于ClassOne.

ant脚本是一个简单的例子:

<project>
    <property name="build.dir"     value="build"/>
    <property name="lib.dir"     value="lib"/>
    <property name="src.dir"     value="src/main/java"/>
    <target name="generate" >
        <mkdir dir="${build.dir}"/>
        <javac source="1.6" target="1.6" srcdir="${src.dir}" destdir="${build.dir}" 
               debug="true" includeantruntime="false"
               includes="some/pkg/ClassTwo.java">
        </javac>
    </target>
</project>
Run Code Online (Sandbox Code Playgroud)

但是在gradle中,我一直遇到一个javac(或JavaCompile任务)无法找到ClassOne的问题.这就好像sourcedir没有指向应该的位置 - 事实上我就像在命令行上运行javac一样.我认为gradle'JavaCompile'任务的'source'属性就像ant'srcdir'属性一样工作,但事实并非如此.所以这是我正在尝试的gradle脚本:

apply plugin: 'java'

task compileOne (type: JavaCompile) {
    source = sourceSets.main.java.srcDirs
    include 'some/pkg/ClassTwo.java'
    classpath = sourceSets.main.compileClasspath
    destinationDir = sourceSets.main.output.classesDir
}
Run Code Online (Sandbox Code Playgroud)

但它导致:

C:\test\>gradle generate
:generate
C:\test\src\main\java\some\pkg\ClassTwo.java:7: cannot find symbol
symbol  : class ClassOne
location: class some.pkg.ClassTwo
                ClassOne cone = new ClassOne();
                ^
C:\test\src\main\java\some\pkg\ClassTwo.java:7: cannot find symbol
symbol  : class ClassOne
location: class some.pkg.ClassTwo
                ClassOne cone = new ClassOne();
                                    ^
2 errors
:generate FAILED
Run Code Online (Sandbox Code Playgroud)

那么我如何在gradle中实现一个与ant javac等价的东西呢?

ant javac似乎有聪明才能去编译所有其他相关的类,但我想对于gradle JavaCompile我需要设置一个sourceSet来做那个..不确定..

谢谢!

I S*_*son 23

感谢@PeterNiederwieser在评论中的原帖上的讨论,我将在此提供完整性的答案.

要以非常类似于ant javac的方式使用Gradle JavaCompile函数,您需要sourcepath通过options.compilerArgs属性提供编译器选项.因此,现在可用的gradle脚本如下:

apply plugin: 'java'

task compileOne (type: JavaCompile) {
    source = sourceSets.main.java.srcDirs
    include 'some/pkg/ClassTwo.java'
    classpath = sourceSets.main.compileClasspath
    destinationDir = sourceSets.main.output.classesDir
}

compileOne.options.compilerArgs = ["-sourcepath", "$projectDir/src/main/java"]
Run Code Online (Sandbox Code Playgroud)

特别注意允许所有工作的最后一行(唯一的区别).结果是它实际上会在构建时编译ClassOne和ClassTwo - 而不是仅尝试您指定的单个显式文件.任何其他类(不是必需的)仍然未编译 - 通过查看构建目录确认.

谢谢彼得!


小智 5

我尝试将 @I Stevenson 答案与gradle版本6.4.1一起使用。有一些变化让我感到惊讶,所以希望这对其他人有帮助。此任务的变化是:

destinationDir -> destinationDirectory(正在孵化)(我也遇到了类型问题)

compileOne.options.compilerArgs -> options.sourcepath这也在任务中定义

我还需要在编译中添加注释处理,因为我正在使用项目 lombok。我知道您的问题没有要求注释处理,因此我将在任务中发表评论,指出这是额外的。

apply plugin: 'java'
task compileOne (type: JavaCompile) {
    source = sourceSets.main.java.srcDirs
    include 'some/pkg/ClassTwo.java'
    classpath = sourceSets.main.compileClasspath
    destinationDirectory = new File("${buildDir}/classes/java/main") 
    options.sourcepath = sourceSets.main.java.getSourceDirectories()
    options.annotationProcessorPath = sourcesSet.main.compileClasspath//extra for lombok
}
Run Code Online (Sandbox Code Playgroud)