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]

Reply via email to