0

I have a page class defined as below (I've removed all custom fields).

public class TwoColPage extends PageImpl {
   //TODO: metadata fields
}

In my JSP I have

<jsp:useBean id="pageModel" type="org.company.models.TwoColPage" scope="request"/>

When I run the page, I get the following exception

Stacktrace: org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:574) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) root cause

java.lang.ClassCastException: org.dd4t.contentmodel.impl.PageImpl cannot be cast to org.company.models.TwoColPage org.apache.jsp.WEB_002dINF.views.pages.two_002dcolumn_002dpage_jsp._jspService(two_002dcolumn_002dpage_jsp.java:120) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168) org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) javax.servlet.http.HttpServlet.service(HttpServlet.java:622) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:729) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Should I be extending/implementing a different base class/interface or is there something else I am missing here?

I see that the getPage method of PageFactory returns interface Page, which PageImpl does implement (indirectly via GenericPage which is marked as deprecated)

1

This is fixed in dd4t-java version 2.0.6. Any class you want to deserialize page data into must implement the org.dd4t.contentmodel.Page interface or extend the PageImpl class:

public class MyPageImpl implements Page {
    // Code here
}

The PageFactory class has two new methods:

<T extends Page> T getPage(final String uri, final Class<T> pageModel ) throws FactoryException;

<T extends Page> T findPageByUrl (String url, int publicationId, Class<T> pageModel) throws FactoryException;

So deserialising your custom objects goes like this:

MyPageImpl page = pageFactory.getPage("tcm:x-x-64", MyPageImpl.class);

// OR

MyPageImpl page = pageFactory.findPageByUrl("/index.hml",7,MyPageImpl.class);
1

What it is trying to do here is downcasting, which is not really a good idea.

Simple Example:

  • PageImpl is Animal
  • TwoColPage is Cat
  • Not all Animals are Cats, so the compiler throws an error

The problem comes from this line in PageFactoryImpl

page = deserialize(pageSource, PageImpl.class);

It fixes the type of Page to PageImpl meaning the page (Super Class) cannot be cast to my page (Sub Class)

  • A better solution might be to wrap the PageImpl in your custom page class. – Quirijn Jun 10 '16 at 10:17
  • Care to share an example? Thanks :) – Chris Morgan Jun 10 '16 at 10:19
  • 1
    On second thought, it would be nice to overload the PageFactory.getPage method: PageFactory.getPage(String url, Type class) That would allow you to specify your own class to deserialize into. – Quirijn Jun 13 '16 at 16:47
  • Yes. That is exactly what I was thinking actually. Where T implements Page interface – Chris Morgan Jun 13 '16 at 16:53
  • See github.com/dd4t/dd4t-2-java/issues/64 – Quirijn Jun 13 '16 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.