java.lang.ClassCastException: cannot be cast to com.ocpsoft.pretty.faces.rewrite

Splash Forums PrettyFaces Users java.lang.ClassCastException: cannot be cast to com.ocpsoft.pretty.faces.rewrite

This topic contains 21 replies, has 3 voices, and was last updated by  Lincoln Baxter III 7 years, 2 months ago.

Viewing 15 posts - 1 through 15 (of 22 total)
  • Author
    Posts
  • #17755

    tdruttenberg
    Participant

    I have this in my pretty-config.xml:

    <rewrite redirect=”301″ match=”ONDList” processor=”dne.nmt.ond.action.util.RemoveEmptyParams” />

    And here is my processor — I did not change the process method at all:

    public class RemoveEmptyParams implements Processor {

    public String process(RewriteRule arg0, String arg1) {

    // TODO Auto-generated method stub

    return null;

    }

    }

    I don’t want to include the full stack trace because it’s very long. Here is what may be the relevant part:

    java.lang.ClassCastException: dne.nmt.ond.action.util.RemoveEmptyParams cannot be cast to com.ocpsoft.pretty.faces.rewrite.Processor

    com.ocpsoft.pretty.faces.rewrite.processor.CustomClassProcessor.process(CustomClassProcessor.java:35)

    com.ocpsoft.pretty.faces.rewrite.RewriteEngine.processOutbound(RewriteEngine.java:83)

    com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedResponse.rewrite(PrettyFacesWrappedResponse.java:180)

    com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedResponse.encodeURL(PrettyFacesWrappedResponse.java:79)

    com.sun.faces.context.ExternalContextImpl.encodeActionURL(ExternalContextImpl.java:375)

    org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:220)

    org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:185)

    org.jboss.seam.faces.FacesManager.interpolateAndRedirect(FacesManager.java:96)

    org.jboss.seam.jsf.SeamNavigationHandler.handleNavigation(SeamNavigationHandler.java:36)

    com.ocpsoft.pretty.faces.application.PrettyNavigationHandler.processFacesNavigation(PrettyNavigationHandler.java:59)

    com.ocpsoft.pretty.faces.application.PrettyNavigationHandler.handleNavigation(PrettyNavigationHandler.java:48)

    com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:130)

    javax.faces.component.UICommand.broadcast(UICommand.java:387)

    org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)

    org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)

    org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)

    org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)

    com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)

    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)

    com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)

    javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)

    com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:112)

    jcifs.http.NtlmHttpFilter.doFilter(NtlmHttpFilter.java:125)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)

    org.jboss.seam.web.RewriteFilter.doFilter(RewriteFilter.java:63)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)

    org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)

    org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)

    org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)

    org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)

    org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)

    org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)

    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

    I have no clue how to proceed from here.

    Tanya

    #19999

    Are you sure you are implementing the correct processor class? It looks like it, but I tried your processor and everything worked fine (aside from the fact that you aren’t allowed to return null.)

    But I did not receive a CCException.

    What version of PrettyFaces are you using? What version of JSF?

    #20000

    It does however appear that there is a bug that Query Parameters are not available to Rewrite Processors, so I’ll need to look in to that.

    #20001

    tdruttenberg
    Participant

    These are my imports:

    import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule;

    import com.ocpsoft.pretty.faces.rewrite.Processor;

    The jar file I’m using is

    prettyfaces-jsf12-3.0.2.jar (I admit I deleted a bunch of numbers after the 3.0.2).

    JSF 1.2.

    ?

    #20002

    Well, strange, I’m sorry it’s being tricky; what you have should be working for you. Could you attempt to reproduce this problem in a sample app and send it over? It works fine for me:

    import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule;
    import com.ocpsoft.pretty.faces.rewrite.Processor;

    public class RemoveEmptyParams implements Processor
    {
    public String process(final RewriteRule rule, final String url)
    {
    String result = url.replaceAll("\?[^=]+=&", "?");
    result = result.replaceAll("&[^=]+=&", "&");
    result = result.replaceAll("&[^=]+=$", "");
    return result;
    }
    }

    However, I needed to fix a bug in PrettyFilter. You can copy this file into your classpath to see the fix now, but this will be in the next of 3.0.2-SNAPSHOT (after I clean up the hack-ish code that I wrote to get it working:

    package com.ocpsoft.pretty;

    /*
    * PrettyFaces is an OpenSource JSF library to create bookmarkable URLs.
    * Copyright (C) 2009 - Lincoln Baxter, III <lincoln@ocpsoft.com> This program
    * is free software: you can redistribute it and/or modify it under the terms of
    * the GNU Lesser General Public License as published by the Free Software
    * Foundation, either version 3 of the License, or (at your option) any later
    * version. This program is distributed in the hope that it will be useful, but
    * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
    * for more details. You should have received a copy of the GNU Lesser General
    * Public License along with this program. If not, see the file COPYING.LESSER
    * or visit the GNU website at <http://www.gnu.org/licenses/>.
    */
    import java.io.IOException;
    import java.util.List;

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    import com.ocpsoft.pretty.faces.config.PrettyConfig;
    import com.ocpsoft.pretty.faces.config.PrettyConfigurator;
    import com.ocpsoft.pretty.faces.config.mapping.PathParameter;
    import com.ocpsoft.pretty.faces.config.rewrite.Redirect;
    import com.ocpsoft.pretty.faces.config.rewrite.RewriteRule;
    import com.ocpsoft.pretty.faces.rewrite.RewriteEngine;
    import com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedRequest;
    import com.ocpsoft.pretty.faces.servlet.PrettyFacesWrappedResponse;
    import com.ocpsoft.pretty.faces.url.QueryString;
    import com.ocpsoft.pretty.faces.url.URL;

    /**
    * @author Lincoln Baxter, III <lincoln@ocpsoft.com>
    */
    public class PrettyFilter implements Filter
    {
    private static final Log log = LogFactory.getLog(PrettyFilter.class);

    private static final String REWRITE_OCCURRED_KEY = "com.ocpsoft.pretty.rewrite";

    private ServletContext servletContext;
    private String facesDynaViewId = "";

    /**
    * Determine if the current request is mapped using PrettyFaces. If it is, process the pattern, storing parameters
    * into the request map, then forward the request to the specified viewId.
    */
    public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain chain)
    throws IOException, ServletException
    {
    ServletResponse response = new PrettyFacesWrappedResponse((HttpServletResponse) resp, getConfig());

    try
    {
    log.debug("Character encoding: " + req.getCharacterEncoding());

    // TODO refactor this into a chain?
    rewrite((HttpServletRequest) req, (HttpServletResponse) resp);
    if (resp.isCommitted())
    {
    log.trace("Rewrite occurred, reponse is committed - ending request.");
    }
    else
    {
    URL url = getRequestURL(req);
    if (getConfig().isURLMapped(url))
    {
    PrettyContext prettyContext = PrettyContext.newInstance((HttpServletRequest) req);

    String viewId = prettyContext.getCurrentViewId();
    if (!response.isCommitted())
    {
    if (prettyContext.shouldProcessDynaview())
    {
    log.trace("Forwarding mapped request [" + url.getURL() + "] to dynaviewId [" + viewId + "]");
    req.getRequestDispatcher(facesDynaViewId).forward(req, response);
    }
    else
    {
    List<PathParameter> params = prettyContext.getCurrentMapping().getPatternParser().parse(url);
    QueryString query = QueryString.build(params);

    ServletRequest request = new PrettyFacesWrappedRequest((HttpServletRequest) req,
    query.getParameterMap());

    log.trace("Sending mapped request [" + url.getURL() + "] to resource [" + viewId + "]");
    if (url.getDecodedURL().matches(viewId))
    {
    chain.doFilter(request, response);
    }
    else
    {
    req.getRequestDispatcher(viewId).forward(request, response);
    }
    }
    }
    }
    else
    {
    ensurePopulatedContext(req);
    log.trace("Request is not mapped using PrettyFaces. Continue.");
    chain.doFilter(req, response);
    }
    }
    }
    catch (Exception e)
    {
    throw new ServletException(e);
    }
    }

    /**
    * Apply the given list of {@link RewriteRule}s to the URL (in order,) perform a redirect/forward if required.
    * Canonicalization is only invoked if it has not previously been invoked on this request. This method operates on
    * the requestUri, excluding contextPath.
    *
    * @return True if forward/redirect occurred, false if not.
    */
    private void rewrite(final HttpServletRequest req, final HttpServletResponse resp)
    {
    /*
    * FIXME Refactor this horrible method.
    */
    if (!rewriteOccurred(req))
    {
    RewriteEngine rewriteEngine = new RewriteEngine();
    URL url = getRequestURL(req);

    try
    {

    String queryString = req.getQueryString();
    if ((queryString != null) && !"".equals(queryString))
    {
    queryString = "?" + queryString;
    }
    else if (queryString == null)
    {
    queryString = "";
    }

    String decodedUrl = url.getDecodedURL() + queryString;
    String newUrl = decodedUrl;
    for (RewriteRule c : getConfig().getGlobalRewriteRules())
    {
    if (c.matches(newUrl))
    {
    newUrl = rewriteEngine.processInbound(c, newUrl);
    if (!Redirect.CHAIN.equals(c.getRedirect()))
    {
    /*
    * An HTTP redirect has been triggered; issue one if we have a url or if the current url has been
    * modified.
    */
    if (c.getUrl().isEmpty() && !decodedUrl.equals(newUrl))
    {
    /*
    * The current URL has been rewritten - URLEncode it and redirect
    */
    // TODO fix this garbage
    String[] parts = newUrl.split("\?", 2);
    URL decoded = new URL(parts[0]);
    decoded.setEncoding(url.getEncoding());
    newUrl = decoded.getEncodedURL() + ((parts[1] == null) || "".equals(parts[1]) ? "" : "?")
    + parts[1];

    String redirectURL = resp.encodeRedirectURL(req.getContextPath() + newUrl);
    resp.setHeader("Location", redirectURL);
    resp.setStatus(c.getRedirect().getStatus());
    resp.flushBuffer();
    break;
    }
    else if (!c.getUrl().isEmpty())
    {
    /*
    * This is a custom location - don't URLEncode, just redirect
    */
    String redirectURL = resp.encodeRedirectURL(newUrl);
    resp.setHeader("Location", redirectURL);
    resp.setStatus(c.getRedirect().getStatus());
    resp.flushBuffer();
    break;
    }
    }
    }
    }

    if (!decodedUrl.equals(newUrl) && !resp.isCommitted())
    {
    /*
    * The URL was modified, but no redirect occurred; forward instead.
    */
    req.getRequestDispatcher(newUrl).forward(req, resp);
    }

    }
    catch (Exception e)
    {
    throw new PrettyException("Error occurred during canonicalization of request <[" + url + "]>", e);
    }
    finally
    {
    setRewriteOccurred(req);
    }
    }
    }

    private void setRewriteOccurred(final ServletRequest req)
    {
    req.setAttribute(REWRITE_OCCURRED_KEY, true);
    }

    private boolean rewriteOccurred(final ServletRequest req)
    {
    return Boolean.TRUE.equals(req.getAttribute(REWRITE_OCCURRED_KEY));
    }

    private void ensurePopulatedContext(final ServletRequest request)
    {
    PrettyContext.getCurrentInstance((HttpServletRequest) request);
    }

    public PrettyConfig getConfig()
    {
    if (servletContext == null)
    {
    log.warn("PrettyFilter is not registered in web.xml, but is registered with JSF "
    + "Navigation and Action handlers -- this could cause unpredictable behavior.");
    return new PrettyConfig();
    }
    return (PrettyConfig) servletContext.getAttribute(PrettyContext.CONFIG_FILES_ATTR);
    }

    private URL getRequestURL(final ServletRequest request)
    {
    String url = ((HttpServletRequest) request).getRequestURI();
    String contextPath = ((HttpServletRequest) request).getContextPath();

    if (url.startsWith(contextPath))
    {
    url = url.substring(contextPath.length());
    }

    URL result = new URL(url);

    String encoding = request.getCharacterEncoding();
    if (encoding != null)
    {
    result.setEncoding(encoding);
    }

    return result;
    }

    /**
    * Load and cache configurations
    */
    public void init(final FilterConfig filterConfig) throws ServletException
    {
    log.info("PrettyFilter starting up...");
    servletContext = filterConfig.getServletContext();

    PrettyConfigurator configurator = new PrettyConfigurator(servletContext);
    configurator.configure();
    facesDynaViewId = configurator.getFacesDynaViewId();

    log.info("PrettyFilter initialized.");
    }

    public void destroy()
    {
    }
    }

    #20003

    I would also make sure that you are using the correct fully-qualified class name in the processor=”” configuration. That’s the only thing that sounds like it might possibly be wrong off the top of my head.

    #20004

    tdruttenberg
    Participant

    Lincoln, I was working on the sample app and something occured to me.

    I *think* in my other app I’m using JSF 1.2, because I checked the MANIFEST of one of my JSF jar’s. Can you tell me how exactly to find out which JSF I am using? Maybe the problem has to do with the version of JSF I am using.

    TDR

    #20005

    tdruttenberg
    Participant

    My sample app works like a charm. *Exactly* as advertised. The app I’m having trouble with is a seam app. Any special tricks for doing this in seam?

    #20006

    Yeah you can find out, but that really shouldn’t matter (at least for the exception you are getting… we can take a look though.) There’s always a chance, because using the wrong version of prettyfaces/jsf tends to cause strange issues ;)

    Questions:

    Which app-server/version are you using?

    Where are your JSF Jars?

    If you open the JSF jars, take a look inside the META-INF/manifest.mf, it should tell you which version you have.

    #20007

    tdruttenberg
    Participant

    I am using JBoss EAP 5.0. Definitely JSF 1.2.

    I just created a brand new seam app with almost no alterations and get this same error.

    I use Jboss dev studio and the Create Seam Web Project wizard.

    My project is an EAR and I had to install the prettyfaces jar file both in EarContent/lib AND WEB-INF/lib.

    Have you successfully using prettyfaces in this type of project?

    #20008

    Did you get it working? You should not have to install in both EAR and WAR.

    #20009

    tdruttenberg
    Participant

    I thought you gave up on me!

    I had to install in both EAR and WAR. I got class not found when I only installed in WAR. I forget what symptom when I only installed in EAR. I couldn’t figure out why it worked out this way since the lib’s from the WAR are available to the EAR, but I couldn’t get it to work.

    Have you got this to work in a seam project?

    I would like to spend more time on this, but I don’t have the java no-how to figure it out myself.

    #20010

    No, I haven’t given up on you :) but I’m not very experienced with EAR deployments :( I’m hoping one of the other users has some ideas, but I’m continuing to look in to it.

    Could you tell me the exception you get when you put it just in WAR and just in EAR?

    Thanks,

    #20011

    I think placing PrettyFaces in both the EAR and WAR is causing this problem. If the Processor interface and your implementation class is loaded by different ClassLoaders, funny things (like ClassCastExceptions) can happen… :-)

    It would be really interesting to find out why placing PrettyFaces only in the WAR file does not work in your setup.

    #20012

    tdruttenberg
    Participant

    I thought I updated this yesterday. Hmmm wonder what happened to that.

    Interesting that you say that, chkal. I came across a posting on the jboss dev studio forum yesterday that suggested the same thing — namely that a jar appearing twice in the classpath can cause ClassCastException.

    For some reason the prettyfaces libraries are not seen by my RemoveEmptyParams class unless the prettyfaces jar is in the EAR classpath.

    I create the class in ond-ejb. There are pink lines and Xes everywhere indicating the class cannot find the prettyfaces Processor class. I add the Web App Libraries (which includes prettyfaces.jar) to the build path on ond-ejb. And still for some reason my class cannot compile. It’s as if it’s not even there.

    I’m going to try it again now to double-check, but I tried it yesterday to doublecheck and sure enough the problem persisted.

Viewing 15 posts - 1 through 15 (of 22 total)

You must be logged in to reply to this topic.

Comments are closed.