4

私はこのバグを新しいものなしで修正するために数日検索しました。

マルチレベルのサブレポートを含むレポートがあり、すべてが正常に機能しiReport 3.7.5ます。私は第1レベルと第2レベルでサブレポート式として使用しsubreport.jasper、すべて(メインレポートとサブレポート)を同じパスに配置しました。subreportA.jaspersubreportB.jasper

にデプロイしようとすると問題が発生しますJasperServer。最初のメインレポートをアップロードしようとすると、iReportウィザードは最初のレポートsubreport.jrxmlをリソースフォルダーに添付し、repo:subreport.jrxmlまたはでアクセスするように提案しましたrepo:subreport.jasper。次に、第2レベルのサブレポートを手動でアップロードし、同じことを行ってサブレポートの式を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フォルダーで使用します。

また、データベースレコードを検索して、それらが同じフォルダーにあり、同じ親フォルダーを持っていることを確認しました。

4

4 に答える 4

10

ロングトークの前にスモールトーク;)

(もちろん、この長い詳細な記事をすべて読むように勧めたくはありません!太字のマーカーだけで問題を解決できるかもしれませんが、このトリッキーな内容をさらに詳しく説明する価値があると思いました!)

これにさらに数時間を費やしたので(数週間前に解決した後、現在変更がありましたが、適切に文書化するのを忘れ、どのように行ったかを忘れ、アップロードおよび構成時にこの情報をどのような形式でも再度取得できませんでしたto/in JasperServer) ...ここでは、サブレポートの参照、その仕組み、および試すことができるものに関して、さまざまなサイトで言及されているいくつかの集約機能を示します...

(うまくいけば、いくつかある場合は、ここで私のまたは他の調査結果を更新します)

ショートカットの詳細 / ベスト プラクティス?! 4

ジャスパーの機能が同様の「ラッピング」ソリューション自体を提供するまで...

*.jrxml、*.jasper ファイルをプレビュー モードでローカルに実行するか、JasperServer でリモートで実行することに関連するすべての問題を回避するために、私は現在、単一の *.jrxml ファイルのみを操作できる次のアプローチを使用しています。マルチ開発者環境で、変更なしでローカルおよびリモートで、環境ごとのディレクトリ構造 (パス、名前) の独立したリファクタリングをサポートします(= 必要に応じて ;-) ):

  • jasper-utils-*.jarを使用する
    • プロジェクト(Java)のクラスパスに入れます(Project->Properties->Java Build Path->Libraries->Add
    • ../jasperserver/WEB-INF/lib/あなたのフォルダに入れます
  • jr.utl.EnvScriptletマスターレポートで醜いサブレポートパス/参照マジックを実行する カスタム Jasper Java Scriptletを参照する
    • REPORT_SCRIPTLETマスター レポートに属性を追加して定義します:レポート プロパティ -> レポート -> データ セット -> スクリプトレット クラス: jr.utl.EnvScriptlet
  • いくつかのカスタム プロパティ ファイルjr.utl.propertiesまたは別の方法で提供されたシステム プロパティを使用して(Java システム プロパティを設定する他の方法でも問題なく動作します - すでに設定されているプロパティは、ロードされたファイル プロパティを上書きします)

    • プロパティによる現在の環境情報jr.utl.env(prod、myOsUsrName、test、demo、staging、local など)
      • サブレポート参照をどのように生成する必要があるか/どのように見えるかを決定します
    • サーバー サブレポートの親ディレクトリ プロパティの参照
    • たとえば、これらのプロパティ ファイルの内容を環境ごとに 1 つここに配置します。
    • サーバー上で:../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
        |- ソース/レポート
           |- jr.utl.properties (バージョン管理では無視され、以下のテンプレートに基づいてユーザー固有に生成されます)
           |- jr.utl.template.properties (上記の jr.utl.properties を生成する ANT ビルド タスクのソース)
              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

  • マスターサブレポート式を次のように定義する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は最善の方法ではないかもしれませんが、おそらくほとんどのユースケースで機能します
  • 既存の 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/ (これは、視覚的な名前付きパスと混同しないでください。たとえばFinancial Reports/Expenses/Current Year

一般: Jasper Studio、JasperServer

(およびカスタム Java Jasper パッケージの使用などの他の「Jasper ランタイム環境」):

  • Jasperランタイム環境によって異なるレポート パラメータ「プレフィックス」を宣言することをお勧めします。BASE_DIR
    • ここで重要なのは、サフィックス/が含まれている可能性があると想定するのが最善のように思われること です
      • たとえば$P{BASE_DIR} + "subrep1.jrxml"、これはに解決する必要があります repo:subrep1.jrxml
    • 詳細については、たとえばここを参照してください ( を探してくださいSUBREPORT_DIR)

( 1 : ディレクトリのような構造を扱う場合、私は個人的に一般的に悪い習慣を見つけます (この点で Jasper Reports を見ていません))

JasperStudio デザイナー (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ファイルのみを操作したい場合(私がそうしているように3subrep1.jrxml )、次のようなものを参照する必要があります。net.sf.jasperreports.engine.JasperCompileManager.compileReport($P{BASE_DIR} + "subrep1.jrxml")

( 3 :*.jasperファイルを明示的に必要とせず、なぜそれらを処理したいのかわかりません。ところで、JasperServer WebGUI は*.jrxmlファイルのアップロードのみをサポートしているようです)

JasperServer Web GUI

(たとえば、一部の Tomcat アプリケーション サーバーによって提供され、そのデータを一部の postgres データベースに保存する)

シナリオ 1: 添付されたサブレポート リソースを参照する

  • 一般的にレポートを再利用したくない場合は、supreport をマスター レポートに追加しても問題ないようです (そのため、GUI リポジトリ ツリーには表示されません。以下のサブ項目で、マスターの外部で参照する方法を参照してください)。
  • サブレポートを添付する場合、通常はそのファイル名をそのリソース ID として持つ必要があります。たとえば、subrep1.jrxml上記のリソース ID を使用してアップロードしますsubrep1.jrxml(したがって、ローカルの設計参照とサーバー参照の処理がより簡単になります)。
  • 上記のサンプル レポートを使用して、アップロードするマスター レポートに設定BASE_DIRする必要があります。repo:
    • したがって、サブレポート式$P{BASE_DIR} + "subrep1.jrxml"であり$P{BASE_DIR} + "somesubdir/subrep2.jrxml"、サーバーでも機能するはずです
    • 推奨されません! :この2のような絶対パスを使用して、他のレポートからこれらのレポートを引き続き参照できます。repo:/x/y/z/masterrep.jrxml_files/masterrep.jrxml_

2:この場合はお勧めしません。文書化されておらず、変更される可能性があります。以下で説明するように、サブレポートを「GUIリポジトリパス」に配置することをお勧めします)

シナリオ 2: repo サブレポート リソースを参照する

  • サブレポートをマスター リポジトリ id-path にアップロードするとします/x/y/z/(上に示すように)。

  • ここでも、2 つの異なるユースケースを区別する必要があります

    • サブレポートをスタンドアロン レポートとして使用したくありません(常に他のマスター レポートにのみ含まれます)。

      • この場合、それを使用してアップロードしAdd Resource->File->JRXML、参照する必要があります

      • ../subrep1.jrxmlまたは、基礎となるロジックが相対パス式を処理できない./subrep1.jrxmlように見えるため、機能しません(そして、おそらくそうではない可能性があります) (これは実際にはいいでしょう :-( )...

      • したがって、ここで行う必要があるのは、masterrep.jrxml の中に絶対正規パスを指定することです。BASE_DIRrepo:/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")(ヌルポインタ例外)
      • マスター レポートのサブレポート セクションが空になる:
        • $P{REPORT_CONTEXT}.getRealPath("subrep1.jrxml")
        • $P{REPORT_CONTEXT}.getProperty("REPORT_FILE_RESOLVER").resolveFile("subrep1.jrxml")

追加のヒント

はレポートのデザインと展開プロセスを可能な限り自動化したいので、ローカルの *.jrxml ファイルを処理して、 およびその他の変換に関する展開可能な *.jrxml ファイル変換を処理するANT タスクをいくつか作成しBASE_DIRました。

jasper サーバー postgres メタ データベースのリソース ID パス構造を簡単に調査するのに役立つSQL (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 フォーラムの質問には、次のようなものがあります。

于 2013-12-04T11:45:34.720 に答える
3

このメカニズムがすべての場合に機能するかどうかはわかりませんが、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>

それができたら、次の 2 つの選択肢からサブレポートの場所を定義できます。

<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、スタジオで使用でき、サーバーにデプロイするときにすべてが引き続き機能します。

于 2014-07-29T11:23:47.123 に答える
0

拡張機能を完全に削除して、「repo:/ subreportFolder/subreportName」を使用してみてください。メインレポートはiReportのjasperファイルをプルしますが、jasperserverではjrxmlをアップロードします。

于 2012-08-02T13:56:17.737 に答える
0

私はこの答えの100%ではありませんが、サブレポートをjrxmlリソースとしてアップロードし、「repo://subreport.jrxml」を配置して機能させる必要があります。当時のこの記事を読んだら、うまくいったかどうか、または見つけた解決策を教えてください。よろしく

于 2011-03-21T11:47:18.507 に答える