Hi,
I'm developing a custom validator which uses it's own tag (I needed an attribute). I've followed the J2EE tutorial to a t, plus I've scoured many lines of source code to find the solution to my problem. Everything I see matches with what I've done, yet when I attempt to include the custom tag on my JSP it doesn't work.
I should mention that I load all of my JSPs on startup... So this error occurs on init of the JSP containing the custom tag.
[Servlet Error]-[AcctID]: Failed to load servlet: javax.servlet.ServletException: Failed to load JSP file: /AcctID.jsp
at com.ibm.ws.webcontainer.webapp.WebAppServletManager.loadJSPMappedServlet(WebAppServletManager.java:691)
at com.ibm.ws.webcontainer.webapp.WebAppServletManager.loadServlet(WebAppServletManager.java:172)
at com.ibm.ws.webcontainer.webapp.WebAppServletManager.loadAutoLoadServlets(WebAppServletManager.java:542)
at com.ibm.ws.webcontainer.webapp.WebApp.loadServletManager(WebApp.java:1277)
at com.ibm.ws.webcontainer.webapp.WebApp.init(WebApp.java:283)
at com.ibm.ws.webcontainer.srt.WebGroup.loadWebApp(WebGroup.java:387)
at com.ibm.ws.webcontainer.srt.WebGroup.init(WebGroup.java:209)
at com.ibm.ws.webcontainer.WebContainer.addWebApplication(WebContainer.java:1005)
at com.ibm.ws.runtime.component.WebContainerImpl.install(WebContainerImpl.java:136)
at com.ibm.ws.runtime.component.WebContainerImpl.start(WebContainerImpl.java:356)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:505)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:808)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:354)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:578)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:299)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:256)
at com.ibm.ws.runtime.component.ContainerImpl.startComponents(ContainerImpl.java:536)
at com.ibm.ws.runtime.component.ContainerImpl.start(ContainerImpl.java:413)
at com.ibm.ws.runtime.component.ApplicationServerImpl.start(ApplicationServerImpl.java:128)
at com.ibm.ws.runtime.component.ContainerImpl.startComponents(ContainerImpl.java:536)
at com.ibm.ws.runtime.component.ContainerImpl.start(ContainerImpl.java:413)
at com.ibm.ws.runtime.component.ServerImpl.start(ServerImpl.java:183)
at com.ibm.ws.runtime.WsServer.start(WsServer.java:128)
at com.ibm.ws.runtime.WsServer.main(WsServer.java:225)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at com.ibm.ws.bootstrap.WSLauncher.main(WSLauncher.java:105)
at com.ibm.etools.websphere.tools.runner.api.ServerRunnerV5$1.run(ServerRunnerV5.java:97)
No message text associated with key Failed.to.load.JSP.file:./AcctID.jsp in bundle com.ibm.ejs.resources.seriousMessages
Failed to load JSP file: /AcctID.jsp
Keep in mind that this JSP does NOT load at all. Any attempt to view the JSP will fail. I know that this has to do with my custom tag because if I remove it, the JSP works fine (with no errors).
The custom tag, custom validator and associated classes are in a separate JAR file then my web app. However, the TLD is in my web-app (WEB-INF/tld/).
As you can see from the stack trace above, there is absolutely no reference to my own code. It's all internal. This just makes things harder to track down.
So, could anyone help me figure out why my custom tag is not working? Here's the info you'll probably need:
The AcctID.jsp usage:
<h:inputText id="acctNum" value="#{changeBean.accountNumber}"
size="7" title="User ID">
<d:requiredValidator name="User ID" />
</h:inputText>
The TLD declaration:
<tag>
<name>requiredValidator</name>
<tag-class>jsf.taghandlers.RequiredValidatorTag</tag-class>
<description>
This tag ensures that a value is input into the field. The field
must not be null, must not be an empty String "" and must be a
String.
</description>
<attribute>
<name>name</name>
<required>true</required>
<type>String</type>
<description>
A descriptive name of the field BEING VALIDATED. This name is
used in the case of a validation failure to communicate what
component is required.
</description>
</attribute>
</tag>
The custom tag class:
public class RequiredValidatorTag extends ValidatorTag {
/** This validators ID. To be defined in the faces-config.xml file of your
* application. It is: "RequiredValidator" */
public static final String REQUIRED_VALIDATOR_ID = "RequiredValidator";
String name;
public RequiredValidatorTag() {
super();
System.out.println("RequiredValidatorTag called");
super.setValidatorId(REQUIRED_VALIDATOR_ID);
name = "";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
protected Validator createValidator() throws JspException {
System.out.println("createValidator() called. Calling super...");
RequiredValidator validator = (RequiredValidator)super.createValidator();
System.out.println("Super called successfully");
validator.setName(name);
return validator;
}
}
Parts of the validator class:
public class RequiredValidator implements Validator, StateHolder {
//vars
public RequiredValidator() {
this("");
}
public RequiredValidator(String name) {
System.out.println("RequiredValidator called");
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
//validation...
}
//StateHolder implementation methods...
}
Finally, the declaration in the
faces-config.xml:
<validator>
<description>Required Field Validator</description>
<validator-id>RequiredValidator</validator-id>
<validator-class>
jsf.validators.RequiredValidator
</validator-class>
<attribute>
<description>
A descriptive name of the field BEING VALIDATED. This name is
used in the case of a validation failure to communicate what
component is required.
</description>
<attribute-name>name</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</validator>
None of my System.out's are printed, it never gets that far. Please let me know if you need any other information.
Sorry so long.
Thanks,
CowKing