Wednesday, January 10, 2007

OC4J Rmi Client: NoClassDefFoundError: javax/ejb/EJBHome

Trying to run an OC4J rmi client where the oc4jclient.jar was packaged with the project (no longer in the jdeveloper home directory) produced some vexing problems with the following error:
java.lang.NoClassDefFoundError: javax/ejb/EJBHome
at java.lang.Class.getDeclaredMethods0(Native Method)
...
despite having the ejb.jar file on the classpath. After much frustration, it turns out that oc4jclient.jar uses a Class-Path attribute in its manifest:
Class-Path: lib/ejb.jar lib/mail.jar lib/oc4j_orb.jar lib/orbbase.jar
lib/iiop_support.jar lib/jms.jar lib/jta.jar ../../lib/xmlparserv2.ja
r ../../opmn/lib/optic.jar ../../oracle/jlib/oraclepki.jar ../../jlib
/oraclepki.jar ../../oracle/jlib/ojpse.jar ../../jlib/ojpse.jar
The problem seems to be that although the application classloader does have ejb.jar on the classpath, the oc4jclient.jar gets loaded with a different classloader that can't see it, and expects the ejb.jar to be in a lib dir relative to itself. Turns out you can ignore all the other jar references, only ejb.jar is required (luckily). So, where ever you place the oc4jclient.jar, just create a lib dir in the same directory and drop the ejb.jar into it--then the problem should be solved.

Another bit of weirdness was that it wouldn't seem to work with jdk 1.5.0_06. We looked in the ext dir for anything that might be messing it up but didn't find anything obvious. It seems too bizarre to the the jdk version was also causing a problem, but simply switching to 1.5.0_02 would fix other classpath problems.

4 comments:

Anonymous said...

Clark,
You've only uncovered half the problem. Check out http://tripoverit.blogspot.com/2007/03/oc4jclient-gotchas.html for some more.

Additionally, oc4j is not yet certified to run with jdk1.5+

Cheers.

Clark Updike said...

oc4j has been 1.5 compliant since around Feb 2006, AFAICT. We released a production app on OAS 10.1.3 in June 2006 using EJB3 (requires 1.5). Regarding all those jars in the manifest, as I mentioned I don't think they are all required (not sure why most of them are listed there). We were able to get an RMI client running against standalone OC4J once the issue described in the post was ironed out (we did some rich client prototyping using ormi).
Note that you can generate an ormi client in JDev by selecting the session bean and then using the context menu in JDev to select "New Sample Java Client" which will run against embedded oc4j (10.1.3). I think there was something similar in 10.1.2 but don't know for sure.

Anonymous said...

mmm..was talking about 10.1.2.02
(http://www.oracle.com/technology/software/products/ias/files/as_certification_r2_101202.pdf)

Just a tip; you can run a 1.5 jvm for an Oracle10gAS client (even though it is not supported).
Just dont do it with an IBM JVM. Doesnt work.

I'm really surprised that you keep mentioning a 'standalone /embedded oc4j'. You'd never want to test your production code with it anyway. Trust me, there are lots of intricacies about packaging a client for the full App Server than there are for a embedded/standalone version.

Cheers and good luck

Clark Updike said...

As I said, it was a prototype. We used standalone oc4j since we didn't have ormi turned on in the OAS instance (and we don't have developer access to our development OAS--don't ask). And the intricacies of going from embedded to standalone are way more than going from standalone to OAS in our experience.