是否可以在JBoss定时服务中使用Seam?

时间:2010-01-15 08:24:38

标签: java service jboss seam

我已经开始编写一些新的JBoss定时服务,该服务旨在使用一些现有的接缝组件。但由于不存在的上下文,我似乎无法访问这些组件。是否可以在JSF的典型情况下使用它们?

一个小小的片段来展示我想要做的事情......

@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!
    }
}

例如:抛出以下异常:

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)

3 个答案:

答案 0 :(得分:7)

有一种方法有点脏,有很多开发人员不会使用这样的黑客,但它会解决你的问题:

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();
    }
}

我在一个项目中使用过它,在那里找不到其他有用的东西。如果有人有另一个解决方案,我期待在这里看到它:)。

答案 1 :(得分:1)

您为组件定义了哪些范围?可能是应用程序上下文,因为它在错误中如此说明。

...

所以我在源代码周围探索并发现上下文存储在名为Contexts的类中。所有上下文似乎都是特定于线程的,因为它们封装在ThreadLocal-instances中。这意味着必须为定时服务的线程指定...

问题仍然存在:如何为特定线程创建上下文。

答案 2 :(得分:1)

你不能注入loader实例,而不是用静态调用找到它吗?我对Seam不太熟悉,但也许(在课堂上):

@In private MyInterface loader;

然后,在您的方法中,只需使用loader

看起来,Seam有应用程序/无状态范围,在您的情况下似乎是合适的:

@Scope(ScopeType.APPLICATION)

@Scope(ScopeType.STATELESS)

尝试其中之一 - 因为您的课程似乎不需要会话/请求中的任何信息,所以不使用与Web相关的范围更合适。

因此,在上述范围之一中定义MyServiceMyInterface,并尝试注入和查找方法。

检查关于上下文和并发的Seam tutorial

This thread似乎很有帮助。

And from this thread似乎有一个@Asynchronous注释,您可以使用。