Test Foro de elhacker.net SMF 2.1

Programación => Programación General => 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):

ConjuntoVehiculos
Vehiculo
Furgoneta extends Vehiculo
Coche extends Vehiculo

Entonces al ejecutar:
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:
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
Cita de: 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):

ConjuntoVehiculos
Vehiculo
Furgoneta extends Vehiculo
Coche extends Vehiculo

Entonces al ejecutar:
schemagen -d . -cp *.java -encoding utf-8

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

Cita de: K-YreX en 18 Diciembre 2020, 12:53 PM
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
Cita de: rub'n en 18 Diciembre 2020, 19:54 PM
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:

CodigoFuente/
|_ ConjuntoVehiculos.java
|_ Vehiculo.java
|_ Coche.java
|_ Furgoneta.java

Entonces desde línea de comandos al ejecutar

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).

Cita de: rub'n en 18 Diciembre 2020, 19:54 PM
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:

CodigoFuente/
|_ ConjuntoVehiculos.java
|_ ConjuntoVehiculos.class
|_ Vehiculo.java
|_ Vehiculo.class
|_ Coche.java
|_ Coche.class
|_ Furgoneta.java
|_ Furgoneta.class

Y ejecutando:
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 (java) [Seleccionar]

@XmlRootElement(name = "vehiculos")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConjuntoVehiculos {
  @XmlElementRefs({
    @XmlElementRef(name = "Vehiculo", type = Vehiculo.class),
    @XmlElementRef(name = "Coche", type = Coche.class),
    @XmlElementRef(name = "Furgoneta", type = Furgoneta.class)
  })
  private ArrayList<Vehiculo> vehiculos;
  //...
}


Fichero Vehiculo.java
Código (java) [Seleccionar]

@XmlRootElement(name = "Vehiculo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Vehiculo implements Serializable {
  //...
}


Fichero Coche.java
Código (java) [Seleccionar]

@XmlRootElement(name = "Coche")
@XmlAccessorType(XmlAccessType.FIELD)
public class Coche extends Vehiculo {
  //...
}


Fichero Furgoneta.java
Código (java) [Seleccionar]

@XmlRootElement(name = "Furgoneta")
@XmlAccessorType(XmlAccessType.FIELD)
public class Furgoneta extends Vehiculo {
  //...
}


Y el schema xsd que quiero obtener es:
Código (xml) [Seleccionar]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Coche" type="coche"/>

  <xs:element name="Furgoneta" type="furgoneta"/>

  <xs:element name="Vehiculo" type="vehiculo"/>

  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>

  <xs:complexType name="conjuntoVehiculos">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Vehiculo"/>
        <xs:element ref="Coche"/>
        <xs:element ref="Furgoneta"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="vehiculo"><!-- ... --></xs:complexType>
 
  <xs:complexType name="coche"><!-- ... --></xs:complexType>

  <xs:complexType name="furgoneta"><!-- ... --></xs:complexType>
</xs:schema>


Pero como no reconoce la clase Coche.class, me genera el siguiente xsd:
Código (xml) [Seleccionar]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Furgoneta" type="furgoneta"/>

  <xs:element name="Vehiculo" type="vehiculo"/>

  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>

  <xs:complexType name="conjuntoVehiculos">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Vehiculo"/>
        <xs:element ref="Furgoneta"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="vehiculo"><!-- ... --></xs:complexType>

  <xs:complexType name="furgoneta"><!-- ... --></xs:complexType>
</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 (java) [Seleccionar]
@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
Cita de: rub'n en 21 Diciembre 2020, 18:02 PM
que tal doc? que es la que hay?

quitale el
Código (java) [Seleccionar]
@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 (xml) [Seleccionar]

  <xs:element name="Furgoneta" type="furgoneta"/>

  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>

  <xs:complexType name="conjuntoVehiculos">
    <xs:sequence>
        <xs:element ref="Furgoneta" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- ... -->
Título: Re: [JAXB] Generar xsd mediante schemagen
Publicado por: rub'n en 22 Diciembre 2020, 09:04 AM
Cita de: K-YreX en 22 Diciembre 2020, 01:17 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 (xml) [Seleccionar]

  <xs:element name="Furgoneta" type="furgoneta"/>

  <xs:element name="Vehiculos" type="conjuntoVehiculos"/>

  <xs:complexType name="conjuntoVehiculos">
    <xs:sequence>
        <xs:element ref="Furgoneta" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- ... -->


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