Il codice su cui sto lavorando utilizza jaxb2-maven-plugin
da org.codehaus.mojo
per generare classi Java dallo schema XSD. Sto cercando un modo per implementare automaticamente i metodi equals()
e hashCode()
per quelle classi, ma sembra che non ci sia un modo. So che ci sono altri plugin MAVEN JAXB2 che lo fanno (http://confluence.highsource.org/display/J2B/Home per esempio), ma mi stavo chiedendo se qualcuno di voi ha riscontrato questo problema prima e se c'è un modo per riparandolo. Sto generando le classi usando l'obiettivo xjc
.Generazione di hashCode() ed equals() durante la creazione di classi Java utilizzando il plug-in Maven di Mojo Jaxb2
risposta
JAXB2 Nozioni di base che menzioni non è una proprietà di maven-jaxb2-plugin
, è un set indipendente di plug-in JAXB 2.x che puoi utilizzare con XJC - o jaxb2-maven-plugin
o qualsiasi altra cosa.
<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>
Quello che volevo chiedere - perché non usare solo maven-jaxb2-plugin
? Ha molte più funzionalità rispetto al plugin Codehaus - incluso il supporto per la configurazione dei plugin JAXB2.
Non sarei affatto d'accordo nell'usare le classi generate da JAXB come oggetti business nel codice. Le classi generate da JAXB sono bean che hanno lo scopo di spostare essenzialmente le informazioni sugli elementi dal file xml, ai campi del bean. Personalmente ho sempre il mio servizio SOAP per convertire queste classi di bean generate ai miei oggetti di business reali, poiché XML-> Java e viceversa la conversione non è in bianco e nero tutto il tempo. Si noti che questa è la mia opinione personale e mi piacerebbe che alcuni altri valutassero ciò che fanno in questa situazione.
Per rispondere alla domanda, utilizzare un altro plug-in o semplicemente utilizzare l'IDE per eseguire alcuni metodi equals e hashCode.
Spero che questo aiuti.
EDIT:
ho dimenticato di mettere il mio ragionamento per questo, le scuse. Diciamo che nella prossima versione del tuo progetto vuoi aggiungere un po 'di comportamento alle tue classi generate da JAXB, ma vuoi anche apportare alcune modifiche allo schema. Ora stai rigenerando le classi generate da JAXB, inserendo i vecchi comportamenti e rendendo la tua applicazione molto più suscettibile ai bug a mio parere. Le classi generate da JAXB dovrebbero riflettere i tipi di schemi XML (e quindi i messaggi SOAP) non la logica aziendale. Spero che abbia un senso.
Sono d'accordo con questo e disponiamo di Business Objects separati. Il motivo principale per cui avrei bisogno è scrivere dei test unitari, ma grazie comunque per la punta! – manub
manub: è possibile utilizzare EqualsBuilder.reflectionEquals di Apache Commons Lang per confrontare le classi generate con JAXB senza aggiungere hashCode ed equals tramite un plugin Maven. –
@ChrisEineke Con tutte le penalità di riflessione delle prestazioni. – lexicore
Si potrebbe anche prendere in considerazione l'utilizzo di un fluent builder interface (facilita la gestione delle classi JAXB generate) e un riferimento a un file di catalogo nel caso si faccia riferimento a uno schema xmldsig-core (accelera il processo di generazione, come no vengono interrogati gli schemi remoti del W3C - i loro server di solito ritardano la risposta).
<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>
Ecco come il file di catalogo si presenta come:
--
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"
Ed ecco il link al xmldisg-core-schema.xsd: http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd
Si prega di notare che il link non è rotto - il server W3C sta ritardando la risposta di alcuni secondi. Posso essere molto complicato se ciò accade durante il processo di compilazione automatizzata, che include la generazione JAXB.
La mia risposta è per coloro che non possono permettersi alcuna dipendenza di terze parti dal loro codice generato.
Il plug-in org.jvnet.jaxb2_commons:jaxb2-basics aggiunge un sacco di org.jvnet
incluso nel codice generato e il progetto dipenderà da org.jvnet.jaxb2_commons:jaxb2-basics-runtime
.
Il plug-in org.andromda.thirdparty.jaxb2_commons:commons-lang-plugin genera codice che dipende da commons-lang:commons-lang
. Questa dipendenza potrebbe essere più facile da sopportare a seconda della situazione.
Alla fine ho trovato this source code, potrebbe essere incluso in com.sun.xml.bind:jaxb-xjc ad un certo punto (versione 2.2.4?), Ma fino ad allora non riesco a vedere altra soluzione che scrivere il proprio plugin.
PS: Non riesco ad accedere a confluence.highsource.org, ottengo un 404. Immagino che potrebbe essere stato utile.
PPS: nella mia situazione, l'applicazione che sto creando è destinata a un ambiente che ha un insieme molto limitato di librerie Java consentite (restrizioni di sicurezza incongrue). Sono stato un po 'deluso dal fatto che il numero jaxb2_commons
includa un gruppo di dipendenze org.jvnet
nella sorgente generata, solo per l'aggiunta di un noioso metodo equals
. Riesco a capire la strategia di jvnet, i loro strumenti sono molto potenti, potrei semplicemente provare e usare un martello per rompere un pazzo. Tuttavia, mi è dispiaciuto notare che è stato così difficile trovare uno strumento adatto alla mia situazione.
è importante dire che l'opzione da usare con il plugin andromda è '-Xcommons-lang'. – logoff
Questo è il modo più semplice di fare. Si prega di aggiornare la versione secondo le vostre esigenze.
<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>
C'è anche un plugin fluente-builder per JAXB che non necessariamente genera le dipendenze per codice di terze parti. Inoltre, è un vero modello di progettazione "Builder", mentre il plugin "fluent-api" aggiunge solo metodi di tipo builder alle classi generate. È: https://github.com/mklemm/jaxb2-rich-contract-plugin Ha anche opzioni per rendere immutabili le classi generate e può generare metodi per copiare lo stato di oggetti esistenti in una nuova istanza di builder, supportando anche la copia di oggetti "parziale".
Sono andato per davvero! Grazie :) – manub
Sei sicuro che funzioni? Ottengo "Impossibile eseguire l'obiettivo org.codehaus.mojo: jaxb2-maven-plugin: 1.5: xjc (xjc) sul progetto XXX: parametro non riconosciuto -Xequals" OPPURE "Impossibile trovare artefatto" a seconda delle versioni che utilizzo. Per quanto riguarda l'altro plugin, tutti i link verso di esso sono rotti. – ampofila
@ampofila No, non sono sicuro di questo specifico XML, solo che jaxb2-basics non dipende da alcun plugin Maven specifico. Uso solo il plugin maven-jaxb2. Il plugin è ospitato nel repository centrale di Maven quindi è sicuramente disponibile: http://mvnrepository.com/artifact/org.jvnet.jaxb2.maven2/maven-jaxb2-plugin Sto riavviando il server dei documenti. – lexicore