web-dev-qa-db-fra.com

Comment utiliser une personnalisation de classe pour résoudre les conflits générant des fichiers

J'essaie d'utiliser Maven pour générer des fichiers JAXB à utiliser par le framework Spring, mais Maven affiche les erreurs suivantes:

Je comprends qu'il ne peut pas générer de fichiers avec les noms, mais je ne sais pas comment résoudre le problème. Jusqu'à présent, j'ai visité les liens suivants. 1 , 2 ,

org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 5; columnNumber: 39; A class/interface with the same name "hello.wsdl.SearchFlights" is already in use. Use a class customization to resolve this conflict.
....
org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 12; columnNumber: 43; (Relevant to above error) another "SearchFlights" is generated from here.
....
org.xml.sax.SAXParseException; systemId: http://www5v80.elsyarres.net/service.asmx?wsdl; lineNumber: 371; columnNumber: 42; A class/interface with the same name "hello.wsdl.GetFlightDetails" is already in use. Use a class customization to resolve this conflict.
....

Plugin Maven

    <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.12.3</version>
        <executions>
            <execution>
                <goals>
                    <goal>generate</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <schemaLanguage>WSDL</schemaLanguage>
            <generatePackage>hello.wsdl</generatePackage>
            <schemas>
                <schema>
                    <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
                </schema>
            </schemas>
        </configuration>
    </plugin>

J'ai ajouté ce qui suit package-info.Java fichier dans le hello.wsdl package mais cela n'a pas aidé.

@XmlSchema( 
    namespace = "ElsyArres.API",
    elementFormDefault = XmlNsForm.QUALIFIED) 
package hello.wsdl;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
13
Daniel Newtown

Le message d'erreur que vous rencontrez indique essentiellement que certains noms dans la section types de votre wsdl sont utilisés deux fois. Dans votre cas tous <element>tags ont le même nom que leurs types correspondants (définis comme <complexType>).

Exemple:

  <s:element name="SearchFlights">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="SoapMessage" type="tns:SearchFlights" />
      </s:sequence>
    </s:complexType>
  </s:element>

  <s:complexType name="SearchFlights">
    <s:complexContent mixed="false">
      <s:extension base="tns:SoapMessageBase">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Request" type="tns:SearchFlightsRequest" />
          <s:element minOccurs="0" maxOccurs="1" name="Response" type="tns:SearchFlightsResponse" />
        </s:sequence>
      </s:extension>
    </s:complexContent>
  </s:complexType>

C'est assez rare.

Il existe essentiellement deux options pour résoudre ces problèmes:

Utilisez autoNameResolution

 <plugin>
     <groupId>org.jvnet.jaxb2.maven2</groupId>
     <artifactId>maven-jaxb2-plugin</artifactId>
     <version>0.13.1</version>
     <executions>
         <execution>
             <goals>
                 <goal>generate</goal>
             </goals>
         </execution>
     </executions>
     <configuration>

         <args>
             <arg>-XautoNameResolution</arg>
         </args>

         <schemaLanguage>WSDL</schemaLanguage>
         <generatePackage>hello.wsdl</generatePackage>
         <schemas>
             <schema>
                 <url>http://www5v80.elsyarres.net/service.asmx?wsdl</url>
             </schema>
          </schemas>
      </configuration>
  </plugin>

Le plugin résoudra tous les conflits de noms en ajoutant des numéros à chaque nom entrant en collision. Dans le cas mentionné ci-dessus de SearchFlights cela entraînera la génération de SearchFlights et SearchFlights2.

Une meilleure façon serait d'utiliser un fichier de liaison pour résoudre tous les conflits de noms à l'avance. Les fichiers de liaison contiennent principalement des règles d'expression et de transformation XPATH. Un fichier de liaison qui s'ajoute à chaque nom des déclarations est le suivant:

<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings wsdlLocation="http://www5v80.elsyarres.net/service.asmx?wsdl"
            xmlns:jaxws="http://Java.Sun.com/xml/ns/jaxws"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
            xmlns:jaxb="http://Java.Sun.com/xml/ns/jaxb" version="2.1"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='ElsyArres.API']">
        <jaxb:schemaBindings>
            <jaxb:nameXmlTransform>
                <jaxb:elementName suffix="Elem"/>
            </jaxb:nameXmlTransform>
        </jaxb:schemaBindings>
    </jaxws:bindings>
</jaxws:bindings>

Il existe d'autres options pour jaxb:nameXmlTransform comme des suffixes et précédant d'autres types d'éléments xml (comme des types).

Malheureusement, je n'ai pas pu travailler sur ce fichier de liaison avec le org.jvnet.jaxb2.maven2:maven-jaxb2-plugin (mais je suis sûr qu'il y a une configuration qui fonctionne)

Il fonctionne néanmoins avec le org.codehaus.mojo:jaxws-maven-plugin et la configuration suivante.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.4.1</version>
    <executions>
        <execution>
            <goals>
                <goal>wsimport</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <bindingFiles>
         <bindingFile>${basedir}/src/main/resources/bindings.xjb</bindingFile>
        </bindingFiles>
        <wsdlUrls>
            <wsdlUrl>http://www5v80.elsyarres.net/service.asmx?wsdl</wsdlUrl>
        </wsdlUrls>
        <vmArgs>
            <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
        </vmArgs>
    </configuration>
</plugin>
33
jah

Si le correctif autoNameResolution

 <args>
     <arg>-XautoNameResolution</arg>
 </args>

ne fonctionne pas, essayez:

 <args>
     <arg>-B-XautoNameResolution</arg>
 </args>
11
trunkc

Suppression de <generatePackage></generatePackage> tag résout le problème.

Cependant, la conséquence de cette suppression est que vos packages seront créés à partir de l'espace de noms xml. Par exemple, l'espace de noms example.com/xyz se traduira par le package com.example.xyz

10
Hamid Mohayeji

La suppression de generatePackage comme le mentionne hamid-mohayeji corrige de nombreux cas (au moins les cas où vos xsds sont sensés). Le paramètre essaie de mettre toutes les entités dans le même espace de noms et cela risque de mal tourner dans les cas non simples. Cependant, l'omission du package vous laisse des packages créés à partir de l'espace de noms. Par exemple http://www.co.com/srvc/api/common deviendrait package com.co.srvc.api.common .

Cela peut être résolu en ajoutant un fichier de liaison simple. Configurer <bindingDirectory>src/main/resources/bindings</bindingDirectory> dans le pom et ajoutez un fichier de liaison quelque chose.xjb au répertoire de liaison. Ici, vous devez vous référer à l'individu relativement à ce fichier.

Ce fichier définit individuellement les packages pour chaque fichier xsd:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://Java.Sun.com/xml/ns/jaxb" jaxb:version="2.0">

    <jaxb:bindings schemaLocation="../schemas/common.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.mycomp.myapp.co.common" />
        </jaxb:schemaBindings>
    </jaxb:bindings>

    ... more bindings

</jaxb:bindings>
3
thoredge