Why CDI beans do not support final methods

I just rushed into the notorious JavaEE CDI error under GlassFish server:

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]. 

the error is quite understandable in that he does not like the final methods inside the CDI bean, but I cannot understand why.

This link

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

they explain that this is related to serialization, but I don’t understand why serializing a class with a final method should be more complicated than with non-final methods.

+7
java java-ee cdi
source share
2 answers

Well, there are several ways to implement a proxy object. But since you expect the proxy server to be of the same type as the proxied bean, you will have to use inheritance (or demand interfaces, which you could then implement, but this would not be an approach where each POJO could be a bean for CDI).

That is, they expand internally from the class you want to implement, generate some proxy code around this and provide you with this subclass.

Then this proxy handles all the magic to make sure you always have a bean that matches your context (and this bean has all the beans member variables pointing to the right beans).

That way, you really don't get the type of bean you want to insert, but the proxy subclass of that bean. This does not work very well with finite methods and classes and private constructors.

If the class is not final, the proxy server can extend this class, however, it cannot easily rewrite the final method. This may be required (if, for example, your bean is serialized, the proxy must deserialize it).

More complex methods are associated with this. You can introduce this functionality by manipulating the byte code of your class with an agent (for example, removing the final modifiers, inserting the default constructor ...) and maybe even mixing it with inheritance, but this has not yet been implemented (and also not trivial to support several JVM implementations).

From the linked resource, note that this is planned for a future version:

Note

A future Weld release is likely to support a non-standard workaround for this limitation using the non-portable JVM APIs: Sun, IcedTea, Mac: Unsafe.allocateInstance () (most efficient) IBM, JRockit: ReflectionFactory.newConstructorForSerialization ()

But we have not yet managed to realize this.

+12
source share

The container creates a proxy object for the classes introduced. Thus, the container does not use your classes, but these classes are extended. Banning Java extends final classes, so you cannot use final classes in CDI.

+10
source share

All Articles