3

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?

scatolone
  • 733
  • 1
  • 5
  • 21
  • I tried to fix the JNDI lookups, but I can't get it to work. It works if the ejb is one of the classes of the war, but the lookup fails if the ejbs are in the jar. I suspect this is because the jar is not an ejb module anymore, but it is just a regular jar. – scatolone Sep 24 '21 at 07:52
  • In most cases your task means - port application on another technology. I.e. you've JEE/Jakarta EE and now have to move to kubernetes/micso-services with spring claud and spring boot. If you have an EJB module I expect wab apps use those beans, so you'll have to port enterprise beans on RESTful web services etc. – Victor Gubin Sep 30 '21 at 13:47
  • I'm not moving to another technology, the effort would be too much. I would like to know if it is possible to package the ejb jar with a war only... If it's not, I'll give up on this task and I'll keep the EAR as it is now. – scatolone Oct 01 '21 at 14:17
  • 1
    If you are using enterprise java beans and JEE application servers - you need EAR (enterprise archive). Leave everything as it is. – Victor Gubin Oct 01 '21 at 14:25

3 Answers3

1

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.

TacheDeChoco
  • 3,683
  • 1
  • 14
  • 17
  • I don't have any ejb-jar.xml because my ejbs are configured through annotations – scatolone Sep 27 '21 at 13:38
  • Yes I understood that, but as I said, this was an attempt to see whether this would work better when ejb are stated directly (instead of being scanned by detecting ejb annotations). First make your ejbs work inside a war, and in second step, make them automatically discovered. – TacheDeChoco Sep 27 '21 at 14:11
1

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;
}

scatolone
  • 733
  • 1
  • 5
  • 21
0
  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

  • About the first link, it is exactly what I did. I extracted the war from the ear and made the ejb module as a dependency... it doesn't work. About the second link, I have lookups already. They don't work if I extract the war from the ear. – scatolone Sep 30 '21 at 07:39
  • 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 .war project? If so, try adding the EJB module as a "provided" dependence per https://stackoverflow.com/a/42847318/8528208 – smithderek553 Sep 30 '21 at 14:47
  • Yes, my project is maven based and the ejb.jar is a dependency. Suppose I use the "provided" scope, who should provide it? In the link you mentioned, the "provided" scope works because the ejb is packaged and deployed together with a EAR, I don't have an EAR. – scatolone Oct 01 '21 at 14:09
  • Try placing the ejb.jar in your WAR's WEB-INF/lib. I've updated my answer post. – smithderek553 Oct 01 '21 at 21:32
  • Nope, it doesn't work because the scope of the ejb dependency is "provided" and it isn't provided by anyone, so I have a lot of ClassNotFoundException – scatolone Oct 20 '21 at 16:35