1

In the oficial Java EE documentation https://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html says "Session beans can implement asynchronous methods". Following this tutorial I'm not able to execute a method asynchronously.

It actually Works, but like any other synchronous method. (It doesn´t start any other thread).

@ManagedBean(name = "inicioSSCCBean") 
@SessionScoped
public class InicioSSCCBean implements Serializable {

    ...

    @Asynchronous
    public Future<String> sendMessage() {
        String status;
        try {
            // Call to SAP server...
        } catch (MessagingException ex) {
            // Error handler
        }
        return new AsyncResult<String>(status);
    }

    public void otherMethod() {
        String result = sendMessage().get();    // The result is what I expect
        System.out.println(result); 
    }

    ...

}

Do anyone know how to implement an async call from a session bean? The main goal is to make a call to a SAP service, and get the results asynchronously.

I´m using JSF 2.2, PrimeFaces.

Thanks in advance.

juanmorschrott
  • 573
  • 5
  • 25

2 Answers2

6

You misunderstood the Java EE tutorial. The term "Session bean" refers to enterprise session beans (EJBs), not to session scoped managed beans (JSF/CDI beans).

The @javax.ejb.Asynchronous annotation, as its package already hints, works only in EJBs. EJBs are recognizable by having a @javax.ejb.Xxx annotation on the class, such as @Stateless or @Stateful.

Below is the correct kickoff example:

@Stateless
public class YourService {

    @Asynchronous
    public void asyncDoSomething() {
        // ...
    }

}

@ManagedBean
public class YourBean {

    @EJB
    private YourService yourService;

    public void submit() {
        yourService.asyncDoSomething();
    }

}

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • It's very important analyze the safety of threads when you are working with JSF. Ther's a enormeous probability of user start many threads for the same task... Thanks for the suggestions @BC. – Cold Aug 03 '17 at 21:54
  • @Cold: See also 2nd "See also" link. That part is already elaborated over there along with concrete examples. – BalusC Aug 04 '17 at 06:01
1

Aside from the fact that you're trying to use the wrong kind of bean, you'll have to understand how Future works.

When you call Future.get(), the thread will block until the Future has a result. Therefore sendMessage().get() will act exactly like a synchronous call.

However if you call sendMessage() and then perform other tasks before calling get(), it will be performed asynchronously. As you realize an asynchronous call is only useful when you don't need the result right away, making it less useful than it seems in most cases.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I tried whithout the get() method but it keeps working the same way. I´m using a JBoss AS 7 server. Don´t know if any specific configuration is needed. Thanks in advance. – juanmorschrott Sep 16 '16 at 12:41
  • 1
    Ah, the second common problem. You can't call the asynchronous method it from the same class. You'd want a service class (for example) with the asynchronous method injected into your bean. – Kayaman Sep 16 '16 at 12:43
  • No, `@Asynchronous` has no effect at all in JSF managed beans. – BalusC Sep 16 '16 at 21:20
  • @BalusC Oh, I missed that completely (and it's been quite a while since I've been involved with pure Java EE). However he did fall into the trap of calling `get()` immediately. – Kayaman Sep 17 '16 at 10:15