5

My company recently wrote gradle plugin for vanilla configuration (repositories, common dependencies across projects, etc). Overall, this has greatly simplified our build process and uncovered a few inconsistencies across projects. We recently tried to add a sourcesJar task to the plugin and it's not working.

Here's the broken plugin:

package com.mycompany.plugins

import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.tasks.bundling.Jar

class OurJavaPlugin implements Plugin<Project> {

    void apply(Project project) {

        def date = com.mycompany.util.UtilityFunctions.getDate()

        project.configure(project) {
            println('Applying Java properties to: ' + project.name)

            apply plugin: 'java'
            apply plugin: 'maven'
            apply plugin: 'idea'
            apply plugin: 'eclipse'

            version = date

            // Use the local repos
            repositories {
                maven {
                    url "$externalDependenciesRepo"
                }
                maven {
                    url "$internalDependenciesRepo"
                }
            }

            uploadArchives {
                repositories {
                    mavenDeployer {
                        // Deploy to internal repo
                        repository(url: "$internalDependenciesRepo")
                    }
                }
            }

            // Common dependencies
            dependencies {
                compile group: 'log4j', name: 'log4j', version:'1.2.17'
                compile group: 'org.slf4j', name: 'slf4j-log4j12', version:'1.6.6'
                compile group: 'org.slf4j', name: 'slf4j-api', version:'1.6.6'
                testCompile "junit:junit:$junit_version"
            }

            eclipse.project {
              natures 'org.springsource.ide.eclipse.gradle.core.nature'
            }

            task sourcesJar(type: Jar, dependsOn: classes) {
                classifier = 'sources'
                from sourceSets.main.allSource
            }

            artifacts {
                archives sourcesJar
            }
        }
    }
}

This plugin works great, except for the sourcesJar. When I add that into the mix (and compile/deploy to our local repo) I get this error when I try to build a project that uses the plugin:

$ gradle :myProject:clean -x Test
Applying Java properties to: myProject

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\me\Documents\code\root\myProject\build.gradle' line: 1

* What went wrong:
A problem occurred evaluating project ':myProject'.
> Failed to apply plugin [id 'customjava']
   > Could not find method sourcesJar() for arguments [{type=class org.gradle.api.tasks.bundling.Jar, dependsOn=task ':analytics-isr:classes'}, com.mycompany.plugins.OurJavaPlugin $_apply_closure1$_closure6@4c1d59cd] on project ':myProject'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.352 secs
Opal
  • 81,889
  • 28
  • 189
  • 210
fbl
  • 2,840
  • 3
  • 33
  • 41
  • Isn't it working when you add the code as is? What's happening? – Opal Jun 17 '16 at 06:23
  • if I put the code inside the .configure if gives me an error. I will update with the error as soon as I can. – fbl Jun 17 '16 at 15:40
  • I updated the question to include the error messages – fbl Jun 28 '16 at 15:00
  • Could you please grant me the bounty you offered? It does not happen automatically :) – Opal Jul 04 '16 at 15:01
  • 1
    Sorry, was out of town by the time SO would allow me to grant it. +200 to you, and a heartfelt "Thanks!" from my team. – fbl Jul 05 '16 at 15:29

1 Answers1

6

When you define a task in build.gradle script one (out of 4) of task method is called - you can see the first one here. As you can also see none of these methods matches the DSL - with which - you define a task in build.gradle. Why? Because before execution every build.gradle is evaluated to translate the DSL to appropriate methods invocations. For further details please have a look at this question.

The mentioned mechanism does not work in a custom plugin - here the code is interpreted as is without translating it. As you can see here there's no sourcesJar method defined on Project class. To create a task inside a plugin you need to invoke on of the mentioned task methods, e.g.:

task('sourcesJar', type: Jar, dependsOn: classes) {
   classifier = 'sources'
   from sourceSets.main.allSource
}

which invokes exactly this method (I know the arguments order is different but this is how groovy works - trust me).

Also you don't need project.configure(project) {...}, project.with {...} will be enough.

tschumann
  • 2,776
  • 3
  • 26
  • 42
Opal
  • 81,889
  • 28
  • 189
  • 210