【问题标题】:How to compile multiple xsd files in Gradle JAXB/XJC?如何在 Gradle JAXB/XJC 中编译多个 xsd 文件?
【发布时间】:2017-01-20 12:50:34
【问题描述】:

我对 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
}

【问题讨论】:

    标签: ant jaxb gradle schema xjc


    【解决方案1】:

    我自己解决了。这是可行的解决方案。

    //  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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
    }
    

    【讨论】:

    • 分享是关怀,感谢您的回答。但我收到Execution failed for task ':jaxb'. > class com.sun.tools.xjc.XJC2Task doesn't support the nested "$" element.。有什么想法吗?
    • 是的。我也一样。
    • 好的,所以使用上面的第二个来避免“$”问题......而是陷入 java.lang.NoClassDefFoundError: com/sun/xml/bind/api/ErrorListener 问题. :-/ 这一点,再加上缺乏对目录文件的支持,使得 Gradle(以及 Groovy)对于我们的目的几乎毫无用处。我的意思是嘘。什么样的构建工具连对 XML 的成熟稳定支持都没有??
    • 不需要用 ${} 包装 schemaDir。您可以将其删除或简单地将路径保留为字符串
    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    这是另一个工作示例。我把我的 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'
    }
    

    【讨论】:

    • 这行得通,但我有一个问题你没有。我的挂起是因为我的一个名称空间的 URL 就是这样。 ......当然它不存在。此构建的旧 maven 变体使用目录来重写它。问题是我不知道在哪里插入它。我已经尝试了几个地方。虽然这是一个属性。 jaxb.java.net/nonav/2.0.2/docs/xjcTask.html
    【解决方案4】:

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

    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" ]
                }
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多