I have two similar methods. One is intended to handle objects, the other vectors:
@SuppressWarnings("unused")
private void printRows(PrintWriter out, Vector<?> dataOb,
String[] columns, String[] columnType,
Hashtable<?, ?> columnAccessors,
String trOptions, String tdOptions)
throws ServletException
{
System.out.println("At Printing Rows, Vector...");
// If the object is a vector, loop through the elements.
Vector<?> v = (Vector<?>) dataOb;
Enumeration<?> e = (Enumeration<?>) v.elements();
while (e.hasMoreElements())
{
tryRow(out, e.nextElement(),
columns, columnType, columnAccessors, trOptions, tdOptions);
}
}
private void printRows(PrintWriter out, Object dataOb,
String[] columns, String[] columnType,
Hashtable<?, ?> columnAccessors,
String trOptions, String tdOptions)
throws ServletException
{
System.out.println("At Printing Rows, Object...");
// If the object is an array, loop through the objects.
Object[] objects = null;
try {objects = (Object[]) dataOb;}
catch (Exception e1) { ExceptionToolkit.exceptionHandler (e1, "Can't assign data to objects"); }
System.out.println("At Printing Rows, have objects...");
for (Object object: objects)
{
System.out.println("At Printing Rows, have objects, looping...");
tryRow(out, object, columns, columnType, columnAccessors, trOptions, tdOptions);
}
}
If I understand Java and polymorphism correctly, if a call the method with a vector, the first function should be called, but if I call it with anything else which is an object, the second method should be called.
However, when my program goes to call the function, somehow it is getting the wrong one because instead of processing correctly, I get this:
CLASS: class hu.flux.models.PersonColumn: name
CLASS: class hu.flux.models.PersonColumn: phone
At Printing Rows, Object...
Can't assign data to objects: java.lang.ClassCastException: java.util.Vector cannot be cast to [Ljava.lang.Object;
java.lang.ClassCastException: java.util.Vector cannot be cast to [Ljava.lang.Object;
at hu.flux.tables.TableServlet.printRows(TableServlet.java:97)
at hu.flux.tables.TableServlet.service(TableServlet.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:674)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:579)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:930)
at org.apache.jsp.ShowPeople_jsp._jspService(ShowPeople_jsp.java:68)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:68)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:376)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:674)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:462)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:401)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at hu.flux.ControllerServlet.gotoPage(ControllerServlet.java:84)
at hu.flux.ControllerServlet.service(ControllerServlet.java:47)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:201)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:163)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:556)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:401)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:242)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:267)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:245)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:260)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
At Printing Rows, have objects...
If I understand the stacktrace correctly, it is telling me that it is failing because dataOb is a vector, but if this is true, shouldn't the other method have caught the call?
Did I misunderstand something about Java's polymorphism? Should something in the signature be different? Do I really need to check whether the object is an instance of vector before calling that specific function, instead of relying on polymorphism to handle the distinction? Is there a good way to fix this problem from within one or the other of the printRows() methods?