Inject a EJB into a JSF converter with JEE6 [duplicate]
Asked Answered
A

4

14

I have a stateless EJB that acceses my database. I need this bean in a JSF 2 converter to retreive an entity object from the String value parameter. I'm using JEE6 with Glassfish V3.

@EJB annotation does not work and gets a NPE, because it's in the faces context and it has not access to the EJB context.

My question is: Is it still possible to Inject this bean with a @Resource or other annotation, or a JNDI lookup, or do I need a workaround?


Solution

Do a JNDI lookup like this:

  try {
   ic = new InitialContext();
   myejb= (MyEJB) ic
     .lookup("java:global/xxxx/MyEJB");   
  } catch (NamingException e) {
   e.printStackTrace();
  }
Amagasaki answered 7/1, 2010 at 10:12 Comment(0)
S
6

I never used JSF 2.0 (only 1.0), but chapter 5.4 of the spec says:

[...] allow the container to inject references to container managed resources into a managed bean instance before it is made accessible to the JSF application. Only beans declared to be in request, session, or application scope are eligble for resource injection.

But so far I understand, a JNDI lookup should do the trick.

Swage answered 7/1, 2010 at 10:41 Comment(3)
JNDI lookup doesn't work. I tried @EJB(mappedName="java:global/myProject/myEJB") where the value is the one that glassfish outputs in console as "portable JNDI name" of my EJB while deployingAmagasaki
don't use @EJB annotation. Get the target component using InitialContext.Adulteress
@bugspy.net: still hanging in the ol' J2EE days with lot of ignorance?Puleo
H
2

Other (yet not so pretty) solution may be using binding instead of converterId. Using JSF managed beans only:

<f:converter binding="#{app.personConverter}" />

Where appBean stands for something like: @ManagedBean(name="app") @ApplicationScoped class AppBean { @EJB private PersonService ps; private Converter personConverter; }

There MAY be a nicer solution in CDI-style (JSR-299) but i've failed to make this one running:

<f:converter binding="#{cdiBean}" />

Where cidBean ought to be: @Named class CdiBean implements Converter { @EJB ... }

Fails with 'Default behavior invoked of requiring a converter-id passed in the constructor'

Anyhow first approach using binding and app scoped JSF bean works.

Hooray answered 31/1, 2010 at 9:19 Comment(0)
M
2

The Seam Faces extension for JSF 2.0 and CDI allows @Inject support directly in Validators and Converters.

Check it out: http://ocpsoft.com/java/seam-faces-3-0-0-alpha2-jsf-2-0-just-got-even-easier/

Maegan answered 14/6, 2010 at 22:29 Comment(0)
D
2

i don't know if this solution is pretty... but it does work:

@ManagedBean
public class AcquisitionConverter implements Converter
{
    @EJB
    private AcquisitionService service;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        ...
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        ...
    }
}

and

<h:inputText value="#{flowController.acquisition}" converter="#{acquisitionConverter}">

with jsf 2.1.3 (mojarra) and glassfish 3.1.1

Drunken answered 19/1, 2012 at 0:36 Comment(3)
The @FacesConverter annotation is by the way superflous in this construct (and only confusing to starters). Remove it.Puleo
the converter="#{acquisitionConverter}" was the things that didnt work for meFitts
I finally managed to get it working with @Named @ApplicationScope on the converter, the trick was to create an @FacesConfig(version = FacesConfig.Version.JSF_2_3) @ApplicationScoped ApplicationConfig class, that triggers JSF to look for the CDI beans, otherwise it didn't work even though faces-config.xml had version=2.3Methanol

© 2022 - 2024 — McMap. All rights reserved.