CuriousMind
CuriousMind

Reputation: 8953

Does @EJB work only for interfaces?

I am new to EJB and i am currently writing some simple EJB's (EJB 3.0).

This is what i am trying -->

Remote Client -> Calls EJB (remote) (and this EJB calls a Local EJB).

EJB 1:

Interface

package com.vipin.server.local.bean;

import javax.ejb.Local;

@Local
public interface UtilLocalBeanLocal {

    public String addString();
}

Class implementing this interface:

package com.vipin.server.local.bean;

import javax.ejb.Local;
import javax.ejb.Stateless;

@Stateless(mappedName="UtilLocalBeanMappedName")
@Local(value=UtilLocalBeanLocal.class)
public class UtilLocalBean implements UtilLocalBeanLocal {

    public UtilLocalBean() {

    }

    @Override
    public String addString() {

        return "Added from Local bean"; 
    }
}

So, this EJB i am creating to be "locally" used by another EJB.

EJB 2:

Interface

package com.vipin.bean.session;

import javax.ejb.Remote;

@Remote
public interface FirstBeanRemote {

    public String callMe();
}

Class implementing this interface.

package com.vipin.bean.session;

import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.vipin.server.local.bean.UtilLocalBeanLocal;

@Stateless(mappedName="FirstBeanMappedName")
@Remote(value=FirstBeanRemote.class)
public class FirstBean implements FirstBeanRemote {

    @EJB(name="UtilLocalBeanMappedName")
    private UtilLocalBeanLocal utilLocalBeanLocal;

    /*@EJB(name="UtilLocalBeanMappedName")
    private UtilLocalBean utilLocalBean;*/

    public FirstBean() {

    }

    @Override
    public String callMe() {

        return "Hi there!" + utilLocalBeanLocal.addString();
    }
}

I have created a remote client which will invoke EJB -> FirstBean and this EJB will internally invoke UtilLocalBean (injected with @EJB annotation) as below code snippet:

@EJB(name="UtilLocalBeanMappedName")
private UtilLocalBeanLocal utilLocalBeanLocal; 

In this I am using the "interface" to which the EJB instance gets injected. And it works fine.

The problem starts when i use like this:

@EJB(name="UtilLocalBeanMappedName")
private UtilLocalBean utilLocalBean;

--> I am using the class name itself, not the interface.

In this scenario when i start JBOSS AS (7.1.1 final), it throws exception:

00:07:33,104 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC00001: Failed to start service jboss.deployment.subunit."EJB30TestProjEAR.ear"."EJB30TestProj.jar".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.subunit."EJB30TestProjEAR.ear"."EJB30TestProj.jar".INSTALL: Failed to process phase INSTALL of subdeployment "EJB30TestProj.jar" of deployment "EJB30TestProjEAR.ear"

...

Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS014544: No EJB found with interface of type 'com.vipin.server.local.bean.UtilLocalBean' for binding UtilLocalBeanMappedName

...

00:07:33,421 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) {"JBAS014653: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"JBAS014671: Failed services" => {"jboss.deployment.subunit.\"EJB30TestProjEAR.ear\".\"EJB30TestProj.jar\".INSTALL" => "org.jboss.msc.service.StartException in service jboss.deployment.subunit.\"EJB30TestProjEAR.ear\".\"EJB30TestProj.jar\".INSTALL: Failed to process phase INSTALL of subdeployment \"EJB30TestProj.jar\" of deployment \"EJB30TestProjEAR.ear\""},"JBAS014771: Services with missing/unavailable dependencies" => ["jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean.ValidatorFactoryjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBeanMissing[jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean.ValidatorFactoryjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean]","jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean.Validatorjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBeanMissing[jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean.Validatorjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.FirstBean]","jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean.Validatorjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBeanMissing[jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean.Validatorjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean]","jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean.ValidatorFactoryjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBeanMissing[jboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean.ValidatorFactoryjboss.naming.context.java.comp.EJB30TestProjEAR.EJB30TestProj.UtilLocalBean]"]}}}

Does @EJB works when it is applied to interface only? Any inputs highly appreciated.

Upvotes: 0

Views: 1334

Answers (1)

Brett Kail
Brett Kail

Reputation: 33956

Yes, @EJB can only be used with a business interface (or superinterface). In EJB 3.1, you can use @EJB with the EJB class if you declare a no-interface view (it's the default if the EJB has no other interfaces, or it can be explicitly specified with @LocalBean).

Upvotes: 1

Related Questions