JasperServer: невозможно найти исключение подотчета

Я искал пару дней, чтобы исправить эту ошибку, но ничего нового.

У меня был отчет, который включает в себя многоуровневые подотчеты, на iReport 3.7.5 все работает нормально. Я использовал subreport.jasper в качестве выражения подотчета на первом уровне, а также subreportA.jasper, subreportB.jasper на втором уровне и разместил все (основной отчет и подотчеты) по одному пути.

Проблема возникает, когда я пытаюсь развернуть его на своем JasperServer. Когда я пытаюсь загрузить первый основной отчет, мастер iReport предлагает мне прикрепить первый subreport.jrxml в папке ресурсов и получить к нему доступ с помощью repo:subreport.jrxml или repo:subreport.jasper. Затем я вручную загружаю вложенные отчеты второго уровня и делаю то же самое, изменяя выражение вложенного отчета на repo:subreportA.jasper и repo:subreportB.jasper.

Я получил ошибку компиляции: Unable to locate the subreport with expression: ""repo:subreport.jasper"". java.lang.Exception: repo:subreport.jrxml not found.

Я пробую дюжину решений, и ничего не работает. используя: SUBREPORT_DIR в начале,

используя полный путь: repo:/Circuit_Reports/Connectivity/Connectivity_files/,

переключаться между .jasper и .jrxml.

используя jasperserver_api_engine_impl_0_fix.jar в папке lib в качестве исправления этой ошибки,

Я также просмотрел запись базы данных, чтобы убедиться, что они находятся в одной папке и имеют одну и ту же родительскую папку.


person karimhammoda    schedule 06.12.2010    source источник
comment
Привет, каримхаммода, примите мой ответ, если он работает для вас или, по крайней мере, проясняет ваше понимание. Спасибо   -  person Andreas Covidiot    schedule 10.03.2014


Ответы (4)


Smalltalk перед Longtalk ;)

(Конечно, я не хочу побуждать вас читать весь этот длинный и подробный пост! Жирным шрифтом может быть уже достаточно, чтобы решить ваши проблемы, но я счел, что стоит задокументировать этот сложный материал в более подробной документации. подробно!)

Поскольку я потратил на это еще пару часов (после того, как я решил это несколько недель назад, сейчас было изменение, но я забыл правильно его задокументировать, забыл, как я это сделал, и не мог снова получить эту информацию в любой форме - при загрузке и настройке to/in JasperServer) ... вот некоторые агрегированные функции, упомянутые на различных сайтах в отношении ссылок на подотчеты, как это работает и что можно попробовать ...

(Я обновлю свои или другие выводы здесь, если, надеюсь, они будут)

Краткие сведения/рекомендации?!4

Пока, возможно, функциональность Jasper не предоставляет аналогичное решение для «обертывания» ...

Чтобы обойти все проблемы, связанные с запуском файлов *.jrxml, *.jasper либо локально в режиме предварительного просмотра, либо удаленно на JasperServer, я теперь использую следующий подход, который позволяет работать только с одним файлом *.jrxml, который будет работать локально и удаленно без модификаций, в среде с несколькими разработчиками, поддерживая независимый рефакторинг структур dir (пути, имена) для каждой среды (= как и должно быть ;-)):

  • using some jasper-utils-*.jar
    • put it in your project (Java) class path (Project->Properties->Java Build Path->Libraries->Add)
    • поместите его в папку ../jasperserver/WEB-INF/lib/
  • 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
  • используя файл настраиваемых свойств jr.utl.properties или иные предоставленные системные свойства (любой другой способ установки системных свойств Java также подойдет и будет работать — где уже настроенные свойства переопределяют свойства загруженного файла) для настройки различные среды, включая вашу

    • 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
    • ссылки на свойства родительского каталога подотчета сервера
    • взять напр. это содержимое файла свойств и поместите здесь по одному для каждой среды:
    • на ваших серверах: ../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/
      
    • в вашем локальном пути исходного кода/сборки Java JasperSoft Studio (Eclipse): например. ../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                  (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/
        
  • определение параметров основного отчета BASE_DIR, например. $P{REPORT_SCRIPTLET}.getProp("mycompany.allsubreports.parentdir") (соответствует некоторому свойству, зависящему от среды, в вашем файле jr.utl.properties)

  • 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(...) здесь не работает :-( (не знаю почему)
  • не забудьте перезагрузить сервер, когда поместите все файлы на сервер!

(4: Конечно, я все еще вижу некоторые незначительные улучшения, но они кажутся намного лучше, чем все уродливые решения, которые я нашел до сих пор. Улучшения, которые я бы увидел:

  • использование функции REPORT_SCRIPTLET или скриптлета может быть не лучшим способом, но, вероятно, он будет работать в подавляющем большинстве случаев использования.
  • although both existing Jasper classes suggest this they do not seem to be able to handle the above properly:

(5: соответствующая специальная обработка закодирована здесь: EnvScriptlet.java/getSubrepPath( Строка,Строка,логическое значение,Строка[]))

Вступление (Фон)

Первое, что нужно знать, это то, что обработка/настройка в JasperStudio сильно отличается от обработки на Jasper Server (Repository)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 нашего основного отчета будет: /x/y/z/ (который не следует путать с визуальным именованным путем, например, который может быть Financial Reports/Expenses/Current Year)

В общем: Jasper Studio, JasperServer

(и другие «среды выполнения Jasper», такие как использование пользовательского пакета Java Jasper):

  • 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
    • см. напр. здесь для более подробной информации (ищите SUBREPORT_DIR)

(1: что я лично считаю плохой практикой в ​​целом (не рассматривая Jasper Reports в этом отношении) при работе со структурами, подобными каталогам)

JasperStudio Designer (плагин Eclipse)

(официальный преемник IReport с большим количеством функций)

(если вы не используете функцию предварительного просмотра, это может быть вам неинтересно)

  • 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:
      • выражения относительного пути в BASE_DIR не работают, поскольку рабочим каталогом является каталог eclipse, например. 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)
      • на всякий случай вы можете наткнуться (как и я): Eclipse->Window->Preferences->JasperStudio->Report Execution->Virtualizer Temporary Path - это что-то несвязанное (не полезное здесь), связанное с хранением результатов отчета "кэширование"
      • конечно, я мог бы написать задачу ANT, чтобы заменить этот локальный шаблон на основе копии фильтра регулярного выражения при каждом использовании/выдаче, но это не лучший способ справиться с этим.
  • если вы хотите работать исключительно с *.jrxml файлами (как я делаю3), вы должны сослаться на некоторые subrep1.jrxml следующим образом: net.sf.jasperreports.engine.JasperCompileManager.compileReport($P{BASE_DIR} + "subrep1.jrxml")

(3: мне явно не нужны файлы *.jasper, и я не понимаю, почему я хочу иметь с ними дело. Кстати, веб-интерфейс JasperServer, кажется, поддерживает только загрузку файлов *.jrxml)

Веб-интерфейс JasperServer

(например, предоставляется некоторым сервером приложений Tomcat и хранит свои данные в некоторой базе данных postgres)

Сценарий 1: ссылка на прикрепленный(е) ресурс(ы) подотчета

  • если вы не хотите повторно использовать свой отчет в целом, можно добавить свой вспомогательный отчет в основной отчет (чтобы он не был виден в дереве репозитория графического интерфейса — см. ниже подпункт, как вы все равно можете ссылаться на него вне вашего основного отчета)
  • если вы прикрепите свой подотчет, он должен, как правило, иметь свое имя файла в качестве идентификатора ресурса, например. наш subrep1.jrxml сверху загружается с идентификатором ресурса subrep1.jrxml (таким образом упрощается обработка ссылок на локальный дизайн и ссылок на сервер)
  • 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
    • НЕ рекомендуется!: вы все равно можете ссылаться на эти отчеты из других отчетов с абсолютными путями, такими как этот2: repo:/x/y/z/masterrep.jrxml_files/masterrep.jrxml_

(2: что я бы не рекомендовал в этом случае; это недокументировано и может измениться; лучше поместите свои подотчеты в «путь репозитория GUI», как описано ниже)

Сценарий 2: ссылки на ресурсы подотчетов репозитория

  • предположим, что мы загружаем наши подотчеты в главный репозиторий с идентификатором пути /x/y/z/ (как показано вверху)

  • снова нам нужно различать два разных варианта использования.

    • мы НЕ хотим использовать вложенный отчет как отдельный отчет (он всегда будет включен только в другие основные отчеты)

      • в этом случае мы должны загрузить его с помощью Add Resource->File->JRXML и сослаться на него

      • ../subrep1.jrxml или ./subrep1.jrxml не работают, так как кажется, что лежащая в основе логика не может обработать выражение относительного пути ..вероятно, . тоже) (что на самом деле было бы неплохо :-( )

      • поэтому здесь нам нужно указать абсолютный канонический путь в BASE_DIR нашего masterrep.jrxml, например, repo:/x/y/z/

    • мы также хотим использовать вложенный отчет как отдельный отчет

      • в этом случае мы должны загрузить его, используя Add Resource->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)
      • resulting in empty subreport sections in master report:
        • $P{REPORT_CONTEXT}.getRealPath("subrep1.jrxml")
        • $P{REPORT_CONTEXT}.getProperty("REPORT_FILE_RESOLVER").resolveFile("subrep1.jrxml")

Дополнительные подсказки

Поскольку мне нравится автоматизировать процесс проектирования и развертывания отчета настолько, насколько это имеет смысл, я написал несколько задач ANT, которые обрабатывают локальный файл *.jrxml для развертывания файла *.jrxml. преобразования относительно BASE_DIR и других преобразований.

SQL помогает легко исследовать структуры пути идентификатора ресурса в метабазе данных postgres сервера jasper (после чего-то вроде 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, связанные с этим, включают:

person Andreas Covidiot    schedule 04.12.2013
comment
Я упростил ответ, предоставив некоторые функции *.jar через пакет jasper utils. Таким образом, там могут быть спрятаны дальнейшие упрощения/модификации. - person Andreas Covidiot; 09.12.2013
comment
Это еще проще (без jasper-utils.jar) с использованием пакетов ресурсов для конкретных отчетов (содержащих определенные свойства, такие как пути подотчетов и т. д., на которые можно ссылаться через $R{subrep1.parentdir} ), отчет-единица-прикрепленные файлы jar (не требуется глобальный перезапуск сервера для изменений/обновлений), в то время как все они также могут быть связанными ресурсами и, таким образом, легко повторно использоваться , избегая избыточности. Я обновлю свой ответ соответственно позже. - person Andreas Covidiot; 18.07.2016

Не уверен, что этот механизм работает во всех случаях, но он точно работает для JasperSoft Studio 5.6.0 и Jasper 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 в студии, и все будет работать при развертывании на сервере.

person OldCurmudgeon    schedule 29.07.2014
comment
Этот ответ был полезен для меня. Однако я не использую Jasper Reports Server (поэтому я не могу использовать параметр REPORT_CONTEXT, чтобы решить, нахожусь ли я на сервере), я читаю экземпляр JasperReport из базы данных и устанавливаю его в коде Java как параметр SUBREPORT. Мой subreportExpression это $P{SUBREPORT} != null ? $P{SUBREPORT} : "subreport.jasper". Такой отчет JRXML и его подотчет работают у меня как в коде Java, так и в JasperSoft Studio 6.3.1 без каких-либо изменений JRXML. - person Jiri Patera; 20.03.2017

Я не на 100% согласен с этим ответом, но: вам нужно загрузить свой подотчет в качестве ресурса jrxml и поместить «repo://subreport.jrxml», чтобы он заработал. Если вы прочтете это в один из тех дней, скажите мне, сработало ли это или какие решения вы нашли. С Уважением

person Delatour    schedule 21.03.2011

Попробуйте полностью удалить расширение и используйте "repo:/subreportFolder/subreportName". Основной отчет загружает файл jasper в iReport, но на jasperserver вы загружаете файл jrxml.

person user1571603    schedule 02.08.2012