简体   繁体   English

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

[英]How to compile a single java file with gradle?

( UPDATED : Thanks to comments from Peter N below.) 更新:感谢下面 Peter N 的评论。)

I have a java package with several classes and therefore files within it.我有一个 java package 有几个类,因此里面有文件。 However I only want to compile one of those files initially so that I can then use it to update the other classes in the package.但是,我最初只想编译其中一个文件,以便我可以使用它来更新 package 中的其他类。 It's a factory for the other classes and as a result is dependent on them - ie.它是其他类的工厂,因此依赖于它们 - 即。 it has references to them.它有对它们的引用。

I've been attempting to use a JavaCompile gradle task to do this.我一直在尝试使用JavaCompile gradle 任务来执行此操作。 As a result I've read the documentation for JavaCompile and attempted to search for examples but seems there is very little out there.结果,我阅读了 JavaCompile 的文档并尝试搜索示例,但似乎那里几乎没有。 I've even posted on the gradle forums , but slow going so far.我什至在gradle 论坛上发帖,但到目前为止进展缓慢。

I'm able to do what is required readily with an ant script using the ant javac task.我可以使用 ant javac 任务通过 ant 脚本轻松完成所需的操作。 But I'd like to do it in gradle (and without using the ant.javac method - if I have to do that I'll just use ant).但我想在 gradle 中执行此操作(并且不使用 ant.javac 方法 - 如果我必须这样做,我将只使用 ant)。

I've created an example case with just two source files for two classes in the one package.我创建了一个示例案例,其中一个 package 中的两个类只有两个源文件。

Both files are in a package called some.pkg and we therefore have the following directory structure:这两个文件都位于名为 some.pkg 的 package 中,因此我们具有以下目录结构:

  • .\build.gradle .\build.gradle
  • .\src\main\java\some\pkg\ClassOne.java .\src\main\java\some\pkg\ClassOne.java
  • .\src\main\java\some\pkg\ClassTwo.java .\src\main\java\some\pkg\ClassTwo.java

ClassOne:一级:

package some.pkg;

import some.pkg.*;

public class ClassOne {
    public void doStuff() {
    }
}

ClassTwo:二类:

package some.pkg;

import some.pkg.*;

public class ClassTwo {
    public void ClassTwo() {
        ClassOne cone = new ClassOne();
        cone.doStuff();
    }
}

As you can see, ClassTwo (our class we want to compile standalone) depends on ClassOne.如您所见,ClassTwo(我们想要独立编译的 class)依赖于 ClassOne。

The ant script is a simple case of: 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>

But in gradle, I keep having an issue where javac (or JavaCompile task) can not find ClassOne.但是在 gradle 中,我一直遇到 javac(或 JavaCompile 任务)找不到 ClassOne 的问题。 It's as though the sourcedir is not pointing where it should - and indeed as though I was just running javac on the command line.就好像 sourcedir 没有指向它应该指向的位置——实际上就好像我只是在命令行上运行 javac 一样。 I was thinking the gradle 'JavaCompile' task's 'source' property was working like the ant 'srcdir' property, but that appears to not be the case.我在想 gradle 'JavaCompile' 任务的 'source' 属性就像 ant 'srcdir' 属性一样工作,但情况似乎并非如此。 So here is the gradle script I'm currently trying:所以这是我目前正在尝试的 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
}

But it results in:但这会导致:

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

So how do I achieve an ant javac equivalent in gradle?那么如何在 gradle 中实现 ant javac 等效项?

ant javac seems to have the smarts to go and compile all the other related classes, but I guess for gradle JavaCompile I will need to set up a sourceSet to do that.. not sure.. ant javac 似乎对 go 具有智能并编译所有其他相关类,但我想对于 gradle JavaCompile 我需要设置一个源设置。

Thanks!谢谢!

Thanks to the discussion with @PeterNiederwieser on the original post in the comments, I'll provide the answer here for completeness.感谢与@PeterNiederwieser 就评论中的原始帖子进行的讨论,为了完整起见,我将在此处提供答案。

To have gradle JavaCompile function in a manner very similar to the ant javac, you need to provide the sourcepath compiler option via the options.compilerArgs property.要以与 ant javac 非常相似的方式使用 gradle JavaCompile 函数,您需要通过options.compilerArgs属性提供sourcepath编译器选项。 Therefore, the gradle script that now works is as follows:因此,现在可以运行的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"]

Note specifically the last line (the only difference) which allows all to work.特别注意最后一行(唯一的区别),它允许所有人工作。 The result of which is that it will actually compile both ClassOne and ClassTwo at build time - rather than only attempting the single explicit file you specified.其结果是它实际上会在构建时同时编译 ClassOne 和 ClassTwo - 而不是仅尝试您指定的单个显式文件。 Any other classes (that are not required) remain uncompiled - as confirmed by looking in the build directory.任何其他类(不是必需的)保持未编译状态 - 通过查看构建目录确认。

Thanks Peter!谢谢彼得!

I tried to use @I Stevenson answer with gradle version 6.4.1 .我尝试在gradle版本6.4.1 中使用@I Stevenson 答案。 There were a couple of changes that surprised me so hopefully this helps someone else.有一些变化让我感到惊讶,所以希望这可以帮助其他人。 Changes in this task are :此任务的变化是:

destinationDir -> destinationDirectory (incubating)(I also had issue with type) destinationDir -> destinationDirectory (正在孵化)(我也遇到了类型问题)

compileOne.options.compilerArgs -> options.sourcepath this is also defined within task compileOne.options.compilerArgs -> options.sourcepath这也在任务中定义

I also needed to add annotation processing in my compilation because I am using project lombok.我还需要在我的编译中添加注释处理,因为我使用的是 lombok 项目。 I understand that your question did not ask for annotation processing so I will make a comment in the task that states that this is extra.我知道您的问题没有要求进行注释处理,因此我将在任务中发表评论,指出这是额外的。

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
}
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[0]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM