Is it possible to use Seam in a JBoss timed service?

天涯浪子 提交于 2019-12-05 02:44:45

问题


I've started to write some new JBoss timed service that was meant to use some existing seam components. But it seems that I can't access these components because of non-existing contexts. Is it possible to use them other than in the typical situation with JSF?

A little snippet to demonstrate what I want to do...

@Service
public class MyService extends DefaultTimedService implements TimedObject, DefaultServiceInterface {
    @Timeout
    public void ejbTimeout(Timer timer) {
        MyInterface loader = (MyInterface) Component.getInstance(MyInterface.SEAM_NAME, true);
        // throws no context!
    }
}

That throws the following exception for example:

java.lang.IllegalStateException: No application context active
    at org.jboss.seam.Component.forName(Component.java:1945)
    at org.jboss.seam.Component.getInstance(Component.java:2005)

回答1:


There is one way that is a little dirty and there are many developers that would not use such a hack ever but it will solve your problem:

import org.jboss.seam.contexts.Lifecycle;

@Service
public class MyService extends DefaultTimedService implements TimedObject, DefaultServiceInterface {
    @Timeout
    public void ejbTimeout(Timer timer) {
        Lifecycle.beginCall();

        MyInterface loader = (MyInterface) Component.getInstance(MyInterface.SEAM_NAME, true);
        // will not throw no context!
        // also the Component.getInstance(MyInterface.SEAM_NAME, true,true); call
        // is another way you could inject that component. 

        Lifecycle.endCall();
    }
}

I have used it in one project where I couldn't find anything else that worked. If anybody has another solution I am looking forward to seeing it here :).




回答2:


What scope have you defined for the component? Probably application context as it says so in the error.

...

So I poked around the source and found out that contexts are stored in a class named Contexts. All contexts seems to be thread specific, because they are encapsulated in ThreadLocal-instances. That means that has to specified for thread of the timed service...

The question remains though: how do create a context for a specific thread.




回答3:


Can't you inject the loader instance, instead of of locating it with that static call? I'm not quite familiar with Seam, but perhaps (in the class body):

@In private MyInterface loader;

and then, in your method, just use the loader.

As it seems, Seam has the application /statelesss scopes, which seems the appropriate one in your case:

@Scope(ScopeType.APPLICATION)

or

@Scope(ScopeType.STATELESS)

Try one of those - since your class doesn't seem to need any information from the session/request, it's more appropriate not to use a web-related scope.

So define MyService and MyInterface in one of the above scopes, and try both injection and your lookup method.

Check the Seam tutorial on contexts and concurrency

This thread seems helpful.

And from this thread it seems there is an @Asynchronous annotation, that you might use.



来源:https://stackoverflow.com/questions/2070262/is-it-possible-to-use-seam-in-a-jboss-timed-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!