2016-04-08 18 views
1

セッションがありますが、私はRunnableを実装して@Stateless豆に注入されたBeanのアイデンティティ」をスコープ:SessionContextを新しいスレッドに伝播する方法はありますか(WELD-001303の取得)?

@Stateless 
@LocalBean 
public class Test implements Runnable { 
    @Inject 
    Identity identity; 
    @Inject 
    Logger log; 

    @Override 
    public void run() { 
     log.warn("Test: " + this + " " + identity.getAccount().getId()); 
    } 
} 

非同期のRunnable上で呼び出す豆もあります:

@Stateless 
@LocalBean 
public class BeanContextExecutor implements Executor { 
    @Asynchronous 
    @Override 
    public void execute(Runnable command) { 
     command.run(); 
    } 
} 

そして最後に、呼び出しは次のようになります。

@Stateless 
public class OtherBean { 
    @Inject 
    BeanContextExecutor executor; 
... 
     executor.execute(command); 
... 
} 

私は次のエラーを取得しています、これを実行している:

... 
Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped 
... 

SessionContextをバックグラウンドスレッドに伝播する方法はありますか?

また、このRunnableをManagedExecutorServiceに送信して、ContextServiceでプロキシを作成してプロキシを送信しても、同じエラーが表示されるようにしました。

ありがとうございました!私は新しいスレッドのためのダミーセッションコンテキストを作成するためにBoundSessionContextを使用しても、手動でバックグラウンドスレッドで、その状態を利用可能にするために必要なセッションBeanをコピーする必要がありましたBeanContextExecutorで回避策として

答えて

0

@Inject 
BoundSessionContext boundSessionContext; 
// Backed by a ConcurrentHashMap<Runnable, Identity> which stores the state of the session scoped bean before spawning a new thread 
@Inject 
GlobalExecutionContext globalExecutionContext; 
@Inject 
Instance<Identity> identityInstance; 
@Inject 
Cloner cloner; 
@Inject 
private BeanManager beanManager; 

@Asynchronous 
@Override 
public void execute(Runnable command) { 
    HashMap<String, Object> storage = new HashMap<>(); 
    boundSessionContext.associate(storage); 
    boundSessionContext.activate(); 

    Identity identity = globalExecutionContext.remove(command); 
    Bean<Identity> bean = (Bean<Identity>) beanManager.resolve(beanManager.getBeans(Identity.class)); 
    Identity localIdentity = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean)); 

    cloner.copyPropertiesOfInheritedClass(identity, localIdentity); 

    command.run(); 

    boundSessionContext.invalidate(); 
    boundSessionContext.deactivate(); 
    boundSessionContext.dissociate(storage); 
} 

例はアプローチを示すためのもので、任意の型のBeanをサポートするように改良することが可能です。しかし、私はこのアプローチがまったく好きではありません。コンテキストの伝搬の問題を解決するには、より良い解決策が必要です。

更新: 初期セッションが期限切れになっても、発信者IDをバックグラウンドスレッドで保持したいと思っています。上記の解決策がこれに適しているようです。

関連する問題