Migrate JSF managed beans to CDI managed beans
Asked Answered
B

1

12

I'm planning to convert a web app from using JSF managed bean to using CDI managed beans. I know I'll need to do below:

  1. Add a empty beans.xml file in WEB-INF.
  2. Replace all JSF @ManagedBean to CDI @Named annotations.
  3. Replace all JSF scope annotations with CDI or OmniFaces scope annotations.
  4. Replace all JSF @ManagedProperty with CDI @Inject annotations.

Is that all that needs to be done? Are there any gotchas that I need to be aware of?

Banausic answered 22/3, 2016 at 13:18 Comment(2)
Answer depends on the server used. On e.g. Tomcat you'd need to install CDI itself too.Trillby
I'm using TOMEE. So, CDI is already available. I'm more worry about gotcha in the webapp. It is hard to test every aspect of the app. So, if there are known gotcha, it would be nice to know to watch out for.Banausic
T
10

Basically, that's indeed all you need to do provided that you're on a Java EE server already. When on Tomcat, you'd need to manually install CDI first. Instructions for both Weld and OpenWebBeans are detailed in the blog How to install CDI in Tomcat?

The below gotchas need to be taken care of:

  • While OmniFaces 2.x "officially" requires JSF 2.2, OmniFaces 2.0/2.1 is technically backwards compatible with JSF 2.1 and should in TomEE's case work on TomEE 1.x with JSF 2.1 as well, but OmniFaces 2.2 has a hard JSF 2.2 dependency (due to the new <o:viewAction> tag) and won't deploy on TomEE 1.x without upgrading its MyFaces JSF implementation to a 2.2 compatible version, or itself being upgraded to TomEE 7.x. See also OmniFaces Compatibility Matrix.

  • When you deploy an EAR with multiple WARs with each its own OmniFaces library, then generally all CDI functionality will work in only one WAR as the CDI context of a WAR-provided library is incorrectly interpreted as EAR-wide. This is an oversight in CDI spec and yet to be fixed in a future CDI version. See also OmniFaces Known Issues (CDI).

  • When you want to use OmniFaces-provided CDI injection support in @FacesConverter or @FacesValidator, and you're going to create/use a CDI 1.1 compatible beans.xml (and thus not a CDI 1.0 compatible one or an empty one), then you need to make sure that you have explicitly set bean-discovery-mode="all" in beans.xml. See also @FacesConverter showcase.

  • When replacing @ManagedBean(eager=true), be aware that standard CDI has no direct equivalent for this. You would use @Observes for this. OmniFaces offers @Eager annotation for the purpose. See also How to configure a start up managed bean?

  • When replacing @ManagedProperty in JSF 2.0/2.1/2.2, be aware that you can't inject #{param.xxx}, #{cookie.xxx} and #{initParam.xxx} directly via @Inject alone, while that was just possible via @ManagedProperty. OmniFaces offers respectively @Param, @Cookie and @ContextParam for the purpose. Only in JSF 2.3 there's a new @javax.faces.annotation.ManagedProperty annotation which can be used exactly the same way as original @javax.faces.bean.ManagedProperty which got deprecated since JSF 2.3.

Trillby answered 22/3, 2016 at 15:17 Comment(1)
Thanks BalusC. I did 1 - 4, and have done a few tests and all appears to be working. Surprised to be that seamless. Side note: I recently migrated this app from Websphere 8.1 (myfaces2.0) to TOMEE 1.7 (myfaces 2.1.17). Since then, we've been experiencing memory issue. TOMEE server hung after one week of running, due to max out heap. I noticed a lot of viewscoped beans in the memory dump. I'm hoping omnifaces' viewscoped can help eliminate this issue. I just don't understand why the problem is not happening in Websphere. Oh well, thanks for the pointers.Banausic

© 2022 - 2024 — McMap. All rights reserved.