Build same sourceSets with different java target compatibility

I am working on converting our existing build ANT to Gradle and one place I need help is in one of the projects I have need to built for multiple java version compatibility (1.5 ad 1.8). The ANT script currently accomplish this using series of execution; first it compile the source code with 1.8 compatibility (javac target=“1.8”,source=“1.8”) put the classes in build/classes folder, then create jars and wars out of that under folder build/lib folder, then delete build/classes and then compile again the source code with 1.5 compatibility to same build/classes folder, then package jars and wars inside build/lib and so on in the same ANT file.

When I start writing conversion to Gradle, so far I am able to get things built as like as ANT. The please I am stuck is to manage build.gradle handle javaComplie again with 1.5 java compatibility. I read the discussion on Build multiple source & target compatibility in this forum (Build multiple source & target compatibility ), but that don’t help me in finalizing approach.

So fat I am organized one build.gradle per every sub project. The one I have requirement to build multiple java compatibility is actually another sub project. I guess I can have another build gradle script let’s say build_java_1.5.gradle in the same folder and invoke it to accomplish, but it looks to me an inconsistent way. So let me take it here in public forum to see how people manage such requirement in same build.gradle file.

My current script contains below snippets,

tasks.withType(JavaCompile) {
//enable compilation in a separate daemon process
//options.fork = true
options.encoding="UTF-8"
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
compileJava.options.debugOptions.debugLevel = "source,lines,vars"
compileTestJava.options.debugOptions.debugLevel = "source,lines,vars"

}

//Chamge the default source set and library location
sourceSets {
    main {
        java {
            srcDirs = ["src"]
            //outputDir = ["build"]
            libsDirName = "lib"
        }
        //We need to include selective files from src folder into the Jar
        resources {
            srcDirs = ["src"]
            //excludes = ["com/**/*"]
            includes = ["masterData/*"]
        }
    }
} 

compileJava.doFirst {
    println "JAVA_HOME : " + System.properties['java.home']
    println "Java version : " + org.gradle.internal.jvm.Jvm.current()
    println "source compatibility : " + sourceCompatibility
    println "target compatibility : " + targetCompatibility
}

And then few tasks that creates Jars and Wars.
task copyServerMigrateFiles(type: Copy) {
from("${projectDir}/src/backup.properties")
into (‘build/lib/’)
}

// Create custom jar
task createServerApiJar(type: Jar) {
    description ("Create normal jar '${tklm_server_api_jar}.jar'.")
    dependsOn 'copyCustomFiles'
    doFirst {
    	println "Processing -create_server_api_jar"
    }
...
...
...
}

task createMbeanWar(type: War) {
..
...
...
}

So far its good. Can someone help me finalizing approach to get the same sourceSets built with java 1.5 compatibility? An example of javaCompile defined multiple times in a same build.gradle would be great help.

Why do you need it built multiple times?
If it is compiled with 1.5 source and target compatibility, it should also run fine on any newer JVM.
If you really need it compiled multiple times, I’d recommend to have a separate set of tasks for that, so just declare an additional task of type JavaCompile that uses the same files as input but compiles into a different output directory and with different settings. (Two tasks should never have overlapping output directories or they disturb each others up-to-date checks, cache correctness etc.

The requirement is some of these Jars needs to be back ported to older version of product to support functionality such as migration. As you suggest, the javaCompile task I added looks working, but need some tweak. For example

task test1.5_build (type: JavaCompile) {
    
    //enable compilation in a separate daemon process
    sourceCompatibility = "1.5"
    targetCompatibility = "1.5"

    println "JAVA_HOME : " + System.properties['java.home']
    println "Java version : " + org.gradle.internal.jvm.Jvm.current()
    println "source compatibility : " + sourceCompatibility
    println "target compatibility : " + targetCompatibility
    
    //source = sourceSets.main.java.srcDirs
    source = fileTree(dir: 'src', include: [ 'abc/xyz/*','abc/xyz/*export/v2v/*'])
    
    destinationDirectory = file('build/classes/main')
    classpath = sourceSets.main.compileClasspath + 	files ('build/classes-old/java/main') //The classpath declared earlier.
}

But this prints the println statements even without calling this custom task. doFirst or doLast doesn’t seems obeying setting and printing it. That’s something I want to get rid of as during execution I like to give java source compatibility printed proper for each step.

I don’t know what you mean by “doesn’t seems obeying”.
Of course your println statements are executed always, you execute them during the configuration phase and use the eager task creation API.
If you want to execute something during execution phase, you need to do it in a doLast or doFirst block.
Only the configuration of the task should be done outside such a block and thus execute during the configuration phase.

But actually I stiil don’t understand why you don’t simply always use the files compiled with targetCompatibility 1.5 as they should run fine on any newer Java version too.