Gradle Deprecations


(Christian Dietrich) #1

we currently get the following warning in our build

Registering invalid inputs and outputs via TaskInputs and TaskOutputs methods has been deprecated. This is scheduled to be removed in Gradle 5.0.

the “bad” place is the following

task genSourcesManifest {
	outputs.file(sourcesManifestFile)
	doLast {
		def f = new File(sourcesManifestFile)
		f.parentFile.mkdirs()
		def writer = new PrintWriter(f)
		writer.println("Manifest-Version: 1.0")
		writer.println("Bundle-ManifestVersion: 2")
		writer.println("Bundle-SymbolicName: ${project.name}.source")
		writer.println("Bundle-Version: ${qualifiedVersion}")
		if (project.hasProperty('title'))
			writer.println("Bundle-Name: ${project.title} Sources")
		else
			writer.println("Bundle-Name: Sources")
		writer.println("Bundle-Vendor: Eclipse Xtext")
		writer.println("Eclipse-SourceBundle: ${project.name};version=\"${qualifiedVersion}\"")
		writer.close()
	}
}

sourcesJar {
	dependsOn genSourcesManifest
	inputs.file(sourcesManifestFile)
	manifest {
		from sourcesManifestFile
	}
}

how shall be change this?

(originally reported as https://github.com/eclipse/xtext/issues/1280)


(Stefan Wolf) #2

@cdietrich Thank you for reporting and sorry I didn’t follow up on the Github issue.

The registration of the file input seems file. My guess would have been that it points to the wrong file. Does the file exist when the sourcesJar task executes?
How can I reproduce the deprecation warning?
Which Gradle version are you using?

Cheers,
Stefan


(Christian Dietrich) #3

we use 4.10 and it still happens with 4.10.2
you can find it on this project:


(./gradlew clean build)
the intention is

sourcesJar {
	dependsOn genSourcesManifest
  • makes sure genSourcesManifest is executed.
  • genSourcesManifest task creates the file

(Christian Dietrich) #4

@Stefan_Wolf please let me know if you need anything else to reproduce


(Stefan Wolf) #5

I think I found the reason. Some subprojects do not contain production code and no META-INF/MANIFEST.MF file. That causes the genManifest task to be skipped since it has no sources: https://scans.gradle.com/s/xx6qgy5dahkpk/timeline?task=5l52ywrbdjnpa&taskFilter=:org.eclipse.xtend.lib.tests

Now the jar task will generate the manifest in build/tmp/jar/MANIFEST.MF, but that happens after the genManifest task executed. I think you should change the destination dir of the genManifest task to a different directory than to the default tmp dir of the jar task.

You see the problem when re-running assemble: https://scans.gradle.com/s/63aumrpecf7lq/timeline?task=7cazsglzhmre4
All the genManifest tasks run again, since the copied manifest has been replaced by the manifest generated by Gradle.

The jar task in not skipped, since it always has the manifest (generated by Gradle) to package up.

The three deprecations I saw in the build have been caused by this issue: https://scans.gradle.com/s/xx6qgy5dahkpk/deprecations?openUsages=WzBd

The inputs.file() declaration is also superfluous, since the manifest file (content) is already added as an input to the jar task automatically when using manifest.from. If it isn’t, then this would be a bug.

I changed the code in manifest-gen.gradle to make it work:

File manifestFile = project.file("$buildDir/tmp/genManifest/MANIFEST.MF")

task genManifest(type: Copy) {
	inputs.property('qualifiedVersion', qualifiedVersion)
    from "META-INF/MANIFEST.MF"
    into "$buildDir/tmp/genManifest/"
    doLast {
    	def f = manifestFile
    	def modifiedText = f.text.replace(baseVersion + '.qualifier', qualifiedVersion)
    	def writer = new PrintWriter(f)
    	writer.print(modifiedText)
    	writer.close()
    }
}

jar {
	dependsOn genManifest
	manifest {
		if (manifestFile.isFile()) {
			from manifestFile
		}
	}
}

//------------------------------------------------------
// Generate a manifest for the source bundle

def sourcesManifestFile = "$buildDir/tmp/genSourcesManifest/MANIFEST.MF"

task genSourcesManifest {
	outputs.file(sourcesManifestFile)
	inputs.property('qualifiedVersion', qualifiedVersion)
	inputs.property('projectName', project.name)
	inputs.property('projectTitle', project.findProperty('title')).optional(true)
	doLast {
		def f = new File(sourcesManifestFile)
		f.parentFile.mkdirs()
		def writer = new PrintWriter(f)
		writer.println("Manifest-Version: 1.0")
		writer.println("Bundle-ManifestVersion: 2")
		writer.println("Bundle-SymbolicName: ${project.name}.source")
		writer.println("Bundle-Version: ${qualifiedVersion}")
		if (project.hasProperty('title'))
			writer.println("Bundle-Name: ${project.title} Sources")
		else
			writer.println("Bundle-Name: Sources")
		writer.println("Bundle-Vendor: Eclipse Xtext")
		writer.println("Eclipse-SourceBundle: ${project.name};version=\"${qualifiedVersion}\"")
		writer.close()
	}
}

sourcesJar {
	dependsOn genSourcesManifest
	manifest {
		from sourcesManifestFile
	}
}

Note that the tasks are still not up-to-date on a re-run in different minutes, since the manifest contains the build time: https://scans.gradle.com/s/lwgiusildbxss/timeline?task=7cazsglzhmre4

Hope that helps,
Cheers,
Stefan


(Christian Dietrich) #6

hi @Stefan_Wolf , thanks for your help.
this does not seem to work. since the if (manifestFile.isFile()) { is false the manifest will not be added. (at least in a clean workspace, see https://github.com/eclipse/xtext-lib/tree/cd_xtext_issue1280 branch

~Christian


(Stefan Wolf) #7

Yes, you are right, the evaluation of the if condition happens to early.
Then I think we need to resort to a configure task:

task configureManifest {
	dependsOn genManifest
	doLast {
		if (manifestFile.isFile()) {
			jar.manifest {
				from manifestFile
			}
		}
	}
}

jar {
	dependsOn configureManifest, genManifest
}

Does that work?


(Christian Dietrich) #8

Hello Stefan, yes it works fine now. thanks