I think Rick may be able to provide more insight than me given his
work on vm class loading, but I'll take a shot at this one....
I think the difference between the two exceptions is based on when the
VM discovers it has an invalid class. The second exception shows us
that the bad class is openejb.org.superbiz.cmp2.MovieBean, which is a
class we generated directly using ASM. In "Style 1", I think
something about the code in EjbHomeProxyHandler was causing the VM to
perform a full verify on the class (FWIU the vm only verifies what is
needs to improve VM startup time). Was EjbHomeProxyHandler doing
something like scanning all the Method objects? Anyway, in "Style 1",
for some reason the vm didn't have (or didn't provide) additional
information about which class was having the error, which based on my
coding experience is a pretty common situation. In "Style 2", the vm
clearly knows what's going on and tells us everything necessary to fix
the problem.
In the long term, we could catch this problem with the verifier or if
they turn that off, we could just fill in a do nothing implementation.
-dain
On May 21, 2008, at 4:52 PM, David Blevins wrote:
There seems to be some major difference between these two styles of
EJBException creation. I ran into this working on a CMP example I
intend to use for the whole CMP+JPA->JPA merging logic. The real
error is that I forgot to implement "setEntityContext" which is an
easy mistake to make as the CMP2 bean class is abstract and compiles
just fine without it. I got the first stack trace below, which is
useless, and decided on a whim to tweak EjbHomeProxyHandler line 213
to the second style shown below. I was and am shocked at the
difference in the stack trace.
[Style 1] throw new EJBException(re.getMessage(), (Exception)
detail);
Yields:
java.lang.ClassCastException: java.lang.AbstractMethodError
at
org
.apache
.openejb
.core.ivm.EjbHomeProxyHandler._invoke(EjbHomeProxyHandler.java:213)
at
org
.apache
.openejb
.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:274)
at org.superbiz.cmp2.$Proxy26.create(Unknown Source)
at org.superbiz.cmp2.MoviesTest.test(MoviesTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun
.reflect
.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun
.reflect
.DelegatingMethodAccessorImpl
.invoke(DelegatingMethodAccessorImpl.java:25)
at
com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:
32)
[Style 2] throw new EJBException(re.getMessage()).initCause(detail);
Yields:
javax.ejb.EJBException: The bean encountered a non-application
exception.; nested exception is:
java.lang.AbstractMethodError:
openejb.org.superbiz.cmp2.MovieBean.setEntityContext(Ljavax/ejb/
EntityContext;)V
at
org
.apache
.openejb
.core.ivm.EjbHomeProxyHandler._invoke(EjbHomeProxyHandler.java:213)
at
org
.apache
.openejb
.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:274)
at org.superbiz.cmp2.$Proxy26.create(Unknown Source)
at org.superbiz.cmp2.MoviesTest.test(MoviesTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun
.reflect
.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun
.reflect
.DelegatingMethodAccessorImpl
.invoke(DelegatingMethodAccessorImpl.java:25)
at
com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:
32)
Caused by: java.lang.AbstractMethodError:
openejb.org.superbiz.cmp2.MovieBean.setEntityContext(Ljavax/ejb/
EntityContext;)V
at
org
.apache
.openejb.core.cmp.CmpContainer.setEntityContext(CmpContainer.java:318)
at
org
.apache
.openejb.core.cmp.CmpContainer.createEJBObject(CmpContainer.java:592)
at
org.apache.openejb.core.cmp.CmpContainer.invoke(CmpContainer.java:250)
at
org
.apache
.openejb
.core.ivm.EjbHomeProxyHandler.create(EjbHomeProxyHandler.java:267)
at
org
.apache
.openejb
.core.ivm.EjbHomeProxyHandler._invoke(EjbHomeProxyHandler.java:158)
... 21 more
Able to verify the stack trace behavior is this way in both intellij
and maven. Obviously the stack trace for style #1 completely
obfuscates the problem which is itself a big problem.
Anyone have any idea, what causes this difference?
Needless to say, I'll shortly be switching all our code over....
-David