Verwenden von CDI anstelle von @ManagedBean: UnproxyableResolutionException, weil die Superklasse keinen Konstruktor für keine Argumente hat

8

Ich versuche, CDI für meine JSF / Java EE-Anwendung zu verwenden. Ich habe die folgende Klassenhierarchie:

%Vor%

Wenn ich versuche, die Anwendung auf GF 3.1 zu implementieren, erhalte ich die folgende CDI / Weld-Ausnahme:

  

SEVERE: Ausnahme beim Laden der   App: WELD-001435 Normale Bohnen   Klasse   com.web.AbstraktCrudController   ist nicht proxybar, weil es keine hat   No-Args-Konstruktor.   org.jboss.weld.exceptions.UnproxyableResolutionException:   WELD-001435 Normale Klasse der Bohnen   com.web.AbstraktCrudController   ist nicht proxybar, weil es keine hat   No-Args-Konstruktor.           bei org.jboss.weld.util.Proxies.getUnproxyableClassException (Proxies.java:215)           bei org.jboss.weld.util.Proxies.getUnproxyableTypeException (Proxies.java:166)           bei org.jboss.weld.util.Proxies.getUnproxyableTypesException (Proxies.java:191)           bei org.jboss.weld.bootstrap.Validator.validateBean (Validator.java:134)           an org.jboss.weld.bootstrap.Validator.validateRIBean (Validator.java:148)           bei org.jboss.weld.bootstrap.Validator.validateBeans (Validator.java:363)           bei org.jboss.weld.bootstrap.Validator.validateDeployment (Validator.java:349)           bei org.jboss.weld.bootstrap.WeldBootstrap.validateBeans (WeldBootstrap.java:416)           at org.glassfish.weld.WeldDeployer.event (WeldDeployer.java:178)           bei org.glassfish.kernel.event.EventsImpl.send (EventsImpl.java:128)           bei org.glassfish.internal.data.ApplicationInfo.start (ApplicationInfo.java:265)           unter com.sun.enterprise.v3.server.ApplicationLifecycle.deploy (ApplicationLifecycle.java:402)           unter com.sun.enterprise.v3.server.ApplicationLifecycle.deploy (ApplicationLifecycle.java:221)           unter org.glassfish.deployment.admin.DeployCommand.execute (DeployCommand.java:351)           bei com.sun.enterprise.v3.admin.CommandRunnerImpl $ 1.execute (CommandRunnerImpl.java:360)           unter com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand (CommandRunnerImpl.java:375)           unter com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand (CommandRunnerImpl.java:1072)           unter com.sun.enterprise.v3.admin.CommandRunnerImpl.access $ 1200 (CommandRunnerImpl.java:101)           unter com.sun.enterprise.v3.admin.CommandRunnerImpl $ ExecutionContext.execute (CommandRunnerImpl.java:1221)           unter com.sun.enterprise.v3.admin.CommandRunnerImpl $ ExecutionContext.execute (CommandRunnerImpl.java:1210)           unter com.sun.enterprise.v3.admin.AdminAdapter.doCommand (AdminAdapter.java:375)           unter com.sun.enterprise.v3.admin.AdminAdapter.service (AdminAdapter.java:209)           bei com.sun.grizzly.tcp.http11.GrizzlyAdapter.service (GrizzlyAdapter.java:166)           unter com.sun.enterprise.v3.server.HK2Dispatcher.dispath (HK2Dispatcher.java:117)           unter com.sun.enterprise.v3.services.impl.ContainerMapper.service (ContainerMapper.java:234)           bei com.sun.grizzly.http.ProcessorTask.invokeAdapter (ProcessorTask.java:824)           unter com.sun.grizzly.http.ProcessorTask.doProcess (ProcessorTask.java:721)           unter com.sun.grizzly.http.ProcessorTask.process (ProcessorTask.java:1014)           unter com.sun.grizzly.http.DefaultProtocolFilter.execute (DefaultProtocolFilter.java:220)           unter com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter (DefaultProtocolChain.java:135)           unter com.sun.grizzly.DefaultProtocolChain.execute (DefaultProtocolChain.java:102)           bei com.sun.grizzly.DefaultProtocolChain.execute (DefaultProtocolChain.java:88)           unter com.sun.grizzly.http.HttpProtocolChain.execute (HttpProtocolChain.java:76)           unter com.sun.grizzly.ProtocolChainContextTask.doCall (ProtocolChainContextTask.java:53)           bei com.sun.grizzly.SelectionKeyContextTask.call (SelectionKeyContextTask.java:57)           bei com.sun.grizzly.ContextTask.run (ContextTask.java:69)           bei com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork (AbstractThreadPool.java:530)           bei com.sun.grizzly.util.AbstractThreadPool $ Worker.run (AbstractThreadPool.java:511)           bei java.lang.Thread.run (Thread.java:637)

Auch wenn ich der Basisklasse einen No-Args-Konstruktor hinzufüge, beschwert sich Weld immer noch mit der gleichen Ausnahme, dass die Klasse nicht proxyfähig ist, weil sie über finale Methoden verfügt. Warum zwingt mich WELD, mein Klassendesign zu ändern? Alles hat mit der JSF @ManagedBean-Annotation funktioniert.

Ich würde jede Hilfe schätzen. Danken, Theo

    
Theo 01.10.2010, 14:44
quelle

3 Antworten

15
  

Warum zwingt mich WELD, mein Klassendesign zu ändern? Alles hat mit der Annotation JSF @ManagedBean funktioniert.

Nun, Weld / CDI funktioniert nicht auf die gleiche Weise. Mein Verständnis ist, dass wenn Sie injection verwenden, um einen Verweis auf eine Bean zu erhalten, was Sie erhalten, in meist ein Proxy-Objekt. Dieses Proxyobjekt untergliedert Ihre Bean und überschreibt die Methoden zum Implementieren der Delegierung. Und dies führt zu einigen Einschränkungen für die Klassen CDI kann Proxy.

Die CDI-Spezifikation sieht so aus:

  

5.4.1. Unproxyable Bohnenarten

     

Bestimmte legale Bean-Typen können nicht sein   durch den Container:

     
  • Klassen, die keinen nichtprivaten Konstruktor mit nicht haben   Parameter,
  •   
  • Klassen, die als final deklariert sind oder finale Methoden haben,
  •   
  • primitive Typen,
  •   
  • und Array-Typen.
  •   

Wenn ein Einspritzpunkt dessen deklariert   Typ kann nicht von der   Container wird mit a zu einer Bean aufgelöst   normaler Bereich, der Container   erkennt automatisch das Problem und   behandelt es als ein Bereitstellungsproblem.

Mein Vorschlag wäre, die Methoden nicht endgültig zu machen.

Referenzen

  • CDI-Spezifikation
    • Abschnitt 5.4. "Client-Proxies"
    • Abschnitt 5.4.1 "Unproxyable Bohnenarten"
    • Abschnitt 6.3. "Normale Bereiche und Pseudo-Bereiche"
Pascal Thivent 01.10.2010, 15:28
quelle
0

Ich bin dabei, von JSF-verwalteten Beans zu CDI-verwalteten Beans zu migrieren, und ich habe gerade bestätigt, dass ich super erfolgreich in einer abgeleiteten CDI-Bean (mit 'benutzerdefiniertem' @Descendant-Qualifikationsmerkmal), die eine Vorgänger-CDI-Bean (mit @Default-Qualifier) ​​'erweitert'.

CDI-Bean-Vorgänger mit @Default-Qualifikationsmerkmal:

%Vor%

Vorfahren Bohne hat folgendes:

%Vor%

CDI-Bean-Nachkommen mit @Descendant-Qualifikationsmerkmal:

%Vor%

Die Nachkommen-Bean hat folgendes:

%Vor%

Ich musste super.init () hinzufügen / verwenden, weil Methoden in der CDI-Bean der Vorgängerklasse NullPointerException ausgelöst haben, da @PostConstruct der Vorgänger-Bean nicht in CDI @Descendant-Bean ausgeführt wird.

Ich habe gesehen / gehört / gelesen, dass es empfohlen wird, @PostConstruct anstelle der Constructor-Methode zu verwenden, wenn CDI verwendet wurde, also hatte der Konstruktor von ancest bean die Initialisierungslogik und der Konstruktor von ancest bean wurde automatisch aufgerufen / ausgeführt, wenn JSF verwendet wurde verwaltete Beans.

    
Howard 21.11.2012 09:09
quelle
0

Weil die angenommene Antwort richtig aber unvollständig ist, denke ich, dass ich meine zwei Cents nur für zukünftige Leser hinzufügen kann.

Das Problem, auf das OP gestoßen ist, kann auf zwei Arten gelöst werden:

  1. Durch Entfernen von final Schlüsselwort aus Methoden und Klasse selbst
  2. Eine solche "unproxyable class" mit @Singleton oder @Dependent pseudo-scope markieren (natürlich wenn es Sinn macht). Es wird funktionieren, weil CDI kein Proxy-Objekt für pseudo-beschränkte Beans erstellt.

Im OP-Anwendungsfall wurde der zweite Ansatz IMHO empfohlen, da Controller eindeutig als Singletons gekennzeichnet werden können.

Ich hoffe, es hilft jemandem

    
G. Demecki 11.11.2015 19:27
quelle

Tags und Links