You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@geronimo.apache.org by Tomasz Mazan <wi...@wp.pl> on 2007/09/26 17:18:14 UTC

Module dependencies and classloaders

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.getObject(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.fillInjectionProperties(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 ?

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.


Re: Module dependencies and classloaders

Posted by David Jencks <da...@yahoo.com>.
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.
>