You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by Chen Yang <cy...@hrsg.ca> on 2015/08/17 17:06:48 UTC

Fop Servlet error with tomcat running on Windows Server 2008 R2

Hi all,

I've been trying to deploy my FOP servlet to run on windows environment, but have had no success. It worked fine in the Linux setup; but in windows server, I can only get a PDF file when there is no image included.

I have all my images stored in another server and the servlet gets the image via URL inside my XML file. I made sure there is no whitespace in any URLs. (permissions & firewall setting are both been checked as well)

URL example:
<question id="577" comment="8">
<chart_url><![CDATA[http://testserver.com/output/img/54bf3f6c6371cf16d7b4519dd5187878.png]]></chart_url>
</question>

But Tomcat is somehow linked me to The resource path file:/C:/tomcat/bin/  and of course my image files are not there... so it's not valid. Not sure why tomcat wouldn't just use the image via URL like in Linux.

Any help will be appreciated!

Chen

Environment setup

*         JRE 1.8.0_45

*         Tomcat 8.0.23

*         Windows Server 2008 R2

*         FOP trunk

Full error Message from Tomcat

HTTP Status 500 - javax.xml.transform.TransformerException: org.xml.sax.SAXException: The resource path [file:/C:/tomcat/bin/] is not valid

type Exception report

message javax.xml.transform.TransformerException: org.xml.sax.SAXException: The resource path [file:/C:/tomcat/bin/] is not valid

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.xml.transform.TransformerException: org.xml.sax.SAXException: The resource path [file:/C:/tomcat/bin/] is not valid
java.lang.IllegalArgumentException: The resource path [file:/C:/tomcat/bin/] is not valid
                org.apache.fop.servlet.FopServlet.doGet(FopServlet.java:166)
                javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
                javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
                org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

javax.xml.transform.TransformerException: org.xml.sax.SAXException: The resource path [file:/C:/tomcat/bin/] is not valid
java.lang.IllegalArgumentException: The resource path [file:/C:/tomcat/bin/] is not valid
                com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:755)
                com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:357)
                org.apache.fop.servlet.FopServlet.render(FopServlet.java:288)
                org.apache.fop.servlet.FopServlet.renderXML(FopServlet.java:255)
                org.apache.fop.servlet.FopServlet.doGet(FopServlet.java:157)
                javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
                javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
                org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Servlet Code

package org.apache.fop.servlet;

import java.net.*;
import java.io.*;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.io.output.ByteArrayOutputStream;

import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.MimeConstants;

import java.util.Calendar;
import java.text.SimpleDateFormat;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;

import org.xml.sax.SAXException;

public class FopServlet extends HttpServlet {

    /** Name of the parameter used for the XSL-FO file */
    protected static final String FO_REQUEST_PARAM = "fo";
    /** Name of the parameter used for the XML file */
    protected static final String XML_REQUEST_PARAM = "xml";
    /** Name of the parameter used for the XSLT file */
    protected static final String XSLT_REQUEST_PARAM = "xslt";
    /** Name of the parameter used for the ROOT URL */
    protected static final String ROOT_REQUEST_PARAM = "root_url";

    /** The TransformerFactory used to create Transformer instances */
    protected TransformerFactory transFactory = null;
    /** The FopFactory used to create Fop instances */
    protected FopFactory fopFactory = null;
    /** URIResolver for use by this servlet */
    protected URIResolver uriResolver;

    public void init() throws ServletException {
        this.uriResolver = new ServletContextURIResolver(getServletContext());
        this.transFactory = TransformerFactory.newInstance();
        this.transFactory.setURIResolver(this.uriResolver);
        //Configure FopFactory as desired
        ResourceResolver resolver = new ResourceResolver() {
            public OutputStream getOutputStream(URI uri) throws IOException {
                URL url = getServletContext().getResource(uri.toASCIIString());
                return url.openConnection().getOutputStream();
            }

            public Resource getResource(URI uri) throws IOException {
                return new Resource(getServletContext().getResourceAsStream(uri.toASCIIString()));
            }
        };
        FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), resolver);
        //configureFopFactory(builder);

        try {
            String confFile = "C:\Program Files\tomcat\webapps\pdf_servlet\WEB-INF\iss-fop.xconf";
            builder = new FopConfParser(new File(confFile)).getFopFactoryBuilder();
        }catch(SAXException e) {
            System.out.println(e);
        }catch(IOException e) {
            System.out.println(e);
        }
        fopFactory = builder.build();
    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException {
        try {
            //Get parameters
            String foParam = request.getParameter(FO_REQUEST_PARAM);
            String xmlParam = request.getParameter(XML_REQUEST_PARAM);
            String xsltParam = request.getParameter(XSLT_REQUEST_PARAM);
            String RootParam = request.getParameter(ROOT_REQUEST_PARAM);

            //Analyze parameters and decide with method to use
            if (foParam != null) {
                renderFO(foParam, response);
            } else if ((xmlParam != null) && (xsltParam != null)) {
                renderXML(xmlParam,xsltParam,RootParam,response);
            } else {
                response.setContentType("text/html");
                PrintWriter out = response.getWriter();
                out.println("<html><head><title>Error</title></head>\n"
                          + "<body><h1>FopServlet Error</h1><h3>No 'fo' "
                          + "request param given.</body></html>");
            }
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }

    public static String now(String dateFormat) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(cal.getTime());
    }

    /**
     * Converts a String parameter to a JAXP Source object.
     * @param param a String parameter
     * @return Source the generated Source object
     */
    protected Source convertString2Source(String param) {
        Source src;
        try {
            src = uriResolver.resolve(param, null);
        } catch (TransformerException e) {
            src = null;
        }
        if (src == null) {
            src = new StreamSource(new File(param));
        }
        return src;
    }

    private void sendPDF(byte[] content, HttpServletResponse response) throws IOException {
        //Send the result back to the client
        response.setContentType("application/pdf");
        File pdfFileName = new File(now("MM/dd/yyyy"));
        response.addHeader("content-disposition","inline;filename=" + pdfFileName + ".pdf");
        response.setContentLength(content.length);
        //response.setContentLength(out.size());
        response.getOutputStream().write(content);
        response.getOutputStream().flush();
    }

    protected void renderFO(String fo, HttpServletResponse response)
                throws FOPException, TransformerException, IOException {

        //Setup source
        Source foSrc = convertString2Source(fo);

        //Setup the identity transformation
        Transformer transformer = this.transFactory.newTransformer();
        transformer.setURIResolver(this.uriResolver);

        //Start transformation and rendering process
        render(foSrc, transformer, response);
    }


    protected void renderXML(String xml, String xslt,String rootUrl,HttpServletResponse response)
                throws FOPException, TransformerException, IOException {

        //Setup sources
        StreamSource xmlSrc = new StreamSource(new URL(rootUrl + "/output/xml/" + xml).openStream());
        StreamSource xsltSrc = new StreamSource(new URL(rootUrl + "/output/xslt/" + xslt).openStream());

        //Setup the XSL transformation
        Transformer transformer = this.transFactory.newTransformer(xsltSrc);
        transformer.setURIResolver(this.uriResolver);

        //Start transformation and rendering process
        render(xmlSrc, transformer, response);
    }


    protected void render(Source src, Transformer transformer, HttpServletResponse response)
                throws FOPException, TransformerException, IOException {

        FOUserAgent foUserAgent = getFOUserAgent();

        //Setup output
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        //Setup FOP
        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

        //Make sure the XSL transformation's result is piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        //Start the transformation and rendering process
        transformer.transform(src, res);

        //Return the result
        sendPDF(out.toByteArray(), response);
    }

    /** @return a new FOUserAgent for FOP */
    protected FOUserAgent getFOUserAgent() {
        FOUserAgent userAgent = fopFactory.newFOUserAgent();
        //Configure foUserAgent as desired
        return userAgent;
    }

}