如何在Gradle JAXB / XJC中编译多个xsd文件?

时间:2014-05-12 21:29:19

标签: ant jaxb gradle schema xjc

我对Gradle相当新,我在尝试使用Gradle Ant XJC编译多个模式文件时遇到了一些问题。

使用以下代码,我能够成功编译1个模式。但是,我不确定如何对多个模式文件执行相同操作。

请问任何建议?

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Task : XJC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
final def packageName = "org.test.webservice.domain"
final def schemaFile = "misc/resources/schemas/employee-v3/wadl/employee.xsd"

configurations { provided }
project.ext.generatedSrcDir = file("$buildDir/generated-src")
dependencies {
    provided 'com.sun.xml.bind:jaxb-impl:2.2.6'
    provided 'com.sun.xml.bind:jaxb-xjc:2.2.6'
}
task jaxb {
    println 'Starting JAXB XJC...'
    ext {
        packagePath = packageName.replaceAll("\\.", "/")
        srcFile = file(schemaFile)
        destDir = new File(project.ext.generatedSrcDir, packagePath)
    }

    inputs.file srcFile
    outputs.dir destDir
    project.ext.generatedSrcDir.mkdirs()
    ant.taskdef(name: 'xjc',
            classname: 'com.sun.tools.xjc.XJCTask',
            classpath: configurations.provided.asPath)

    doLast {
        project.ext.generatedSrcDir.mkdirs()
        ant.xjc(schema: srcFile, package: packageName,
                destdir: project.ext.generatedSrcDir)
    }

    task generateSources() {}
    sourceSets.main.java.srcDirs += project.ext.generatedSrcDir
    generateSources.dependsOn jaxb
    compileJava.dependsOn generateSources
    eclipseClasspath.dependsOn generateSources
//    ideaClasspath.dependsOn generateSources
}

4 个答案:

答案 0 :(得分:4)

我自己解决了。这是工作解决方案。

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Task : XJC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
final def packageName = "org.test.webservice.domain"
final def schemaDir = "misc/resources/schemas/employee-sda-v3/wadl"

configurations { provided }
project.ext.generatedSrcDir = file("$buildDir/generated-src")
dependencies {
    provided 'com.sun.xml.bind:jaxb-impl:2.2.6'
    provided 'com.sun.xml.bind:jaxb-xjc:2.2.6'
}
task jaxb {
    println 'Starting JAXB XJC...'
    ext {
        packagePath = packageName.replaceAll("\\.", "/")
        destDir = new File(project.ext.generatedSrcDir, packagePath)
    }

    outputs.dir destDir
    project.ext.generatedSrcDir.mkdirs()
    ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.provided.asPath)

    doLast {
        project.ext.generatedSrcDir.mkdirs()
        ant.xjc(package: packageName, destdir: project.ext.generatedSrcDir){
            schema(dir: ${schemaDir}, includes: "**/*.xsd")
        }
    }

    task generateSources() {}
    sourceSets.main.java.srcDirs += project.ext.generatedSrcDir
    generateSources.dependsOn jaxb
    compileJava.dependsOn generateSources
    eclipseClasspath.dependsOn generateSources
//    ideaClasspath.dependsOn generateSources
}

答案 1 :(得分:2)

jacobono's gradle-jaxb-plugin编译输入目录中的所有模式。 我觉得这个插件比Ant XJC更稳定。在我的项目中,在某些机器上,Ant XJC不会无缘无故地生成类,尽管结果是成功的。也许这是配置的问题,但恕我直言,甚至设置更容易与插件。

答案 2 :(得分:2)

这是另一个工作示例。我把build.gradle文件的完整版本。 您可以在xjc内部的架构上设置目录并包含过滤器。 如果你有嵌套" $"元素不受支持'像上面的错误,然后在我的例子下面将有所帮助

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

sourceCompatibility = 1.8
targetCompatibility = 1.8

task genJaxb {
    ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
    ext.classesDir = "${buildDir}/classes/jaxb"
    ext.schemaDir = "${projectDir}/src/main/resources"

    outputs.dir classesDir

    doLast() {
        project.ant {
            taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
                    classpath: configurations.jaxb.asPath
            mkdir(dir: sourcesDir)
            mkdir(dir: classesDir)

            xjc(destdir: sourcesDir) {
                schema(dir: schemaDir, includes: "**/*.xsd")
                arg(value: "-wsdl")
                produces(dir: sourcesDir, includes: "**/*.java")
            }

            javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true,
                    debugLevel: "lines,vars,source",
                    classpath: configurations.jaxb.asPath,
                    includeantruntime: "false") {
                src(path: sourcesDir)
                include(name: "**/*.java")
                include(name: "*.java")
            }

            copy(todir: classesDir) {
                fileset(dir: sourcesDir, erroronmissingdir: false) {
                    exclude(name: "**/*.java")
                }
            }
        }
    }
}

jar {
    baseName = 'myProject'
    version = '0.0.1'
    from genJaxb.classesDir
}

repositories {
    mavenLocal()
    mavenCentral()
}

configurations {
    jaxb
}

dependencies {
    compile("com.google.code.gson:gson:2.3",
            "commons-lang:commons-lang:2.6",
            "commons-collections:commons-collections:3.2.1",
            "commons-codec:commons-codec:1.10",
            "commons-io:commons-io:2.4",
            "org.springframework.ws:spring-ws-core:2.2.1.RELEASE"
            )
    compile("wsdl4j:wsdl4j:1.6.1")
    jaxb("com.sun.xml.bind:jaxb-xjc:2.2.4-1")
    compile(files(genJaxb.classesDir).builtBy(genJaxb))
    testCompile("junit:junit",
                "org.powermock:powermock-api-mockito:1.6.2",
                "org.powermock:powermock-module-junit4:1.6.2",
                )
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

答案 3 :(得分:2)

这可能是没有任何外部插件的最简单的解决方案。 它有任何其他影响吗?

task prepareXSD2Java{

    def xsdSourceDir = xsdPackageName.replace(".","/")

    FileTree xsdFilesTree = fileTree(dir: "$projectResourceDir/$xsdSourceDir")
    xsdFilesTree.include '*.xsd'


    doLast{
        xsdFilesTree.getFiles().each {
            File xsdFile -> 
            def xsdPackageExt = xsdFile.name.replace("-","_")
            xsdPackageExt = xsdPackageExt.take(xsdPackageExt.lastIndexOf("."))
            String xsdFileName = xsdFile.getAbsolutePath();

            exec {
                executable = "xjc"
                args = [ "-d", "$projectSourceDir", "-p", 
                       "$xsdPackageName.$xsdPackageExt", "$xsdFileName" ]
            }
        }
    }

}