huruyosi’s blog

プログラミングとかインフラとかのメモです。

リリース用のパッケージを作成する時にJasperReportの.jrxmlをコンパイルする方法

課題

今はiReportで.jrxmlのデザインとコンパイルを行い出力された.jasperをソースの一部としてリポジトリにコミットしているが、時折、.jasperがコミットされないことがあるので、リリース用のパッケージを作成する時にコンパイルしパッケージに含めることでリリース漏れをなくしない

コンパイルの方法

分かっている範囲では下の3つ

一つ目が今行っている方法です。 二つ目は始めた頃に使っていたけど、レポートを作成する度にコンパイルするので無駄な処理を行っているのと、もっと大きな問題としてコンパイルすると新しいクラスが定義されJVMにロードされるのでPermgenを食いつぶしてOutOfMemoryが発生します。 三つ目の方法を調べたのでそのメモだけ残します。

ant タスク

公式ドキュメント JasperReports 6.2.0 - Ant Compile Sample に書いてある通りです。 ダウンロードページ http://community.jaspersoft.com/project/jasperreports-library/releases にある jasperreports-{ver}-project.zip に含まれている samples が参考になります。

使い方

<taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask"> 
  <classpath refid="classpath"/>
</taskdef>

でタスクを定義して、

<target name="compile1"> 
  <mkdir dir="./build/reports"/> 
  <jrc 
    srcdir="./reports"
    destdir="./build/reports"
    tempdir="./build/reports"
    keepjava="true"
    xmlvalidation="true">
   <classpath refid="runClasspath"/>
   <include name="**/*.jrxml"/>
  </jrc>
</target>

コンパイルを行います。filesetタグを使うこともできます。

<target name="compile2">
  <mkdir dir="./build/reports"/> 
  <jrc 
    destdir="./build/reports"
    tempdir="./build/reports"
    keepjava="true"
    xmlvalidation="true">
   <src>
    <fileset dir="./reports">
     <include name="**/*.jrxml"/>
    </fileset>
   </src>
   <classpath refid="runClasspath"/>
  </jrc> 
</target> 

サンプルを見る方法

ant タスクでDBサーバを立ち上げた後に、見たいサンプルを ant でコンパイルし、レポートを生成します。

DBサーバの起動方法

$ cd /opt
$ unzip /tmp/jasperreports-{ver}-project.zip
$ cd jasperreports-{ver}/demo/hsqldb
$ ant runServer

バーコードを例にしたサンプルの作成

Jasper Report5.xの頃に使っていた方法です。今のwikiを見ると少し手順が変わっているようす。

$ cd /opt
$ cd jasperreports-{ver}\demo\samples
$ cd barbecue
$ ant 

community.jaspersoft.com

maven の場合

公式の方法が分からなかったので、mavenにアップロードされているものかgithubで公開されているプラグインを使います。

Compile Jasper Reports with Maven | BowerStudios.com github.com

githubのソースを見るとこの程度なら自前で作ってもいいと思えました。

sinsengumi.net

D3.js の勉強を始める 3回目 - 終わり

写経一通り終わり

前回、前回と行ってきた D3.jsのチュートリアル が終わりました。

huruyosi.hatenablog.com

huruyosi.hatenablog.com

次の目標は ギャラリーを参考にして基本的な円グラフを作成する。

13.棒グラフの作成 の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap13/index.html

f:id:huruyosi:20151220142252p:plain

14.散布図の作成 の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap14/index.html

f:id:huruyosi:20151220142303p:plain

15.スケール の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap15/index.html

f:id:huruyosi:20151220142337p:plain

16.軸 の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap16/index.html

f:id:huruyosi:20151220142436p:plain

D3.js の勉強を始める 2回目

今回は チャプター7~10まで

前回の続きになり、チャプター7~10まで

http://ja.d3js.info/alignedleft/tutorials/d3/

今のとこは順調にいけている。ここまではD3.jsを使うための準備だったと思う。SVGを使っているとN88-BASICやX-BASICでワクワクしながらプログラム言語を勉強していた頃を思い出す。

ここまではD3.jsの出力先の指定にselectAll()だけしか出てこないので、出力先をひとつになってしまった。複数の出力先を作るのはどうやるのだろうか。進めていけばでてくるかな。

作成したもの。 https://github.com/huruyosiathatena/d3js_study

10.SVG の基本 の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap10/index.html

f:id:huruyosi:20151220141025p:plain

11.SVG の描画 の結果

https://github.com/huruyosiathatena/d3js_study/blob/649774ef6cd49670f2eb5b691e8c5801cb83f614/d3js/src/main/resources/static/chap11/index.html

f:id:huruyosi:20151220141028p:plain

D3.js の勉強を始める

かっこいいグラフを作りたくて D3.jsの勉強を始めました。手ごろなチュートリアルがあるので写経を行っています。

写経の結果は github (https://github.com/huruyosiathatena/d3js_study)にあります。Spring bootのWebアプリに組み込む予定なので、Spring bootで動かしています。

01. このチュートリアルについて ~ 05.メソッドのチェイン まで

JavaScriptとチェインメソッドの説明だったので、さくっと終了

06. データのバインディング

既存の要素が無いけど、selectAllと書くのはちょっと気持ち悪かった。 WEB インスペクタを使って結果を確認する件は、ChromeFirefoxのWebインスペクタではチュートリアル通りだったけど、Firebugを使うと__data__が出てこなかった。console.log(d3.selectAll("p")[0][0].__data__)console.log(d3.selectAll("p")[0][1].__data__)とやると確認できた。これでいいのかな?

f:id:huruyosi:20151216014034p:plain

07.データの使い方 以降

今日は chapter 6 までで終わり。

GitHubからのcloneで「Problem with the SSL CA cert (path? access rights?)」

落ちは過去に行った設定が原因での自爆でした。環境は CentOS 7.1 です。

事象

$ git clone https://github.com/xxxx/a_repository.git

ってやる実行と

Cloning into 'a_repository'...
fatal: unable to access 'https://github.com/xxxx/a_repository.git': Problem with the SSL CA cert (path? access rights?)

となり失敗してしまう。

こまった

逃げない

検索してみるとgit config --global http.sslVerify false という目先のエラーだけを解決しようとするブログは多いけど、SSL的に証明書のチェックは適切にやりたいので見送り。

ROOTCAの証明書を追加する方法

tetsuyai.hatenablog.com

sudo yum --disableplugin=priorities info ca-certificatesを行うと、インストール済みになった。

ダウンロードしてopenssl x509 -in DigiCertHighAssuranceEVRootCA.crt -fingerprint -nooutopenssl x509 -in DigiCertHighAssuranceEVRootCA.crt -serial -nooutでチェックしたものを/etc/pki/tls/certs/ca-bundle.crtに追加してもだめ。

  ~/.gitconfigで 証明書を指定する

derekmolloy.ie

になった ~/.gitconfigに証明書を記載する方法でごまかす事にして 編集すると随分昔に自己署名証明書で試した時の記述が残っていた。

cat ~/.gitconfig
[http]
#       sslCAInfo = /home/huruyosi/ssl/test_root.cert
        sslVerify = true
[user]
~ 省略 ~

sslCAInfo をコメントアウトして解決。なんともお粗末な結果。

アクセス数が少ないサイトで翌朝にアクセスすると java.net.SocketException: Broken pipe が発生する

事象

昨日は使えたのに、次の日になると調子java.net.SocketException: Broken pipeが発生していました。

スタックトレースは下の通りで、 MySQLサーバとの通信でエラーが起きています。

10:10:21.580 [http-nio-8080-exec-3] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: ] with root cause
java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.8.0_65]
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) ~[na:1.8.0_65]
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153) ~[na:1.8.0_65]
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[na:1.8.0_65]
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[na:1.8.0_65]
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3626) ~[mysql-connector-java-5.1.37.jar!/:5.1.37]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2452) ~[mysql-connector-java-5.1.37.jar!/:5.1.37]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2617) ~[mysql-connector-java-5.1.37.jar!/:5.1.37]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2546) ~[mysql-connector-java-5.1.37.jar!/:5.1.37]
        at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4873) ~[mysql-connector-java-5.1.37.jar!/:5.1.37]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
        at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
        at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc-8.0.28.jar!/:na]
        at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc-8.0.28.jar!/:na]
        at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) ~[tomcat-jdbc-8.0.28.jar!/:na]
        at com.sun.proxy.$Proxy68.setAutoCommit(Unknown Source) ~[na:na]
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1471) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61) ~[hibernate-entitymanager-4.3.11.Final.jar!/:4.3.11.Final]
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:170) ~[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380) ~[spring-orm-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654) ~[spring-aop-4.2.3.RELEASE.jar!/:4.2.3.RELEASE]

原因

色々と調べるとMySQLがアイドルコネクションと判断すると接続を切断し、Spring Bootから検知できてないのが問題。

対応

コネクションプールのデフォルトは Tomcat JDBC Connection Poolということなので、 コネクションの活性確認を定期的に行う設定を追加します。

spring:
  datasource:
    url: jdbc:mysql://localhost/db_test?autoReconnect=true
    username: db_user
    password: xxxxxx
    driverClassName: com.mysql.jdbc.Driver
    validationQuery: SELECT 1
    testOnBorrow: true
    testWhileIdle: true
    timeBetweenEvictionRunsMillis: 1800000

matsumana.info

spring boot をjar で実行した時にjasper reportのサブレポートを指定する

前回の記事でTODOで残った件です。

huruyosi.hatenablog.com

java.io.InputStream を使う

ググってみるとサブレポートのsubreportExpressionのclassにjava.io.InputStreamを指定し、値に getClass().getResource("/path/to/my/report/in/a/jar/subreport.jasper").openStream() を指定するといいみたいです。SUBREPORT_DIRからの変更としてはすっきりする書き方。

stackoverflow.com

別解

net.sf.jasperreports.engine.JasperReport を使う。

s.ameblo.jp