Wsimport of multiple equal services with various unnecessary operations

Asked

Viewed 511 times

0

In Java, I am using the wsimport tool. The process works. However there are some problems.

I have to wsimport into the services of several different suppliers (all of them third parties, I have no control over them). Wsdls are almost identical, only changing the destination URL.

Each of these Wsdls define a lot of different operations/methods. It turns out that out of this lot of operations, only a couple or three I’ll really need. Almost at the end of each of these Wsdls there is this:

  <wsdl:service name="Exemplo">
    <wsdl:port name="ExemploSoap" binding="tns:ExemploSoap">
      <soap:address location="https://www.example.com/wsIntegracao/exemplo.asmx" />
    </wsdl:port>
    <wsdl:port name="ExemploSoap12" binding="tns:ExemploSoap12">
      <soap12:address location="https://www.example.com/wsIntegracao/exemplo.asmx" />
    </wsdl:port>
  </wsdl:service>

From one WSDL to another almost nothing changes. In general, the only thing that changes are these Urls that are on the stretch up there.

This is the relevant part of pom.xml. I have it for each service/WSDL different, so each of them will generate a distinct JAR (there is one pom.xml for each service, each in a separate folder).

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>wsimport</goal>
                    </goals>
                    <configuration>
                        <wsdlFiles>
                            <wsdlFile>servico-teste.wsdl</wsdlFile>
                        </wsdlFiles>
                        <wsdlLocation>servico-teste.wsdl</wsdlLocation>
                        <wsdlDirectory>${basedir}</wsdlDirectory>
                        <packageName>br.com.example.servico2</packageName>
                        <verbose>true</verbose>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
                <compilerArgs>
                    <arg>-Xlint:none</arg>
                </compilerArgs>
            </configuration>
        </plugin>

The differences between a pom.xml and others are minimal. Virtually only the package name to be generated and the WSDL file name.

As I mentioned, the process works. But this way, if I have 20 different services, 20 almost identical JAR files will be generated. If each of them has 100 classes, this will generate 2000 different classes in 20 Jars, of which only 3 or 4 I use effectively.

So I have two questions:

  1. Is there any way to optimize wsimport to need to run it only once when the services are equal or sufficiently similar, where only the URL in soap:address location range?

  2. Is there any way to instruct wsimport to generate only the classes needed for a particular part of the WSDL, and not for everything that is referenced in the WSDL?

  • @Renancarlos I rejected your issue because it didn’t seem to be improving my question at all, just adding formatting where it shouldn’t be. If you still think that your edition was valid, I would like to hear it. Anyway, I appreciate the attention and commitment.

2 answers

1

If you can generate in a single jar, you will not need to worry. I do so, have a jar only with my webservices classes.

So, all that’s common is superscript causing classes to be shared.

If you want to insist on several jars, I did some tests and it is possible, however it will be necessary some "gambiarra" to leave round.

As the link below:

https://metro.java.net/2.0/guide/Compiling_multiple_WSDLs_that_share_a_common_schema.html

You will see that if you make a Binding like mine, the shared schema will go to a specific package. In my Binding, schemas are inside the wsdls (attention).

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1">

    <bindings scd="x-schema::bons1"
        xmlns:bons1="http://www.dominio.net/services/metadata/v2.0">
        <schemaBindings>
            <package name="br.common.metada" />
        </schemaBindings>
    </bindings>

    <bindings scd="x-schema::e"
        xmlns:e="http://www.dominio.net/services/errors/v1.0">
        <schemaBindings>
            <package name="br.common.errors" />
        </schemaBindings>
    </bindings>

</bindings> 

But I haven’t found a way to not generate specific classes, so here I suggest you edit the schemas that will be shared keeping only what you want to generate, or delete the classes from the packages that you don’t want.

Then, when generating the specific classes, point to the generated Episode in xjc according to the link.

I found it very laborious, but I had already asked me this question and it was the closest that I got.

  • Hello, performing the generation by operation is something that does not exist yet, if it were by service there yes we have some plugins, I use the Apache CXF but even so it generates classes for all operations, if all its services have the same structure it could even be made to use the generated obejtos and change the endpoint and Qname, but may have other properties to change, and if one of the servants change would already break the contract, the best memso is as you spoke, all in a jar and let the automatic generation take care of everything.

  • I liked the answer. I will test tomorrow.

0


To btafarelo response helped me a lot, but it still wasn’t the ideal solution.

Also, this answer Soen’s helped me a lot, although it was not yet the complete solution.

First, I took one of the Wsdls and switched the URL there by putting a generic URL, generating the classes in Maven the same way I already did.

In Java, instead of instantiating the main class of the service to integrate using the default constructor, I started using the constructor that receives a URL and a QName. This constructor is also generated by Ws-import by default.

By invoking that constructor, as in Soen’s answer, I pass Urls that start with http://localhost/wsdl. Inside the folder META-INF, then I create a file jax-ws-catalog.xml with the following content:

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
    <system systemId="http://localhost/wsdl/servico1.wsdl" uri="wsdls/servico1.wsdl"/>
    <system systemId="http://localhost/wsdl/servico2.wsdl" uri="wsdls/servico2.wsdl"/>
    <system systemId="http://localhost/wsdl/servico3.wsdl" uri="wsdls/servico3.wsdl"/>
</catalog>

Inside a briefcase wsdls, i add the WSDL files I downloaded from each service. This folder is placed inside the JAR/WAR generated from the application. This file jax-ws-catalog.xml instructs JAX-WS to search for these Wsdls locally.

This way, I only need to use wsimport once. Finally, to reduce the number of unnecessary things generated, I can edit the generic WSDL.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.