JSF 2: NoSubmittedReportException

Help
2012-07-07
2012-10-10
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-07

    In the posting in this forum JSF2 ConversationScope, yanlanglois seems
    to imply that it is possible to use the plugin with JSF 2, in spite of the
    conversation scope difficulties that were encountered.

    When I try to use JSF 2 with the plugin I get the following stack trace:

    SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/dart] threw exception [dartForm:inlineReport] with root cause
    net.sf.jasperreports.jsf.engine.fill.NoSubmittedReportException: dartForm:inlineReport
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.createJRFiller(DefaultFiller.java:211)
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.doFill(DefaultFiller.java:168)
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.fill(DefaultFiller.java:103)
        at net.sf.jasperreports.jsf.renderkit.ReportRenderer.encodeContent(ReportRenderer.java:79)
        at net.sf.jasperreports.jsf.component.UIOutputReport.encodeContent(UIOutputReport.java:157)
    

    Does anyone have the plugin working in JSF 2?

    -=> Gregg <=-

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-08

    After walking through the plugin with a debugger and hunting for a day, I
    finally discovered that it appears that it is necessary to install a custom
    Facelets View Handler to use the plugin. You must put the following in your
    faces-config.xml:

    <application>
            <resource-bundle>
                <base-name>com.yourCompany.messages</base-name>
                <var>msgs</var>
            </resource-bundle>
            <view-handler>net.sf.jasperreports.jsf.application.FaceletReportViewHandler</view-handler>
        </application>
    

    It would be helpful if this were added to the Getting Started page.

    Once I did this, I at least got a no class def error that made it abundantly
    clear that the code will not work in JSF 2 without porting it. The first error
    you run into is:

    Jul 7, 2012 9:14:29 PM com.sun.faces.config.ConfigManager initialize
    INFO: Unsanitized stacktrace from failed start...
    com.sun.faces.config.ConfigurationException: 
      Source Document: jndi:/localhost/dart/WEB-INF/faces-config.xml
      Cause: Class \\\'net.sf.jasperreports.jsf.application.FaceletReportViewHandler\\\' is missing a runtime dependency: java.lang.NoClassDefFoundError: com/sun/facelets/FaceletViewHandler
        at com.sun.faces.config.processor.AbstractConfigProcessor.createInstance(AbstractConfigProcessor.java:275)
        at com.sun.faces.config.processor.ApplicationConfigProcessor.setViewHandler(ApplicationConfigProcessor.java:523)
        at com.sun.faces.config.processor.ApplicationConfigProcessor.processViewHandlers(ApplicationConfigProcessor.java:843)
    ...
    

    So the initial start of porting means:

    at minimum following BalusC on Stack
    Overflow
    .

    I\\'ll try this and see how far I get.

    If I\\'m wrong about the need for the FaceletViewHandler, please let me know
    so that I can go bark up a different tree.

    -=> Gregg <=-

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-08

    I did discover that the ReportViewHandler parent of the
    FaceletReportViewHandler implements the JSF 2 view handler approach, so I put
    it into the view-handler declaration in place of FaceletReportViewHandler
    which uses the JSF 1.2 view handler approach. This got me past the
    NoClassDefError above; however, I still cannot get past the
    NoSubmittedReportException. I have walked the plugin code multiple times and
    it looks like the following code chain in UIReport is never invoked:

    processDecodes
        executeDecodes
            decodeSource(context);
            decodeReport(context);
    

    This ultimately leads to the DefaultFiller.createJRFiller method generating
    the NoSubmittedReportException, because its report variable is set to null.
    This happens because the above mentioned UIReport code chain never executes
    which in turn never invokes the UIReport.setSubmittedReport method to set the
    report value.

    Any ideas on why the UIReport chain is not being invoked?

    -=> Gregg <=-

     
  • Alonso Dominguez

    Hi Gregg,

    First of all, sorry for the delay giving you a response. You did a good work
    guessing the logic inside plugin's lifecycle (and thumbs up for that reference
    to BalusC at SO).

    However, It seems that you are using the last version of the trunk in your
    application instead one of the beta releases. As you could notice, the code at
    that "branch" is not working at all with JSF 2.0 (and behaving in a weird way
    with JSF 1.2). In fact, it's just an approach to simplify plugin's lifecycle
    so it could be more easy to port to JSF 2.

    Anyway, since it's not working the team now is focusing on revert back to
    beta-4 behaviour as it was more stable and, at least, with a few workarounds,
    it could be used in JSF 2. This branch of the plugin has taken too long and
    tried to go a bit far so know we are narrowing the scope to get a final
    release for JSF 1.2 and then quickly moving on to a JSF-2 migration.

    Alonso

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-10

    Thanks for the reply. I discovered exactly what you have stated before I saw
    your reply. At this point, I have everything setup in the latest RI JSF 2
    using the Beta 1.0.4 build and I can see that it is trying to fill the report
    up to the point where it tries to load an image. I tried your suggestion to
    another user where you specify the absolute path using IMAGES_DIR_NAME (note
    you had a typo in you previous post where you used singular IMAGE instead of
    plural IMAGES), but it doesn't work. Some more work with the debugger shows
    that it doesn't work because the FrameRenderer class in the renderkit.html
    package has an empty encodeChildren method, hence the child f:attribute is
    never processed!

    Is there any possibility that you can fill this method in and post a new
    build, or is it likely that the code will fail in some other place?

     
  • Alonso Dominguez

    Hi Gregg,

    Please, find patch for the FrameRenderer at this issue report:
    https://sourceforge.net/tracker/?func=detail&aid=3542484&group_id=212447&atid
    =1021785

    Since you are mentioning the "IMAGES_DIR_NAME" attribute I guess you are
    trying to use the HTML export. it would be good to have any feedback from you
    regarding this as it is one of the features that gave me more headaches.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-12

    I implemented your patch as follows:

        public void encodeChildren(final FacesContext context,
                final UIComponent component)
        throws IOException { 
            super.encodeChildren(context,component); 
        }
    

    I did this so that I could easily place a breakpoint on the super line to make
    sure that children are being encoded. This method is being called. When I step
    one line past the super invocation while still in the encodeChildren method
    and look at the HtmlReportFrame component, it still does not have any
    children.

    The code also stops at a breakpoint on the for loop in
    DefaultFiller.processParameterMap, but, obviously, since there are no encoded
    children for the HtmlReportFrame component, it skips the loop and doesn't
    store any parameters.

    My xhtml for the reportFrame is as follows:

                        <jr:reportFrame id="inlineReport" source="reportSource" 
                            value="/resources/report/dartTest/dartTest.jasper" 
                            height="300px" width="80%" 
                            format="csv">
                            <f:attribute name="IMAGES_DIR_NAME" value="C:\DevApps\workspace\DART\WebRoot\resources\report\dartTest"/>
                    </jr:reportFrame>
    

    I see the frame for the report come up in the page, but it still cannot access
    the byte data for the image, because, I continue to suspect, it cannot find
    the image path and it cannot find that because no children are coming in with
    the reportFrame component. I did check the TLD definition and it appears to be
    set correctly with body content of JSP. Clearly, even if the path is
    incorrect, the component should at least have the attribute child attached to
    it, but it has no children.

    Any ideas?

     
  • Alonso Dominguez

    You said you were using JSF RI right? Attribute tags don't produce any child
    component in the JSF view tree (not at least with Mojarra). AttributeTag
    extends the JSP 2.1 standard TagSupport class instead of the JSF
    UIComponentELTag, used to define JSF components.

    You should check if your component contains any IMAGES_DIR attribute rather
    than any children.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-17

    I have succeeded in getting an inline report to display using JSF 2 Mojarra
    2.1.10 and primefaces 3.3.1.

    Unfortunately, I still cannot load images within the report.

    After a lot of digging and debugging over several days I determined that
    IMAGES_DIR_NAME is not the correct parameter to use. I had it setup as
    follows:

    <jr:reportFrame id="inlineReport" source="reportSource" 
        value="/resources/report/dartTest/dartTest.jasper" 
        height="300px" width="80%" 
        format="html">
        <f:param name="IMAGES_DIR_NAME" value="C:\DevApps\workspace\DART\WebRoot\resources\report\dartTest"/>
        <f:param name="IS_OUTPUT_IMAGES_TO_DIR" value="true"/>
        <!-- f:param name="IMAGES_DIR" value="/dart/resources/report/dartTest"/ -->
        <!-- f:param name="IMAGES_URI" value="resources/report/dartTest"/ -->
    </jr:reportFrame>
    

    It is an export parameter and it does not get passed beyond the report
    parameter map to the export parameter map which are two independent and
    mutually exclusive maps as far as I can tell based on extensive tracing
    through the plugin and jasperreports code. In addition this parameter only
    controls the output directory name of exported report files that are
    generated during export and then placed into files. This behavior can be
    seen by asking iReport to generate a HTML preview of a report. If you look at
    the output location where the .jasper report file is stored you will see the
    generated HTML file (in my case dartTest.html) and a corresponding directory
    (in my case dartTest.html_files) that contains generated files, IF you are
    using the "images to align" property set to a default value of true. It is not
    responsible for defining where to obtain predefined images associated with a
    report. It simply changes the name of the directory dartTest.html_files where
    output files will be placed.

    In addition, parameters passed as children of the report frame tag are only
    passed into and managed in the REPORT_PARAMETERS_MAP and appear to only be
    passed to the report for use as input parameters that can be manipulated
    within the report. As mentioned above they are not placed into the export
    parameters map by the plugin code.

    I ran into one issue with the "images to align" property
    net.sf.jasperreports.export.html.using.images.to.align where the images were
    being generated and stored on disk but not loaded into the report leading to
    multiple broken images in the output. The issue is that such generated image
    files are not sent to the browser within the generated report stream. The fix
    for this issue is to create and then set the
    net.sf.jasperreports.export.html.using.images.to.align property to false
    within the Properties associated with the top level report object within
    iReport---click on the background of the report to select the main report
    object, scroll through the list of properties associated with this object
    until you find a property called "Properties" and then add this property to
    the list. This causes the old fashioned alignment via dummy images to be
    changed to align via table cells and CSS. I also added some additional
    properties as follows:

        net.sf.jasperreports.export.html.remove.emtpy.space.between.rows false
        net.sf.jasperreports.export.html.white.page.background true
        net.sf.jasperreports.export.html.flush.output true
    

    I have tried various combinations of things to get my images to load
    within the report, but nothing has worked so far. One critical thing that I
    found that at least allowed the report to load sans images and then display
    was to place the images in the classpath. If you also place the images in a
    subdirectory, say, images directly below the classes directory, then you must
    change the path in the report to be images/imageFile.jpg. This stopped a Byte
    Data not found
    crash error for the images, but the images are not displayed
    in the browser. Tried this (may not have this setup quite right yet)
    and also plan on trying this and, if necessary, the webapp sample from
    the jasperreports distribution. Hard to believe that it is this hard to get
    images to display within the report.

    If anyone has any additional ideas or is willing to iterate with me, it would
    be appreciated.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-19

    One thing I have noticed is that I get 404 errors for the two images
    coffee.jpg and coffee_stain.jpg and the URL returned via FireBug is http://lo
    calhost:8080/dart/net.sf.jasperreports.jsf/nullimg_0_0_4
    and http://localhost:8080/dart
    /net.sf.jasperreports.jsf/nullimg_0_0_0,
    when the images are in the classpath and the
    report properties for the images match the relative paths within the
    classpath. This gets past the Byte Not Found errors from JR, but JR doesn't
    seem to be sending them to the browser or the names or paths are not passed.

    The HTTP header via FireBug follows:

    Content-Length  1084
    Content-Type    text/html;charset=utf-8
    Date    Thu, 19 Jul 2012 18:09:24 GMT
    Server  Apache-Coyote/1.1
    Request Headersview source
    Accept  image/png,image/*;q=0.8,*/*;q=0.5
    Accept-Encoding gzip, deflate
    Accept-Language en-us
    Connection  keep-alive
    Cookie  JSESSIONID=D12EFCF40D1718783023D65B57325C90
    Host    localhost:8080
    Referer [url]http://localhost:8080/dart/net.sf.jasperreports.jsf/render.jsf?net.sf.jasperreports.jsf.clientId=dartForm%3AinlineReport&net.sf.jasperreports.jsf.viewId=/view/demoReport.jsp[/url]
    User-Agent  Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1
    
     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-19

    I also tried placing the dartTest.jasper file at the root of the webapp
    classpath and changed the reportFrame value accordingly. This would place it
    such that images under the images directory also in the classpath are in the
    proper relative location to the report, but still no luck.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-19

    This link seems to be the most likely to be
    correct based on lots of searching on the web. It seems to cover most of the
    options, except the servlet option from the JR demo webapp.

     
  • Alonso Dominguez

    Plugin's engine injects its own FileResolver into JasperReports engine (

    net.sf.jasperreports.jsf.engine.interop,FacesFileResolver
    

    ). The idea is to be able to reference resources that can be resolved using
    the internal mechanism of the plugin implemented at

    net.sf.jasperreports.jsf.resource.DefaultResourceResolver
    

    . This means that when defining a report, images and other additional
    resources can be referenced as URLs, classpath resources, context-relative or
    relative to current report file (value established for the report's

    value
    

    attribute).

    If the resource can't be found then an

    UnresolvedResourceException
    

    should be thrown, if no exception is thrown then either the plugin is able to
    find the resources or the custom FileResolved is not being consumed at all.

    In the other hand, I need to check why the URLs for those resources are a sort
    of "nullimg_X_X_X" as it seems a bit weird.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-22

    The DefaultResourceResolver.resolveResource method is definitely being invoked
    when I trace through this in the debugger. I have
    /resources/report/dartTest/dartTest.jasper as the location of the compiled
    report and I have located it just below the webapp root, which I can see in
    the debugger leads this method to correctly treat this as a context resource.
    This makes sense, since the report sans the images does get displayed. My
    guess is the JasperReports can't resolve the images and is probably swallowing
    an exception and simply passing back a null for the image name/URL. This might
    explain why there is no exception stack trace.

    The FacesFileResolver constructor is also invoked from the HtmlExporter via
    the ExporterBase, but nothing else is ever invoked in either of these two
    classes beyond these two methods when I place a breakpoint at the top of every
    method in each of these two classes. Is something supposed to be to get the
    images to display? If so, then exposing the call hierarchy should help to
    explain why the pertinent methods are not invoked.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-22

    I also did the following experiment. I changed the path in the imageExpression
    for one of the images to be
    /resources/report/dartTest/images/coffee_stain.png, recompiled the report,
    cleaned everything for the umpteenth time and reran and got a japser reports
    repository exception. So I assume it that JR assummed that I was using a
    repository approach for image delivery and, of course, this didn't work.

    I then put the imageExpression path back to images/coffee_stain.png, cleaned
    and reran and was back where I started. Then I removed the images directory
    from the class path and got the original Byte data not found at :
    images/coffee_stain.png exception as follows:

    Jul 21, 2012 8:58:22 PM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/dart] threw exception [net.sf.jasperreports.engine.JRException: Byte data not found at : images/coffee_stain.png] with root cause
    net.sf.jasperreports.engine.JRException: Byte data not found at : images/coffee_stain.png
        at net.sf.jasperreports.repo.RepositoryUtil.getBytesFromLocation(RepositoryUtil.java:324)
        at net.sf.jasperreports.engine.RenderableUtil.getRenderable(RenderableUtil.java:121)
        at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:505)
        at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:442)
        at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257)
        at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:472)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillTitle(JRVerticalFiller.java:337)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:273)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:144)
        at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:891)
        at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:804)
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.printWithFiller(DefaultFiller.java:176)
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.doFill(DefaultFiller.java:151)
        at net.sf.jasperreports.jsf.engine.fill.DefaultFiller.fill(DefaultFiller.java:88)
        at net.sf.jasperreports.jsf.renderkit.ReportRenderer.encodeContent(ReportRenderer.java:86)
        at net.sf.jasperreports.jsf.component.UIOutputReport.encodeContent(UIOutputReport.java:122)
        at net.sf.jasperreports.jsf.lifecycle.RenderResponsePhaseListener.invokeContextCallback(RenderResponsePhaseListener.java:135)
        at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1281)
    

    So clearly, having the images in the class path must be mostly satisfying JR.
    Also, notice that JR is using

    net.sf.jasperreports.repo.RepositoryUtil.getBytesFromLocation(RepositoryUtil.java:324)
    

    so this is possibly what should be looked at to determine how JR is trying to
    grab the image, whether correctly or not.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-22

    And notice the

    net.sf.jasperreports.engine.fill.JRFillImage
    

    key class. This class is where each of the different types of imageExpressions
    are handled, such as the string images/coffee_stain.png or a java.io.File
    or URL, etc.

     
  • Gregg Leichtman

    Gregg Leichtman - 2012-07-22

    Inside the net.sf.jasperreports.engine.export.JRHtmlExporter class, the
    following code exists:

    writer.write("<img");
    ...
    Some "if-then logic follows and then this:
    
        String imageName = getImageName(imageIndex);
        imagePath = imagesURI + imageName;
    

    The getImageName returns the img_0 part of the name. The imagesURI comes from
    a JRHtmlExporterParameter IF ONE IS SET. Since I have not set one, this value
    is null. This implies that the file name is then nullimg_0_.... I did not
    follow the code further to find where the additional _0_0 filename suffix is
    coming from, but I'm not sure that it is very important. It looks like I may
    have been wrong about IMAGES_DIR_NAME's importance in resolving this issue. It
    looks like it might be necessary to specify one (and only one, since the
    presence of one precludes the need for either of the other two based on review
    of the code) of the following exporter parameters: IMAGES_DIR_NAME, IMAGES_DIR
    or IMAGES_URI even when a stream is used instead of an actual file on disk.
    Note that the code looks for a null IMAGES_DIR_NAME and if found it converts
    it into a java.io.File as IMAGES_DIR and then into an IMAGES_URI. If it is not
    found, it looks for an IMAGES_DIR and follows the same pattern.

    In addition, I confirmed that when the input image files are located within
    the class path and the image expression references them without a leading /,
    the bytes within the files are definitely loaded into a stream buffer by the
    JRFillImage class. If a leading / is provided, the JR code assumes that the
    provided path is an absolute path within the file system and NOT a path
    leading from the webapp root, which is different from what the JSF plugin
    assumes. It assumes a leading / is a path starting at the webapp root. I will
    try to set IMAGES_DIR_NAME as an exporter parameter (NOT a report parameters)
    as I described above in this post for other exporter parameters and see if
    this helps.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks