Hot questions for Using Enterprise JavaBeans in session bean

Question:

I just ran into a deployment error when deploying two stateless session beans each with dependency to the other and using @Inject.

@Stateless
class BeanA {
    @Inject 
    BeanB b;

    public void doSomething() {
        b.doSomething();
    }
}

@Stateless
class BeanB {
    @Inject
    BeanA a;

    public void doSomeOtherThing() {
        a.doSomeOtherThing();
    }
}

When deploying this, I get this exception from Glassfish / weld:

org.jboss.weld.exceptions.DeploymentException: WELD-001443 Pseudo scoped bean has circular dependencies.

Injecting the Beans with @EJB instead of @Inject, everything works fine. Now I have two questions.

First - what happens inside weld that this won't be allowed?

Second (probably more important) - is this bad practice on architectural side and if yes do you know any patterns to avoid it? From my current knowledge was that business driven services on the same layer are allowed to communicate with each other in any way they need.


Answer:

As written in the spec

The container is not required to support circular chains of dependencies where every bean participating in the chain has a pseudo-scope.

Here, you didn't add scope annotation to your session beans so they have the default scope @Dependent. Dependent being a pseudo-scope, it's normal to have this error.

To solve this, add @ApplicationScoped to at least one of your bean. In fact it's a good practice to put your stateless session bean in application context, it prevents CDI to recreate its proxy around the existing EJB each time you inject it.

Regarding circularities, it's not a bad practice, but should be used only when needed since it can bring more complexity to understand your app, debug it and prevent these kind of errors.

Question:


Answer:

Web services are a system integration technology. If you had some data and/or logic which you wanted to make available to other applications within your company, or to external applications, you would use web services. There are different types of Web services approaches and REST web services are one of the popular types of web services.

So, web services are just a 'presentation' layer. You could already have an existing application which you could expose to other applications for interaction by creating a Web service layer.

The data access and business logic which do the real work behind the web services layer could be written in plain Java or they could use different frameworks which can help with various tasks.

If you wanted your business logic to support transactions, access control, distribution across servers for load balancing, clustering to share state across servers, etc., you could use frameworks to help you with these complex tasks.

EJB is one approach to writing business logic which involves conforming to some standard interfaces, so that you could then declaratively add support services like transaction management, authentication and authorization, load balancing, clustering etc. with relatively less effort.

Question:

I have read for stateful session bean:

"While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by moving it from memory to secondary storage"

So what is this secondary storage? Is it the underline database? Also, how is an object saved (persisted) in a relational database like Oracle?


Answer:

Java EE is only a specification and it is up to the JEE compliant application server (such as Glassfish, Wildfly, or WebLogic) to determine exactly what the secondary storage is.

WebLogic, at least by default, passivates the EJB:s to disk which is described by this image:

The WildFly/JBoss (which is my application server of choice) documentation is quite sparse regarding this, but a fair guess is that the default behaviour is to passivate the EJB:s to disk as well, though I cannot swear on it.

So, once again, the specification doesn't give any rules on how to passivate the EJB:s, it is up to the implementation.

Question:

given that the default persistence context for EJB (including stateless) is TRANSACTION_SCOPED as I know, is the statement 'transaction can span multiple business methods with stateless bean' valid even if the persistence context is defaulted to TRANSACTION_SCOPED or it's only specific to the popular use case of stateless bean persistence context (i.e. EXTENDED)

An answer supported with a reference is highly appreciated

EDIT:

the use case that I am asking about is something like that :

@Stateless
TransactionManagement(TransactionManagementType.BEAN)
public class MyStatelessBean(){
  @PersistenceContext(unitName="pU",type=PersistenceContextType.TRANSACTION) //default
  @Resource UserTransaction tx;

  public method1(){
    tx.begin();
    //bla bla bla
  }

  public method2(){
    tx.commit();
  }
}

and in the client:

callerMethod(){
   myStatelessBean.method1();
   myStatelessBean.method2();
}

will the transaction remain alive with no issues after returning from method1() and then can be committed in a separate call from the client to another method method2() ? and what can be a use case for such scenario ?


Answer:

EDIT: based on the change of the original post. Since you are using BEAN managed transaction you take reposnsibility for the transaction and its scope. You have two cases:

You use a remote client , if remote will not have transaction UserTransaction associate so the two methods will be executed in two different contexts. Since your transaction is BEAN managed the container will not take over. It is a Stateless Session Bean so you don't have guarantees that the second method will be invoked on the exact same instance of the Stateless bean. So you see why the answer is NO.

Your client is actualy another EJB. As long as you reuse the same transaction manager which is the case when you use Hibernate for example the two methods will participate in the same transaction.

Hi both TRANSACTION_SCOPED and EXTENDED scoped persistence contexts can span over several business methods. In the case of TRANSACTION_SCOPED persistence context the context is limited within the boundaries of the transaction. But there is something that is called TRANSACTION PROPAGATION and one transaction can span over multiple business methods. This is the reason why in the documentation it is stated that it can span over multiple business methods.

Here is a link of transaction propagation explained

The main difference between TRANSACTION_SCOPED and EXTENDED is that EXTENDED context can span over multiple trasactions and this is why it is always bound to Stateful session bean. Once the Statefull session bean is removed, the persistence context is closed.

A very bried example of transaction propagation is:

@EJB class A {

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public methodA

}

@EJB
class B {

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public methodB()

}

In this case since methodA has required attribute and methodB has required attribute a call of B from A the transaction context will be propagated. The key point here is that if both EJB A as access to EntityManager and EJB B has access to EntityManager the session will be the same for both EJBs within the same transaction.

Now if we switch methodB declaration to be @TransactionAttribute(TransactionAttributeType.NEW) instead a new transaction will be created in paralel to transaction initiated in methodA

The default value when no @TransactionAttribute is defined is REQUIRED. As such in the normal case all transactions are propagated.

Question:

I am using Wildfly 8.1 and Postgres 9.2 with latest jdbc driver (non XA configured)

If I have a Session Bean like this:

@Stateless
public class MySessionBean {
  @Resource(lookup="jdbc/mydb")
  Datasource ds;

  @PersistenceContext // defaults to datasource lookup name "jdbc/mydb"
  EntityManager em;

  public void method1() {
    // will ds.getConnection() and 
    // the underlying connection used by em be the same?
  }
}

Will ds.getConnection() be the same underlying connection used by the EntityManager (em) inside the method call of method1() ?

If they share the same jta-transaction, how is it that I don't need XA datasources and just regular one ? (assuming the lookup name for the datasource is also de default datasource for the EntityManager)

I can't find the corelation in the ejb 3.1 specs.

Besides the question I understand that I need to close the datasource connection myself but the transaction will be managed by the container (correct me if I am wrong)


Answer:

I don't think the connection is the same. As far as I understand you will get 2 different connections on the same pool which is managed by the application server.

If so you can't have a simple transaction shared across 2 connection. You must share the transaction manager between the 2 resources and so use XA.

Question:

I'm trying to access an EJB Stateless session bean from a local service. But when I call a method that is located on the bean, I get a NPE because the stateless bean is null.

Here is the code:

The sateless bean:

@Startup
@Stateless(name = "LoginBean")
@LocalBean
public class LoginBean {


    public List<Long> getItemsForClient(String clientId, Long itemId) {
        System.out.println("clientID: " + clientId);
        System.out.println("itemID: " + itemId);

        List<Long> ret = new ArrayList<Long>();
        ret.add((long) 123456);
        ret.add((long) 123457);
        ret.add((long) 123458);
        ret.add((long) 123459);
        return ret;

    }

    }

The service:

@Stateless
@Path("/ctofservice")
public class CtoFService {

    @EJB
    LoginBean loginBean;

    public CtoFService() {

    }

    @GET
    @Produces("text/plain")
    @Path("test")
    public String convertCtoF() {

        Long l = (long) 123456;
        List<Long> servicesForClient = loginBean.getItemsForClient("cliID", l);
        return itemsForClient.toString();


    }

And the ApplicationConfig:

@ApplicationPath("/")
public class ApplicationConfig extends Application {

    @SuppressWarnings("unchecked")
    @Override
    public Set<Class<?>> getClasses() {

        Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
        addRestResourceClasses(resources);
        return resources;
    }

    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(CtoFService.class);    
    }
}

I've been trying for a while and looking for possible solutions, but nothing came up.

I'm using JBoss AS 7.1 and RESTEasy that cames with it.

When the bean should get instantiated?

Thanks.


Answer:

I solved it by adding beans.xml file, It wasn´t present at the moment that I created the project, and I came across to that file searching for a solution after hours.

So I placed the file in WEB-INF directory

The file contains:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

And the problem is solved, I can access the beans through the webService.

Thanks for trying to help.

Question:

I am trying to have a basic template for a single session bean. Then, I took the example included in the "The Architecture of the counter":

https://docs.oracle.com/javaee/7/tutorial/ejb-basicexamples002.htm

However, when running the example, I am not able to print the value of count.hitCount.

I found the common problem when accessing the variable is not having the getter. For instance, in index.html:

<ui:define name="title">
        This page has been accessed #{count.hitCount} time(s).
</ui:define>

However, in the Count.java is including the getter getHitCount():

@Named
@SessionScoped
public class Count implements Serializable {

    @EJB
    private CounterBean counterBean;

    private int hitCount;

    public Count() {
        this.hitCount = 0;
    }

    public int getHitCount() {
        hitCount = counterBean.getHits();
        return hitCount;
    }
    public void setHitCount(int newHits) {
        this.hitCount = newHits;
    }

Finally, the CounterBean.java increases the variable:

@Singleton
public class CounterBean {
    private int hits = 1;

    // Increment and return the number of hits
    public int getHits() {
        return hits++;
    }
}

Thank you for your help and comments, they are highly appreciated.


Answer:

The facelet with a counter of times it got displayed:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
  <h:head>
    <title>Facelet Title</title>
</h:head>
  <h:body>
    This page displayed #{counterController.hitCount} times.
  </h:body>
</html>

The CounterController is a @RequestScoped bean to increment the CounterBean.hitCount in its @PostConstruct method:

package x;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;

@Named( value = "counterController" )
@RequestScoped
public class counterController
{

  @EJB
  private CounterBean counterBean;

  @PostConstruct
  public void initialize()
  {
    counterBean.incHitCount();  
  }

  public int getHitCount()
  {
    return counterBean.getHitCount();
  }

  public CounterController()
  {
  }

}

CounterBean is a @Singleton EJB to store the hitCount. @StartUp annotation do it an eagerly constructed bean (created on application startup, before any client request accepted):

package x;

import javax.ejb.Singleton;
import javax.ejb.Startup;
import lombok.Data;

@Singleton
@Startup
public class CounterBean
{
  private int hitCount;

  public int getHitCount()
  {
    return hitCount;
  }

  public void incHitCount()
  {
    hitCount++;
  }

  public CounterBean()
  {}
}

Question:

My job is to write kind of a webservice adapter using a Servlet which then calls an adapter EJB (SOAP webservice) which in turn calls the existing service methods (also EJBs). The existing architecture is based on EJB 2.0, which I can't change for now. External customers are supposed to access the Servlet and not the webservice class directly. The reason for this is that some pre-processing needs to be done using information in the HTTPRequest (fetching and mapping user-id from certificate resp. the HTTP Header). So, the Servlet reacts on the doPost() method, performs a preprocessing like parsing and marshalling the SOAP XML data and then calls the adapter EJB (stateless Session Bean), more precisely the webservice methods which will then trigger existing service methods in a different EJB. This works well so far until the EJBs require an existing Session resp. SessionContext, like in the following case where transaction rollback is handled:

protected void preventTransactionRolledBackException() {
    if (this.getSessionContext().getRollbackOnly()) {
        this.getSessionContext().setRollbackOnly();
    }
}

In my setup, SessionContext is always null. As the whole application is already quite complex I try to post a simplified setup using only the Servlet and one EJB, hoping I'm not excluding something relevant. System: WebSphere Application Server 8.5

Servlet:

public class NewZekEclsServiceServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String operation = null;
        response.setContentType("text/xml");
        try { 
            PrintWriter out = response.getWriter(); 
            // Get Header data
            // Get Attribute data
            // Get Body data:
            InputStream body = request.getInputStream();
            String xml = IOUtils.toString(body, "UTF-8");

            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            docBuilderFactory.setNamespaceAware(true); // required as several namespaces might be used
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));

            operation = getOperation(doc); // method which scans the xml to retrieve the correct operation to use.

            if (operation.equalsIgnoreCase("Ping")) {

                // Calling the Adapter Bean:
                EclsTestBeanBean eclsTestBean = new EclsTestBeanBean();
                eclsTestBean.ejbCreate();

                PingIn pingIn = new PingIn();
                PingOut pingOut = eclsTestBean.ping(pingIn);

                String xmlString = convertEclsObjectToSOAPString(pingOut);
                out.print(xmlString);

            }
        }
    }
}

EJB (generated by Rational Application Developer 9.0):

/**
 * Bean implementation class for Session Bean: EclsTestBean
 *
 * @ejb.bean
 *  name="EclsTestBean"
 *  type="Stateless"
 *  jndi-name="ejb/ch/zek/ecls/EclsTestBeanHome"
 *  view-type="remote"
 *  transaction-type="Bean"
 *
 * @ejb.home
 *  remote-class="ch.zek.ecls.EclsTestBeanHome"
 *
 * @ejb.interface
 *  remote-class="ch.zek.ecls.EclsTestBean"
 *
 */
public class EclsTestBeanBean implements javax.ejb.SessionBean {

    private Log log = LogFactory.getLog(EcodeAbfragenAction.class);

    private SessionContext mySessionCtx;

    public SessionContext getSessionContext() {
        return mySessionCtx;
    }

    public void setSessionContext(SessionContext ctx) {
        mySessionCtx = ctx;
    }

    public void ejbCreate() throws CreateException {}
    public void ejbActivate() {}
    public void ejbPassivate() {}
    public void ejbRemove() {}

    /**
     * Basic ping service for ECLS
     * @param parameters
     * @return
     * @throws PingEntityNotFoundException
     * @throws PingPermissionException
     * @throws PingSystemException
     */
    public ch.zek.ecls.PingOut ping(ch.zek.ecls.PingIn parameters) throws java.rmi.RemoteException, ch.zek.ecls.PingPermissionException, ch.zek.ecls.PingEntityNotFoundException, ch.zek.ecls.PingSystemException {

        PingOut pingOut = new PingOut();
        String pingAnswer = "Ping_ECLS_v1";
        String adapter = "";
        String operation = "";

        Parameter[] msgParams = new Parameter[1];
        String eclsEnvironment = "TEST";
        pingAnswer += "_" + eclsEnvironment;

        logAvailableEjbs();

        try {
            if (mySessionCtx != null) { // Why can it be null at all?
                log.debug("mySessionCtx: " + mySessionCtx.getContextData());
            } else {
                log.debug("mySessionCtx was null");
                InitialContext ic = new InitialContext();
                mySessionCtx = (SessionContext) ic.lookup("java:comp/env/sessionContext"); // gives error:  javax.naming.NameNotFoundException: Name "comp/env/sessionContext" not found in context "java:".
                System.out.println("mySessionCtx: " + mySessionCtx);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // creating the SOAP data... not relevant for the problem.
        msgParams[0] = new Parameter();
        msgParams[0].setValue(pingAnswer);
        SystemMessage systemMessage = new SystemMessage();
        systemMessage.setCode("OK");
        systemMessage.setMessage("Ping");
        systemMessage.setParameter(msgParams);
        pingOut.setSystemMessage(systemMessage);

        return pingOut;
    }

    /**
     * ONLY USED DURING DEVELOPMENT:
     * Helper method to print "accessible" EJBs.
     */
    protected void logAvailableEjbs() {
        try {
            //Get the Initial Context for the JNDI lookup for a local EJB
            InitialContext ic = new InitialContext();

            NamingEnumeration<NameClassPair> list;
            String level = "";
            String name = "";
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }
            level = "ejb";
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }   
            level = "java:comp";
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }
            level = "java:comp/env";
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }
            /*
            level = "java:comp/env/ejb"; // Throws Error!
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }
            */
            level = "java:global";
            list = ic.list(level);
            while (list.hasMore()) {
                name = list.next().getName();
                System.out.println(level + "/" + name);
            }
        } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

We are testing the setup using the SoapUI tool (http://www.soapui.org). Again, we get proper results for a simple Ping() service, but as soon as session-related stuff is required it fails.

Of course I did some research, especially interesting was this link: How to get SessionContext in JBOSS which also refers to: http://javahowto.blogspot.co.uk/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html

And regarding EJB lifecycle: docs.oracle.com/cd/E13224_01/wlw/docs100/guide/ejb/session/conSessionBeanLifeCycle.html J2EE-Tutorial: docs.oracle.com/javaee/6/tutorial/doc/gipss.html#gipsx (sorry, can't post more than 2 links...)

But as commented in the code, I can't access java:comp/env/ejb/sessionContext. Well... not even java:comp/env/ejb. I wrote a dirty helper method to see what is actually accessible to the EJB and get the following output:

SystemOut     O /jta
SystemOut     O /eis
SystemOut     O /cell
SystemOut     O /thisNode
SystemOut     O /DefaultDatasource
SystemOut     O /services
SystemOut     O /jdbc
SystemOut     O /servername
SystemOut     O /com.ibm.websphere.ejbcontainer
SystemOut     O /com
SystemOut     O /zek
SystemOut     O /wm
SystemOut     O /ejb
SystemOut     O /Increment
SystemOut     O /tm
SystemOut     O ejb/ivtEJBObject
SystemOut     O ejb/ch
SystemOut     O ejb/mgmt
SystemOut     O java:comp/ValidatorFactory
SystemOut     O java:comp/TransactionSynchronizationRegistry
SystemOut     O java:comp/ORB
SystemOut     O java:comp/Validator
SystemOut     O java:comp/UserTransaction
SystemOut     O java:comp/env
SystemOut     O java:comp/BeanManager
SystemOut     O java:comp/websphere
SystemOut     O java:comp/HandleDelegate
SystemOut     O java:global/com.ibm.ws.AppNameSpaces
SystemOut     O java:global/NewZekEar
SystemOut     O java:global/SchedulerCalendars
SystemOut     O java:global/DefaultApplication
SystemOut     O java:global/cell
SystemOut     O java:global/query
SystemOut     O java:global/ManagementEJB
SystemOut     O java:global/ivtApp

I also tried to use annotation:

@Resource
private SessionContext mySessionCtx;

or setting the transaction type differently:

transaction-type="Container"

Nothing helped. I understood that the SessionContext should be automatically created. But if not - which option does one have to create a new one? Further question: The servlet also "creates" a session which I can access (request.getSession() ), but this is something different (HTTPSession). I guess I can't share or "convert" this session object to the session Bean?


Answer:

You've instantiated the EclsTestBeanBean yourself:

EclsTestBeanBean eclsTestBean = new EclsTestBeanBean();

EJB relies on wrapping the object in a proxy to allow the container to add extra services, including dependency injecting the session context, which means only the container can create them and give them out. You'll also find this object won't perform any of the EJB services, it's just a POJO here.

To request an EJB from the container, you need to either request it via dependency injection or look it up from JNDI, as per this answer:

JPA entity manager not correctly injected - Weblogic

Then the next problem will be that your bean doesn't seem to be available in JNDI - I think this is because you haven't defined a local or remote interface for it. That's fine in EJB3, where the "no-interface" view is used, but not in EJB2: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jst.ejb.doc.user%2Ftopics%2Fcearch.html

So I'd suggest - write yourself an interface, (hopefully) then EclsTestBeanBean then becomes available in JNDI, and look it up from there rather than instantiating it.

(With the @Resource annotation, be aware that all the annotation-based work was added in EJB3 as well.)

Question:

I have recently learnt about stateful and stateless session beans in ejb. I can work along with stateless session beans without any problem (created several applications) but i am finding it hard to implement an application with a stateful session bean.

Here is my scenario : A customer can login using an id and do transactions in his/her account. I want to save the id in to a session bean at the login servlet itself , so that i can retrieve the id from the session to perform transactions.

I know how to work with httpSessions but not with these ejb sessions (stateful beans). Please guide , i want to save the account id to the session (ejb stateful session) and retrieve it back in another servlet.

I have used httpSessions , below is my code:

HttpSession session=request.getSession();
session.setAttribute("accountID", accountid);

But the above is the normal session, how do i use the account session bean to save the id and retrieve it.

Thank you


Answer:

please refer to this tutorial here , it create a simple Stateful Session Bean (EJB) and use it in a web application context

update thanks to @Gimby:

The key point being that the 'client' (the web application itself in this case) keeps a reference to the stateful bean by sticking it in the session, which keeps the stateful bean active on the server side.

the first thing you need to do is trying to get your EJB from the HttpSession like the following :

MyBean bean = (MyBean) request.getSession().getAttribute("myBean");

then check if the bean is null or not null , if its null create a EJB and add it to the session , like the following :

if(bean == null){
          // EJB is not present in the HTTP session
          // so let's fetch a new one from the container
          try {
            InitialContext ic = new InitialContext();
            bean = (MyBean) 
             ic.lookup("java:global/MyBean");

            // put EJB in HTTP session for future servlet calls
            request.getSession().setAttribute(
              "myBean", 
              bean);

          } catch (NamingException e) {
            throw new ServletException(e);
          }
    }

so that way the first time you need the bean you will create it and add it to the session , the second , third , ... etc , you will have it stored in the session .

Hope That Helps .

Question:

I have the following html page, the servlet class and the bean class implemented in my eclipse project that runs on wildfly 8.

The problem I have is every time I call the servlet with some values the add operation in the bean class returns a zero. I know I'm not doing a trivial thing correct. What should I change to get the correct value from the add operation.

AddServlet.java

 import java.io.IOException;
 import java.io.PrintWriter;
 import javax.ejb.EJB;
 import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import ejb.AddEjb;

@WebServlet("/AddServlet")

public class AddServlet extends HttpServlet {
  private static final long serialVersionUID=1L;
  @EJB

AddEjb bean;
  public AddServlet() {
    super();
  }
  protected void doPost(HttpServletRequest request,
  HttpServletResponse response) throws ServletException,
  IOException {
    PrintWriter out=response.getWriter();
    int i=Integer.parseInt(request.getParameter("t1"));
    int j=Integer.parseInt(request.getParameter("t2"));
    bean.setI(i);
    bean.setJ(j);
    bean.add();
    out.print("Addition using bean is test EJB : " + bean.getK());
  }
}

AddEjb.java

package ejb;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;


@Stateless
@LocalBean
public class AddEjb
{
    private int i,j,k;

    public AddEjb() {

    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
        System.out.println("i set" + this.i);
    }

    public int getJ() {
        return j;
    }

    public void setJ(int j) {
        this.j = j;
        System.out.println("j set" + this.j);
    }


    public int getK() {
        System.out.println("K returned" + this.k);
        System.out.println("K returned" + k);
        return this.k;
    }


    public void setK(int k) {
        this.k = k;
        System.out.println("k set" + this.k);
    }

    public void add()
    {
        this.k = this.i + this.j;
        System.out.println("k set" + this.k);
    }


}

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>First EJB</title>
</head>
<body>
    <form action="AddServlet" method="post">
        Enter 1st Number : <input type="text" name="t1"><br>
        Enter 2nd Number : <input type="text" name="t2"><br>

        <input type=submit>
    </form>
</body>
</html>

Following are the sysout logs

18:14:20,601 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.0.Final "Tweek" started in 9104ms - Started 296 of 349 services (92 services are lazy, passive or on-demand)
18:14:46,936 INFO  [stdout] (default task-2) i set78
18:14:46,942 INFO  [stdout] (default task-2) j set22
18:14:46,945 INFO  [stdout] (default task-2) k set0
18:14:46,949 INFO  [stdout] (default task-2) K returned0
18:14:46,950 INFO  [stdout] (default task-2) K returned0

Answer:

The @Stateless annotation is there to tell the container that instances of this bean can be used interchangeably. When you send a request to a stateless bean, the container chooses a bean instance from the bean pool, and there is no guarantee that any two requests are served by the same instance.

The behaviour you're seeing here is that when you send the "set" requests they are each being served by some bean instances, then when you call the "get" methods they are being served by a totally different instance. Exactly which instance you get is up to the container, and is not defined in the EJB spec.

If you'd like to maintain conversational state between calls, as @Ayhan says, you should use a @Stateful session bean. If you need to share this state between clients, you probably want a @Singleton bean.

Question:

What I want to achieve is to take advantage of EJB feautures and use some kind of automatic pooling.

I thought a SLSB may be suitable, when retaining a local stateless variable (don't know if it is an appropriate definition) - at least from the client/caller POV.

@Stateless
public class CommunicationService implements Serializable
{
    private Process process;

    @PostConstruct
    //@PostActivate maybe?
    public void startProcess()
    {
        try
        {
            process = new ProcessBuilder("running a temporary daemon").start();
        }
        catch(IOException e)
        {
            throw new RuntimeException(e.getMessage(), e);
        } 
    }


    @PreDestroy
    //@PrePassivate maybe?
    public void endProcess()
    {
        if(process.isAlive())
        {
            process.destroy();

            boolean terminated = false;
            try
            {
                terminated = process.waitFor(5, TimeUnit.SECONDS);
            }
            catch(InterruptedException e)
            {
                // ignore
            }

            if(!terminated)
            {
                process.destroyForcibly();
            }
        }
    }

    public int send(String message)
    {
        // do something with the process - may take a long time
        // this is just an example

        PrintStream printStream = new PrintStream(process.getOutputStream());
        printStream.println(message);

        try
        {
            return process.getInputStream().read();
        }
        catch(IOException e)
        {
            return -1;
        }
    }
}

Note that I want a pool of processes, so @Singletons are not suitable.

  1. Is this the correct use of @Stateless EJB instance variable?
  2. Is a @MessageDriven more appropriate?
  3. Is there a more EE way to achive it?

Thanks


Answer:

Contrary to popular belief, it's quite OK to maintain state in SLSBs. It just cannot be client state. §4.7 of the EJB 3.2 Spec says:

The term "stateless" signifies that an instance has no state for a specific client. However, the instance variables of the instance can contain the state across client-invoked method calls. Examples of such state include an open database connection and an object reference to an enterprise bean object.

Therefore, this might be a workable strategy with some caveats:

  • The spec says that "stateless session bean instances are typically pooled". You would need to check that your chosen JavaEE server implementation does actually pool them, because (at least for a while there) some of them would just create a new instance every time;

  • Controlling the number of beans in the pool may be tricky. An implementation may continue to create bean instances even when the pool is full, it just never returns them to the pool;

  • If any type of RuntimeException is thrown from a business method then the bean instance will be discarded without calling the @PreDestroy callback (see §9.3.1 of EJB 3.2 Spec). This will result in process leaks in your system;

Therefore you will need to be intimate with the way in which your server manages SLSB pools.

Question:

I have created a stateless session bean(SLSB) and doing a local call from the same JVM. I have a BO local variable in the SLSB when initializing i am setting this value and in the next call i am performing some business function but in the next call i am unable to get the value which i have set in prev. call. which seems to be according to the SLSB functionality but there is a similar fucntionality which is working in another part of our application. I have confirmed both are SLSB and no connection pooling is done in the ejb-jar.xml and weblogic-ejb-jar.xml(also both are same) also i have debugged both the class but no clue how it is working in the other class.

I am wondering is there any other way in which we can do the state full behaviour of stateless session bean apart from connection pooling.


Answer:

The important (if slightly obvious) lesson here is: Don't store state in stateless session beans. If you want to store conversational state, use a stateful bean, if you want shared state use a singleton bean. You could also use an entity bean to persist the state.

The reason this is working elsewhere is most likely to do with bean pooling. EJB containers mostly use bean pools to store their stateless beans, as this gives the best performance and scalability. When a request comes in, the container chooses a bean from the pool to service it, takes it out of the pool, the bean handles the request, then is placed back in the pool. Which bean gets chosen is up to the container, since in theory they are all interchangeable.

If you're setting a member variable in your bean then finding (some of the time) later calls find the variable set to your value, this shows that the container has given you the same bean instance back. This is non-deteministic - it depends on server load, pool size and the container's strategy.

Question:

I try to implement a remote stateless bean. For the methods in this bean, the return values can be correctly returned. However, for "println" in these methods cannot print any thing to the console. The interface is

public interface HelloWorld {
    public void SayHelloWorld(String name); 
    public String SayHello(String name);
}

The implementation is

@Stateless
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld {

    @Override
    public void SayHelloWorld(String name) {
        System.out.println(name + " say hello to the world!");
    }

    @Override
    public String SayHello(String nameString) {
        System.out.println("This is SayHello()");
        return nameString;
    }

}

The client is

public class HelloWorldTest {

    public static void main(String[] args) {

        try {
            FileInputStream inputStream = new FileInputStream("ejb.properties");
            Properties pro = new Properties();
            pro.load(inputStream);
            InitialContext icContext = new InitialContext(pro);
            HelloWorld hw = (HelloWorld) icContext.lookup("ejb/HelloWorldBean!com.ejbinterface.HelloWorld");
            hw.SayHelloWorld("tom");
            String aa = hw.SayHello("tom");
            System.out.println(aa);
        } catch (NamingException e) {
        e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

I do not know why the println in method "SayHelloWorld" and "SayHello" is not executed. However, the variable "aa"(in client) correctly get the return value.


Answer:

It prints to the console of the server (or, if redirected, to some log file - but this is merely a configuration issue). Just look for the output, if the methods get executed, then the output is there.

Question:

I am new to EJB so please don't mind anything silly in the question.

I have a doubt that someone might be able to solve hopefully.

I have the following Stateful Bean:

@Stateful
public class SessionBean implements SessionBeanRemote {

    private int count = 0;

    @Override
    public int getCount(){
    count++;
    return count;

    }

}

And this is the client that invokes the Bean (Servlet)

@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        InitialContext ctx;
        HttpSession session = null;
        SessionBeanRemote obj;
        try {
            if (session.getAttribute("myBean") == null) {
                ctx = new InitialContext();
                obj = (SessionBeanRemote) ctx.lookup("SessionBean/remote");
                session.setAttribute("myBean", obj);
            } else {
                obj = (SessionBeanRemote) session.getAttribute("myBean");
            }

            System.out.println(obj.getCount());

        } catch (NamingException ex) {
            Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

Now I was wondering if it is ultimately HttpSession that has to hold the session bean then why use EJB at all, why not just store whatever we want to in the session directly rather than having it in the session bean first and then storing that bean in the session.

And also I was wondering if lets say I change my @Stateful annotation to @Stateless and then execute the same code on the client side and store the bean in the session then also I can extract the same bean from the session then what is the difference between stateless and stateful, I know that when new lookup is done there is a chance that same stateless bean might be returned to me where as with stateful bean it is always new when we do a lookup. But is that it?

P.S. As I mentioned earlier, I am new to EJB and all the doubts are based on what I have understood from a few tutorials online and some questions on SO. I have also tried running it locally but unfortunately I am not able to deploy the application on the GlassFish because of following error "Exception while loading the app : EJB Container initialization error". I am trying to look into it.


Answer:

They're two unrelated concepts.

If you seperate concerns, and you should. Then the HTTP session and EJB session(s) operate at logically distinct layers. The http session is for holding an individual web browser and user's state. An EJB session is used for holding transactional, scalable and fault-tolerant and "transparently" (and possibly remote) reference(s) within the context of an Enterprise application client.

The fact that you're using EJB(s) to serve web content, does not mean you cannot also use those same EJB(s) to serve JFC/Swing (or JavaFX) clients.

Question:

I'm querying a DB in this EJB. Result is Iterable (I can't change that).

But since the EJB is @Stateless it will "reuse" the Iterable<>, and the query result just gets added to it. Instead of being a "new" one!

How could i avoid that ?

I don't know if there a "fix" on the Iterable or is there something to be done with the SessionBean? Is this a bad combination?

@Stateless
public class StartSessionBean implements Serializable, StartSessionBeanLocal {
...
public Iterable<VType> resultQuery;
...
    public List<VType> queryThis(String this) {
...
        resultQuery = (Iterable<Type>) "query DB";
        //Do Things here
        return something;
    }
}     

Answer:

You cannot maintain state such as public Iterable<VType> resultQuery; in a stateless session bean. That is what "stateless" means.

In practice what actually happens varies from implementation to implementation. Some will give you a brand new bean each time you call it. Others will select one from a pool and give you that one, with the result that each client may get another's instance of resultQuery.

If you want to maintain state in the EJB then you must use a @Stateful session bean.

Edit: You should not need to maintain the resultQuery field anyway. Just make it a local in your method implementation. Presumably you're using it in a for-each loop as that is what they're for.

Question:

I have a stateful bean:

@Stateful
public class ClientContext {

    private Band band;

    public Band getBand() {
        return band;
    }

    public void setBand(Band band) {
        this.band = band;
    }
}

I have Arquillian test.

public class RequestTest extends Arquillian {

    ...

    @Inject
    private ClientContext context;

    @Inject 
    private RequestProcessor processor;

    @Test
    public void test() {
        context.setBand(new Band());
        Assert.assertNotNull(context.getBand());

        processor.doSomething();
    }

}

And Processor code:

@Stateless
@LocalBean
public class RequestProcessor {

    ...

    @Inject
    private ClientContext context;

    public void doSomething() {
        System.out.println(context.getBand());
    }

}

I expect RequestProcessor to print out the Band. But actually I get null every time. What can be wrong or may be I don't understand Stateful beans correctly?


Answer:

You are answering the question yourself, the main basis about the stateful is the keep just one instance per injection, which will live as long the injecting bean does. so in you need to share a state between beans, you could use a @SessionBean To clarify, the @Stateful means one instance are going to be created for each place where you are injecting it, this is useful when you need to bind some actions and their state to ONE component, so, if you need to create some info and then share between other classes you need to pick how you want to share it: @Singleton: There will be just one instance for the entire app. @SessionScoped: There will by one instance per client. @Stateless: Will create one if there is no other available, after it will be release for use of other clients If you are managing views the you can use too: @RequestScoped: Will create one instance for each request and then destroys it. @ViewScoped: The bean will remain as long the client keep making updates within the same view

Question:

I'm setting up a stateful session bean and want to call it with context.lookup(name) but have no idea how to correctly define the name variable.

I'm working with Intellij and as far as I know there is no way to automatically generate this path as compared to NetBeans. I have tried multiple ways using the guideline I found for this name: java:scope[/app-name]/module-name/bean-name[!fully-qualified-interface-name] However, I always get following error javax.naming.NamingException: Lookup failed for 'RememberEJB' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: RememberEJB not found]

Below is the method which calls the function:

public Response getRememberedPost() {
    try {
        javax.naming.Context context = new InitialContext(); // Could also be InitialContext context = new InitialContext();
        RememberBean rememberBean = (RememberBean) context.lookup("RememberEJB");
        return Response.ok(rememberBean).build();
    }
    catch (NamingException e) {
        e.printStackTrace();
        return Response.noContent().build();
    }
}

I expect the name variable has to be something like "java:global/project-name/folder-for-beans/RememberEJB!src.Beans.RememberLocal" but this still gives the same error.


Answer:

You can refer below from Java EE tutorial:

Accessing Local Enterprise Beans Using the No-Interface View Client access to an enterprise bean that exposes a local, no-interface view is accomplished through either dependency injection or JNDI lookup.

  • To obtain a reference to the no-interface view of an enterprise bean through dependency injection, use the javax.ejb.EJB annotation and specify the enterprise bean’s implementation class:

    @EJB    
    ExampleBean exampleBean;
    
  • To obtain a reference to the no-interface view of an enterprise bean through JNDI lookup, use the javax.naming.InitialContext interface’s lookup method:

    ExampleBean exampleBean = (ExampleBean)InitialContext.lookup("java:module/ExampleBean");
    

So in your case:

    RememberBean rememberBean = (RememberBean)context.lookup("java:module/RememberEJB");

Question:

Does transaction rollback affects Stateful bean state ? For example : if Exception occure's during JMS message handling, does injected Stateful bean will refresh it's state ?

update

There is an option to implement SessionSynchronization interface and afterCompletion method that allows to refresh state of the bean. But the question is - can it be done in automated way ?


Answer:

Depends on exception type, container discards bean instance (such that you can't reference to it again) on rollback due to RuntimeException and keeps bean state after Rollback for ordinary exception.

Question:

Ok I have a scenario here, and I want a standard solution, basically I have exposed EJBsession3 beans as my webservice on the server side and they further call the EJBsession3 bean to execute DAO methods. see below is the sample Code.

//This is a EJB3 session bean and I am using container managed jta transactions 
@Stateless
public class datatypes implements datatypesRemote {

@PersistenceContext(unitName = "EJBtest")
EntityManager entityManager;


public List<Datatype> retrieveAllDatatypes(int targetSystemId,EntityManager ent)
        throws RuntimeException {
    String q = "SELECT oneDatatype from " + Datatype.class.getName()
            + " oneDatatype "
            + "where oneDatatype.targetSystem.targetSystemId = "
            + targetSystemId;

    //entityManager=ent;
    Query query = entityManager.createQuery(q);


    System.out.println("Query retrieveAll" + q);
    @SuppressWarnings("unchecked")
    List<Datatype> templates = query.getResultList();
    return templates;
}

}

The class above is basically my DAO class that will handle queries now below is my web services class

 @WebService(serviceName="backend")
    @Stateless
    public class backEndForm implements backEndFormRemote {
    //@PersistenceContext(name = "EJBtest")
    //EntityManager entityManager;

   private datatypesRemote data= new datatypes();

        public List<Datatype> retrieveAllDatatypes(int id){      
            //entityManager.clear();
            data=new datatypes();
            return  data.retrieveAllDatatypes(id,null);
        }
    }

Now the Issue is like this my web client calls my web service method and that method further calls the DAO methods that will fetch the data from data base and return to the web service and web service will return data to the requesting client But when I execute my SQL query the entity manager is null I don't know why so a non standard solution I developed is to pass the entity manager from the web services class to the DAO class, as you can see in the sample code which is commented out.

So my question, is there any other Standard way to do it ? why the entity manager is null in the second ejb3 bean and not in the first ejb3 bean ?


Answer:

Injection does not happen when you create objects with the new operator. You need to let your container create the datatypes bean and inject it into your backEndForm:

@WebService(serviceName="backend")
@Stateless
public class backEndForm implements backEndFormRemote {

    @EJB
    private datatypesRemote data;

    public List<Datatype> retrieveAllDatatypes(int id){      
        return  data.retrieveAllDatatypes(id,null);
    }
}

Question:

I am not able to lookup local session beans from within an EJB module in WebLogic 10.3.6.

In the following example I could use injection, but in the actual product we will need to access local session beans from non-managed objects, so this is for demonstration of the problem. I also know it'll work with a remote interface, but why since I should be able to do it locally.

@Local
public interface MyBeanLocal {

    public void foo();

}

@Stateless(name = "MyBean")
public class MyBean implements MyBeanLocal {

    @Override
    public void foo() {
        System.out.println("Foo");      
    }

}

Here the client tries to look up the local session bean. This very same code seems to work in other application servers, but not in WebLogic.

@Stateless
public class CustomerInbound implements CustomerInboundLocal {

    @Override
    public void someOperation() throws Exception {

        try {

            // Exception is thrown here when looking up the object
            MyBeanLocal testLocal = (MyBeanLocal) 
                    new InitialContext().lookup("java:comp/env/MyBean");

            testLocal.foo();

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
}

Exception:

javax.naming.NameNotFoundException: While trying to look up comp/env/MyBean in /app/ejb/test-inject#CustomerInbound.; remaining name 'comp/env/MyBean'
    at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
    at weblogic.jndi.internal.ApplicationNamingNode.lookup(ApplicationNamingNode.java:144)
    at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:254)
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:412)
    at weblogic.jndi.factories.java.ReadOnlyContextWrapper.lookup(ReadOnlyContextWrapper.java:45)
    at weblogic.jndi.internal.AbstractURLContext.lookup(AbstractURLContext.java:130)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at beans.CustomerInbound.someOperation(CustomerInbound.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.oracle.pitchfork.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:34)
    at weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:54)
    at com.oracle.pitchfork.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:42)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy134.someOperation(Unknown Source)
    at beans.CustomerInbound_xaxie8_CustomerInboundLocalImpl.__WL_invoke(Unknown Source)
    at weblogic.ejb.container.internal.SessionLocalMethodInvoker.invoke(SessionLocalMethodInvoker.java:39)
    at beans.CustomerInbound_xaxie8_CustomerInboundLocalImpl.someOperation(Unknown Source)
    at beans.CustomerWSFacade.customerIn(CustomerWSFacade.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.oracle.pitchfork.spi.MethodInvocationVisitorImpl.visit(MethodInvocationVisitorImpl.java:34)
    at weblogic.ejb.container.injection.EnvironmentInterceptorCallbackImpl.callback(EnvironmentInterceptorCallbackImpl.java:54)
    at com.oracle.pitchfork.spi.EnvironmentInterceptor.invoke(EnvironmentInterceptor.java:42)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
    at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
    at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy133.customerIn(Unknown Source)
    at beans.CustomerWSFacade_jg1q6w_WSOImpl.__WL_invoke(Unknown Source)
    at weblogic.ejb.container.internal.WSOMethodInvoker.invoke(WSOMethodInvoker.java:22)
    at beans.CustomerWSFacade_jg1q6w_WSOImpl.__WL_customerIn_WS(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at weblogic.wsee.server.ejb.WsEjb.invoke(WsEjb.java:54)
    at weblogic.wsee.jaxws.WLSEjbInstanceResolver$WLSEjbInvoker.invoke(WLSEjbInstanceResolver.java:192)
    at weblogic.wsee.jaxws.WLSInstanceResolver$WLSInvoker.invoke(WLSInstanceResolver.java:74)
    at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:151)
    at com.sun.xml.ws.server.sei.EndpointMethodHandlerImpl.invoke(EndpointMethodHandlerImpl.java:268)
    at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:100)
    at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:866)
    at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:815)
    at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:778)
    at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:680)
    at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:403)
    at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:539)
    at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:253)
    at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:140)
    at weblogic.wsee.jaxws.WLSServletAdapter.handle(WLSServletAdapter.java:171)
    at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:708)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
    at weblogic.wsee.util.ServerSecurityHelper.authenticatedInvoke(ServerSecurityHelper.java:103)
    at weblogic.wsee.jaxws.HttpServletAdapter$3.run(HttpServletAdapter.java:311)
    at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:336)
    at weblogic.wsee.jaxws.JAXWSServlet.doRequest(JAXWSServlet.java:99)
    at weblogic.servlet.http.AbstractAsyncServlet.service(AbstractAsyncServlet.java:99)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3732)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

Answer:

You must declare a reference to the EJB in order to look it up from java:comp. You can either use the @EJB annotation (with or without injection, see What does the @EJB annotation do?), or you can declare the reference in web.xml using <ejb-ref>.

Otherwise, if you were using a newer version of WebLogic that supported EE 6, you could use the portable java:global, java:app, or java:module namespaces in order to look up the EJB directly, but since WebLogic 10.3.6 only supports EE 5, you would need to use the configured binding name of the EJB.

Question:

I am reading the book. It said the Singleton session bean will never be re-created in the event of a system exception, unlike other kind of session beans. So, I have some questions.

  1. Will both of stateless and stateful session beans be re-created in the event of a system exception ?

  2. When the singleton session bean instance encounters exceptions, could it continue to work well to response other requests ?


Answer:

  1. Stateless beans are created for every method call as necessary. Stateful beans will be destroyed, and the client needs to explicitly create a new one.

  2. Yes, singleton beans are never destroyed, so the same instance will be used for subsequent method calls even when beans of another type would be destroyed.

Question:

Program:

@Local
interface AInter{
//...
}
class A implements AInter{
//...
}
@Local
interface BInter extends AInter{
//...
}
class B implements BInter {
//...
}
In Backing:
@Inject
BInter binter; //It's work fine
But If i tried 
@Inject
AInter aInter; //But if i try to access A interface from my backing.

It showed warning like this

Multiple beans are eligible for injection to the injection point JSR-299 5.2.1

Please, Can anyone explain clearly i stucked here.If i continue this way in future it will make any problem.

Thanks.


Answer:

You are trying to inject an instance of AInter bean, but CDI container does not know which implementation to inject. You should use annotation qualifier to give him a hint, or use alternatives etc.