This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I'm trying to deploy a web-application in WAS CE (built off of Apache Geronimo). Everything builds and deploys fine but when I try to run the application it complains that various jars are missing.
The application complains that it is missing referenced class files from Hibernate/Spring/etc when I try to run it so I added the required JARs to the web application. This did not solve the problem.
However if I add them to the server classpath it works fine. This is obviously not the desired outcome. Why would it only work when the JARs are in the classpath?
Thanks in advance [ June 15, 2006: Message edited by: Bear Bibeault ]
Joined: Sep 12, 2005
Just as a side-note I forgot to mention...
I'm including a data access JAR that I built myself. That JAR is what uses Hibernate/Sprint/etc, not the web-app. The JARs that the data access project uses are the ones that I am forced to put in the server classpath.
I would assume it would work like any other JAR that has dependencies, where you simply add the needed classes (or JAR) to the application classpath through the manifest file. Any clue why that isn't working here?
There isn't just "a" classpath in Websphere. If you want to face the full horror then do a web search for "Websphere classloading" and read some of the articles you get.
Short answer is (I think, I'm a little confused about what you put where and what calls what) that the Websphere server classpath represents a classloader that is the parent of your web application's classloader. Thus a class in your web application can call another class in your web application or a class in the server classpath. But a class in the server classpath can't call a class in your web application, or in any other web application in the server. I think the last sentence describes your problem.
Joined: Sep 12, 2005
From what I've read, that seems plausible. But then my question is, why the hell is WAS CE trying to load/use classes in the web-app within the enterprise application? And why is it focusing on the JARs needed by the utility JAR?
And to clarify the project structure a bit more I've tried to describe the project structure below:
util.jar src lib - hibernate3.jar - spring.jar - etc.
The bottom diagram shows the utility jar I'm using in the web-app. It (during build-time) has a copy of all the jars it needs within it. The goal of this is to keep it independent of the ear it is being used in. It references all of its JARs from its own lib folder.
The top diagram shows the layout of the EAR. I have the web application along with a second lib folder that contains all the jars for the enterprise application (this includes the utility jar). The web-app complains that its missing referenced jars if I don't include spring/hibernate/etc. but adding references to the JARs through the manifest file doesn't accomplish anything. Only when I add the JARs to the server classpath will anything work.
They don't need to be in the server's classpath, and if you can avoid it I would recommend taking them out since different EARs may use different versions of the same JAR or different static objects (by putting them in the server's class path your making any static objects created by the jar the same accross all EARS).
To be accessible otherwise, they need be in an EAR and every JAR that references them in that EAR must have an entry in their MANIFEST.MF files. You could also set them up as a resource bundle in the admin console.
Oh, missed the part about wars, yea wars are a little tricky... in order to be accessible in a webapp during runtime, the jar has to be placed in the WEB-INF\lib folder.
As far as I recall WSAD does not do this for you, you have to manually copy the jar to this folder. And yes, its sort of a pain (especially if you rebuild that JAR alot) which is why its always good to have build scripts.
Joined: Sep 12, 2005
Thanks for your input. I have already added the JARs used by the web-app to its WEB-INF/lib folder. That didn't solve the problem. However, is there some special references I need to build for them? a.k.a. Do I need to reference the JARs somehow in web.xml or the Manifest file for the web-app?
You shouldn't, putting them in the WEB-INF/lib folder should be enough for them to be read by applications within the WAR. You could add them to the manifest.mf (since having them there couldn't hurt) but it shouldn't be neccessary.
I am working with Adam on this project and have been trying a different approach. I have the three projects: ear project, web project, and api project with all the libraries in the /lib folder of the api project. I then include these (along with the jarred api project classes) in the top level of my ear project. So the ear file looks like this:
api project.jar web project.war hibernate.jar spring.jar etc...
The manifests of all three projects contain the jars.
The project deploys without a problem, then, using the eclipse wtp web services explorer, I test the service. Everything goes fine until I call query.list() on a hibernate query. At this point I get an exception thrown and the server shuts down. The messege printed out is: CharScanner; panic: ClassNotFoundException: org.hibernate.hql.ast.HqlToken
The interesting thing is that hibernate classes are being used fine up to that point. It makes it look like hibernate or part of it cannot refer to its own classes. Which makes no sense at all.