このコードが機能しない理由を理解できません。これはWildfly 10.1で実行されているCDI SessionScoped BeanへのアクセスがJava 8並列ストリームで機能しない
WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
:基本的に私はparallelStream()関数の中にCDI ViewScoped豆からCDI SessionScoped Beanにアクセスしたい、私はこの例外を取得します。
ViewScoped豆:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
@ViewScoped
@Named
public class TestController implements Serializable {
private static final long serialVersionUID = 1L;
@Inject SessionController sessionController;
public void works() {
List<Function<String, String>> functions = new ArrayList<>();
functions.add((String input) -> {
return sessionController.getSomething();
});
functions.add((String input) -> {
return sessionController.getSomethingElse();
});
functions.stream().forEach(f -> f.apply("input"));
}
public void doesNotWork() {
List<Function<String, String>> functions = new ArrayList<>();
functions.add((String input) -> {
return sessionController.getSomething();
});
functions.add((String input) -> {
return sessionController.getSomethingElse();
});
functions.parallelStream().forEach(f -> f.apply("input"));
}
}
SessionScoped豆:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class SessionController implements Serializable {
private static final long serialVersionUID = 1L;
public String getSomething() {
return "something";
}
public String getSomethingElse() {
return "else";
}
}
XHTML:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:form>
<p:commandButton value="Works" action="#{testController.works}" />
<br />
<p:commandButton value="Does Not Work" action="#{testController.doesNotWork}" />
</h:form>
</h:body>
</html>
スタックトレース:
Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at com.SessionController$Proxy$_$$_WeldClientProxy.getSomething(Unknown Source)
at com.TestController.lambda$3(TestController.java:33)
at com.TestController.lambda$5(TestController.java:38)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
私たちは、セッションは、特定のスレッドすることができる理論、ないハード証拠を持っています。
回避策がある場合はまた興味があります。実際のコードはこれよりはるかに複雑ですので、並列ストリームの利点を失うことなく、事前にSessionControllerの結果をプリロードすることはできません。
パフォーマンス上の理由からparellelストリームが重要な現実的なケースはまだありません –
この場合、各関数で異なるSQLクエリを実行しているため、完了するまでに最長のものを待つだけです私たちのSQL Serverに対して –
パラレルストリームはIO操作で使用されることはありません。代わりに、非常に長いリストの要素をN個の部分に分割し、N個の部分リストの合計を並行して実行し、最終的に副題を合計するなど、並列計算を実行するために使用することを意図しています。 –