Use this task to troubleshoot errors related to Contexts
and Dependency Injection (CDI) for the Java Platform,
Enterprise Edition (Java EE)
applications.
About this task
When you use a CDI implementation, you might experience
errors during application deployment or when CDI interacts with other Java EE components. You might also
experience problems with producers, interceptors and decorators or
diagnostic trace. Use this task to fix these errors that might occur.
Procedure
- Troubleshoot application deployment problems. At
application deployment time, the container must validate each injection
point in the application and is satisfied by only one source of that
dependency.
- Resolve ambiguous dependency.
An ambiguous
dependency, or javax.enterprise.inject.AmbiguousResolutionException
exception, occurs when the container resolves an injection points
type and qualifiers to more than one managed bean, producer method,
or producer field.
The exception tells you the injection point
that was being processed, and the candidate beans that remained at
the end of the type-safe resolution process. Anything other than a
single bean is an application error:
javax.enterprise.inject.AmbiguousResolutionException:
There is more than one api type with : com.ibm.websphere.samples.AppObject
with qualifiers : Qualifiers: [@com.ibm.websphere.samples.MyQualifier()]
for injection into Field Injection Point, field name : loginCheck,
Bean Owner : [Name:loginBean,WebBeans Type:MANAGED,API Types:[java.lang.
Object,com.ibm.websphere.samples.LoginBean],
Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.
Default,javax.inject.Named]]
found beans: Name:newObject,WebBeans Type:PRODUCERMETHOD, API Types:[com.ibm.websphere.
samples.AppObject,java.lang.Object], Qualifiers:[javax.enterprise.inject.
Any,com.ibm.websphere.samples.MyQualifier,javax.inject.Named]
Name:newObject2,WebBeans Type:PRODUCERMETHOD, API Types:[com.ibm.websphere.
samples.AppObject,java.lang.Object], Qualifiers:[javax.enterprise.inject.
Any,com.ibm.websphere.samples.MyQualifier,javax.inject.Named]
To
resolve the error complete one of the following actions:
- Disambiguate the injection point by adding a qualifier to the
injection point and if necessary, one source of the dependency.
- If necessary, annotate one of the sources
of contextual instances with @Alternative or @Specializes, if some
of the dependencies should not be considered for injection.
- Resolve an unsatisfiable dependency.
An
unsatisfiable dependency, or javax.enterprise.inject.UnsatisfiedResolutionException,
occurs when there is no corresponding source for objects matching
an injection point in the application. The API type of the field,
along with the optional set of qualifier annotations, dictates the
set of beans that are valid to satisfy the dependency. Causes of unsatisfiable
dependency are as follows:
- There is no managed bean that is assignable to the type on the
injection point.
- There is no producer method of any managed bean whose return type
is assignable to the injection point.
- There is no producer field in any managed bean whose type is assignable
to the injection point.
- One of the previously mentioned scenarios are valid, but the Qualifier
annotations on the injection point are not present on the bean or
producer.
Note: Resolve the error by making a dependency
with the API type and qualifiers available by introducing a new bean,
removing qualifiers, or adding producers fields or methods. Section
5.2 of the Contexts and Dependency Injection for Java specification describes the type-safe resolution
in detail.
javax.enterprise.inject.UnsatisfiedResolutionException: Api type
[com.ibm.websphere.samples.myType] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Default()]
for injection into Field Injection Point, field name : loginCheck,
Bean Owner : [Name:loginBean,WebBeans Type:MANAGED,
API Types:[java.lang.Object,com.ibm.websphere.samples.LoginBean],
Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.
inject.Default,javax.inject.Named]]
If
the dependency is an Enterprise JavaBean (EJB) in a separate EJB module,
verify the EJB module is listed in the classpath of the META-INF/MANIFEST.MF
directory that is inside of the web project with the failing @Inject
annotation. In Eclipse, establish this relationship under Deployment
Assembly properties of the web project.
- Resolve passivating scope dependencies.
Passivation
is the act of moving an idle object that is held in memory auxiliary
storage. A passivating scope, such as the built-in scopes, @SessionScoped
and @ConversationScoped, requires that any bean using the scope be
passivation-capable. A bean is passivation-capable if it is either
a stateful session bean or any other managed bean that is both serializable
and has no non-serializable interceptors and decorators. Causes of
passivating scope dependencies include the following:
- Changing the scope of an existing bean to a passivating scope,
such as @SessionScoped or @ConversationScoped.
- Adding non-serializable decorators or interceptors to an existing
passivation capable bean.
Resolve the error as follows:
- Ensure that the bean in question is serializable.
- Ensure all interceptors and decorators of the bean implement serializable.
- Change the scope of the managed bean to a non-passivating scope.
In the following exception, the myCDIBean bean has java.io.Serializable
as an API type, therefore, the problem is an interceptor or decorator
of this bean:
Caused by: org.apache.webbeans.exception.WebBeansConfigurationException:
Passivation scoped defined bean must be passivation
capable, but bean : Name:myCDIBean,WebBeans Type:MANAGED,API
Types:[com.ibm.websphere.samples.myCDIBean java.io.Serializable,java.lang.
Object,com.ibm.websphere.samples.myLocalIface],
Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.
Default,javax.inject.Named] is not passivation capable
- Troubleshoot errors that result from CDI interacting with
other Java EE components.
The @Inject annotation provides an additional type of Java EE dependency injection. Its
relation to injection that is defined in Java EE
5 is as follows:
- Injection using annotations other than the @Inject annotation
behave as in previous releases, and only dependencies injected using
the @Inject annotation are contextual instances as defined by Contexts
and Dependency Injection for Java (JSR299).
- Use producer fields and producer methods to provide limited CDI
features (such as type-safe injection) of Java EE dependencies obtained using the @Resource,
@PersistenceContext, @PersistenceUnit, and @WebServiceRef annotations.
If you cannot obtain a value for an Expression Language (EL)
reference to a managed bean for JavaServer Pages (JSP) and JavaServer
Faces (JSF) components, consider the following approaches:
- Ensure that the bean class is annotated using the @Named annotation
or is annotated with a stereotype that defines the @Named annotation.
- Ensure that the EL expression matches the class name of the bean
class, after converting the first character to lowercase. When you
use the @Named annotation qualifier with a value member (for example,
@Named("myName")), this specifies the bean name (a special case qualifier)
but does not change the EL name of that bean.
For EJB components:
- You can inject session beans with the @Inject and @EJB annotations.
When you inject stateful session beans with the @Inject annotation,
the session beans can take advantage of type-safe injection using
qualifiers, and can have their life cycle managed by their CDI scope.
- Session beans are eligible for interception and decoration even
when they are not obtained with the @Inject annotation, unlike other
managed beans.
- If the dependency is an Enterprise JavaBean (EJB)
in a separate EJB module, verify the EJB module is listed in the classpath
of the META-INF/MANIFEST.MF directory that is inside of the web project
with the failing @Inject annotation. In Eclipse, establish this relationship
under Deployment Assembly properties of the web project.
For web service components:
- Troubleshoot producer errors.
- Looping in producer methods. When you use
a producer method, each parameter is treated as an injection point
in which the container provides the dependency. Therefore, the source
of contextual objects that fulfill those parameter injection points
must not be the same class that contains the producer method.
- Duplicate producer methods (two @Produces annotations
with same qualifiers in the same class). If a class
has multiple producer fields, these fields cannot have the same API
type and an identical set of qualifiers, as such a guaranteed ambiguous
dependency would not be injectable.
org.apache.webbeans.exception.definition.DuplicateDefinitionException:
PassivationCapable bean id is not unique:
PRODUCERFIELD#class#com.ibm.websphere.samples.AppObject#
@javax.enterprise.inject.Any(),@com.ibm.websphere.samples.AppScopeBinding2
(),@javax.inject.Named(value=),
bean:Name:a2b,WebBeans Type:PRODUCERFIELD,API Types:[java.lang.Object,
com.ibm.websphere.samples.AppObject],
Qualifiers:[javax.enterprise.inject.Any,com.ibm.websphere.samples
.AppScopeBinding2,javax.inject.Named]
- Troubleshoot interceptor and decorator errors.
- Enable interceptor, decorator enablement interceptors,
and decorators in the beans.xml file. All except EJB session beans
apply only to contextual instances of beans. Contextual instances
are instances obtained using the @Inject annotation or by calling
methods on the BeanManager interface.
- Interceptors and decorators in multiple bean deployment
archives (BDA). The set of enabled interceptors and decorators of
a bean class are a collection of the enabled interceptors and decorators
across the entire EAR file. The order of interceptors and decorators
that are defined in different beans.xml files is undefined.
- Use diagnostic trace to help determine why an error occurred.
- Obtain a trace for CDI by specifying JCDI=all:com.ibm.ws.webbeans*=all:org.apache.webbeans*=all.
- Obtain a list of all discovered managed beans by searching for
org.apache.webbeans.config.BeansDeployer in trace.log file. Each managed
bean, along with its type (interceptor, decorator, producer, enterprise
(EJB)) is displayed.
- Obtain a detailed listing of each bean and its type and qualifiers
by searching for the getBeans string.
- Obtain an additional trace for interacting with Java EE injection and the EJB container
by specifying EJBContainer=all:MetaData=all:Injection=all.
- Obtain an additional trace for interacting with web-related
scopes and life cycles by specifying all:com.ibm.ws.wswebcontainer*=all.
- Avoid heavyweight operations in default constructors of
managed beans.
Each injection point for a given managed
bean receives a new client proxy that calls the default constructor
of the underlying bean class, in addition to the actual bean instance
that might be created when using the proxy. Additionally, because
dependency injections occur after the constructor completes, constructors
cannot use injected dependencies. See the @PostConstruct annotation
life cycle callback for a place to put post-injection logic that runs
in the underlying instance only.