On Sep 26, 2007, at 8:18 AM, Tomasz Mazan wrote:


I'm trouble with module dependencies and classloaders - it's a big
aggravation during development.
I'll try to describe my application architecture:

CoreApplication.ear - main application
|- ModuleDao.jar - contains EJB3 entities and DAO layer (SessionBeans) \- ModuleServices.jar - SessionBeans with business logic and WebServices

Dispatcher.jar - application that dispatches requests from CoreApplication
to subsystems
 Contains all dispatcher classes and compiles classes of EJB entities

Using deployment descriptors I've defined dependencies, so CoreApplication
depends on Dispatcher.
So you see that EJB entities are included in 2 modules, and - what is
strange to me - CoreApplication uses those loaded with Dispatcher. I've checked it changing those classes and redeploying CoreApplication. I tried
also put <hidden-classes> to deployment descriptors of:
- Core Application
- ModuleDao
- ModuleServices
but it caused exception like:

17:03:15,453 ERROR [OpenEJB] The bean instance null threw a system
exception:java.lang.LinkageError: Class core/dao/ejb3/Product violates
loader constraints
java.lang.LinkageError: Class core/dao/ejb3/Product violates loader
constraints
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2395)
        at java.lang.Class.getDeclaredMethod(Class.java:1907)
at java.io.ObjectStreamClass.getPrivateMethod (ObjectStreamClass.java:1354)
        at java.io.ObjectStreamClass.access$1700(ObjectStreamClass.java:52)
        at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:421)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:400)
        at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:297)
        at java.io.ObjectStreamClass.initProxy(ObjectStreamClass.java:491)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java: 1508) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java: 1463)
        at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java: 1699)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
        at
org.apache.openejb.core.ivm.naming.CrossClassLoaderJndiReference.copy( CrossClassLoaderJndiReference.java:53)
        at
org.apache.openejb.core.ivm.naming.CrossClassLoaderJndiReference.getOb ject(CrossClassLoaderJndiReference.java:36)
        at
org.apache.openejb.core.ivm.naming.Reference.getContent (Reference.java:40) at org.apache.xbean.naming.context.ContextUtil.resolve (ContextUtil.java:61)
        at
org.apache.xbean.naming.context.AbstractContext.lookup (AbstractContext.java:112)
        at
org.apache.xbean.naming.context.AbstractContext.lookup (AbstractContext.java:597)
        at
org.apache.openejb.core.stateless.StatelessInstanceManager.fillInjecti onProperties(StatelessInstanceManager.java:204)
        at
org.apache.openejb.core.stateless.StatelessInstanceManager.getInstance (StatelessInstanceManager.java:127)
        at
org.apache.openejb.core.stateless.StatelessContainer.invoke (StatelessContainer.java:156)
        at
org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod (EjbObjectProxyHandler.java:211)
        at
org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke (EjbObjectProxyHandler.java:65)
        at
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke (BaseEjbProxyHandler.java:320)
        at
org.apache.openejb.util.proxy.Jdk13InvocationHandler.invoke (Jdk13InvocationHandler.java:49)
        at $Proxy103.createCustomer(Unknown Source)
        

I would be happy to could redeploy changes in ejb3 entites (let's say - only
methods body) for CoreApplication.ear with no need to redeploying
Dispatcher. Is it possibly or should I entirelly change my way ?

I don't understand the situation yet.

what is Product? an ejb? a data object? Is it a parameter or return value of an ejb in Dispatcher?

are the ejb refs from the app to Dispatcher local or remote?

Finally, IIUC you want different class files in Dispatcher and the app for the Product class, but you intend to maintain serialization compatibility. Is this correct?

Assuming that you are going to use only remote ejb refs between the app and Dispatcher, and that you succeed in maintaining seriailzation compatibility (which I suspect you will find to be rather difficult) I think you need to decouple the classloaders entirely. One way of course is to just leave out the module dependency: this might require you to use a different form of ejb-ref in the geronimo plan. First I would try marking the dependency

<import>services</import> as this should make the gbeans (ejbs in this case) visible to the app without any classloader relationship.

I think that trying to maintain serialization compatibility between 2 different versions of the Product class is unlikely to be worth the trouble. Can you put the operations that need to be updated in another class that works on a data object that won't need updating? Maybe something like a strategy pattern?

Product.setStrategy(Strategy strategy) // application sets the methods it wants to use

Product.doSomething() // delegates to strategy object.

Hope this has something to do with your question :-)

thanks
david jencks


regards
Beniamin
--
View this message in context: http://www.nabble.com/Module- dependencies-and-classloaders-tf4523003s134.html#a12903190 Sent from the Apache Geronimo - Users mailing list archive at Nabble.com.


Reply via email to