In an effort to remove 'static' declarations throughout my app (to help JVM's GC), I removed 'static' from the definition of the Converter class below. So that resulted in the infamous error below:
Apr 13, 2013 4:10:38 AM org.apache.myfaces.application.ApplicationImpl internalCreateConverter SEVERE: Could not instantiate converter jsf.CustomerController$CustomerControllerConverter java.lang.InstantiationException: jsf.CustomerController$CustomerControllerConverter at java.lang.Class.newInstance0(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at org.apache.myfaces.application.ApplicationImpl.internalCreateConverter(ApplicationImpl.java:1626) at org.apache.myfaces.application.ApplicationImpl.createConverter(ApplicationImpl.java:1545) at javax.faces.application.ApplicationWrapper.createConverter(ApplicationWrapper.java:158) I assume 'static' is necessary, because only one copy of the class is created per application. Correct? So, can I define the class as a @Singleton @Lock(READ) to resolve the issue? Per NetBeans generated JSF controller/bean code, the Converter is usually defined in the same .java file as the controller or @ManagedBean. Honestly, I do 'not' want to use addConverter() or converterId="..." in the xhtml. I prefer to use @FacesConverter, since this has been working for me throughout the app. package jsf; import jpa.entities.Customer; import jpa.session.CustomerFacade; import java.io.Serializable; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.FacesConverter; @ManagedBean(name = "customerController") @RequestScoped public class CustomerController implements Serializable { @EJB private jpa.session.CustomerFacade ejbFacade; public CustomerController() { } @FacesConverter(forClass = Customer.class) public class CustomerControllerConverter implements Converter { public Object getAsObject(FacesContext facesContext, UIComponent component, String value) { if (value == null || value.length() == 0) { return null; } /* * 2012-07-10 when user enters invalid/incomplete value (e.g. "irene", see below) in AutoComplete * WARNING: For input string: "irene" java.lang.NumberFormatException: For input string: "irene" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:492) at java.lang.Integer.valueOf(Integer.java:582) at jsf.pointOfContact.pf_PointOfContactController$PointOfContactControllerConverter.getKey(pf_PointOfContactController.java:1625) at jsf.pointOfContact.pf_PointOfContactController$PointOfContactControllerConverter.getAsObject(pf_PointOfContactController.java:1620) at org.primefaces.component.autocomplete.AutoCompleteRenderer.getConvertedValue(AutoCompleteRenderer.java:529) at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030) at javax.faces.component.UIInput.validate(UIInput.java:960) * */ try { Integer test = getKey(value); } catch (java.lang.NumberFormatException e) { return null; } CustomerController controller = (CustomerController) facesContext.getApplication().getELResolver(). getValue(facesContext.getELContext(), null, "customerController"); return controller.ejbFacade.find(getKey(value)); } java.lang.Integer getKey(String value) { java.lang.Integer key; key = Integer.valueOf(value); return key; } String getStringKey(java.lang.Integer value) { StringBuffer sb = new StringBuffer(); sb.append(value); return sb.toString(); } public String getAsString(FacesContext facesContext, UIComponent component, Object object) { if (object == null) { return null; } if (object instanceof Customer) { Customer o = (Customer) object; return getStringKey(o.getCustomerId()); } else { throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Customer.class.getName()); } } } } Thanks, Howard