Running BIRT reports which are based on model objects in a separate plugin cause ClassNotFoundException

StackOverflow https://stackoverflow.com/questions/21777485

문제

I am developing an eclipse Rich Client application which contains a model plugin and a report plugin. Reports in the report plugin access the model via a data access class in the model plugin. The model objects are persisted to the file system using XMLEncoder.

In the report plugin a report tries to access a model object via the data access class but a ClassNotFoundException is thrown.

I debugged the report and I can see that, although the BIRT classloader is initially active, when the files are deserialised the eclipse.osi default classloader is being used.

What do I need to do in order to be able to load the classes?

JS in BIRT

importPackage(Packages.com.acme.model.dao);
model = new Packages.com.acme.model.dao.AtfObjects();
list = model.getProtocols(path);

AtfObjects

public static List<Protocol> getProtocols(String path) throws Exception
{
    List<Protocol> result = new ArrayList<Protocol>();

    File file = new File(path);
    if (file.exists())
    {
        String xml = FileUtils.read(file);

        try
        {
            Trace.out("P1");
            Protocol pp = new Protocol();  // <-- this works
            Trace.out("Class: %s", pp.getClass().getName());
            Trace.out("ClassLoader: %s", pp.getClass().getClassLoader());
            Trace.out("Deserialise %s", file);
            Class c = Class.forName("com.acme.model.Protocol");
            Object o = c.newInstance();  // <-- this works
            XMLSerializer xs = new XMLSerializer();
            Protocol p = xs.deserialize(xml, Protocol.class); // <-- this fails
            result.add(p);
        }
        catch (Exception e)
        {
        }
    }

    return result;
}


@Override
public Object deserialize(String xml) throws SerializationException
{
    XMLDecoder decoder = null;
    InputStream in = null;

    try
    {
        in = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        decoder = new XMLDecoder(in);
        Object object = (Object) decoder.readObject();  // <-- ClassNotFound Protocol
        decoder.close();

        return object;
    }
    catch (Exception e)
    {
        throw new SerializationException(e);
    }
도움이 되었습니까?

해결책

I'm not sure how good this solution is. It avoids the ClassNotFoundException when debugging but it remains to be seen how well it works when the report is used from within the application at runtime.

public static List<Protocol> getProtocols(String path) throws Exception
{
    List<Protocol> result = new ArrayList<Protocol>();
    File file = new File(path);
    if (file.exists())
    {
        String xml = FileUtils.read(file);

        try
        {
            Trace.out("P1");
            Protocol pp = new Protocol();
            Trace.out("Class: %s", pp.getClass().getName());
            Trace.out("ClassLoader: %s", pp.getClass().getClassLoader());

            // FORCE THREAD CLASSLOADER
            Thread.currentThread().setContextClassLoader(
                    pp.getClass().getClassLoader());
            XMLSerializer xs = new XMLSerializer();
            Protocol p = xs.deserialize(xml, Protocol.class);
            result.add(p);
        }
        catch (Exception e)
        {
        }
    }

    return result;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top