【问题标题】:Using jaxws-maven-plugin with -clientjar option使用带有 -clientjar 选项的 jaxws-maven-plugin
【发布时间】:2014-01-14 13:57:17
【问题描述】:

我正在使用 jaxws-maven-plugin 为 Web 服务使用者应用程序执行 wsimport。我在 wsimport 上使用 -clientjar 选项,该选项于 2010 年随 JAX-WS 2.2.2 RI 一起引入。我这样做是因为我想将 WSDL 捆绑到 jar 中。

我在制作 pom 时没有问题。对于插件配置,我会执行以下操作:

<configuration>
    ...
    <args>
        <arg>-clientjar</arg>
        <arg>bundled-wsdl.jar</arg>
    </args>
</configuration>

当我执行构建我创建的 jar 时,我们称它为 myapp.jar,其中包含文件 bundled-wsdl.jar。在bundled-wsdl.jar 的META-INF 目录中,我找到了我喜欢的wsdl 和xsd。我对使用-clientjar 选项生成的java 代码也很满意。到目前为止一切顺利。

但是这些东西应该在myapp.jar的META-INF中,对吧? 它位于bundled-wsdl.jar 的 META-INF 中这一事实对我没有多大帮助。

有趣的是,我确实在myapp.jar 的 META-INF 中获得了一个 wsdl 文件,它使应用程序真正工作。我不知道它是如何到达那里的。 xsd 文件也不存在,仅在bundled-wsdl.jar 的 META-INF 中。

基本问题是如何在Maven项目中正确使用wsimport -clientjar选项?

Java 1.7.0_45。

【问题讨论】:

    标签: java maven wsimport


    【解决方案1】:

    -clientjar 选项的文档记录真的很差,恕我直言。 以下是我认为它的工作原理:

    当使用-clientjar &lt;jarfile&gt; 选项时,三个会发生:

    1. 您将在指向的目录中生成一个&lt;jarfile&gt; wsimport 工具的 -d 参数。这将包含在 它包括 WSDL 和任何相关的 XSD 文件。这个小包根本不会用于任何事情。如果您想使用它,这完全取决于您。但在你看到下面的(2)之前。除了作为一种文档形式之外,我不确定该 jarfile 还能用于什么用途。
    2. 您将获得一份 WSDL 副本,放入名为 META-INF/wsdl/&lt;svcname&gt;.wsdl。生成的类将使用这个 无参数代理构造函数中的文件。所以这实际上是 如果您请求带有 -clientjar 的捆绑 WSDL 文件,则使用该文件 选项。
    3. 生成的代码将发生变化,因此wsdlLocation,如果您在@WebServiceClient 类上使用默认的无参数构造函数,将是捆绑的 WSDL(来自 (2)),而不是远程 WSDL .实际上,如果您在命令行中同时使用 -wsdllocation-clientjar,那么您使用 -wsdllocation 指定的任何内容都将无效,因为 -clientjar 将优先。

    所以我们必须关注 (2) 和 (3),因为这是唯一实际使用的...至少如果您按原样使用生成的代码。

    有趣的是,(2) 的结果只是一个 WSDL 文件。该文件可能嵌入了指向 XSD 文件的链接,但据我所知,此类链接永远不会被关注。原因是当我们说 Web 服务使用者在运行时需要 WSDL 时,它实际上只需要 WSDL 本身,而不需要模式。该模式被“硬编码”到消费者中,并且无法在运行时更改它。因此没有理由在运行时读取模式信息。 (这是我的理解)

    关于 (2) 中包含的 WSDL 需要注意的第二件事:它实际上只是原始 WSDL 的副本,因此它可能没有您想要的端点。实际上在大多数情况下不会。这意味着在这种情况下,您需要自己设置端点:

    // Use no-arg constructor. Means it uses the WSDL bundled into the 
    // META-INF/wsdl directory rather than trying to retrieve WSDL over the
    // network.
    service = new HelloSvc_Service();
    hello = service.getHelloSvcPort();
    
    // Since we're using a bundled WSDL the web service URL cannot 
    // be derived from that (it would be wrong!). So we have to set
    // it explicitly.
    ((BindingProvider) hello).getRequestContext().put(
                    BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                    "http://myhellowebservice-address");
    

    【讨论】:

      【解决方案2】:

      这个插件的文档是个笑话。一种解决方法是在创建后手动从客户端 jar 中提取内容,如下所示:

      <build>
          <plugins>
              <plugin>
                  <!--
                      Generates JAXWS classes for all of the WSDL files in $[project.base.dir}/src/wsdl.
                  -->
                  <groupId>org.jvnet.jax-ws-commons</groupId>
                  <artifactId>jaxws-maven-plugin</artifactId>
                  <version>2.3</version>
                  <executions>
                      <execution>
                          <goals>
                              <goal>wsimport</goal>
                          </goals>
                          <configuration>
                              <args>
                                  <arg>-clientjar</arg>
                                  <arg>${project.build.directory}/wsimport-client.jar</arg>
                              </args>
                              <wsdlUrls>
                                  <wsdlUrl>https://webservice.com/service.wsdl</wsdlUrl>
                              </wsdlUrls>
                          </configuration>
                      </execution>
                  </executions>
                  <configuration>
                      <target>2.1</target>
                      <verbose>true</verbose>
                  </configuration>
              </plugin>
              <plugin>
                  <!--
                      Unjar the wsimport-client.jar created in the jaxws-maven-plugin to the WAR's classes folder
                  -->
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-antrun-plugin</artifactId>
                  <version>1.7</version>
                  <executions>
                      <execution>
                          <phase>process-resources</phase>
                          <configuration>
                              <target>
                                  <unzip src="${project.build.directory}/wsimport-client.jar" dest="${project.build.directory}/classes" />
                              </target>
                          </configuration>
                          <goals>
                              <goal>run</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
      

      取自这里:https://gist.github.com/mpellegrini/5439304

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,我必须解压缩创建的 jar 并重新压缩到一个 jar 中(因此,将内部 jar 中的 wsdl 文件放入最终的 jar 中)。 感谢 peterh 的评论,我想我理解了“技巧”:在 Maven 输出中,我可以看到类似的日志

        jaxws:wsimport args: [..., <strong>-Xnocompile</strong>, -clientjar wsdl.jar, ...]

        所以wsimport 命令在没有 编译che 代码的情况下启动,实际上wsdl.jar 是在target/classes 文件夹中创建的。 我认为wsimport只是用wsdl生成源码和jar,然后编译和打包按以下步骤完成。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多