UnserializableDependencyException: WELD-001413: The bean declares a passivating scope but has a non-passivation-capable dependency
Asked Answered
Q

2

10

I have the below CDI managed bean:

@Named
@SessionScoped
public class InfoPageController implements Serializable {

    @Inject
    private InfoPageMapper mapper;

}

It throws the below exception during deployment to GlassFish 4.1:

Exception while loading the app : CDI deployment failure:WELD-001413: The bean Managed Bean [class de.triaconsulting.cashyourgame.fe.controller.InfoPageController] with qualifiers [@Default @Any @Named] declares a passivating scope but has a non-passivation-capable dependency Managed Bean [class de.triaconsulting.cashyourgame.fe.mapper.InfoPageMapper] with qualifiers [@Any @Default]
org.jboss.weld.exceptions.UnserializableDependencyException: WELD-001413: The bean Managed Bean [class de.triaconsulting.cashyourgame.fe.controller.InfoPageController] with qualifiers [@Default @Any @Named] declares a passivating scope but has a non-passivation-capable dependency Managed Bean [class de.triaconsulting.cashyourgame.fe.mapper.InfoPageMapper] with qualifiers [@Any @Default]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointPassivationCapable(Validator.java:477)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:395)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:291)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:515)
    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:490)
    at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:419)
    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
    at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:225)
    at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:356)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:356)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
    at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
    at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    at java.lang.Thread.run(Thread.java:745)

How is this caused and how can I solve it?

Quinonez answered 28/8, 2015 at 13:41 Comment(2)
The message mentions InfoPageMapper but I didn't see any definition in your post - except the reference in InfoPageController that is. Message stripped down a bit: The bean Managed Bean [... InfoPageController] ... declares a passivating scope but has a non-passivation-capable dependency Managed Bean [... InfoPageMapper]Cypripedium
I do believe that simply means not all injected beans / properties of the session scoped bean are Serializable. And it seems to be pointing the finger at InfoPageMapper.Valerianaceous
L
26

The solution first, followed by an explanation:

The simplest you can do is mark the field InfoPageMapper mapper in InfoPageController as transient:

@Named
@SessionScoped
public class InfoPageController implements Serializable {

    @Inject
    transient private InfoPageMapper mapper;

And now the explanation:

The error message states this in readable language:

The bean InfoPageController, which is SessionScoped, must be serializable, but it requires InfoPageMapper, which is not serializable nor transient - it is not possible to determine how to serialize InfoPageController.

In CDI, there are some scopes (most often SessionScope) which require beans to be Serializable - mostly because they are somehow connected to HTTP Session, which can contain more objects that fit into memory and from time to time the server may need to swap them to disk.

It seems you got this because InfoPageController implements Serializable. But this is not enough according to Java serialization principles. You need to ensure that all member fields of your Serializable class are one of: - primitive type (int, boolean) - an object that is serializable (all serialization rules apply recursively) - the field is marked with keyword transient (which is placed at the same level as e.g. private keyword)

The trick with CDI is that you may mark all injected fields as transient, because they are injected again when the object is deserialized from disk into memory. Therefore you will not loose the transient object which would otherwise be null when deserialized, because it was not stored to disk previously.

Another solution is to make the injected bean InfoPageMapper serializable too. But then the problem may repeat recursively with fields injected into InfoPageMapper. Transient keyword solves your problem where it happens and does not force other benas to be serializable if they don't need to be.

Lyford answered 29/8, 2015 at 9:30 Comment(3)
Before marking the field transient I will double check if the field belong to the session coped bean. If InfoPageMapper is a bean with default scope (@Dependent) you implicitly make it a session scoped bean. So it is duplicated over each session. If the mapper has more a controller role, you probably better inject the session scoped element in it, at each invocation the correct data will be retrieved.Northumbrian
@Northumbrian - you are right, in some cases it makes sense to make injected bean as SessionScoped. From technical point of view, it would be also a Serializable bean, therefore it would solve the problem with exception. From logical point of view, the application might behave differently, as multiple beans would share the same bean in scope of a session.Liborio
Maybe a little advice: For my test cases I also forgot to set the discovery-mode from "annotated" to "all" in the beans. xml <<version="2.0" bean-discovery-mode="all">>.Complacent
T
1

By your server error message, check de.triaconsulting.cashyourgame.fe.mapper.InfoPageMapper. Is InfoPageMapper implements Serializable or not?

You inject InfoPageMapper object in Session Scope of InfoPageController object. Session scope objects and it's member need to serialize. So InfoPageMapper object must be able to serialize.

So InfoPageMapper must be implement Serializable Interface.

If you don't want to serialize InfoPageMapper object in InfoPageController, you can set transient keyword at this variable.

Trellas answered 28/8, 2015 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.