Hi all, I'm having a serious problem with j2ee Classloading. I have "inherited" a J2EE application where all business classes (invoked by the EJB) are placed in the Application's Server classpath (Weblogic 8.1.4).
Very bad because every time a class is changed the a.s. must be restarted.
So I re-enginereed the package putting the business classes in a jar that is referenced by the EJB's MANIFEST file.
This way all the classes would be loaded by the EJB classloader and no need to start/stop weblogic.
Unfortunately it's not such !! I discovered that all business classes are loaded via REFLECTION
and the application server cannot find them using the standard J2EE Classloader mechanism.
java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at irma.business.Dispatcher.callService(Dispatcher.java:70) .............. Caused by: java.lang.NoClassDefFoundError: irma/utility/log/LogPrintStream at irma.business.service.LoginService.login(LoginService.java:79)
On the other hand they're found if I put the classes on the application server classpath.
Has anybody got advice for this ? Should I refactor the application giving up reflection ? Thanks a lot in advance.
My first instinct would be to advice you getting rid of the reflection stuff. The reflection is useful in certain type of scenarios, when the name of the class is known only at runtime (for example). It is also probably 600-800 times slower than usual java calls and although modern jvms improved a lot (special jrocket, because ejbs uses a lot of reflection) it still might be considered a pretty bad choice, especially if used in business methods. However if you are seeking other possibilities then can you please post your manifest that references the business classes? Also can you describe your packaging architecture? Do you have an ear containing multiple ejbs, or independent jars? How is located the jar containing the business classes with respect to your ejbs? Regards.
If you don't have a problem getting in dependance of WLS forget the manifest file and do it like this:
Make a EJB.jar with the bean, component and home interface, xml-files for all beans or group them in one or more ejb.jar (like put all beans from the presentation layer in one ejb.jar, the ejbs from the data access layer in another...).
Make a web.war with servlet classes, xml-files, jsps, gifs, htmls.
Make a common.jar with all other classes.
Put them all together in a application jar, a ear.jar. Now the important part is to put all ejb.jar and web.wars in the ear.jar with no path.
Add the common.jar and all 3rd party tools in the ear.jar with the path "APP-INF/lib".
Add all properties files that you would put into the classpath (log4j.xml, appplication.properties...) in the ear.jar with the path "APP-INF/classes".
Create a application.xml and put it into the "meta-inf" path of the EAR. It should look like that:
When you are deploying like that you'll have no problems with hot deployment and classloading!