Ожидаемая? Компонент с ограниченным объемом запроса CDI, введенный в производителя, внедренный в зависимый компонент, дает WELD-001303: нет активных контекстов

Предположим, что RequestScope активен (используя @InRequestScope модуля cdi)

Дано

package at.joma.stackru.cdi;

public class Product {

    public Product(String withValue){
        this.value = withValue;
    }

    public String value;

}
  • введение продукта в эту активную область запроса
package at.joma.stackru.cdi;
import javax.inject.Inject;

import org.jglue.cdiunit.AdditionalClasses;
import org.jglue.cdiunit.CdiRunner;
import org.jglue.cdiunit.InRequestScope;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(CdiRunner.class)
@AdditionalClasses({ Producer.class, SomeCache.class })
public class ExpectedTest {

    @Inject
    Product productA;

    @Inject
    Product productB;

    @Test
    @InRequestScope
    public void testScoping() {
        Assert.assertNotNull(productA);
        System.out.println(productA.value);
        Assert.assertNotNull(productB);
    }

}
  • использование зависимого источника (с параметром InjectionPoint, поэтому должен быть зависимым)
package at.joma.stackru.cdi;

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;

public class Producer {

    public static final String VALUE_B = "valueB";

    public static final String VALUE_A = "valueA";

    @Inject
    SomeCache someCache;

    @Produces
    public Product produceProduct(InjectionPoint ip) {
        if (!VALUE_B.equals(someCache.getCacheValue())) {
            someCache.setCacheValue(VALUE_A);
        } else {
            someCache.setCacheValue(VALUE_B);
        }
        return new Product(someCache.getCacheValue());
    }

}
  • и этому производителю должен быть введен bean-компонент с областью запроса
package at.joma.stackru.cdi;

import javax.enterprise.context.RequestScoped;

@RequestScoped
public class SomeCache {

    private String cacheValue;

    public String getCacheValue() {
        return cacheValue;
    }

    public void setCacheValue(String cacheValue) {
        this.cacheValue = cacheValue;
    }

}

Когда это не удается, причина запроса bean-объекта bean с

org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:708)
    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 at.joma.stackru.cdi.SomeCache$Proxy$_$$_WeldClientProxy.getCacheValue(Unknown Source)
    at at.joma.stackru.cdi.Producer.produceProduct(Producer.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88)
    at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:78)
    at org.jboss.weld.injection.producer.ProducerMethodProducer.produce(ProducerMethodProducer.java:95)
    at org.jboss.weld.injection.producer.AbstractMemberProducer.produce(AbstractMemberProducer.java:167)
    at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:183)
    at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:69)
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:101)
    at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:761)
    at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:861)
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92)
    at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:375)
    at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:386)
    at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70)
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48)
    at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72)
    at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121)
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:159)
    at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:96)
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:101)
    at org.jboss.weld.bean.ContextualInstanceStrategy$ApplicationScopedContextualInstanceStrategy.get(ContextualInstanceStrategy.java:141)
    at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:99)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
    at at.joma.stackru.cdi.ExpectedTest$Proxy$_$$_WeldClientProxy.testScoping(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.jglue.cdiunit.CdiRunner$2.evaluate(CdiRunner.java:179)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
  • Это ожидаемое поведение для CDI?
  • Если да, то из-за зависимой псевдо области действия Producer?
  • Почему это не дает сбоя, если SomeCache является областью приложения, а не областью запроса?

Что является разумным решением для SomeCache?

Этот (неработающий) запрос в области видимости SomeCache действительно кэширует некоторые данные, необходимые производителю для создания первого bean-объекта, который должен быть введен. Так может

  • ни быть зависимым (поскольку это делает кеширование бесполезным)
  • и при этом это не должно быть областью применения или статическим (слишком широкая область)

В идеале он должен автоматически находиться в той же области действия bean-компонента, куда вводится Product, - в примере ExpectedTest. Вполне может быть другой настраиваемой областью действия cdi, но она не должна зависеть от определения клиентом / пользователем, определяющим эту область Можно назвать это "транзитивным компонентом, зависящим от области видимости", если это имеет смысл.

1 ответ

Это ожидаемое поведение для CDI? -> Нет

Причиной сбоя было то, что cdi-unit не регистрирует / сообщает, что не может настроить область запроса. И поэтому я пропустил определение следующей зависимости. Кстати, один определяется как предусмотрено в cdi-unit. Так что все дело в объемах:)

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
Другие вопросы по тегам