views:

712

answers:

2

I'm having trouble following this guide to "extract" my interfaces and entities from my EAR to use them from another Web Application:

  • I use NetBeans 6.8 and Glassfish 3.0.1
  • "Java Class Library" project
    • contains all the entities and interfaces
  • "Java EE Application" project
    • class library added to the project, is packaged into the EAR
    • contains EJB implementations, MDBs, Test
  • "Java Web Application" project
    • class library added to the project, is packaged into the WAR
    • contains REST interface

When I build and deploy the Web Application, all goes well.

When I build the JEE application, I can see the jar-file (interfaces, entities) being included. But when I try to deploy the EAR, Glassfish refuses it with a java.lang.NoClassDefFoundError error:

[#|2010-03-28T18:25:59.875+0200|WARNING|glassfishv3.0|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=28;_ThreadName=Thread-1;|Error in annotation processing: java.lang.NoClassDefFoundError: mvs/core/StoreServiceLocal|#]

[#|2010-03-28T18:25:59.876+0200|SEVERE|glassfishv3.0|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=28;_ThreadName=Thread-1;|Exception while deploying the app
java.lang.IllegalArgumentException: Invalid ejb jar [CoreServer]: it contains zero ejb. 
Note: 
1. A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean. 
2. EJB3+ entity beans (@Entity) are POJOs and please package them as library jar. 
3. If the jar file contains valid EJBs which are annotated with EJB component level annotations (@Stateless, @Stateful, @MessageDriven, @Singleton), please check server.log to see whether the annotations were processed properly.

'mvs/core/StoreServiceLocal' is an interface which is defined in the library jar file.

What am I doing wrong?

I'm using EJB3 Annotations, so there is no bean-specific deployment descriptor:

mvs/core/ShopperService.java:

@Stateless
public class ShopperService implements ShopperServiceLocal, ShopperServiceRemote {
}

mvs/core/ShopperServiceLocal.java:

@Local
public interface ShopperServiceLocal {
}
+1  A: 

Your "Java EE Application" project must contain the interfaces (that currently can't be loaded at runtime, hence the NoClassDefFoundError). And If you want to call the EJBs from another webapp, create an additional "client" jar (with the interfaces only).

Pascal Thivent
Ok thanks. So the challenge then is only to keep the "client" jar in sync, right? Whenever I make changes to the interfaces or entities, I need to export them into the client jar again.
Hank
@Hank Yes. Best practice is to produce this client ejb-jar as part of an automated build (using Maven or Ant). This solves the sync issue.
Pascal Thivent
@Pascal - thanks that's what I thought. Fantastic help!
Hank
A: 

I'm not sure about the detailed structure of your EAR file you listed above. 'Within' the EAR file should be one WAR file (for the web container) and another JAR file which contains your EJB (for the EJB container). Both have to know about the EJB interfaces as their appropriate containers have separate class loaders.

If you don't need full blown EJB functionality then EJB lite (which comes with EJB 3.1) allows you just to create one WAR file where you can put both in. This WAR could contain your EJBs and servlets for instance. This gives you an easier deployment with just one WAR file. But EJB lite is only helpful if your EJBs don't need to provide any remote interfaces.

If you need remote interfaces for your EJBs then an EAR file is the right way. This EAR file should contain a WAR file for web purposes and a JAR files for your EJB definitions.

Achim Tromm