[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Newsgroup Home]
|
[news.eclipse.platform.rcp] Re: Classloader / Serialization issue
|
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