(UPDATED: Thanks to comments from Peter N below.)
I have a java package with several classes and therefore files within it. 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. 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. As a result I've read the documentation for JavaCompile and attempted to search for examples but seems there is very little out there. I've even posted on the gradle forums, but slow going so far.
I'm able to do what is required readily with an ant script using the ant javac task. 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).
I've created an example case with just two source files for two classes in the one package.
Both files are in a package called some.pkg and we therefore have the following directory structure:
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.
The ant script is a simple case of:
<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. 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. 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. So here is the gradle script I'm currently trying:
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?
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..
Thanks!
By default, Gradle will compile Java code to the language level of the JVM running Gradle. With the usage of Java toolchains, you can break that link by making sure a given Java version, defined by the build, is used for compilation, execution and documentation.
Thanks to the discussion with @PeterNiederwieser on the original post in the comments, I'll provide the answer here for completeness.
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. Therefore, the gradle script that now works is as follows:
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. Any other classes (that are not required) remain uncompiled - as confirmed by looking in the build directory.
Thanks Peter!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With