2012-01-30 11 views
8

Kod, nad którym pracuję, używa jaxb2-maven-plugin z org.codehaus.mojo do generowania klas Java ze schematu XSD. Poszukuję sposobu automatycznego implementowania metod dla tych klas, ale wydaje się, że nie ma sposobu. Wiem, że są inne wtyczki JAXB2 Maven, które to robią (np. Http://confluence.highsource.org/display/J2B/Home), ale zastanawiałem się, czy ktokolwiek z was napotkał ten problem wcześniej i czy jest jakiś sposób na naprawić to. Generuję klasy, używając celu xjc.Generowanie funkcji hashCode() i equals() podczas tworzenia klas Java za pomocą dodatku Mojo Jaxb2 maven plugin

Odpowiedz

12

JAXB2 Podstawowe informacje, o których wspomniałeś, nie są własnością maven-jaxb2-plugin, jest to samodzielny zestaw wtyczek JAXB 2.x, których możesz używać z XJC - lub jaxb2-maven-plugin lub czymkolwiek.

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>jaxb2-maven-plugin</artifactId> 
      <version>1.3.1</version> 
      <executions> 
       <execution> 
        <id>xjc</id> 
        <goals> 
         <goal>xjc</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <arguments> 
        <argument>-Xequals</argument> 
        <argument>-XhashCode</argument> 
       </arguments> 
      </configuration> 
      <dependencies> 
       <dependency> 
        <groupId>org.jvnet.jaxb2_commons</groupId> 
        <artifactId>jaxb2-basics</artifactId> 
        <version>0.11.1</version> 
       </dependency> 
      </dependencies> 
     </plugin> 

Co chciałem zapytać - dlaczego nie po prostu użyć maven-jaxb2-plugin? Ma znacznie więcej funkcji w porównaniu do wtyczki Codehaus - w tym obsługa konfiguracji wtyczek JAXB2.

+0

Poszedłem na to właściwie! Dzięki :) – manub

+1

Jesteś pewien, że to działa? Otrzymuję komunikat "Nie udało się wykonać celu org.codehaus.mojo: jaxb2-maven-plugin: 1.5: xjc (xjc) w projekcie XXX: nierozpoznany parametr -Xequals" OR "Nie można znaleźć artefaktu" w zależności od wersji, których używam. Jeśli chodzi o drugą wtyczkę, wszystkie linki do niej są zepsute. – ampofila

+0

@ampofila Nie, nie jestem pewien co do tego konkretnego XML, tylko że podstawa jaxb2 nie zależy od żadnej konkretnej wtyczki Maven. Korzystam tylko z wtyczki maven-jaxb2. Wtyczka jest hostowana w centralnym repozytorium Maven, więc jest z pewnością dostępna: http://mvnrepository.com/artifact/org.jvnet.jaxb2.maven2/maven-jaxb2-plugin Wznawiam serwer dokumentów. – lexicore

4

Zdecydowanie nie zgadzam się z używaniem generowanych przez JAXB klas jako obiektów biznesowych w kodzie. Klasy generowane przez JAXB to komponenty bean, które mają zasadniczo przesuwać informacje o elementach z pliku xml do pól komponentu bean. Osobiście zawsze moja usługa SOAP konwertuje te wygenerowane klasy komponentów bean do moich rzeczywistych obiektów biznesowych, ponieważ XML-> Java i odwrotnie, konwersja nie jest czarno-biała przez cały czas. Zauważ, że jest to moja osobista opinia i chciałbym, aby niektórzy inni rozważali, co robią w tej sytuacji.

Aby odpowiedzieć na twoje pytanie, użyj innej wtyczki lub po prostu użyj swojego IDE, aby uzyskać kilka równań i metod hashCode.

Nadzieję, że pomaga.

EDIT:

zapomniałem umieścić moje rozumowanie do tego, przeprosiny. Powiedzmy, że w następnej wersji twojego projektu chcesz dodać trochę więcej zachowań do wygenerowanych przez JAXB klas, ale także chcesz wprowadzić pewne zmiany w swoim schemacie. Teraz regenerujesz wygenerowane przez JAXB klasy, przywracając stare zachowania i sprawiając, że Twoja aplikacja jest bardziej podatna na błędy. Wygenerowane klasy JAXB mają odzwierciedlać typy schematów XML (a więc i komunikaty SOAP), a nie logikę biznesową. Mam nadzieję, że ma to sens.

+0

Zgadzam się z tym i mamy oddzielne obiekty biznesowe. Głównym powodem, dla którego potrzebowałbym tego, było pisanie testów jednostkowych, ale dzięki za wskazówkę! – manub

+1

manub: Możesz użyć EqualsBuilder.reflectionEquals Apache Commons Lang do porównywania wygenerowanych przez JAXB klas bez dodawania hashCode i jest równa za pomocą wtyczki Maven. –

+0

@ChrisEineke Ze wszystkimi karami wykonania refleksji. – lexicore

2

Możesz również rozważyć użycie fluent builder interface (ułatwia obsługę wygenerowanych klas JAXB) i odwołanie do pliku katalogu w przypadku, gdy odwołujesz się do schematu xmldsig-core (przyspiesza proces generowania, ponieważ nie zdalne schematy z W3C są sprawdzane - ich serwery zazwyczaj opóźniają odpowiedź).

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>jaxb2-maven-plugin</artifactId> 
      <version>1.5</version> 
      <dependencies> 
       <dependency> 
        <groupId>net.java.dev.jaxb2-commons</groupId> 
        <artifactId>jaxb-fluent-api</artifactId> 
        <version>2.0.1</version> 
        <exclusions> 
         <exclusion> 
          <groupId>com.sun.xml</groupId> 
          <artifactId>jaxb-xjc</artifactId> 
         </exclusion> 
        </exclusions> 
       </dependency> 
       <dependency> 
        <groupId>org.jvnet.jaxb2_commons</groupId> 
        <artifactId>jaxb2-basics</artifactId> 
        <version>0.6.4</version> 
        <exclusions> 
         <exclusion> 
          <groupId>com.sun.xml</groupId> 
          <artifactId>jaxb-xjc</artifactId> 
         </exclusion> 
        </exclusions> 
       </dependency> 
      </dependencies> 
      <executions> 
       <execution> 
        <goals> 
         <goal>xjc</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory> 
       <packageName>[your package name goes here]</packageName> 
       <outputDirectory>${build.directory}/generated/src/main/java</outputDirectory> 
       <bindingDirectory>${basedir}/src/main/resources/xsd</bindingDirectory> 
       <extension>true</extension> 
       <catalog>${basedir}/src/main/resources/xsd-catalog/catalog.cat</catalog> 
       <extension>true</extension> 
       <arguments>-Xfluent-api -Xequals -XhashCode -XtoString</arguments> 
      </configuration> 
     </plugin> 

Oto jak wygląda plik katalogowy:

-- 
    sample catalog file. 

    double hyphens are used to begin and end a comment section. 
-- 

SYSTEM "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" "xmldsig-core-schema.xsd" 

A oto link do xmldisg-core-schema.xsd: http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd

Zwróć uwagę, że związek nie jest zepsuty - serwer W3C po prostu opóźnia odpowiedź o kilka sekund. Czy mogę mnie bardzo uciążliwe, jeśli dzieje się to podczas procesu zautomatyzowanej kompilacji, która obejmuje generowanie JAXB.

1

Moja odpowiedź jest dla tych, którzy nie mogą sobie pozwolić na uzależnienie trzeciej części od ich wygenerowanego kodu.

Wtyczka org.jvnet.jaxb2_commons:jaxb2-basics dodaje wiele wygenerowanych kodów do org.jvnet, a projekt będzie zależał od org.jvnet.jaxb2_commons:jaxb2-basics-runtime.

Wtyczka org.andromda.thirdparty.jaxb2_commons:commons-lang-plugin generuje kod zależny od commons-lang:commons-lang. Ta zależność może być łatwiejsza do wykonania w zależności od sytuacji.

W końcu znalazłem this source code, może to być w pewnym momencie zawarte w com.sun.xml.bind:jaxb-xjc (wersja 2.2.4?), Ale do tego czasu nie widzę innego rozwiązania niż napisanie własnej wtyczki.

PS: Nie mogę uzyskać dostępu do confluence.highsource.org, otrzymuję 404. Przypuszczam, że to mogło być pomocne.

PPS: W mojej sytuacji aplikacja, którą buduję, jest skierowana do środowiska, które ma bardzo ograniczony zestaw dozwolonych bibliotek Java (niepoprawne ograniczenia zabezpieczeń). Byłem trochę zawiedziony faktem, że jaxb2_commons zawiera szereg zależności od org.jvnet w wygenerowanym źródle, tylko po to, aby dodać nudną metodę equals. Rozumiem strategię jvnet, ich narzędzia są bardzo potężne, mogę po prostu próbować i używać młota do złamania nakrętki. Mimo to przykro mi było zauważyć, że tak trudno było znaleźć odpowiednie narzędzie do mojej sytuacji.

+0

Ważne jest, aby powiedzieć, że opcja do użycia z wtyczką andromda to '-Xcommons-lang'. – logoff

2

To jest najprostszy sposób. Zaktualizuj wersję zgodnie ze swoimi wymaganiami.

<plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>jaxb2-maven-plugin</artifactId> 
        <version>1.5</version> 
        <dependencies> 
         <dependency> 
          <groupId>org.jvnet.jaxb2_commons</groupId> 
          <artifactId>jaxb2-commons-lang</artifactId> 
          <version>2.3</version> 
         </dependency> 
        </dependencies> 
        <executions> 
         <execution> 
          <id>JAXB generate content classes</id> 
          <phase>generate-sources</phase> 
          <goals> 
           <goal>xjc</goal> 
          </goals> 
          <configuration> 
           <schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory> 
           <outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory> 
           <schemaFiles>**/*.xsd</schemaFiles> 
           <packageName>com.lexus.web.content.model</packageName> 
           <arguments>-Xcommons-lang</arguments> 
          </configuration> 
         </execution> 
        </executions> 
       </plugin> 
1

Istnieje również plugin fluent-builder dla JAXB, który niekoniecznie generuje zależności od kodu strony trzeciej. Co więcej, jest to prawdziwy wzór projektowy "Builder", podczas gdy wtyczka "fluent-api" po prostu dodaje do generowanych klas nowe metody. Jest to: https://github.com/mklemm/jaxb2-rich-contract-plugin Posiada również opcje umożliwiające niezmienne generowanie wygenerowanych klas i generowanie metod kopiowania stanu istniejących obiektów do nowej instancji konstruktora, obsługując także "częściową" kopię obiektu.

Powiązane problemy