2015-08-28 30 views
6

ho il seguito CDI bean gestito:UnserializableDependencyException: WELD-001.413: Il fagiolo dichiara un ambito di passivazione, ma ha un non-passivazione-in grado di dipendenza

@Named 
@SessionScoped 
public class InfoPageController implements Serializable { 

    @Inject 
    private InfoPageMapper mapper; 

} 

Esso genera l'eccezione di seguito durante la distribuzione di 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) 

Come è stato causato e come posso risolverlo?

+1

Il messaggio menziona 'InfoPageMapper' ma non ho visto alcuna definizione nel tuo post, ad eccezione del riferimento in 'InfoPageController'. Messaggio ridotto un po ': 'Bean Managed Bean [... InfoPageController] ... dichiara un ambito passivante ma ha una dipendenza gestita non passiva Managed Bean [... InfoPageMapper]' – Thomas

+1

Credo proprio che significhi semplicemente no tutti i bean/proprietà iniettate del bean con scope di sessione sono serializzabili. E sembra puntare il dito su InfoPageMapper. – Gimby

risposta

10

La soluzione prima, seguita da una spiegazione:

Il più semplice che puoi fare è segnare il campo InfoPageMapper mapper in InfoPageController come transient:

@Named 
@SessionScoped 
public class InfoPageController implements Serializable { 

    @Inject 
    transient private InfoPageMapper mapper; 

E ora la spiegazione:

L'errore messaggio lo dice in lingua leggibile:

Il bean InfoPageController, che è SessionScoped, deve essere serializzabile , ma richiede InfoPageMapper, che non è serializzato o transitoria - non è possibile determinare come serializzare InfoPageController .

In CDI, ci sono alcuni ambiti (il più delle volte SessionScope), che richiedono i fagioli di essere Serializable - soprattutto perché sono in qualche modo collegati al HTTP Session, che può contenere più oggetti che si adattano in memoria e di tanto in tanto la il server potrebbe aver bisogno di scambiarli su disco.

Sembra che questo sia dovuto al fatto che InfoPageController implementa Serializable. Ma questo non è abbastanza secondo i principi di serializzazione Java. È necessario assicurarsi che tutti i campi membri della classe Serializable siano uno: - tipo primitivo (int, booleano) - un oggetto serializzabile (tutte le regole di serializzazione si applicano in modo ricorsivo) - il campo è contrassegnato con parola chiave transitoria (che è collocato allo stesso livello di una parola chiave privata)

Il trucco con CDI è che è possibile contrassegnare tutti i campi iniettati come transitori, perché vengono iniettati nuovamente quando l'oggetto viene deserializzato dal disco in memoria. Quindi non perderai l'oggetto transitorio che altrimenti sarebbe nullo quando deserializzato, perché non è stato precedentemente memorizzato sul disco.

Un'altra soluzione è rendere serializzabile anche il bean Injected InfoPageMapper.Ma allora il problema potrebbe ripetersi ricorsivamente con i campi iniettati in InfoPageMapper. La parola chiave transitoria risolve il problema dove si verifica e non impone la serializzazione di altri gruppi se non è necessario.

+0

Prima di contrassegnare il transitorio di campo, ricontrolleremo se il campo appartiene al bean coped di sessione. Se InfoPageMapper è un bean con scope di default (@Dependent) si rende implicitamente un bean con scope di sessione. Quindi è duplicato su ogni sessione. Se il mapper ha più un ruolo del controller, è meglio iniettare l'elemento della sessione in esso, ad ogni chiamata verranno recuperati i dati corretti. – Kazaag

+0

@Kazaag - hai ragione, in alcuni casi ha senso fare bean injected come SessionScoped. Dal punto di vista tecnico, sarebbe anche un bean serializzabile, quindi risolverebbe il problema con eccezioni. Dal punto di vista logico, l'applicazione potrebbe comportarsi in modo diverso, poiché più bean condividono lo stesso bean nell'ambito di una sessione. – OndrejM

+0

Forse un piccolo consiglio: per i miei casi di test ho anche dimenticato di impostare la modalità di ricerca da "annotated" a "all" nei bean. xml << version = "2.0" bean-discovery-mode = "all" >>. – Bluefire

0

Dal messaggio di errore del server, controllare de.triaconsulting.cashyourgame.fe.mapper.InfoPageMapper. È implicabile Serializable o InfoPageMapper?

Si inserisce l'oggetto InfoPageMapper in Session Scope dell'oggetto InfoPageController. Oggetti dell'ambito di sessione ed è necessario serializzare il membro. Quindi l'oggetto InfoPageMapper deve essere in grado di serializzare.

Quindi InfoPageMapper deve essere implementato interfaccia serializzabile.

Se non si desidera serializzare l'oggetto InfoPageMapper in InfoPageController, è possibile impostare la parola chiave transitoria su questa variabile.