Reputation: 3320
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)
Upvotes: 4
Views: 2602
Reputation: 1611
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 :).
Upvotes: 7
Reputation: 597224
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.
Upvotes: 1
Reputation: 8446
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.
Upvotes: 1