John Elion
John Elion

Reputation: 1389

Gradle plugin for XML Beans

I am trying to write a Gradle plugin for XML Beans. I have started with one of the 'Hello from Gradle' plugin examples, and also a plugin published by R. Artavia here. That plugin went straight to jar - I am trying to only generate source. The generated source must then be compiled with other project source and included in a single jar. Other goals include - full plugin - all I should need is "apply plugin: 'xmlbean'" - I can configure source/code gen location and some features if I want to - It detects whether it needs to be rebuilt. (well, eventually!!!)

I am off to a pretty good start, but am blocked defining a new sourceSet. I am getting an error "No such property 'srcDirs'" (or 'srcDir'). It seems there is something I have to define someplace to make a new sourceSet work but I cannot find it. I have tried several different syntaxes (with/without equal sign, brackets, srcDir/srcDirs, etc. - nothing is working...

What do I need to do inside a plugin to make a new sourceSet entry be properly recognized?

Thank you! JKE

File: xmlbean.gradle (includes greeting plugin for the moment for debugging)

apply plugin: xmlbean
apply plugin: 'java'

xmlbean {
  message = 'Hi'
  greeter = 'Gradle'
}

class xmlbean implements Plugin<Project> {

  void apply(Project project) {

    project.extensions.create("xmlbean", xmlbeanExtension)
    Task xmlbeanTask = project.task('xmlbean')
    xmlbeanTask << {

      project.configurations {
        xmlbeans
      }

      project.dependencies {
        xmlbeans 'org.apache.xmlbeans:xmlbeans:2.5.0'
      }

      project.sourceSets {
        main {
          java {
            srcDirs += '$project.buildDir/generated-source/xmlbeans'
          }
        }
        xmlbeans {
          srcDirs = ['src/main/xsd']
        }
      }

      ant.taskdef(name: 'xmlbean',
                  classname: 'org.apache.xmlbeans.impl.tool.XMLBean',
                  classpath: project.configurations.xmlbeans.asPath)
      ant.xmlbean(schema: project.sourceSets.xmlbean.srcDir,
                  srconly: true,
                  srcgendir: "$project.buildDir/generated-sources/xmlbeans",
                  classpath: project.configurations.xmlbeans.asPath)

      println "${project.xmlbean.message} from ${project.xmlbean.greeter}"
    }
    project.compileJava.dependsOn(xmlbeanTask)
  }
}

class xmlbeanExtension {
  String message
  String greeter
}

File: build.gradle

apply from: '../gradle/xmlbeans.gradle'

dependencies {
  compile "xalan:xalan:$ver_xalan",
          ":viz-common:0.0.1",
          ":uform-repository:0.1.0"
}

Console: Error message:

:idk:xmlbean FAILED

FAILURE: Build failed with an exception.

* Where:
Script 'C:\jdev\cpc-maven\try.g2\comotion\gradle\xmlbeans.gradle' line: 32

* What went wrong:
Execution failed for task ':idk:xmlbean'.
> No such property: srcDirs for class: org.gradle.api.internal.tasks.DefaultSourceSet_Decorated
...
BUILD FAILED

Gradle info: version 2.5 / groovy 2.3.10 / JVM 7u55 on Windows 7 AMD64

Upvotes: 0

Views: 2412

Answers (1)

Peter Ledbrook
Peter Ledbrook

Reputation: 4492

You should try to become familiar with the Gradle DSL reference guide, because it's a huge help in situations like this. For example, if you click on the sourceSets { } link in the left navigation bar, you're taken to this section on source sets.

From there, you'll discover that the sourceSets {} block is backed by a class, SourceSetContainer. The next level of configuration nested inside is backed by a SourceSet object, and then within that you have one or more SourceDirectorySet configurations. When you follow the link to SourceDirectorySet, you'll see that there are getSrcDirs() and setSrcDirs() methods.

So how does this help? If you look closely at the exception, you'll see that Gradle is saying it can't find a srcDirs property on DefaultSourceSet_Decorated, which you can hopefully infer is an instance of SourceSet. That interface does not have an srcDirs property. That's because your xmlbeans {} block is configuring a SourceSet, not a SourceDirectorySet. You need to add another nested configuration to gain access to srcDirs.

At this point, I'm wondering whether a new source set is the appropriate solution. Unfortunately it's not clear to me exactly what the plugin should be doing, so I can't offer any alternatives at this point.

Upvotes: 3

Related Questions