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
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.
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.
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:
final
Schlüsselwort aus Methoden und Klasse selbst @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
Tags und Links jsf-2 cdi jboss-weld