2013-12-19 13 views
7

ich entstehen gerade in der berüchtigten JavaEE CDI Fehler unter Glassfish Server:Warum CDI Bohnen unterstützen keine endgültige Methoden

org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions: 
Exception 0 : 
org.jboss.weld.exceptions.DeploymentException: WELD-001437 Normal scoped bean class ASController is not proxyable because the type is final or it contains a final method public final void ASController.selectPath(org.primefaces.event.NodeSelectEvent) - Managed Bean [class ASController] with qualifiers [@Default @Any @Named]. 

der Fehler ganz explikative in der Tatsache, dass er nicht endgültig Methoden innerhalb eines nicht mag CDI Bean, jedoch kann ich nicht nachvollziehen warum.

An diesem Link

http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e1429

sie erklären, es hat etwas mit der Serialisierung zu tun ist, aber ich kann nicht sehen, warum eine Klasse mit einer endgültigen Methode Serialisierung sollte jeden härter als ein mit nicht endgültig Methoden sein.

Antwort

12

Nun, es gibt mehrere Möglichkeiten, wie Sie ein Proxy-Objekt implementieren können. Da Sie jedoch erwarten, dass der Proxy den gleichen Typ wie die Proxy-Bean hat, müssen Sie Vererbung (oder Anforderungsschnittstellen) verwenden, die Sie dann implementieren könnten. Dies wäre jedoch kein Ansatz, bei dem jeder POJO eine Bean sein könnte CDI).

Das heißt, sie erstrecken sich intern von der Klasse, die Sie injizieren möchten, generieren einen Proxy-Code und geben Ihnen diese Unterklasse.

Dieser Proxy verarbeitet dann die ganze Magie, um sicherzustellen, dass Sie immer einen Bean haben, der zu Ihrem Kontext passt (und diese Bean hat alle variablen Variablenbeans, die auf die genau richtigen Beans zeigen).

Sie erhalten also nicht den Typ der Bean, die Sie injizieren möchten, sondern eine Proxy-Subklasse dieser Bean. Dies funktioniert nicht sehr gut mit endgültigen Methoden und Klassen und privaten Konstruktoren.

Wenn die Klasse nicht endgültig ist, kann der Proxy diese Klasse erweitern, aber die endgültige Methode kann nicht einfach überschrieben werden. Dies kann jedoch erforderlich sein (wenn beispielsweise Ihr Bean serialisiert ist, muss der Proxy es deserialisieren).

Es gibt, kompliziertere Möglichkeiten, um das. Man könnte diese Funktionalität injizieren, indem man den Byte-Code seiner Klasse über einen Agenten manipuliert (z. B. die letzten Modifikatoren entfernt, einen Standardkonstruktor einfügt, ...) und vielleicht sogar mit Vererbung mischt, aber dies ist noch nicht implementiert (und auch nicht trivial, um mehrere JVM-Implementierungen zu unterstützen).

aus der verknüpften Ressource ein Hinweis, dass dies für eine zukünftige Version geplant:

Hinweis

Eine zukünftige Version von Weld wahrscheinlich eine Nicht-Standard Abhilfe für diese Einschränkung unterstützen wird, unter Verwendung von nicht tragbaren JVM APIs: Sun, IcedTea, Mac: Unsafe.allocateInstance() (Der effizienteste) IBM, JRockit: ReflectionFactory.newConstructorForSerialization()

Aber wir haben nicht Umgehen Sie dies noch zu implementieren.

+0

ok jetzt klar, die andere Antwort war richtig, aber diese ist aufwendiger. – dendini

10

Container erstellen Proxy-Objekt für injizierte Klassen. Container verwendet also nicht Ihre Klassen, sondern diese Klassen. Java prohibit erweitert die finalen Klassen, sodass Sie keine finalen Klassen in CDI verwenden können.

+0

Meine Klasse ist nicht endgültig, es hat einfach eine endgültige Methode, so CDI kann es erweitern. – dendini

+2

Problem das gleiche, Proxy-Klassen überschreiben Methoden, aber wenn sie endgültige Proxy kann sie nicht überschreiben – Fireworks

Verwandte Themen