JasperServer:无法定位子报表异常

发布于 2024-10-06 20:38:09 字数 992 浏览 6 评论 0 原文

我搜索了几天来修复这个错误,但没有任何新的东西。

我有一份包含多级子报告的报告,在 iReport 3.7.5 上一切正常。我使用 subreport.jasper 作为第一级中的子报表表达式第二级还有 subreportA.jaspersubreportB.jasper将所有(主报表和子报表)放在同一路径中。

当我尝试将其部署到我的 JasperServer 上时出现了问题。 当我尝试上传第一个主报告时,iReport 向导让我在资源文件夹中附加第一个 subreport.jrxml 并使用 repo:subreport.jrxml 访问它repo:subreport.jasper。 然后,我手动上传第二级子报表,并执行相同的操作,将子报表表达式更改为 repo:subreportA.jasperrepo:subreportB.jasper

我收到编译错误:无法找到表达式为“”repo:subreport.jasper”的子报表。 java.lang.Exception: repo:subreport.jrxml not found.

我尝试了十几种解决方案,但没有任何效果。 使用:SUBREPORT_DIR @开头,

使用完整路径:repo:/Circuit_Reports/Connectivity/Connectivity_files/

.jasper.jasper之间切换.jrxml

使用 lib 文件夹中的 jasperserver_api_engine_impl_0_fix.jar 来修复此错误,

我还搜索了数据库记录以确保它们位于同一文件夹中并且具有相同的父文件夹。

I searched for a couple of days to fix this bug with nothing new.

I had a report which include multi-level subreports everything works fine on iReport 3.7.5. I used subreport.jasper as subreport expression in the first level & also subreportA.jasper, subreportB.jasper in the second level & place all (the main report & subreports) in the same path.

The problem raised when I try to deploy it on my JasperServer.
When I try to upload the first main report the iReport wizard offerd me to attach the first subreport.jrxml in resource folder and access it with repo:subreport.jrxml or repo:subreport.jasper.
Then I manually upload the second level subreports and do the same thing change the subreport expression to repo:subreportA.jasper and repo:subreportB.jasper.

I got compilation error : Unable to locate the subreport with expression: ""repo:subreport.jasper"". java.lang.Exception: repo:subreport.jrxml not found.

I try dozen solution and nothing works.
using : SUBREPORT_DIR @ the beginning,

using full path : repo:/Circuit_Reports/Connectivity/Connectivity_files/,

switch between .jasper & .jrxml.

using jasperserver_api_engine_impl_0_fix.jar in lib folder as a fixation to this bug,

I also searched the database record to be sure that they are in the same folder and have the same parent folder.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

灼痛 2024-10-13 20:38:09

Smalltalk 先于 Longtalk ;)

(当然,我不想鼓励您阅读这篇长篇详细文章的所有内容!粗体标记可能已经足以解决您的问题,但我发现值得记录下来更详细的棘手的东西!)

因为我又投入了几个小时(在几周前解决它之后,现在进行了更改,但忘记正确记录它,忘记了我是如何做到的,并且无法再次检索此信息)以任何形式 - 当上传和配置到/在 JasperServer 中时)...这里是各个网站上提到的一些关于子报表引用的聚合功能,它如何工作以及可以尝试什么...

(我将更新我的或其他发现这里是否希望有一些)

快捷方式详细信息/最佳实践?!4

直到 Jasper 功能本身提供了类似的“包装”解决方案...

要解决与运行 *. jrxml、*.jasper 文件可以在预览模式下本地运行,也可以在 JasperServer 上远程运行我现在使用以下方法,该方法允许仅使用单个 *.jrxml 文件,该文件无需修改即可在本地和远程运行,在多开发人员环境,支持每个环境独立重构目录结构(路径、名称)(= 应该如此;-)):

  • 使用一些 jasper-utils-*.jar
    • 将其放入您的项目 (Java) 类路径中(项目 -> 属性 -> Java 构建路径 -> 库 -> 添加
    • 将其放入您的../jasperserver/WEB-INF/lib/文件夹
  • 引用一些自定义 Jasper Java Scriptlet jr.utl.EnvScriptlet 这在你的主报告中实现了丑陋的子报告路径/引用魔法
    • 通过向主报告添加属性来定义REPORT_SCRIPTLET报告属性 ->报告->数据集-> Scriptlet 类:jr.utl.EnvScriptlet
  • 使用一些自定义属性文件jr.utl.properties 或其他提供的系统属性(任何其他方式设置Java 系统属性也很好并且可以工作 - 已经设置的属性将覆盖加载的文件属性)来配置不同的环境,包括您的

    • 通过 jr.utl.env 属性获取当前环境信息(prod、myOsUsrName、test、demo、staging、local,...)
      • 决定子报表引用的生成方式/外观
    • 服务器子报表父目录属性引用
    • 例如,将这些属性文件内容放在每个环境中:
    • 在您的服务器上:../jasperserver/WEB-INF/classes/jr.utl.properties

      jr.utl.env=prod
      mycompany.local.jr.gui.rep.subrep1.parentdir=repo:/x/y/z/
      mycompany.local.jr.gui.rep.subrep2.parentdir=repo:/x/y/z/
      mycompany.local.jr.gui.rep.subrep3.parentdir=repo:/x/y/foobar/
      
    • 在您的本地 JasperSoft Studio (Eclipse) Java src/build 路径中:例如 ../myrepproject/src/java/jr.utl.properties代码>

      jr.utl.env=dietrian
      mycompany.local.jr.gui.rep.subrep1.parentdir=D:/reporting/src/reports/
      mycompany.local.jr.gui.rep.subrep2.parentdir=D:/reporting/src/reports/
      mycompany.local.jr.gui.rep.subrep3.parentdir=D:/reporting/src/reports.otherdir/
      
      • 为了在我们的环境中实现源修改独立性,我们参数化了这些值,并根据以下想法通过一些工作区相关/用户特定的 local.properties 文件生成一次:

        |- build.xml(包含 ANT 构建魔法)      
        |- build.properties(包含全局属性)      
        |- local.properties(在版本控制中被忽略,例如.hgignore,从local.template.properties生成的用户特定)
        |- local.template.properties (生成上述 local.properties 的 ANT 构建任务的来源)
           |- mycomp.local.proj.reporting.dir=D:/reporting
        |- src/报告
           |- jr.utl.properties(在版本控制中被忽略,用户特定根据下面的模板生成)
           |- jr.utl.template.properties(生成上述 jr.utl.properties 的 ANT 构建任务的来源)
              jr.utl.env=${用户名}
              mycompany.local.jr.gui.rep.subrep1.parentdir=${mycomp.local.proj.reporting.dir}/src/reports/
              mycompany.local.jr.gui.rep.subrep2.parentdir=${mycompany.local.jr.gui.rep.subrep1.parentdir}
              mycompany.local.jr.gui.rep.subrep3.parentdir=${mycomp.local.proj.reporting.dir}/src/reports.otherdir/
        


  • defining您的 BASE_DIR 主报告参数,例如
    $P{REPORT_SCRIPTLET}.getProp("mycompany.allsubreports.parentdir") (匹配 jr.utl.properties 文件)

  • 将主子报表表达式定义为 jr.utl.EnvScriptlet.getSubrepPath( $P{BASE_DIR}, "subrep1.jrxml")
    • 自动解析属性中的值,您也可以使用这些变体:
      • jr.utl.EnvScriptlet.getSubrepPathByPropKey( $P{BASE_DIR}, "mycompany.local.jr.gui.rep.subrep1.name")
      • jr.utl.EnvScriptlet.getSubrepPathByPropKeys("mycompany.local.jr.gui.rep.subrep1.parentdir", "mycompany.local.jr.gui.rep.subrep1.name")
    • $P{REPORT_SCRIPTLET}.getSubrepPath(...) 在这里不起作用:-((我不知道为什么)
  • 当您将所有文件放在服务器上时,不要忘记重新启动服务器

4:当然,我仍然看到了一些小的改进,但它似乎比我迄今为止发现的所有丑陋的解决方案要好得多:

  • 使用 REPORT_SCRIPTLET 或 scriptlet 功能。可能不是最好的方法,但它可能适用于绝大多数用例,
  • 尽管现有的 Jasper 类表明它们似乎无法正确处理上述内容:

(5:相关特殊处理编码如下: EnvScriptlet.java/getSubrepPath( String,String,boolean,String[]))

介绍(背景)

首先要知道的是 JasperStudio 中的处理/设置不同处理 Jasper Server(存储库)5 ...

假设我们有以下环境:

  • 我们的 Eclipse 安装目录:C:\eclipse\
  • Eclipse(报告)工作区:C:\workspace\
  • 我们的报告项目位于:C:\workspace\report-project\
  • 我们的报告位于:C:\workspace \report-project\src/reports
  • 主报告 C:\workspace\report-project\src/reports/masterrep.jrxml
  • 一些子报告 C:\workspace\report- project\src/reports/subrep1.jrxml
  • 另一个子报表 C:\workspace\report-project\src/reports/somesubdir/subrep2.jrxml
  • BASE_DIR (在下一节中解释)在我们的工作区主报告中设置为 C:\workspace\report-project\src/reports/
  • 我们的主报告的 Jasper Report Server GUI 存储库 id 路径将是: <代码>/x/y/z/
    (不要与视觉命名路径混淆,例如可以是财务报告/费用/当前年份

一般来说:Jasper Studio、JasperServer

(以及其他“Jasper 运行时环境”)就像自定义 Java Jasper 包用法一样):

  • 声明一个报告参数“前缀”似乎是一个好习惯,它可以根据您的 Jasper 运行时环境而变化,例如名为 <代码>BASE_DIR
    • 这里重要的是,似乎最好假设可能包含后缀/1,因为有您可能已经/想要以空或“无斜杠”路径表达式的方式使用它的情况
      • 例如 $P{BASE_DIR} + "subrep1.jrxml" 应该解析为
        repo:subrep1.jrxml
    • 请参阅此处了解更多详细信息(查找SUBREPORT_DIR)

(1:在处理类似目录的结构时,我个人认为这是一种不好的做法(在这方面不考虑 Jasper Reports))

JasperStudio Designer (Eclipse 插件)

(官方 IReport 后继者,具有更多功能)

(如果您不使用预览功能,这可能对您不感兴趣)

  • 不幸的是,我发现没有实用的方法来完全支持(正常)“团队开发”与子报表(以及可能的其他相关资源),这意味着(目前对我来说未知)不存在分离本地路径和 *.jrxml 文件的可能性 :-(
    • 例如,如果您有版本控制系统并在不同的环境中工作(存储库的不同本地路径和/或不同的开发人员),主报告必须以某种方式包含子报告的本地路径)
      • 我尝试了不同的方法,但都失败了:
      • BASE_DIR 中的相对路径表达式不起作用,因为工作目录是 eclipse 目录,例如 C:\eclipse
      • Eclipse->Window->Preferences->JasperStudio->Properties->Add 例如my.base.dir
        • 它在预览模式下不可用,例如通过 new java.io.File(System.getProperty("my.base.dir")).getCanonicalPath() + "/"我们的 BASE_DIR 表达式(这些道具可能仅供设计器本身使用,但不会在预览运行中设置)
      • 以防万一您可能会偶然发现(就像我一样):Eclipse->Window->Preferences->JasperStudio->Report Execution->Virtualizer Temporary Path 是一些不相关的东西(这里没用)处理报表结果的存储“缓存”
      • 当然,我可以编写一个 ANT 任务来根据每次使用/结帐时的正则表达式过滤器副本来替换这些本地模式,但这似乎不是处理此问题的好方法


  • 任务是根据每次使用/结账时的正则表达式过滤器副本替换这些本地模式,但如果您只想使用 *.jrxml 文件, < /strong> (正如我所做的3),您必须引用一些 subrep1.jrxml,如下所示:net.sf.jasperreports.engine.JasperCompileManager。 compileReport($P{BASE_DIR} + "subrep1.jrxml")

3:我不需要明确需要 *.jasper 文件不明白我为什么要和他们打交道。顺便说一句,JasperServer WebGUI 似乎只支持 *.jrxml 文件的上传)

JasperServer Web GUI

(例如由某些 Tomcat 应用程序服务器提供并将其数据存储在某些 postgres 数据库中)

场景 1:引用附加的子报表资源(s)

  • 如果您一般不想重用您的报告,那么将您的支持报告添加到您的主报告中似乎很好(因此它在 GUI 存储库树中不可见 - 请参阅下面的子项目,如何在您的主报告之外引用它无论如何)
  • 如果您附加子报告,它通常应将其文件名作为其资源 ID,例如上面的 subrep1.jrxml 是使用资源 ID subrep1.jrxml(从而使本地设计引用和服务器引用的处理变得不那么复杂)
  • 采用上面的示例报告,我们必须将 BASE_DIR 设置为 repo :在待上传的主报告中
    • 因此,子报表表达式 $P{BASE_DIR} + "subrep1.jrxml"$P{BASE_DIR} + "somesubdir/subrep2.jrxml" 应该适用于服务器也是如此
    • 不推荐!:您仍然可以使用绝对路径从其他报告引用这些报告,如下所示2repo:/x/y/z/masterrep.jrxml_files/masterrep.jrxml_< /代码>

2:在这种情况下我不推荐这样做;它没有文档记录并且可能会更改;最好将子报表放入“GUI 存储库路径”中,如下所述)

场景 2:参考存储库子报表资源

  • 假设我们将子报表上传到主存储库 id-path /x/y/z/ (如顶部所示)

  • 我们必须再次区分两种不同的用例

    • 我们不想想要使用子报表作为独立报表(它始终只包含在其他主报表中)

      • 在这种情况下,我们应该使用添加资源->文件->JRXML上传它并引用它

      • ../subrep1.jrxml./subrep1.jrxml 不起作用,因为底层逻辑似乎无法处理相对路径表达式..可能 . 也不会)(这实际上很好:-( )

        < /里>

      • 所以我们在这里要做的是在 masterrep.jrxml 的 BASE_DIR 中提供绝对规范路径例如repo:/x/y/z/

    • 我们也希望使用子报表作为独立报表

      • 在这种情况下,我们应该使用添加资源->JasperReport

        来上传它

      • 这显然会创建一个隐藏文件夹repo:/x/y/z/subrep1.jrxml_files,其中包含报表本身和其他资源

      • 这就是为什么我们不仅要调整BASE_DIR(如上所述),还要将子报表表达式调整为例如$ P{BASE_DIR} + "subrep1.jrxml_files/subrep1.jrxml_"(指向子报表本身)

    • 并且可能会删除net.sf.jasperreports.engine.JasperCompileManager.compileReport(...)包装函数,因为服务器会自动执行此操作<强>对于*.jrxml文件

    • 我没有充分调查其他一些可能被错误使用的方法,这些方法对我解决上述问题不起作用(也许其他人在这里有一些结果/更正):

      • $P{REPORT_FILE_RESOLVER}.resolveFile("subrep1.jrxml") (NullPointerException)
      • 导致主报告中的子报告部分为空:
        • $P{REPORT_CONTEXT}.getRealPath("subrep1.jrxml")
        • $P{REPORT_CONTEXT}.getProperty("REPORT_FILE_RESOLVER").resolveFile("subrep1.jrxml")

其他提示

由于我喜欢尽可能地自动化报告设计和部署过程,因此我编写了一些ANT 任务来处理本地 *.jrxml 文件关于 BASE_DIR 和其他转换的可部署 *.jrxml 文件转换。

SQL有助于轻松调查jasper服务器postgres元数据库中的资源ID路径结构(遵循jdbc:postgresql://myjasperhost/jasperserver 例如与 postgres 用户连接):

select
    f.id as folder_id,
    r.id as res_id,
    case when f.hidden = true then 1 else 0 end as hidden,
    f.uri||case when f.uri = '/' then '' else '/' end||coalesce(r.name,'') as res_uri,
    r.resourcetype,
    r.creation_date,
    r.update_date,
    f.uri,
    r.name,
    -- less important
    r.version,
    r.parent_folder,
    r.childrenfolder,
    f.parent_folder,
    f.version,
    f.name
-- select *
from jiresourcefolder f
    left outer join jiresource r on (r.parent_folder = f.id)
where not f.uri like '/themes%'
order by f.uri||coalesce(r.name,'')

相关问题

Jaspersoft 论坛上与此相关的问题包括:

Smalltalk before Longtalk ;)

(Of course I don't want to encourage you to read everything of this long detailed post! The bold markers may already be enough to solve your problems but I found it worth documenting this tricky stuff in some more detail!)

Since I invested another couple of hours on this (after I resolved it some weeks ago, had a change now, but forgot to document it properly, forgot how I did it and could not retrieve this info again in any form - when uploading and configuring to/in JasperServer) ... here is some aggregated functionality mentioned on various sites regarding subreport referencing, how it works and what one can try ...

(I'll update mine or other findings in here if there hopefully will be some)

Short cut details / best practices?!4

Till maybe Jasper functionality provides a similar "wrapping" solution itself ...

To workaround all the problems related to running the *.jrxml, *.jasper files either locally in Preview mode or remotely on a JasperServer I am now using the following approach which allows to work with only a single *.jrxml file, that will work locally and remotely without modifications, in a multi-developer environment, supporting independent refactoring of dir structures (paths, names) per environment (= as it should ;-) ):

  • using some jasper-utils-*.jar
    • put it in your project (Java) class path (Project->Properties->Java Build Path->Libraries->Add)
    • put it in your ../jasperserver/WEB-INF/lib/ folder
  • referencing some custom Jasper Java Scriptlet jr.utl.EnvScriptlet that does the ugly subreport path/reference magic in your master reports
    • define the REPORT_SCRIPTLET by adding an attribute to your master report: report properties -> Report -> Data Set -> Scriptlet Class: jr.utl.EnvScriptlet
  • using some custom properties file jr.utl.properties or otherwise supplied system properties (any other way to set the Java system properties would be fine as well and work - where already set up properties will override loaded file properties) to configure the different environments including your

    • current environment information via jr.utl.env property (prod, myOsUsrName, test, demo, staging, local, ...)
      • which determines how the subreport references must be generated / look like
    • server subreport parent directory property references
    • take e.g. these property file contents and put one per environment here:
    • on your servers: ../jasperserver/WEB-INF/classes/jr.utl.properties

      jr.utl.env=prod
      mycompany.local.jr.gui.rep.subrep1.parentdir=repo:/x/y/z/
      mycompany.local.jr.gui.rep.subrep2.parentdir=repo:/x/y/z/
      mycompany.local.jr.gui.rep.subrep3.parentdir=repo:/x/y/foobar/
      
    • in your local JasperSoft Studio (Eclipse) Java src/build path: e.g. ../myrepproject/src/java/jr.utl.properties

      jr.utl.env=dietrian
      mycompany.local.jr.gui.rep.subrep1.parentdir=D:/reporting/src/reports/
      mycompany.local.jr.gui.rep.subrep2.parentdir=D:/reporting/src/reports/
      mycompany.local.jr.gui.rep.subrep3.parentdir=D:/reporting/src/reports.otherdir/
      
      • to achive source modification independency in our environments we parameterized those values and generate them once via some workspace-dependent/user-specific local.properties file, based on this idea:

        |- build.xml                  (containing the ANT build magic)      
        |- build.properties           (containing global properties)      
        |- local.properties           (ignored in version control, e.g. .hgignore, user-specific generated from local.template.properties)
        |- local.template.properties  (source for ANT build task generating the local.properties above)
           |- mycomp.local.proj.reporting.dir=D:/reporting
        |- src/reports
           |- jr.utl.properties           (ignored in version control, user-specificly generated based on template below)
           |- jr.utl.template.properties  (source for ANT build task generating the jr.utl.properties above)
              jr.utl.env=${user.name}
              mycompany.local.jr.gui.rep.subrep1.parentdir=${mycomp.local.proj.reporting.dir}/src/reports/
              mycompany.local.jr.gui.rep.subrep2.parentdir=${mycompany.local.jr.gui.rep.subrep1.parentdir}
              mycompany.local.jr.gui.rep.subrep3.parentdir=${mycomp.local.proj.reporting.dir}/src/reports.otherdir/
        
  • defining your BASE_DIR master report parameters as e.g.
    $P{REPORT_SCRIPTLET}.getProp("mycompany.allsubreports.parentdir") (matching some environment-dependent property in your jr.utl.properties file)

  • defining the master subreport expressions as e.g. jr.utl.EnvScriptlet.getSubrepPath( $P{BASE_DIR}, "subrep1.jrxml")
    • automatically resolving the values from properties you could also use e.g. these variants:
      • jr.utl.EnvScriptlet.getSubrepPathByPropKey( $P{BASE_DIR}, "mycompany.local.jr.gui.rep.subrep1.name")
      • jr.utl.EnvScriptlet.getSubrepPathByPropKeys( "mycompany.local.jr.gui.rep.subrep1.parentdir", "mycompany.local.jr.gui.rep.subrep1.name")
    • $P{REPORT_SCRIPTLET}.getSubrepPath(...) does not work here :-( (I don't know why)
  • do not forget to restart your server when you put all the files on the server!

(4: Of course I am still seeing some minor improvements here, but it seems much better than all the ugly solutions I found till now. Improvements I would see:

  • using the REPORT_SCRIPTLET or scriptlet functionality may not be the best way to go, but it will probably work in the vast majority of use cases
  • although both existing Jasper classes suggest this they do not seem to be able to handle the above properly:

(5: the relevant special handling is encoded here: EnvScriptlet.java/getSubrepPath(String,String,boolean,String[]))

Intro (Background)

First thing to know is that the handling/setup in JasperStudio is quite different from the handling on Jasper Server (Repository)5 ...

suppose we have the following enviroments:

  • our Eclipse install dir: C:\eclipse\
  • our Eclipse (Report) workspace: C:\workspace\
  • our report project under: C:\workspace\report-project\
  • our reports under: C:\workspace\report-project\src/reports
  • a master report C:\workspace\report-project\src/reports/masterrep.jrxml
  • some subreport C:\workspace\report-project\src/reports/subrep1.jrxml
  • another subreport C:\workspace\report-project\src/reports/somesubdir/subrep2.jrxml
  • the BASE_DIR (explained in next section) in our workspace master report is set to C:\workspace\report-project\src/reports/
  • our Jasper Report Server GUI repo id-path of our master report will be: /x/y/z/
    (which is not to-be-confused with the visual named-path, e.g. which could be Financial Reports/Expenses/Current Year)

In general: Jasper Studio, JasperServer

(and other "Jasper runtime environments" like custom Java Jasper package usage):

  • it seems a good practice to declare a report parameter "prefix" which can vary depending on your Jasper runtime environment e.g. named BASE_DIR
    • important here is that it seems best to assume the suffixed / may be included1 because there are cases where you may have/want to use it in a way where it should be an empty or "unslashed" path expression
      • e.g. $P{BASE_DIR} + "subrep1.jrxml" which should resolve to
        repo:subrep1.jrxml
    • see e.g. here for more details (look for SUBREPORT_DIR)

(1: which I personally find a bad practice in general (not looking at Jasper Reports in this respect) when dealing with directory-like structures)

JasperStudio Designer (Eclipse Plugin)

(the official IReport successor with loads of more functionality)

(if you do not use the preview functionality this may be uninteresting to you)

  • unfortunately I found no practical way to fully support (normal) "team-development" with subreports (and likely other relative resources as well), meaning here the (currently to me unknown) inexistent possiblity to separate local paths and *.jrxml files :-(
    • e.g. if you have a version control system in place and work in different environments (different local paths to repos and/or different developers) the master report has to contain a local path to your subreport in some way)
      • I tried different approaches that failed:
      • relative path expressions in BASE_DIR do not work since the working directory is the eclipse dir, e.g. C:\eclipse
      • Eclipse->Window->Preferences->JasperStudio->Properties->Add e.g. my.base.dir
        • it is not available in the Preview mode, e.g. via new java.io.File(System.getProperty("my.base.dir")).getCanonicalPath() + "/" for our BASE_DIR expression (these props may be only used by the designer itself, but not set in preview runs)
      • just in case you may stumble upon (as I did): Eclipse->Window->Preferences->JasperStudio->Report Execution->Virtualizer Temporary Path is something unrelated (not useful here) dealing with the storage of the report result "caching"
      • of course I could write an ANT task to replace these local pattern based on a regexp filter copy on every usage/checkout, but that seems not a good way to handle this
  • if you solely want to work with *.jrxml files (as I do3) you have to reference some subrep1.jrxml like this: net.sf.jasperreports.engine.JasperCompileManager.compileReport($P{BASE_DIR} + "subrep1.jrxml")

(3: I don't need the *.jasper files explicitely and do not see why I want to deal with them. BTW the JasperServer WebGUI only seems to support the upload of *.jrxml files)

JasperServer Web GUI

(e.g. provided by some Tomcat application server and storing its data in some postgres database)

Scenario 1: reference attached subreport resource(s)

  • if you do not want to reuse your report in general, it seems fine to add your supreport to your master report (so it is not visible in the GUI repo tree - see below subitem how you could reference it outside of your master anyways)
  • if you attach your subreport it should in general have its file name as its resource id, e.g. our subrep1.jrxml from above is uploaded with a resource id of subrep1.jrxml (thus making the handling of local design references and server references less complicated)
  • taking the example reports from above we have to set our BASE_DIR to repo: in the to-be-uploaded master report
    • thus the subreport expressions $P{BASE_DIR} + "subrep1.jrxml" and $P{BASE_DIR} + "somesubdir/subrep2.jrxml" should work on the server as well
    • NOT recommended!: you could still reference these reports from other reports with absolute paths like this2: repo:/x/y/z/masterrep.jrxml_files/masterrep.jrxml_

(2: which I would not recommend in this case; it's undocumented and may change; better put your subreports then into the "GUI repo path" as described below)

Scenario 2: reference repo subreport resource(s)

  • suppose we upload our subreports to the master repo id-path /x/y/z/ (as shown on top)

  • again we have to differentiate two different use cases

    • we do NOT want to use the subreport as a standalone report (it will always only be included in other master reports)

      • in this case we should upload it using Add Resource->File->JRXML and reference it

      • ../subrep1.jrxml or ./subrep1.jrxml do not work since it seems the underlying logic cannot handle the relative path expression .. (and likely . not as well) (which would actually be nice :-( )

      • so what we have to do here is to supply an absolute canonical path in the BASE_DIR of our masterrep.jrxml, e.g. repo:/x/y/z/

    • we want to use the subreport as a standalone report as well

      • in this case we should upload it using Add Resource->JasperReport

      • this obviously creates a hidden folder repo:/x/y/z/subrep1.jrxml_files containing the report itself and other resources

      • that's why we not only have to adjust the BASE_DIR (as above), but also the subreport expression to, e.g. $P{BASE_DIR} + "subrep1.jrxml_files/subrep1.jrxml_" (which points to the subreport itself)

    • and maybe remove the net.sf.jasperreports.engine.JasperCompileManager.compileReport(...) wrapper function, because the server does this automatically for *.jrxml files

    • I did not fully investigate some other likely incorrectly used approaches which did not work for me to solve the mentioned problems (maybe somebody else has some outcome/corrections here):

      • $P{REPORT_FILE_RESOLVER}.resolveFile("subrep1.jrxml") (NullPointerException)
      • resulting in empty subreport sections in master report:
        • $P{REPORT_CONTEXT}.getRealPath("subrep1.jrxml")
        • $P{REPORT_CONTEXT}.getProperty("REPORT_FILE_RESOLVER").resolveFile("subrep1.jrxml")

Additional hints

Since I like to automate the report design and deployment process as much as it makes sense I wrote some ANT tasks that handle the local *.jrxml file to deployable *.jrxml file transformations regarding the BASE_DIR and the other transformations.

SQL helpful to easily investigate the resource id path structures in a jasper server postgres meta database (following something like jdbc:postgresql://myjasperhost/jasperserver connecting e.g. with the postgres user):

select
    f.id as folder_id,
    r.id as res_id,
    case when f.hidden = true then 1 else 0 end as hidden,
    f.uri||case when f.uri = '/' then '' else '/' end||coalesce(r.name,'') as res_uri,
    r.resourcetype,
    r.creation_date,
    r.update_date,
    f.uri,
    r.name,
    -- less important
    r.version,
    r.parent_folder,
    r.childrenfolder,
    f.parent_folder,
    f.version,
    f.name
-- select *
from jiresourcefolder f
    left outer join jiresource r on (r.parent_folder = f.id)
where not f.uri like '/themes%'
order by f.uri||coalesce(r.name,'')

Related Questions

Questions on the Jaspersoft forum related to this one include:

只有一腔孤勇 2024-10-13 20:38:09

不确定此机制是否适用于所有情况,但它肯定适用于 JasperSoft Studio 5.6.0Jasper Reports Server 5.6.0

本质上,我们需要一种简单的方法来检测我们是否在服务器上运行 - 我使用 $P{REPORT_CONTEXT} 参数的存在(或不存在),实验表明该参数存在于服务器上,但不存在预览期间。

<parameter name="OnServer" class="java.lang.Boolean" isForPrompting="false">
    <parameterDescription><![CDATA[Are we running on server]]></parameterDescription>
    <defaultValueExpression><![CDATA[Boolean.valueOf($P{REPORT_CONTEXT}!=null)]]></defaultValueExpression>
</parameter>

完成后,您可以从以下两个选项中定义子报表的位置:

<parameter name="SubReportProducts" class="java.lang.String" isForPrompting="false">
    <parameterDescription><![CDATA[The products subreport]]></parameterDescription>
    <defaultValueExpression><![CDATA[$P{OnServer}.booleanValue() ? "repo:OrderPicksheetProducts.jrxml" : "OrderPicksheetProducts.jasper"]]></defaultValueExpression>
</parameter>

然后包含子报表:

<subreportExpression><![CDATA[$P{SubReportProducts}]]></subreportExpression>

然后您可以在工作室中使用 Preview,并且当您部署到服务器时,所有内容仍然有效。

Not sure if this mechanism works in all cases but it certainly works for JasperSoft Studio 5.6.0 and Jasper Reports Server 5.6.0.

Essentially we need a simple way to detect that we are running on the server - I use the presence (or absence) of the $P{REPORT_CONTEXT} parameter which experiments show is present on the server but not present during preview.

<parameter name="OnServer" class="java.lang.Boolean" isForPrompting="false">
    <parameterDescription><![CDATA[Are we running on server]]></parameterDescription>
    <defaultValueExpression><![CDATA[Boolean.valueOf($P{REPORT_CONTEXT}!=null)]]></defaultValueExpression>
</parameter>

Once you have that you can then define the location of your subreport from a choice of two:

<parameter name="SubReportProducts" class="java.lang.String" isForPrompting="false">
    <parameterDescription><![CDATA[The products subreport]]></parameterDescription>
    <defaultValueExpression><![CDATA[$P{OnServer}.booleanValue() ? "repo:OrderPicksheetProducts.jrxml" : "OrderPicksheetProducts.jasper"]]></defaultValueExpression>
</parameter>

And then include the sub report:

<subreportExpression><![CDATA[$P{SubReportProducts}]]></subreportExpression>

You can then use Preview in studio and all still works when you deploy to server.

内心旳酸楚 2024-10-13 20:38:09

我不是 100% 的答案,但是:您必须将子报告作为 jrxml 资源上传并放置“repo://subreport.jrxml”才能使其工作。
如果您有一天读过这篇文章,请告诉我它是否有效或您找到了哪些解决方案。
问候

I'm not 100% of this answer but : You have to upload your subreport as a jrxml ressource and put "repo://subreport.jrxml" to get it work.
If you read this one of those days tell me if it worked or what solutions you found.
Regards

傲娇萝莉攻 2024-10-13 20:38:09

尝试完全删除扩展并使用“repo:/subreportFolder/subreportName”。主报告在 iReport 中提取 jasper 文件,但在 jasperserver 上上传 jrxml。

Try removing the extension completely and use "repo:/subreportFolder/subreportName". The main report pulls the jasper file in iReport, but on the jasperserver you upload the jrxml.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文