PDFの破損につきまして

389 views
Skip to first unread message

COND北島

unread,
Jul 21, 2021, 5:39:25 AM7/21/21
to RapidReportサポート QAフォーラム
いつもお世話になっております。

以下の2件のような破損したPDFファイルが稀に作成されます。

-----------------------------------------------------------------
①RapidReportで作成したPDFファイルをAdobeで開いた時に「この文書を開くときにエラーが発生しました。文書を読み取り中に問題が発生しました(117)。」とエラーが出ます。

②Adobeで開いた時に空白で表示されます。
-----------------------------------------------------------------

①についてはブラウザで表示するとエラーなく表示されます(ページサイズは0×0mm)。
①②のどちらのPDFファイルをテキストエディタで開いたときに、本来末尾だけに表示されるはずの「startxref 606961 %%EOF」がファイルの途中と末尾の2回表示されます(数字は2回とも違う)

1回だけにするために途中~末尾の間の行を削除してPDFファイルをAdobeで開くと正常に表示されます。
ただ、表示されている内容が期待した内容とは全く別の内容になってしまう場合があります。
表示が異なる件は、エラーなく表示できたPDFでもたまに発生します

以上のような不具合の事例はありませんか?
また、回避方法などあれば教えていただけないでしょうか。

当方のシステムの動作環境は以下の通りです。

---------------------------------------------
<OS>
 CentOS Linux release 7.7.1908 (Core)
<アプリケーション形態>
 Webアプリケーション
 (POST通信を受けてローカルにPDFファイルを出力)
<開発言語>
 Java8
<ミドルウェア>
 Java(AdoptOpenJDK 1.8.0_242)
 Apache HTTP Server(2.4.39)
 Apache Tomcat(8.0.36)
<使用ライブラリ(JAR)>
 iText-2.1.7.jar
 iTextAsian.jar
 systembase.barcode-1.3.jar
 systembase.core-1.6.jar
 systembase.report-4.35.jar
 systembase.report-4.36.jar
 systembase.report-5.4.jar
 systembase.report.pdf-4.35.jar
 systembase.report.pdf-4.36.jar
 systembase.report.pdf-5.4.jar
---------------------------------------------

RapidReport

unread,
Jul 25, 2021, 8:48:30 PM7/25/21
to RapidReportサポート QAフォーラム
吉川です。

ご質問ありがとうございます。
まず、回答としては、報告して頂いたような不具合の事例はありません。

つぎに、次の情報を提示して頂ければ調査致します。
提示できる範囲で構いませんので、どうぞご検討下さい。
1.ソースコード
2.帳票定義ファイル(拡張子.rrpt)

cond_kita

unread,
Jun 26, 2022, 9:41:38 PM6/26/22
to RapidReportサポート QAフォーラム

いつもお世話になっております。

回答いただいてから1年近くも時間が経ってしまい、
申し訳ないです。

ソースコード、 帳票定義ファイルの提供について、
準備が整いました。

提供方法についてご教授いただけますと幸いです。

2021年7月26日月曜日 9:48:30 UTC+9 RapidReport:

RapidReport

unread,
Jun 27, 2022, 12:15:44 AM6/27/22
to RapidReportサポート QAフォーラム
書いていただいた状況から判断すると、
Javaのソースコードに問題がある可能性が高いと思います。

帳票出力を行っている部分のコードを貼り付けてもらうことはできますか?

2022年6月27日月曜日 10:41:38 UTC+9 cond_kita:

cond_kita

unread,
Jun 27, 2022, 8:23:47 PM6/27/22
to RapidReportサポート QAフォーラム

回答いただき、ありがとうございます。

すいません、先のメッセージにて抜けておりましたが、
こちらで解析を進めた結果、
以下の事象となっていることを確認しました。

<事象>
 テンプレートAに対する処理とテンプレートBに対する処理が
 それぞれ別スレッドで並走した場合、テンプレートAの処理で
 テンプレートBにプロットする内容が一部反映される。

> 帳票出力を行っている部分のコードを貼り付けてもらうことはできますか?
  →はい、可能です。ソースコードは以下となります。

--------------------ここから--------------------
@WebServlet("/TestPrint")
public class TestPrintServlet extends BaseServlet {
    @Override
    protected void doProc(Map<String, Object> params) throws ServletException {
            TestPrintService printService = new TestPrintService(conn, params);
            // 帳票出力
            ResultData resultData = printService.createReport();
    }
}

public class TestPrintService {
    public ResultData createReport() {
        // 画像のサブページを作成
        Report gazoReport = ReportUtil.readTemplate("TestPrint_gazo.rrpt");
        gazoReport.fill(new ReportDataSource(gazoData));

        // 帳票の各コンテントの高さを調節するカスタマイザ
        // サブページのサイズに応じてコンテントが自動拡張されないので、Customizerを使用してコンテントのサイズを手動設定する
        TestPrintCustomizer customizer = new TestPrintCustomizer(gazoData.size());

        // 帳票定義の読み込み
        Report report = ReportUtil.readTemplate("TestPrint_main.rrpt", customizer);

        // サブページを挿入
        report.addSubPages("gazoPage", gazoReport.getPages());

        // 各明細はGroupDataProviderを使用して渡す
        GroupDataProvider dataProvider = new GroupDataProvider();
        dataProvider.groupDataMap.put("group_homondate_left", new ReportDataSource(homonDateLeft));

        //帳票の生成は提出先の数だけ行う
        List<HashMap<String, Object>> teishutsusakiList = dao.selectTeishutsuList(this.params);

        for (HashMap<String, Object> teishutsusaki : teishutsusakiList) {

            reportData.setTeishutsusakiData(teishutsusaki);

            // メイン帳票にデータを渡す
            ReportDataSource mainDataSouce = new ReportDataSource(Arrays.asList(reportData));
            report.fill(mainDataSouce, dataProvider);

            String tmpFileName = ReportUtil.getTemporaryReportFileName(String.valueOf(this.params.get("serial_Id")),
                    String.valueOf(this.params.get("UserId")));

            String tmpTeishutsuFileName = getFileName(reportData);

            // PDFをローカルに出力
            ReportPages pages = report.getPages();
            ReportUtil.saveReport(pages, tmpFileName, imageMap);
        }
    }
}

public class ReportUtil {
    public static Report readTemplate(String templateFileName, DefaultCustomizer customizer)
            throws JSONException, IOException {

        int index = templateFileName.indexOf("_");

        if (index < 0) {
            index = templateFileName.indexOf(".");
        }

        String parentDir = templateFileName.substring(0, index);

        InputStream is = ReportUtil.class.getClassLoader()
                .getResourceAsStream("../report/" + parentDir + "/" + templateFileName);

        Map<?, ?> jsonMap = ReadUtil.readJson(is);

        return new Report(jsonMap, customizer);
    }
}
--------------------ここまで--------------------

基本的に御社のHPにて公開されているサンプルコードを用いて
実装を行いましたが、帳票定義ファイルの読み込み箇所のみ、
サンプルとは異なる実装を行っております。

異なる点としてはClassLoaderを使用している点で、
帳票定義ファイルをソースコード上に内包する事情があったためです。


2022年6月27日月曜日 13:15:44 UTC+9 RapidReport:

RapidReport

unread,
Jun 27, 2022, 9:12:40 PM6/27/22
to RapidReportサポート QAフォーラム
ソースコード提示ありがとうございます。

話が戻ってしまいますが、利用されているJARファイルについて、
systembase.report-4.35.jar
systembase.report-4.36.jar
systembase.report-5.4.jar
のように複数のバージョンを置いているようですが、
5.4だけを残して古いものは削除しておくことをお勧めします。
(今回の問題がこのせいで起きている可能性は低いとは思いますが)

提示いただいたソースコードを確認しました。
今回の問題は同じファイルに複数の帳票の内容を出力してしまっていることが原因と思われます。

String tmpFileName = ReportUtil.getTemporaryReportFileName(String.valueOf(this.params.get("serial_Id")),
                    String.valueOf(this.params.get("UserId")));

の部分で出力ファイル名を生成しているようですが、
ここで重複する名前が生成されてしまっていないかをご確認ください。
serial_idというパラメータがユニークにならない状況が発生していないでしょうか。

2022年6月28日火曜日 9:23:47 UTC+9 cond_kita:

cond_kita

unread,
Jun 27, 2022, 10:03:45 PM6/27/22
to RapidReportサポート QAフォーラム

回答いただき、ありがとうございます。

> 5.4だけを残して古いものは削除しておくことをお勧めします。
  →すいません、複数バージョンについて、
   最初の投稿以降に改修を行って現在では
     「systembase.report-4.36.jar」
   のみを残して他バージョンは削除済みです。

> 今回の問題は同じファイルに複数の帳票の内容を出力してしまっていることが原因と思われます。
> serial_idというパラメータがユニークにならない状況が発生していないでしょうか。
  →serial_idについて、値としてはユニークとはならないパラメータとなります。
   
   そして、ご指摘いただいたコメントに基づいて
   こちらで再確認を行った結果、原因がおよそ特定できました。
   
   getTemporaryReportFileNameメソッドですが
   ローカル出力するファイル名を生成するメソッドとなっており、
   ファイル名の末尾に[yyyyMMddHHmmssSSS]形式の文字列を
   付与する実装となっております。
   
   しかし、getTemporaryReportFileNameメソッドがstaticであること、
   加えて上記の[yyyyMMddHHmmssSSS]形式の文字列を生成する際に
   スレッドセーフではないSimpleDateFormatクラスを使用していることで、
   マルチスレッドで動作時にタイミングによって同一の
   日時文字列を生成してしまい、本事象につながっているものと思われます。

   判明した内容を元に改修を進めてみます。
   ご対応いただき、本当にありがとうございました。

2022年6月28日火曜日 10:12:40 UTC+9 RapidReport:
Reply all
Reply to author
Forward
0 new messages