With the release of GateIn 3.6.0.Final we now have the ability to inject CDI beans directly into our portlet classes, whether they extend GenericPortlet or implement the Portlet interface, and any class that implements a Portlet Filter interface.
The injection works just the same as with any other CDI injection, with one small caveat. When deciding which Beans to inject into our portlet or filter, keep in mind that injecting a normal scoped bean, such as @SessionScoped, is fine even though there is no User Session present, because the container will simply inject a client proxy for us, but it's not possible to inject a Bean that is being produced by another Bean that doesn't have a valid context.
To explain this with an example, if we take the following portlet class:
public class BadPortlet extends GenericPortlet { @Inject private Greeting myGreeting; }
and create a producer for it such as:
@SessionScoped public class GreetingProducer implements Serializable { @Produces public Greeting produceGreeting(InjectionPoint point) { ... } }
We receive a ContextNotActiveException because we're trying to produce one Bean from another Bean that is not yet, as there is no User Session during Portlet Container initialization.
When wanting to inject a produced Bean into a portlet class or filter, they need to be produced by @ApplicationScoped or @Dependent scoped Beans.
Here's an example portlet showing how we can use CDI injection:
public class MyPortlet extends GenericPortlet { @Inject MyBean bean; public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/myPage.jsp"); request.setAttribute("myBean", bean); dispatcher.include(request, response); } }
In our JSP we can then access the bean with ${myBean}.
I hope that this introduction into creating CDI enabled portlets and portlet filters will make your next portlet a bit easier to use with CDI!