How to reference a classpathref inside of a taskdef

Hi,

I’m trying to use xdoclet-hibernate to generate some classes and I just can’t seem to figure now to make it work. From the documentation it looks like this should be easy. This is the example given in 14.1.1:

task check << {
    ant.taskdef(resource: 'checkstyletask.properties') {
        classpath {
            fileset(dir: 'libs', include: '*.jar')
        }
    }
    ant.checkstyle(config: 'checkstyle.xml') {
        fileset(dir: 'src')
    }
}

Now, they’ve actually used a fileset and I’ve tried that but it doesn’t work (I’ve tried tons of other things as well… Here’s what I have at the moment which fails telling me that fileset doesn’t support the include “attribute.”

ant.path(id: 'xdoclet.task.classpath') {
  fileset( dir: 'libs', include: '*.jar' )
}
task genHibernateClasses
{
  ant.echo(message:'Generating Hibernate Classes')
  ant.taskdef(
    name: 'xdoclet',
    classname: 'org.xdoclet.ant.XDocletTask',
    classpath: 'xdoclet.task.classpath'
  )
ant.xdoclet(
    destDir: '${buildDir}/classes',
    fileset( dir: 'src/main/java', include: '**/bl/data/dataObjects/**/*.java' )
  )
}

I’ve also tried this:

task genHibernateClasses
{
  ant.echo(message:'Generating Hibernate Classes')
  ant.taskdef(
    name: 'xdoclet',
    classname: 'org.xdoclet.ant.XDocletTask',
    classpath {
      fileset( dir: 'libs', include: '*.jar' )
    }
  )
  ant.xdoclet(
    destDir: '${buildDir}/classes',
    fileset( dir: 'src/main/java', include: '**/bl/data/dataObjects/**/*.java' )
  )
}

This fails with:

  • What went wrong: A problem occurred evaluating root project ‘ib-business-logic’. > Could not find method classpath() for arguments [build_2kt3598fqgbh33a7l94b05pi0o$_run_closure4_closure9@c2754b78] on root project ‘ib-business-logic’.

So … Is the problem the way I’m calling taskdef? I’ve see it called this way in the documetation as well… Here’s an example for an ftp task that’s in the documentation in 29.3:

task ftp << {
    ant {
        taskdef(name: 'ftp',
                classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                classpath: configurations.ftpAntTask.asPath)
        ftp(server: "ftp.apache.org", userid: "anonymous", password: "me@myorg.com") {
            fileset(dir: "htdocs/manual")
        }
    }
}

There I see the taskdef ( blah )… At first blush I thought the problem was that i needed to essentially do:

ant.taskdef() {
  name: blah
  classpath {
    fileset( dir: 'foo', include: 'bar'
  }
}

But that also doesn’t work. I’m surprised that I haven’t found another implementation of this anywhere. I thought the hibernate project itself was now on gradle so I would’ve thought that they’d have examples for this.

Any help would be greatly, greatly appreciated… I may go so far as to write a plugin for it if I can just get past my initial need here. All the documentation I find online is for the maven-xdoclet2 plugin which makes it hard to find anything else.

/geir

Several of your snippets miss the <<. The last snippet uses a different and wrong taskdef syntax. There are other syntax errors. It’s important that you understand the mechanical translation of Ant XML into Gradle code: XML attributes become named arguments, and XML subelements go into ‘{ … }’. Maybe you can give your most promising snippet and the exact problem it causes, and we can improve from there.

And to answer the question in the title, you should be able to use the reference with ‘ant.references[“xdoclet.task.classpath”]’.

So, the last snippet was just pseudo code. The point was just to show that I wanted to embed a classpath declaration as above inside of the taskdef, but that it doesn’t work.

On the note of when to use ‘<<’ and when not to … I have to admit this is a mystery to me, but I assure you I’ve tried both with and without it. Also, I have tried to look this up in the documentation, but I just haven’t found it. I’m sure it’s there, but I haven’t found it.

I would really like to know about the other syntax errors. I admit I’m new to htis, and I also admit I’m doing some experiments with this for which I’ve seen no examples. It’s not all gradle’s fault I realize. The xdoclet2 documentation didn’t list everything out either.

I’ve just tried this:

ant.path(id: 'xdoclet.task.classpath') {
  fileset( dir: 'libs', include: '*.jar' )
}
task genHibernateClasses <<
{
  ant.echo(message:'Generating Hibernate Classes')
  ant.taskdef(
    name: 'xdoclet',
    classname: 'org.xdoclet.ant.XDocletTask',
    classpathref: ant.references["xdoclet.task.classpath"]
  )
ant.xdoclet(
    destDir: '${buildDir}/classes',
    fileset( dir: 'src/main/java', include: '**/bl/data/dataObjects/**/*.java' )
  )
}

and I got this response:

FAILURE: Build failed with an exception.

  • Where: Build file ‘/opt/app/building/git/egp-portals/projects/2012-poc/src/ib-business-logic/build.gradle’ line: 71

  • What went wrong: A problem occurred evaluating root project ‘ib-business-logic’. > fileset doesn’t support the “include” attribute

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

BUILD FAILED

Is this the right approach though? Is there another way to use xdoclet to generate for hibernate? People must be doing this all the time with gradle, right?

Btw, you replied quickly and I very much appreciate it. Thanks for helping me out with this.

Actually, this is the snippet I want to work on, as it’s closest to the way I want it to work. Also, it will help me to understand the ant-mechanics you spoke about above…

task genHibernateClasses() <<
{
  ant.echo(message:'Generating Hibernate Classes')
  ant.taskdef(
    name: 'xdoclet',
    classname: 'org.xdoclet.ant.XDocletTask',
  classpath {
      fileset( dir: 'libs', include: '*.jar' )
    }
  )
  ant.xdoclet(
    destDir: '${buildDir}/classes',
    fileset( dir: 'src/main/java', include: '**/bl/data/dataObjects/**/*.java' )
  )
}

This fails with:

FAILURE: Build failed with an exception.

  • Where: Build file ‘/opt/app/building/git/egp-portals/projects/2012-poc/src/ib-business-logic/build.gradle’ line: 92

  • What went wrong: Execution failed for task ‘:genHibernateClasses’. > Could not find method classpath() for arguments [build_2kt3598fqgbh33a7l94b05pi0o$_run_closure4_closure9@3dbf3ce6] on root project ‘ib-business-logic’.

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

BUILD FAILED

So, a couple of things. I’ve seen examples of that taskdef piece and they’re all a little different. Sometimes with curly brackets sometimes without. The classpath sub element which is a sub-xmlelement I would’ve expected to be listed differently, but then I saw it close to this example in the checkstyle piece I mentioned at the top. So I’m just confused how it’s supposed to be: when do I use a ‘{’ vs a ‘(’ and so on.

Again… Thanks for all the help!

/geir

Ok … Latest attempt. I reread what you said about subelements, looked at basic ant-stuff again, looked at the maven example for xdoclet and came up with this. It’s still failing, but now it’s a new error message and it looks to be xdoclet specific. Anyway, here’s the current code block:

task genHibernateClasses() <<
{
  ant.echo(message:'Generating Hibernate Classes')
ant.taskdef( name: 'xdoclet', classname: 'org.xdoclet.ant.XDocletTask' ) {
    classpath {
      fileset( dir: 'libs' ) {
        include( name: '*.jar' )
      }
    }
  }
  ant.xdoclet {
    fileset( dir: 'src/main/java' ) {
      include( name: '**/bl/data/dataObjects/**/*.java' )
    }
    component( classname: "org.xdoclet.plugin.hibernate.HibernateMappingPlugin" ) {
      destdir: '${buildDir}/classes'
    }
  }
}

It fails now with this, and I think it’s rather generic:

[rafadm@esesslx0217 ib-business-logic]$ gradle genHibernateClasses :genHibernateClasses [ant:echo] Generating Hibernate Classes [ant:xdoclet] log4j:WARN No appenders could be found for logger (org.apache.commons.jelly.parser.XMLParser). [ant:xdoclet] log4j:WARN Please initialize the log4j system properly. [ant:xdoclet] File /opt/app/building/git/egp-portals/projects/2012-poc/src/ib-business-logic/se/ericsson/ibase/bl/data/dataObjects/CollectionArchiveRule.hbm.xml did not pass validation:

[ant:xdoclet]

Line: 15 Column: 73 [ant:xdoclet]

Message: Element type “type” must be declared.

FAILURE: Build failed with an exception.

  • Where: Build file ‘/opt/app/building/git/egp-portals/projects/2012-poc/src/ib-business-logic/build.gradle’ line: 96

  • What went wrong: Execution failed for task ‘:genHibernateClasses’. > org.generama.OutputValidationError:

Line: 15 Column: 73

Message: Element type “type” must be declared.

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

BUILD FAILED

What threw me off doing it thiw way originally was that the checkstyle example in the documentation does the fileset differently: a way that doesn’t look like ant. Does it work that way?

As for the current error message… Any chance that someone here knows enough about xdoclet and hibernate to help me out? This same code works perfectly when used with maven and the xdoclet-maven plugin.

/geir

Got it… What i’m doing is moving a bunch of other people’s code from a mixture of maven and ant to gradle and so I don’t always know what they’re doing with their code. It turns out that they had disabled validation of their mappings themselves and so i simply duplicated taht and now it works. I’m posting the final and working code snippet here for posterity:

In the libs directory I have the xdoclet pieces.

task genHibernateClasses() <<
{
  ant.echo(message:'Generating Hibernate Classes')
  ant.taskdef( name: 'xdoclet', classname: 'org.xdoclet.ant.XDocletTask' ) {
  classpath {
      fileset( dir: 'libs' ) {
        include( name: '*.jar' )
    }
    }
  }
  ant.xdoclet {
    fileset( dir: 'src/main/java' ) {
      include( name: '**/bl/data/dataObjects/**/*.java' )
    }
    component(
       classname: "org.xdoclet.plugin.hibernate.HibernateMappingPlugin",
      destdir: '${buildDir}/classes',
      validate: false
    )
  }
}

I do have a question though. I see a lot of examples where the classpath is resolved like this:

classpath: configurations.axisGenAntTask.asPath

I even did this for some wsdl generation stuff in a different project. But i’m not sure how I’d resolve all of the xdoclet requirements. I’m not finding the proper group/module pieces to include in the dependecies section as a simple providedCompile dependency. For the wsdl generation example I simply added this to dependencies:

axisGenAntTask ‘axis:axis-ant:1.4’, ‘axis:axis:1.4’

But waht is that really. It’s not a compile, testCompile, provided and so on. How does this work? I’m not sure where to find it in the documentation and I would love to clean this one last piece up so that I could reference the classpath piece through a dynamically fetched dependency. Then this would feel truly complete.

Thanks!

/geir

If you look at the Ant documentation, you’ll see that there are different ways to configure a fileset. Again, the Gradle syntax is just a mechanical translation of the Ant syntax.

The latest code snippet looks a lot better. The error doesn’t seem to be related to Gradle anymore.

If you look at the Ant documentation, you’ll see that there are different ways to configure a fileset. Again, the Gradle syntax is just a mechanical translation of the Ant syntax.

The latest code snippet looks a lot better. The error doesn’t seem to be related to Gradle anymore.

The Gradle User Guide explains all of this in detail. For build dependencies you shouldn’t use ‘compile’, ‘providedCompile’, etc. but create a custom configuration:

configurations {

wsdl // or any other name

}

dependencies {

wsdl …

}

You can then use the ‘wsdl’ configuration in the remainder of the build script, for example to pass it off to an Ant task.

I can’t tell you where to get your dependencies from. If you can’t find them in a Maven/Ivy repository, another option is to commit them to source control and add them to a configuration with the ‘files’ or ‘fileTree’ method. Again, the user guide has the details. Look for “dependency management” and “file dependencies”.

There are, but I’ve not seen that one, and if I copy that syntax it fails everytime with error messages like the ones above… Something about fileset not supporting the include attribute or something… I tried it by copying the example from the documentation and got the same error.

Please see http://ant.apache.org/manual/Types/fileset.html. The attribute is spelled ‘includes’, and the subelement is spelled ‘include’.