views:

858

answers:

3

I have an ear which consists of 2 war files one containing junit classes and the other one containing actual application classes which are referenced by the junits. Now when executing the junits i get a java.lang.NoClassDefFoundError

Is it due to the junit class files are located in different ear and hence not able to access the application class files that are located in another ear ?

OR

Whether this is due to the issue with deployment, Though i am able to run the application as well as some of the junits which are independent of application classes located in the other ear ?

A: 

JUnit classes don't belong in WAR or EAR files. They shouldn't be deployed.

You don't say which app server you're using, but if you use WebLogic you can put all your .class files into APP-INF/classes. They'll be visible at the EAR level then, so all WARs can see them.

duffymo
The question is tagged "jboss". Also, running tests inside the container is fairly common practice, since we're not all blessed with "real" unit tests.
skaffman
Missed the jboss tag; I was looking in the text. What's not "real" about JUnit tests? Those are as real as they get. They shouldn't be deployed, in my opinion.
duffymo
I mean that many unit tests are not "pure" unit tests, they require some environmental context, such as to be running inside an appserver. This is common in legacy code bases.
skaffman
Fair enough. Those are more likely to be "integration tests". And it's possible to mock away the dependencies in lots of cases. I still don't see a reason to package them and ship them off to your clients. There's got to be a way to exercise them without having to put them in the same EAR.
duffymo
+2  A: 

According to the strict JavaEE visibility semantics, classes inside a WAR should not be visible to other components of the same EAR. JBoss relaxes this a fair bit, and tries to flatten out the classloading hierarchy to make it less irritating, but the WAR restriction still stands.

The solution I use is to put only web resources into the WAR, and to put the WAR's class files into a seperate JAR inside the EAR. That way, the webapp itself can find the classes, and so can your unit test webapp.

skaffman
A: 

The correct way is to move the common classes into a dedicated JAR, and bundle that at the EAR level. So you will have a structure like this:

  • business-logic-jar
  • main-web-app-war
  • test-web-app-war

You can bundle the JAR as well as any other libs you depend on in your EAR, and reference them using the manifest file of your WARs. In MANIFEST.MF it looks like:

Classpath: business-logic-1.0.jar spring-2.5.5.jar ...

You can still bundle additional JARs inside each WAR's WEB-INF/lib folder, e.g. junit inside the test-web-app-war. If you are using Maven, read the skinny war page for a general approach.

Pavel