[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.platform.rcp] Re: Classloader / Serialization issue

Erwin,

Thanks for this - simplicity itself!
I'll wrap this in some sort of extension point structure and try it out.

Mike E.

Erwin Gribnau wrote:
Hi there,

Sorry for kicking in so late, but I solved a similar problem in a different way.

I patched the library I use (prevayler) to use a custom ObjectInputStream class. This class uses a ClassLoader that is in own of my central plugins. This classLoader has an 'addBundle' call. Every plugin I make that has classes that need to be serialized/deserialized register themselves to this 'DelegatingClassLoader'.

My central plugin has a reference to an instance of 'DelegatingClassLoader'.

The code for the DelegatingClassLoader (with some debug info). There is now code the respond to plugins being unloaded, so it needs some fine-tuning.


/** * @author Erwin Gribnau * */ public class DelegatingClassLoader extends ClassLoader {

    private List bundles = new LinkedList();

    /**
     * @param bundle
     */
    public DelegatingClassLoader(Bundle bundle) {
        this.bundles.add(bundle);
    }

    public void addBundle(Bundle bundle) {
        this.bundles.add(bundle);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.ClassLoader#loadClass(java.lang.String)
     */
    public Class loadClass(String name) throws ClassNotFoundException {
        IStatus is = new Status(Status.INFO, "Delegating class loader", 0,
                "Loading: " + name, null);
        NavalancheCore.getDefault().getLog().log(is);
        Iterator it = bundles.iterator();
        while (it.hasNext()) {
            Bundle b = (Bundle) it.next();
            is = new Status(Status.INFO, "Delegating class loader", 0,
                    "Trying bundle: " + b.getSymbolicName(), null);
            NavalancheCore.getDefault().getLog().log(is);

if (b.getState() == Bundle.ACTIVE
|| b.getState() == Bundle.STARTING
|| b.getState() == Bundle.INSTALLED
|| b.getState() == Bundle.RESOLVED) {
try {
Class klass = b.loadClass(name);
return klass;
} catch (ClassNotFoundException e) {
}
} else {
//Bundle in a state we cannot load from, exit the loop, and
// throw the ClassNotFoundException
break;
}
}
System.out.println("DelegatingClassLoader: Could not load " + name);
throw new ClassNotFoundException();
}
}



Guillaume Duchesneau wrote:

Thanks for your help! I will ask in this newsgroup if anyone knows how to
override a plugin classpath/classloader using the extension mechanism. I
think it might be a good solution to my problem...


Guillaume D.


My 'core' plugins are:



Plugin A : holds base classes
Plugin B : holds domain model (business model classes)
Plugin C : communication interface(s) for serialised comms



Then dependent on all three of these:
- any number of communications implementaton plugins
- any number of business logic plugins



So - yes - the full domain model has to be 'known' by plugin B.



OK - so that's the theory and the 'clean' approach.



However what you really want to do is somehow use the plugin extension mechanism to modify the classpath of the comms implementations so they pick up new classes in additional plugins. Sorry I do not know how you could do this - perhaps create your own classloader that is configured from an extension point?



Note that adding another business model plugin as a dependency for the comms plugin is a very quick configuration change.



As for different comms mechanisms, simply use the extension point mechanism to give your base plugin a class to instantiate that implements the comms interface.



Mike E.










Guillaume Duchesneau wrote:



Hi Mike, thanks for your reply!

So in your case, your "communication" classes (Apache alt-rmi) must be in
the same plugin as the business model classes right? Or you have a
communication plugin depending on a Business model plugin? What I would
like to do is to have an open architecture with "pluggable business
logic". I don't know in advance what business model plugin I will use. I
thought that there might some way to do that using Eclipse extension
concept. Also, I would like to have interchangeable communication
protocol using extensions.


Any other ideas?

Guillaume



Guillaume,



I have a similar architecture with serialised object going between client and server (only in my case the transport protocol is Apache's Alt-Rmi http://incubator.apache.org/projects/altrmi.html ).



My solution is to have a plugin for the domain model - this exists on the client as a base plugin that all others are dependent on. On the server it is simply a JAR on the classpath.



Of course this means that the domain model for the whole application resides in one plugin. This suited me as my domain model is fairly static whilst the business logic changes far more often.



Regards,



Mike E.




Guillaume Duchesneau wrote:



Hello!

I am trying to develop a RCP application that will communicate with a
server using remote invocation over http. I would like to have a plugin
that manages the connection to the server and a series of plugins that
would add business logic in my application. The business logic plugins
depend on my communication plugin. Since my communication protocol is
based on java serialization, my communication plugin must be able to
deserialize classes defined in my business logic plugins. Because of the
way Eclipse deals with plugins and class loaders, I currently get
ClassNotFoundException when trying to deserialize server responses.


Here is short summary of the flow in my app:

1. UI calls a business logic plugin for some operation
2. The business logic plugin does some processing with the UI request and
sends some request to the communication layer plugin to complete its job
3. The communication plugin forwards the request to the server with a
remote invocation over http
4. The server processes the request and sends a response to the client app
5. The communication plugin tries to deserialize the server response but
it can't do it because it does not know about the business object classes
it contains.


I know I could put everything in a single plugin so that all classes would
be "visible" for everybody but I am sure there is a way for a cleaner
design...


Any idea anybody?

Thanks in advance!

Guillaume Duchesneau









-- Mike Evans Incremental Ltd. www.incremental.eu.com