scatolone
scatolone

Reputation: 843

Is there a way to package an EJB module with a WAR without an EAR?

I currently have the following project structure

EAR
|---myapp1.war
|---myapp2.war
|---myapp-ejb.jar

I would like to get rid of the ear and deploy myapp1 and myapp2 on their own. I tried to make myapp-ejb.jar a maven dependency of the two war and everything works fine at compile time. Nevertheless, there are a lot of jndi lookups in the code that fail at deploy time. Is there a way to make this to work?

Upvotes: 3

Views: 1361

Answers (3)

scatolone
scatolone

Reputation: 843

I'm writing an answer to my own question, since I solved the issue. It is perfectly fine to use EJBs with a WAR only (no EAR) as stated here https://docs.oracle.com/cd/E19798-01/821-1841/gippi/index.html. As for the lookups calls, the correct way to do it is described here https://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html. The issue I was facing wasn't really related to the lookups, as I was thinking, but it was due to the way most of the EJBs were initialized. I noticed that in most of the classes there was some nasty initialization code like the following:

@Stateless
public class FooResource
{
    FooEjb fooEjb = lookupFooEjb();
    
    private FooEjb lookupFooEjb()
    {
        javax.naming.Context c = new InitialContext();
        return (FooEjb) c.lookup("java:global/FooApplication/FooModule/FooEJB!FooInterface");
    }
}

This works fine with the EAR because the EJB module is loaded before the WAR archives, so the lookups do not fail. My guess is that when you package the EJBs with the WAR, it loads the EJBs as they are needed, computing the dependencies based on the @EJB annotation, so that kind of initialization fails since the EJB might be not loaded yet. To make it work, I just removed the lookup and added the annotation @EJB.

@Stateless
public class FooResource
{
    @EJB
    FooEjb fooEjb;
}

Upvotes: 1

smithderek553
smithderek553

Reputation: 1

  1. Extract the WAR from the EAR

  2. Scope ejbs as "provided" per https://stackoverflow.com/a/42847318/8528208

  3. Place the ejb.jar in your WAR's WEB-INF/lib per https://stackoverflow.com/a/6968674/8528208

Further documentation at https://www.ibm.com/docs/en/was/8.5.5?topic=modules-ejb-content-in-war

--

Archived edits comments refer to:

Update- Is the ejb.jar in the build class path of your .war? If your project is maven based, is the ejb.jar a dependency of the .war project? If so, try adding the EJB module as a "provided" dependency per https://stackoverflow.com/a/42847318/8528208

--

"An .ear file is a collection of entities (i.e., .war files), so you can simply extract the .war file from the .ear file and deploy it." -per https://stackoverflow.com/a/26658071

If this doesn't help, can you add a lookup attribute in your @EJB annotations such as

@EJB(lookup="java:global/mwf_ejb/UserManager")

Similar to this answer? https://stackoverflow.com/a/10156279/8528208

Upvotes: 0

TacheDeChoco
TacheDeChoco

Reputation: 3913

Theoretically, it is possible to have ejb in a web archive (war).

Although not necessary, you could try to put a 'ejb-jar.xml' file (located in the WAR module’s WEB-INF) to replace the normal auto-discovery mechanism ?

Be also aware that the WAR file must be version 2.5 or later to contain EJB content.

Upvotes: 1

Related Questions