Foro de elhacker.net

Programación => Java => Mensaje iniciado por: K-YreX en 18 Diciembre 2020, 12:53 pm



Título: [JAXB] Generar xsd mediante schemagen
Publicado por: K-YreX en 18 Diciembre 2020, 12:53 pm
He tenido problemas para generar un schema xsd a partir de unas clases .java mediante el comando schemagen.

Tenía las siguientes clases (todas ellas en el mismo directorio . para simplificar):
Código:
ConjuntoVehiculos
Vehiculo
Furgoneta extends Vehiculo
Coche extends Vehiculo
Entonces al ejecutar:
Código:
 schemagen -d . -cp *.java -encoding utf-8
Se me generaba el schema xsd pero me aparecía el siguiente mensaje y no se incluía el elemento Coche en el schema.
Citar
ConjuntoVehiculos.java:14: error: cannot find symbol
                        @XmlElementRef(name = "Coche", type = Coche.class),
                                                                                             ^
    symbol:   class Coche
    location: class ConjuntoVehiculos
Esa anotación @XmlElementRef la tengo junto a otras dos que hacen referencia a Vehiculo y Furgoneta y estas otras no producen ningún problema. He comprobado los nombres y está todo bien escrito.

He hecho varias pruebas incluyendo los ficheros .java uno por uno y compilándolos primero (aunque por lo que he visto, schemagen debe llamar internamente a javac para compilar los ficheros fuente) pero obtenía más errores y no me generaba el schema.

Al final después de mucho probar me ha dado por compilar los ficheros .java (en el mismo directorio) y ejecutar:
Código:
schemagen -d . -cp . ConjuntoVehiculos.java -encoding utf-8
Con esto sí he conseguido generar el schema correctamente, sin errores e incluyendo todos los elementos pero no entiendo por qué ha funcionado. Es decir, no entiendo cómo funciona schemagen. He buscado en muchas webs y en todas aparece un ejemplo sencillo que funciona con el primer comando que he probado y no se explica nada más.

Espero que alguien conozca esta herramienta y pueda ayudarme. :-X

PD: Estoy utilizando schemagen 3.0.0 (recientemente descargado junto con las otras herramientas de JAXB).


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: rub'n en 18 Diciembre 2020, 19:54 pm
He tenido problemas para generar un schema xsd a partir de unas clases .java mediante el comando schemagen.

Tenía las siguientes clases (todas ellas en el mismo directorio . para simplificar):
Código:
ConjuntoVehiculos
Vehiculo
Furgoneta extends Vehiculo
Coche extends Vehiculo
Entonces al ejecutar:
Código:
 schemagen -d . -cp *.java -encoding utf-8

El el mismo directorio cual? original del proyecto? o en otra carpeta ?

He hecho varias pruebas incluyendo los ficheros .java uno por uno y compilándolos primero (aunque por lo que he visto, schemagen debe llamar internamente a javac para compilar los ficheros fuente) pero obtenía más errores y no me generaba el schema.

Tal cual doc asi mismo, es, cuando se compilan los .java estos pasan a ser .class que serán usados luego para crear los .xsd



Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: K-YreX en 19 Diciembre 2020, 00:50 am
El el mismo directorio cual? original del proyecto? o en otra carpeta ?
Para simplificarlo y no tener que lidiar con los paquetes originales del proyecto lo que hice fue copiar todos los .java en un directorio llamémoslo CodigoFuente/ y modifiqué la sentencia package y los imports de los .java (es decir, los eliminé). El directorio en el que estaba trabajando tenía la siguiente estructura:
Código:
CodigoFuente/
|_ ConjuntoVehiculos.java
|_ Vehiculo.java
|_ Coche.java
|_ Furgoneta.java
Entonces desde línea de comandos al ejecutar
Código:
C:\...\CodigoFuente>schemagen -d . -cp *.java -encoding utf-8
me generaba el fichero schema1.xsd en el directorio CodigoFuente/ pero salía en el cmd el error que cité en el otro mensaje de que no se reconocía el símbolo Coche.class y en el xsd me incluía correctamente todas las clases (como xs:element) menos la clase Coche que no aparecía.
Lo que me parece raro pues la clase Coche.java tiene prácticamente la misma estructura que Furgoneta.java (solo cambia algún atributo) y las anotaciones de ambas clases también son iguales. Me dio que pensar que quizás al pasar como argumento *.java se estuviesen compilando los ficheros en este orden:
1. Vehiculo.java -> Vehiculo.class
2. Furgoneta.java -> Furgoneta.class
3. ConjuntoVehiculos.java -> ConjuntoVehiculos.class
4. Coche.java -> Coche.class
Y quizás por eso al compilar ConjuntoVehiculos.java no se reconoce el símbolo Coche.class (porque todavía no existe).

Tal cual doc asi mismo, es, cuando compila los .java estos pasan a ser .class que sera usados luego para crear los .xsd
Respecto a esto, noté que aunque schemagen compile los .java en .class, estos no aparecen en el directorio en el que se está trabajando (CodigoFuente/ en este supuesto). Por eso intenté compilarlos yo y tras varios intentos vi que la única forma en que funcionaba es teniendo todos los ficheros compilados ya y pasar a schemagen únicamente el .java que contiene a los demás. Es decir, teniendo:
Código:
CodigoFuente/
|_ ConjuntoVehiculos.java
|_ ConjuntoVehiculos.class
|_ Vehiculo.java
|_ Vehiculo.class
|_ Coche.java
|_ Coche.class
|_ Furgoneta.java
|_ Furgoneta.class
Y ejecutando:
Código:
C:\...\CodigoFuente>schemagen -d . -cp ConjuntoVehiculos.java -encoding utf-8
Por lo tanto no entiendo cuándo es necesario compilar los .java a .class antes de ejecutar schemagen y qué argumentos hay que pasarle a schemagen con la opción -cp. :huh:

PD: Gracias por responder. Siendo un tema tan raro ya pensaba que no iba a tener respuestas.  :-X


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: rub'n en 19 Diciembre 2020, 13:13 pm
Y tu clases java como están?

Como usas la anotacion @XmlRootElement ?


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: K-YreX en 19 Diciembre 2020, 13:47 pm
Fichero ConjuntoVehiculos.java
Código
  1. @XmlRootElement(name = "vehiculos")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class ConjuntoVehiculos {
  4.  @XmlElementRefs({
  5.    @XmlElementRef(name = "Vehiculo", type = Vehiculo.class),
  6.    @XmlElementRef(name = "Coche", type = Coche.class),
  7.    @XmlElementRef(name = "Furgoneta", type = Furgoneta.class)
  8.  })
  9.  private ArrayList<Vehiculo> vehiculos;
  10.  //...
  11. }

Fichero Vehiculo.java
Código
  1. @XmlRootElement(name = "Vehiculo")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Vehiculo implements Serializable {
  4.  //...
  5. }

Fichero Coche.java
Código
  1. @XmlRootElement(name = "Coche")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Coche extends Vehiculo {
  4.  //...
  5. }

Fichero Furgoneta.java
Código
  1. @XmlRootElement(name = "Furgoneta")
  2. @XmlAccessorType(XmlAccessType.FIELD)
  3. public class Furgoneta extends Vehiculo {
  4.  //...
  5. }

Y el schema xsd que quiero obtener es:
Código
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  3.  
  4.  <xs:element name="Coche" type="coche"/>
  5.  
  6.  <xs:element name="Furgoneta" type="furgoneta"/>
  7.  
  8.  <xs:element name="Vehiculo" type="vehiculo"/>
  9.  
  10.  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>
  11.  
  12.  <xs:complexType name="conjuntoVehiculos">
  13.    <xs:sequence>
  14.      <xs:choice minOccurs="0" maxOccurs="unbounded">
  15.        <xs:element ref="Vehiculo"/>
  16.        <xs:element ref="Coche"/>
  17.        <xs:element ref="Furgoneta"/>
  18.      </xs:choice>
  19.    </xs:sequence>
  20.  </xs:complexType>
  21.  
  22.  <xs:complexType name="vehiculo"><!-- ... --></xs:complexType>
  23.  
  24.  <xs:complexType name="coche"><!-- ... --></xs:complexType>
  25.  
  26.  <xs:complexType name="furgoneta"><!-- ... --></xs:complexType>
  27. </xs:schema>

Pero como no reconoce la clase Coche.class, me genera el siguiente xsd:
Código
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  3.  
  4.  <xs:element name="Furgoneta" type="furgoneta"/>
  5.  
  6.  <xs:element name="Vehiculo" type="vehiculo"/>
  7.  
  8.  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>
  9.  
  10.  <xs:complexType name="conjuntoVehiculos">
  11.    <xs:sequence>
  12.      <xs:choice minOccurs="0" maxOccurs="unbounded">
  13.        <xs:element ref="Vehiculo"/>
  14.        <xs:element ref="Furgoneta"/>
  15.      </xs:choice>
  16.    </xs:sequence>
  17.  </xs:complexType>
  18.  
  19.  <xs:complexType name="vehiculo"><!-- ... --></xs:complexType>
  20.  
  21.  <xs:complexType name="furgoneta"><!-- ... --></xs:complexType>
  22. </xs:schema>


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: rub'n en 21 Diciembre 2020, 18:02 pm
que tal doc? que es la que hay?

quitale el
Código
  1. @XmlRootElement
a las superclases y avisa que tal... o sea a la superclase Vehiculo


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: K-YreX en 22 Diciembre 2020, 01:17 am
que tal doc? que es la que hay?

quitale el
Código
  1. @XmlRootElement
a las superclases y avisa que tal... o sea a la superclase Vehiculo
He probado el cambio que comentas y el resultado sigue sin ser satisfactorio. El error que aparecía sigue apareciendo y además ahora tampoco aparece el elemento Vehiculo en el xsd.
El resultado es el siguiente:
Código
  1.  <xs:element name="Furgoneta" type="furgoneta"/>
  2.  
  3.  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>
  4.  
  5.  <xs:complexType name="conjuntoVehiculos">
  6.    <xs:sequence>
  7.        <xs:element ref="Furgoneta" minOccurs="0" maxOccurs="unbounded"/>
  8.    </xs:sequence>
  9.  </xs:complexType>
  10.  
  11.  <!-- ... -->


Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: rub'n en 22 Diciembre 2020, 09:04 am
He probado el cambio que comentas y el resultado sigue sin ser satisfactorio. El error que aparecía sigue apareciendo y además ahora tampoco aparece el elemento Vehiculo en el xsd.
El resultado es el siguiente:
Código
  1.  <xs:element name="Furgoneta" type="furgoneta"/>
  2.  
  3.  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>
  4.  
  5.  <xs:complexType name="conjuntoVehiculos">
  6.    <xs:sequence>
  7.        <xs:element ref="Furgoneta" minOccurs="0" maxOccurs="unbounded"/>
  8.    </xs:sequence>
  9.  </xs:complexType>
  10.  
  11.  <!-- ... -->

Mmmm, bueno, mejor probare eso tambien, sin hablar tanto, ando con chamba bastante. si logras resolver antes genial.