What I think happens is that your main program and your plugin use
different instances of the XMLBeans library. In particular, I don't
think that substitution groups play any important role here, even though
I would warn you that if the substitution group member elements are
compiled in a different jar than the substitution group head, that would
not be supported by XMLBeans. But, like I said, you don't seem to be in
that situation.

Therefore, you don't need to change the xsd, but you need to set up your
application in such a way that there are no two different classloaders
loading the XMLBeans library; how to do that I don't know, it depends on
your environment really.

Radu

On Wed, 2009-04-22 at 18:43 +0200, Martinez Sergio wrote:
> Hello,
> 
> I have a problem regarding the use of substitution
> groups and class loaders. In practise, I get an exception
> when trying to access a base class defined in a plugin
> which has been loaded with a typical class loader.
> Below I give the schema definition and source code:
> 
> 1. I have created the following XSD (simple_agenda.xsd):
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
> elementFormDefault="qualified" attributeFormDefault="unqualified">
>       <xs:element name="agenda">
>               <xs:complexType>
>                       <xs:sequence>
>                               <xs:element name="version"
> type="xs:string"/>
>                               <xs:element ref="person"
> maxOccurs="unbounded"/>
>                       </xs:sequence>
>               </xs:complexType>
>       </xs:element>
>       <xs:element name="person" type="personType" abstract="false"/>
>       <xs:complexType name="personType" abstract="true">
>               <xs:sequence>
>                       <xs:element name="name" type="xs:string"/>
>               </xs:sequence>
>       </xs:complexType>
>       <xs:complexType name="friendType">
>               <xs:complexContent>
>                       <xs:extension base="personType">
>                               <xs:sequence>
>                                       <xs:element name="telephone" 
>       
> type="xs:string"/>
>                               </xs:sequence>
>                       </xs:extension>
>               </xs:complexContent>
>       </xs:complexType>
>       <xs:element name="friend" type="friendType" abstract="false" 
>       
> substitutionGroup="person"/>
> </xs:schema>
> 
> This schema has then been compiled with XmlBeans scomp command into a
> JAR file (simple_agenda.jar).
> 
> 2. An example of XML file which follows the previous XSD (agenda.xml):
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <agenda xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
> xsi:noNamespaceSchemaLocation="simple_agenda.xsd">
>       <version>1.0.0</version>
>       <friend>
>               <name>Some name</name>
>               <telephone>0123456789</telephone>
>       </friend>
> </agenda>
> 
> 3. The following is a plugin (SimpleAgendaImporter.java) used 
>    to load the XML file agenda.xml:
> 
> package com.mycompany.xmlimport;
> 
> import java.io.File;
> import java.io.IOException;
> import noNamespace.AgendaDocument;
> import noNamespace.PersonType;
> import org.apache.xmlbeans.XmlException;
> 
> public class SimpleAgendaImporter implements Importer {
> 
>     public boolean loadFile(File input_xmlFile) {
>         AgendaDocument agenda_doc = null;
> 
>         try {
>             agenda_doc = AgendaDocument.Factory.parse(input_xmlFile);
>         } catch (XmlException ex) {
>             ex.printStackTrace();
>         } catch (IOException ex) {
>             ex.printStackTrace();
>         }
> 
>         AgendaDocument.Agenda root_agenda = agenda_doc.getAgenda();
>         String version = root_agenda.getVersion();
>         System.out.println("Version: " + version );
> 
>         int num_persons = root_agenda.sizeOfPersonArray();
>         PersonType person;
> 
>         for (int i_per = 0; i_per < num_persons; i_per++) {
>             person = root_agenda.getPersonArray(i_per);
>             System.out.println("Current person's name: " +
>                       person.getName());
>         }
> 
>         return true;
>     }
> }
> 
> N.B.: the compiled JAR for this plugin has been named
> AgendaImporter.jar.
> 
> 4. In the following main program I load and (try to) execute
>    the previous plugin:
>    
> package agendamanager;
> 
> import com.mycompany.xmlimport.IImporterFactory;
> import com.mycompany.xmlimport.Importer;
> import java.io.File;
> import java.io.FilenameFilter;
> import java.net.MalformedURLException;
> import java.net.URL;
> import java.net.URLClassLoader;
> 
> public class Main {
>     
>     public Main() {
>     }
>     
>     public static void main(String[] args) {
>         // --- Load the agenda entries
> 
>         String plugin_dirname = "plugins";
>         File plugin_dir = new File(plugin_dirname);
>         File plugin_file = new File(plugin_dir, "AgendaImporter.jar");
> 
>         IImporterFactory importer_factory = null;
>         Importer importer = null;
> 
>         URLClassLoader fileScroll = null;
>         Class c = null;
> 
>         System.out.println("Loading jar for AGENDA import...");
> 
>         try {
>             fileScroll = new URLClassLoader(
>                       new URL[]{plugin_file.toURI().toURL()});
>         } catch (MalformedURLException ex) {
>             ex.printStackTrace();
>             return;
>         }
> 
>         try {
>             c = fileScroll.loadClass(
>                       "com.mycompany.xmlimport.ImporterFactory");
>         } catch (ClassNotFoundException ex) {
>             System.out.println("Current plug-in (file " +
> plugin_file.getName() +
>                       ") is not for agenda import (I).");
>             return;
>         }
> 
>         try {
>             importer_factory = (IImporterFactory) c.newInstance();
>         } catch (IllegalAccessException ex) {
>             ex.printStackTrace();
>         } catch (InstantiationException ex) {
>             System.out.println("Current plug-in (file " +
>                       plugin_file.getName() +
>                     ") is not for agenda import (II).");
>             return;
>         }
> 
>         importer = importer_factory.getInstance();
> 
>         File xml_agenda = new File("data/agenda.xml");
>         System.out.println("Parsing agenda from file " + 
>               xml_agenda.getName());
>         importer.loadFile(xml_agenda);
>     }
> }
> 
> 5. Here follows the Importer interface...
>    
> package com.mycompany.xmlimport;
> import java.io.File;
> 
> public interface Importer {
>     boolean loadFile( File input_xmlFile );
> }
> 
> 6. Here follows the class IImporterFactory...
> 
> package com.mycompany.xmlimport;
> 
> public interface IImporterFactory {
>   public Importer getInstance();  
> }
> 
> 7. Here follows the class ImporterFactory...
> 
> package com.mycompany.xmlimport;
> 
> public class ImporterFactory implements IImporterFactory {
>     
>     public SimpleAgendaImporter getInstance() {
>         return new SimpleAgendaImporter();
>     }
> }
> 
> ==================================================================
> When executing the main program I get the following exception
> 
> Exception in thread "main" java.lang.ClassCastException: 
> org.apache.xmlbeans.impl.values.XmlAnyTypeImpl cannot be cast to 
> noNamespace.PersonType
> at noNamespace.impl.AgendaDocumentImpl$AgendaImpl.getPersonArray(
> Unknown Source)
> 
> at this line 
> 
>             person = root_agenda.getPersonArray(i_per);
> 
> of the plugin.
> 
> However, if I read in the file agenda.xml directly from the main 
> program (see below), I do not get any exception:
> 
> ----------------------------------------------------------------
> package agendamanager;
> 
> import com.mycompany.xmlimport.Importer;
> import com.mycompany.xmlimport.SimpleAgendaImporter;
> import java.io.File;
> 
> public class Main {
>     
>     public Main() {
>     }
>     
>     public static void main(String[] args) {
>         // --- Load the agenda entries
> 
>         Importer importer = new SimpleAgendaImporter();
> 
>         File xml_agenda = new File("data/agenda.xml");
>         System.out.println("Parsing agenda from file " + 
>               xml_agenda.getName());
>         importer.loadFile(xml_agenda);
>     }
> }
> ----------------------------------------------------------------
> 
> Maybe this kind of problem or a similar one has been implicitly 
> solved in some other mail in this forum, but I really did not succeed 
> in extrapolating a solution to my case.
> Maybe the XSD can be slightly modified in order to overcome
> the problem?
> 
> Thanks to all,
> S. Martinez
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to