How do I override an existing task?

I want to post process the jar file output by a jar task. I have already written a task that can do that (it moves out the output of the jar task to another file and creates a new jar in its place). However other plugins depend upon the jar task, not the new task that I defined.

Thus I would like to in effect override the jar task to post process the jar output by the jar task “in addition” to what the jar task already does. How can I do that?

As an associated question, is/are there guideline(s) that helps me decide whether I should just create a new task or should create a new plugin ? As in this case.

I was able to successfully implement what I requested help for above using

jar {

manifest { // … required by osgi plugin }

doLast() { // … my logic here … } }

However I did run into a sequencing issue. The OSGi plugin runs a post processing phase on the jar to create the manifest. However that logic gets triggered before the logic I write above. What I need is that the manifest creation logic offered by OSGi plugin be performed after, so that the manifest creation happens on the jar I create after post processing output of the jar task. How can I influence the sequence of operations here ?

For those curious - I am implementing the functionality equivalent of the maven-shade-plugin, where I create a “uber-jar” out of the jar I am building and some (not all) of the jars this project depends upon. Thus the manifest creation has to happen on the combined jar, not the initial jar.

The osgi plugin uses the bnd tool to calculate the manifest settings of the jar. You can manually configure the settings for this calculation. If the osgi plugin is applied the manifest property of the jar task points to an instance of org.gradle.api.plugins.osgi.OsgiManifest To create a osgi configuration for an “ueberjar” you might tweak the classesDir and the classpath property of OsgiManifest.

Hope this helps, regards, René

Rene,

Not sure if that is feasible. Supplying other dependency jars in the class path will make the resultant manifest treat these classes as imports, whereas I want to make them local within the jar (since I am going to combine all these into the uberjar).

I looked at the Jar task and the OSGi plugin code, and they seem to be tied at the hip to a fair extent. The jar task will take the .class files and combine them into a .jar and then run the manifest generation, the manifest generation getting influenced by the manifest configuration done by the OSGi plugin. Thus unlike in Maven, I cannot ask them to do specific things I would like to get done in specific phases. (which is how today the java, shade and osgi plugins work in my pom.xmls - by appropriately mapping their tasks on the appropriate phases).

Another option that could work is if I somehow had a placeholder to extract all the .class files I needed to combine from the various jars into the uber jar before the jar task began its work. I haven’t been able to decipher how exactly the Jar task decides what files to bundle together into the .jar, and perhaps if I had an option to tweak that that could help as well.

There’s no way to override the source of a jar task (which is an omission), but you can add to it.

jar {
  from zipTree("some.jar"), zipTree("someOther.jar")
}

You’d likely have to do a little bit more work to deal with duplicate manifest files and those sorts of things though.

You can also override an existing task with:

task jar(type: Jar, overwrite: true) {
  }
2 Likes

I was finally able to resolve the matter by combining both the uberjar creation and bundle signing following the jar task.

https://bitbucket.org/vayana/gradle-bnd-plugin/overview

There probably are cleaner are quicker ways to do it, if so my limited experience is to blame. But at least I was able to make progress and move forward.

Thanks for the help.

@Dhananjay,

@Rene’s suggestion is perfectly valid once we build the jar to include all the contents we want as described by @Luke’s firsts snippet.

In fact, that’s what we were trying to do in https://gist.github.com/69b563a83914b278e2a3 .

Let me see if I can spend some time over the weekend on the plugin you built and we might just be able to lick this.

@Gradleware, the gist above might not work as is; I polished it off as I was waiting to board a flight, so… :stuck_out_tongue:

hello, i would like to publish a jar file to artifactory. When i call artifactoryPublish, i want just to publish an already existing jar .

For that i need to override jar task not to do anything. I can do this by using -x jar . But i can’t do this because a common script will be used to call multiple projects.

If i can override jar task at one particular build.gradle file, then its okay…

I tried this.

task jar(type: Jar, overwrite: true) {

jar.archiveName=‘xyz.jar’ }

This one still builds a jar and uploads that jar.

Could some one tell me how to override jar task to not to do anything. -x jar , is not a option for me. thanks.