如何在没有Maven或ANT的情况下,使用JAXB插件以编程方式使用WsImport?

12

我正在使用WsImport从远程WSDL文件生成一些Java源代码。请注意,这是在常规的Scala项目内完成的,即没有在Maven或Ant构建中完成:

import com.sun.tools.ws.WsImport

def run(wsdlFile: File, destination: File, packageName: String = "generated"): Seq[File] = {        
  sys.props("javax.xml.accessExternalDTD") = "all"
  sys.props("javax.xml.accessExternalSchema") = "all"
  val xjcArgs = "" //TODO
  val args = s"-Xnocompile -XadditionalHeaders $xjcArgs -J-Djavax.xml.accessExternalDTD=all -b http://www.w3.org/2001/XMLSchema.xsd -p $packageName -s $destination $wsdlFile"
  WsImport.doMain(args.split(' '))
}

以上代码运行良好,我用它从上述Scala代码生成Java WSDL客户端程序。但是,现在我还想使用一些WsImport插件(例如这个这个):

val xjcArgs = "-B-Xequals -B-XhashCode -B-Xvalue-constructor"

我遇到了这个错误:no such JAXB option: -Xequals,尽管我已经将以下内容添加到我的类路径中:

"org.jvnet.jaxb2_commons" % "jaxb2-basics" % "1.11.1",
"org.jvnet.jaxb2_commons" % "jaxb2-value-constructor" % "3.0",

我该如何强制WsImport使用这些插件?或者除了直接使用WsImport(如ANT)之外,我可以使用其他工具吗?

尝试使用ANT

上面我使用了com.sun.tools.ws.WsImport,但还有另一个com.sun.tools.ws.ant.WsImport,我不确定该如何使用它。我尝试过这样做:

val task = new com.sun.tools.ws.ant.WsImport2()
task.setPackage(packageName)
task.setWsdl(wsdlFile.getAbsolutePath)
task.setDestdir(destination.getAbsoluteFile)
task.setGenerateJWS(true)
task.setXadditionalHeaders(true)
task.setXnocompile(true)
task.setBinding("http://www.w3.org/2001/XMLSchema.xsd")
task.execute()

上面的代码“几乎可以工作”,但我无法弄清楚如何在Ant任务中设置绑定。 wsimport需要一个-b http://www.w3.org/2001/XMLSchema.xsd,但Ant任务只接受文件作为参数 :(

2个回答

3
你能修改你的val xjcArgs,在里面包含类路径。例如:val xjcArgs = "-cp _path_ofjaxb2-basics.jar:other_plugin_jar_with_path -B-Xequals -B-XhashCode -B-Xvalue-constructor" 确保在WSImport调用中设置了类路径吗?

编辑

根据评论:这是我的ant命令。基本上,你还需要所有支持的jar。

<project name="jaxws-stack" default="wsimport">
<property name="jaxws.home" location="D:/tmp/wsimport"/>
<path id="wsimport.classpath">
    <fileset dir="${basedir}/lib">
            <include name="*.jar"/>
        </fileset>
</path>

<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport" classpathref="wsimport.classpath"/>

<target name="wsimport">
    <wsimport keep="true" verbose="true" wsdl="mywsdlurl_path">
        <xjcarg value="-Xequals"/>
        <xjcarg value="-XhashCode"/>
        <xjcarg value="-Xvalue-constructor"/>
    </wsimport>
</target>

在我的D:/tmp.wsimport目录下,我有以下的jar包:
       233,859 commons-beanutils-1.9.2.jar
       315,805 commons-lang3-3.1.jar
       293,543 commons-lang3-3.1.jar.zip
        60,686 commons-logging-1.1.1.jar
        23,205 istack-commons-runtime-2.21.jar
         7,595 istack-commons-tools-1.1.jar
        25,446 istack-commons-tools-2.21.jar
       866,992 jaxb-impl-2.1.10.jar
     3,147,690 jaxb-xjc-2.1.11.jar
       141,087 jaxb2-basics-1.11.1.jar
       166,736 jaxb2-basics-runtime-1.11.1.jar
       141,604 jaxb2-basics-tools-1.11.1.jar
         5,756 jaxb2-value-constructor-3.0.jar
     1,284,131 jaxws-rt-2.1.4.jar
       510,892 jaxws-tools-2.1.4.jar
        33,739 stax-ex-1.7.7.jar
       130,161 streambuffer-0.9.jar

只需调用Ant的默认目标,就可以获得正确的Java文件。

编辑2以支持命令行/编程调用。

.

选项1:

只调用WSImport。

"jdk_location\bin\java.exe"    -cp "lib\*" com.sun.tools.ws.WsImport -keep -verbose -B-Xequals -B-XhashCode -B-Xvalue-constructor  http://www.webservicex.com/globalweather.asmx?WSDL

选项 2

通过自定义类进行调用。

Java 类:

package test;

import com.sun.tools.ws.WsImport;

public class Test
{
    public static void main(String args []) throws Throwable
    {
        WsImport.doMain(args); 
    }
}

命令提示符调用

"jdk_location\bin\java.exe" -cp ".;lib\*" test.Test  -keep -verbose -B-Xequals -B-XhashCode -B-Xvalue-constructo
r  -Xnocompile http://www.webservicex.com/globalweather.asmx?WSDL

选项2c

这是一个自定义的Java类/方法,您可以在Scala中使用它。请确保已正确设置类路径并使用我列出的jar包。

package test;

import com.sun.tools.ws.WsImport;
public class MyWSImport {

    public static void main(String[] args) throws Throwable {

        String [] input = new String[] {"-keep",
                                "-verbose","-B-Xequals",
                                "-B-XhashCode",
                                "-B-Xvalue-constructor","-Xnocompile",
                                "http://www.webservicex.com/globalweather.asmx?WSDL"};
        WsImport.doMain(input); 

    }

    public void execute() throws Throwable
    {

        String [] input = new String[] {"-keep",
                                "-verbose","-B-Xequals",
                                "-B-XhashCode",
                                "-B-Xvalue-constructor","-Xnocompile",
                                "http://www.webservicex.com/globalweather.asmx?WSDL"};
        WsImport.doMain(input); 
    }
}

还要注意的是,我正在使用com.sun.tools.ws.WsImport,但还有另一个com.sun.tools.ws.ant.WsImport,但我不确定如何调用它。 - pathikrit
这讨论了许多 jar 包,而不仅仅是 jaxb2-basic-1.11.1.jar。http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins 您可以先尝试使用他们的 ant 文件进行验证。 - Optional
让我明天再试一次。 - Optional
@pathikrit 是的,我能够实现这个。稍后会更新答案。 - Optional
请等一下,我的问题明确说明我没有使用ANT!即使我使用了ANT,我也必须通过com.sun.tools.ws.ant.WsImport在程序中调用它。你能告诉我你是如何从Java程序中编程调用它的吗? - pathikrit
显示剩余9条评论

1

我和这个帖子的作者一样,试图从wsdl调整gradle的Java源代码生成,但是卡在了同样的僵局中。

原因是jaxb2-basics实现了com.sun.tools.xjc.Plugin,而@Optional在他的答案中指的是com.sun.tools.ws.WsImport。与此同时,“现代”的Jdk8的wsimport工具实现了com.sun.tools.internal.ws.WsImport并使用com.sun.tools.internal.xjc.Plugin。因此,jaxb2-basics在与Jdk8的wsimport一起使用时变得有点过时。

解决方案是使用替代库来提供“旧”命名空间中的WsImport。例如:com.sun.xml.ws:jaxws-tools:2.3.0。在Gradle中,它看起来像:

configurations {
  jaxws
}

dependencies {
  jaxws 'org.jvnet.jaxb2_commons:jaxb2-basics:0.11.1'
  jaxws 'com.sun.xml.ws:jaxws-tools:2.3.0'

  compile 'org.jvnet.jaxb2_commons:jaxb2-basics-runtime:0.11.1'
}

wsdlServices.each { u ->
  task "ws${u.service}" (type: JavaExec) {
    classpath = configurations.jaxws

    workingDir = generatedDir
    main = 'com.sun.tools.ws.WsImport'
    args = ['-keep', '-Xnocompile', '-B-XtoString', '-B-Xequals', '-B-XhashCode', u.url]

    compileJava.dependsOn path // depends on current task
  }
}

在命令行中,它将是这样的:

java -cp "lib/*" com.sun.tools.ws.WsImport -extension -keep -Xnocompile -B-XtoString 'http://www.webservicex.com/globalweather.asmx?WSDL'

其中 lib 包含

commons-beanutils-1.9.2.jar
commons-collections-3.2.1.jar
commons-lang3-3.2.1.jar
FastInfoset-1.2.13.jar
gmbal-api-only-3.1.0-b001.jar
ha-api-3.1.9.jar
javaparser-1.0.11.jar
javax.annotation-api-1.3.jar
javax.xml.soap-api-1.4.0.jar
jaxb2-basics-0.11.1.jar
jaxb2-basics-runtime-0.11.1.jar
jaxb2-basics-tools-0.11.1.jar
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-impl-2.3.0.jar
jaxb-jxc-2.3.0.jar
jaxb-xjc-2.3.0.jar
jaxws-api-2.3.0.jar
jaxws-rt-2.3.0.jar
jaxws-tools-2.3.0.jar
jcl-over-slf4j-1.7.7.jar
jsr181-api-1.0-MR1.jar
management-api-3.0.0-b012.jar
mimepull-1.9.7.jar
policy-2.7.2.jar
resolver-20050927.jar
saaj-impl-1.4.0.jar
slf4j-api-1.7.7.jar
stax-ex-1.7.8.jar
streambuffer-1.5.4.jar

即使用依赖项的org.jvnet.jaxb2_commons:jaxb2-basics:0.11.1com.sun.xml.ws:jaxws-tools:2.3.0


2
JAXB2-Basics并非“过时”,它只是与“内部”JAXB不兼容。请参见:https://stackoverflow.com/questions/50669567/unrecognized-parameter-xsomeplugin-error-when-using-jaxb-xjc-plugins - lexicore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接