简体   繁体   中英

Stateless EJB keeping state using EJB Schedule

I'm using JBoss AS 7 and a Schedule method on a EJB Stateless. My problem is that even the EJB is a Stateless one, its keeping its state, and this brings me trouble. Here is the example:

The timer:

@Stateless
public class TestTimer {

    @Inject HelloWorldService helloWorld;

    @SuppressWarnings("unused")
    @Schedule(second="*/10", minute="*", hour="*", info="MyTimer")
    private void execute() {
        System.out.println(helloWorld.sayHello());
        System.out.println(this.toString() + " "+ helloWorld.toString());
    }
}

The Injected HelloWorldService:

public class HelloWorldService {

    public String sayHello() {
        return "Hello World!";
    }
}

I was expecting that the line System.out.println(this.toString() + " "+ helloWorld.toString()); would print one different time every time the timer runs, since it would be a new TestTimer instance every time, but I was wrong:

16:43:50,003 INFO  [stdout] (EJB default - 3) foo.service.TestTimer@4a56936f foo.service.HelloWorldService@79e98289
16:44:40,022 INFO  [stdout] (EJB default - 1) foo.service.TestTimer@4a56936f foo.service.HelloWorldService@79e98289

Am I doing something wrong, this is the expected behavior, or what?

The EJB specification doesn't state that stateless beans discard their state after each invocation. It states that application developers must not rely on the bean keeping its state. There's a subtle, but very important difference. The same bean instance may be used multiple times; this doesn't negate stateless-ness.

What matters is that each timer there is a lookup, you may get a different instance of the bean
, but "may" means you may still get the same instance, as it is obtained from a pool of beans
That the container manages for you.
There is nothing wrong with using the same timer object,
as long as it provides the proper functionality.
This means that as a developer you cannot make any assumption on the state of the bean, and whether or not it is will be restored upon a new lookup of the bean.

The stateless beans can be used as many times as it needed. They are not neccecary created every time. You can look at EJB LifeCycle at http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html

This is the expected behavior (per Java EE specs) and is actually a bit more complicated than that.

The app server is managing a pool of staless session beans and using instances from this pool in order to server client requests. If you have some load on the server, then several beans will be used from the pool and each one will have its own state. So, in your test, you would end having sometimes the same string value printed, sometimes another one being printed.

You should not use properties for business logic. However, using properties for technical purposes (eg keep a reference to a DB) is sometimes a good idea.

The container has a pool of stateless session beans. It is internal to the container to handle the number of instances active (as far as i know) For your case it seems same instance is called by the timer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM