2

I am trying iReport/JasperReport in JSF 2 But while i am generating The PDF i got this error. I searched and found some similar problems and solutions, but nothing worked. Sorry for posting the same question again. But I tried all the possible solutions i found, but none worked for me. Please help

java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:637)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:214)
at com.sun.faces.context.ExternalContextImpl.getResponseOutputWriter(ExternalContextImpl.java:723)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.createResponseWriter(FaceletViewHandlingStrategy.java:1009)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:382)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:124)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

Following are the functions

public void init() throws IOException, JRException {
    JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listReportObjects);
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    servletOutputStream = httpServletResponse.getOutputStream();
    ServletContext servletContext = (ServletContext) externalContext.getContext();
    String reportLocation = servletContext.getRealPath("/web/ireport/monthlyReport.jasper");
    jasperPrint = JasperFillManager.fillReport(reportLocation, new HashMap<String, Object>(), beanCollectionDataSource);
}


public void PDF(ActionEvent actionEvent) throws IOException, JRException {
    System.out.println("*****************PDF*********************");
    init();
    JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
}

And the XHTML CODE: ;

My POM FILE :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.nic</groupId>
<artifactId>RFD</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>RFD</name>

<properties>
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>
</properties>

<dependencies>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.3.2</version>
        <scope>provided</scope>
    </dependency>        
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.1.13</version>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.1.13</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>
    <!-- PrimeFaces -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>3.4.1</version>
    </dependency>  
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>all-themes</artifactId>
        <version>1.0.8</version>
    </dependency>
    <dependency>
        <groupId>org.primefaces.extensions</groupId>
        <artifactId>primefaces-extensions</artifactId>
        <version>0.6.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.2</version>
    </dependency>       
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate</artifactId>
        <version>3.2.6.ga</version>
        <exclusions>
            <exclusion>
                <artifactId>antlr</artifactId>
                <groupId>antlr</groupId>
            </exclusion>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.3.2.GA</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-logging</artifactId>
                <groupId>commons-logging</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stdext</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>javax.transaction</groupId>
        <artifactId>jta</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.21</version>
    </dependency>
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.jettison</artifactId>
        <version>1.0.1_5</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.1.1.Final</version>
        <type>jar</type>
        <exclusions>
            <exclusion>
                <artifactId>antlr</artifactId>
                <groupId>antlr</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.8.3</version>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.5</version>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>            
        <version>4.8.0</version>
        <exclusions>
            <exclusion>
                <artifactId>commons-beanutils</artifactId>
                <groupId>commons-beanutils</groupId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>

    <plugins>        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>               
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <compilerArguments>
                    <endorseddirs>${endorsed.dir}</endorseddirs>
                </compilerArguments>                    
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.1</version>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${endorsed.dir}</outputDirectory>
                        <silent>true</silent>
                        <artifactItems>
                            <artifactItem>
                                <groupId>javax</groupId>
                                <artifactId>javaee-endorsed-api</artifactId>
                                <version>6.0</version>
                                <type>jar</type>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jasperreports-maven-plugin</artifactId>
            <version>1.0-beta-2</version>
            <configuration>
                <sourceDirectory>/web/ireport</sourceDirectory>
                <outputDirectory>/web/ireport</outputDirectory>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile-reports</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<repositories>
    <repository>
        <url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url>
        <id>eclipselink</id>
        <layout>default</layout>
        <name>Repository for library EclipseLink (JPA 2.0)</name>
    </repository>
    <repository>
        <url>http://repository.primefaces.org/</url>
        <id>primefaces</id>
        <layout>default</layout>
        <name>Repository for library PrimeFaces 3.2</name>
    </repository>                
</repositories>

Please Help

I have not used the Function getOutputStream() anywhere else in my project.

B.M.
  • 318
  • 2
  • 3
  • 19

4 Answers4

10

You may not have done so directly but several things in your code are suspect and can be modified to get the desired response. The exception you've gotten does not occur for any other reason other than trying to claim the response output stream after the servlet container has attempted to do so or doing so twice

1) The lines

 ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
 HttpServletResponse httpServletResponse = (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
 ServletContext servletContext = (ServletContext) externalContext.getContext();

is making repeated (and unnecessary calls) to context resources.

2) You've failed to call responseComplete() on your FacesContext instance which will almost certainly guarantee that writing a file for download to the stream will fail

3)While I'm not certain on this, I'd recommend you just move your report processing from the actionListener to action on your commandButton and remove the ActionListener argument from the method signature accordingly

4)I don't know what type jasperPrint is, but you can use JasperReport's JasperRunManager.runReportToPdfStream() function that accepts an input stream of .jasper file to output your report.

You can combine all that and use the following :

     FacesContext facesContext = FacesContext.getCurrentInstance(); //Get the context ONCE
     HttpServletResponse response = (HttpServletResponse)       facesContext.getExternalContext().getResponse();
     InputStream reportStream =   facesContext.getExternalContext().getResourceAsStream("/web/ireport/monthlyReport.jasper");
try {
    ServletOutputStream servletOutputStream = response.getOutputStream();
    response.setContentType("application/pdf");
    facesContext.responseComplete();

    try {  // Replace this with your desired JR utility method
        JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, params);
    } catch (JRException ex) {
        //
    }
    servletOutputStream.flush();
    servletOutputStream.close();
} catch (IOException ex) {
   //
} catch (Exception ex) {
       //
   }

Unrelated to your question, you need to be absolutely sure that the path /web/ireport/* is secure. Looks to me like a publicly accessible path.

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • thanks @kolossus, i will try your suggestion and let you know, and about the path `/web/ireport/*` i have a filter for that. – B.M. Dec 04 '12 at 05:22
  • It works but my day was ruined by `` when i was calling the function from it the generated report file was not coming to the browser, after so many different trials i tried `` it worked. Any idea how i can use `` for the same ? Thanks kolossus again :) – B.M. Dec 04 '12 at 11:24
  • 1
    You need to make `ajax="false"` on `` because you need a full web app life cycle request,not an ajax one, to achieve the desired results. This is the only reason that `` worked :). – kolossus Dec 04 '12 at 13:04
  • @BhaskarMalakar,answer above, forgot to reference your username – kolossus Dec 04 '12 at 13:40
  • 1
    works also for me, thanks. It was in my case extracting the facesContext into a variable and closingResponse at the end. 2 hours of looking for cause of that! – argh Aug 04 '15 at 21:21
6

For Others Help i m posting my final working (Solved) Code

public void init() throws IOException, JRException {
    JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(listReportObjects);
    String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/web/ireport/monthlyReport.jasper");
    jasperPrint = JasperFillManager.fillReport(reportPath, new HashMap(), beanCollectionDataSource);
    httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
}


public void pdf() throws IOException, JRException {
    init();
    httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
    servletOutputStream = httpServletResponse.getOutputStream();
    JasperExportManager.exportReportToPdfStream(jasperPrint, servletOutputStream);
    FacesContext.getCurrentInstance().responseComplete();
}

and the xhtml

<h:commandButton id="getPDF" value="PDF" actionListener="#{monthlyReportBean.pdf}" /> 
B.M.
  • 318
  • 2
  • 3
  • 19
1

using FacesContext.getCurrentInstance().responseComplete(); after exporting the report may solve your problem.

dpshkhnl
  • 86
  • 1
  • 6
0

I solved moving my commandbutton after h:form, I mean, outside of any container and it works, so I'm assuming there's something while the command its inside a div or a container, and I have noticed because the "ajax" attribute was set to False but still giving me and "Update" for the containers.

I hove this help.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459