bokusui について

ソフトウェアハウスでのPG・SEから始まり、10年近く勤めた金融系企業の社内SEを数年前にやめ、フリーランス時代を経たのち法人成りしました。システム開発の全工程をこじんまりとやり続けています。

POIでエクセルファイルを読むにはStreamingReaderが必須っPOI

エクセルファイル内のシートをDBに取り込む要件があり、DBサーバであるlinux上で取り込む処理をする必要が出てきました。
とりあえずCSVにでも変換してしまえば後はどうにでもなるので、Apache POIを使って汎用で使えそうな簡易CSV変換ツールを作ってみました。簡単にテストした後、いざ対象となるエクセルファイルで実行してみたところいつまでたっても終わらないし、メモリを数G食うという異常な状態に。
 テストした時のエクセルは数千程度で、いざ実行したエクセルは数万規模の違いがあり、大量データが含まれるエクセルシートの場合にPOIでは問題があるみたいです。で、こりゃ何とかしないとと調べていくと、それを解消してくれる素晴らしいライブラリを発見。
https://github.com/monitorjbl/excel-streaming-reader

上記サイトのREADMEに従い、下記のようにWorkbookFactory.createの箇所を置き換えるのみでした。(inputはエクセルファイルのInputStream)

変えた後は何事もなかったかのようにちゃんと終わりました。
それにしてもPOIは非推奨メソッドをいつ置き換えてくれるのだろう?

追伸
sheet.getNumMergedRegions() 等、サポートしていないメソッドが多数あるようです。
結合セルなどを意識しないで、単純にエクセルファイルを行毎に順次読み取るような処理には適してます。

カテゴリー: Java

EJBタイマーサービスを使ってみることにした

WebLogicを動かしているサーバ上で数分間隔にとある機能を動作させたいという話があり、常駐プロセス起動とかにしたくないので、EJBタイマーサービスを使ってみることにしました。
タイマーサービスの使用は初めてなので、WebLogic12Cの挙動を調べながらの作りこみです。

結果的に下記のようになりました。
5分間隔(0分2秒,5分2秒,10分2秒,15分2秒・・・)でタイマー処理を実行しています。
なお、トランザクション処理は必要無し、処理結果のエラーハンドリングも不要、指定の間隔で単純に起動されればよいような機能です。

WebLogicにおけるEJBタイマーの挙動として確認できたのは、

①タイムアウトを実装しておかないと30秒以上経つとエラーを吐いて、次のタイマーまでは動くのだが、その次以降はまったく動かなくなる

Caused By: weblogic.transaction.internal.TimedOutException: Transaction timed out after 30 seconds
中略・・
Truncated. see log file for complete stacktrace

なぜ30秒なのかというとトランザクションタイムアウト値がそうなっているっぽい。。
https://docs.oracle.com/cd/E28613_01/web.1211/b65951/ejb_jar_ref.htm#i1506703

何をするわけでもないが、とりあえず@Timeoutのアノテーションをつけたメソッドを追加

②処理時間が次回のタイマー処理開始を超えるとタイマーが止まる

例えば、5分間隔で動作させる場合、処理が5分以上掛かってしまうと、次のタイマー実行時にエラーが吐かれて動かない

<2016/11/15 16時55分07秒 JST> <Error> <EJB> <BEA-011088> <The following error occurred while invoking the ejbTimeout(javax.ejb.Timer) method of EJB ChkTimer(Application: appmgr, EJBComponent: /appmgr).
以下、略・・

なので、処理自体をExecutorServiceでスレッド処理にし、処理遅延が起きないようにしてみました

③永続化はしない方がよい

とりあえずサーバ上で空回りするようタイマー稼動テストを数日間したところ、ちゃんと指定間隔通りに動作していたので、機能を概ね実装していざデプロイしてみると、2重起動している状態に、、
なぜかといろいろ調べた結果、空回り開始時にpersistent=falseを指定していなかったので、ずっと残り続けていた模様。
一度、タイマー起動を無しにしたモジュールでデプロイした後、再度タイマーを有効にしてデプロイすることで、やっと2重起動が止まりました。

実行したいスケジュールや処理内容によっては、結構制御が難しいように思いますが、今回の要件ならOKという事で。

情報処理安全確保支援士って何だ?

先日、IPAからこんなメールが来ていました。

=================情報処理技術者試験情報のお知らせ===============
◆お知らせリスト
 ◇ 登録制の新国家資格「情報処理安全確保支援士」制度を開始
~経過措置対象者の登録を受付中~

==========================================================

 筆者の場合、正直合格しても何も得する事は無いのですけど、気分転換と腕試し的な意味合いで情報処理試験に行ってまして、今年春の試験でセキュリティスペシャリストを取っていたので、このメールが来ていたようです。
 何のことだろうとIPAのサイトを見ると、
http://www.ipa.go.jp/siensi/index.html
この業界初と思いますが「士」が付く資格が出来るとの事で、セキュリティスペシャリストに合格していれば、登録とか更新とかいろいろすれば名乗れるそうです。でも、他の「士業」と違って資格が無いと出来ない仕事がある訳でも無いし、維持するには結構お金が掛かるみたいだし、出来たばっかりで知名度無いし、、、暫く様子見ですかね。

gitbucketとredmineを連携させてみる

 そろそろちゃんとソース管理をしないとと思い、既に使っているredmineにgitbucketを連携してみました。
redmineを入れているcentOS6サーバにgitbucketを導入してみます。って、下記を見る限り
http://qiita.com/pppurple/items/2e614a836e2184f70997
とりあえずgitbucketを動かすならwarをダウンロードしてJavaコマンド実行するだけのようですが、
java -jar gitbucket.war
では、どうもうまく動作しません。

で、payara-microにデプロイする形で実行してみます。
java -jar payara-micro-4.1.1.163.jar –port=18080 –deploy gitbucket.war

フロントがapacheなので、httpd.confのProxyPass当たりを追加し、とりあえずはgitbucketの画面が出るようになりました。

次はredmine側にリポジトリを登録します。が、リポジトリのパスはどこなんだろうと調べると、gitbucketデフォルトでは起動ユーザーのhomeに隠れて作られているとの事。このパスをそのままredmineのリポジトリに登録してみましたが、NotFound状態・・

リポジトリのパスを変えないとredmine側から参照できないようなので、ホームディレクトリを指定する実行時引数を追加。

結果的にこうなりました。
java -Dgitbucket.home=/var/lib/gitbucket -jar payara-micro-4.1.1.163.jar –port 18080 –deploy gitbucket.war

gitbucket側でリポジトリを新規作成し、サーバ内に出来た拡張子.gitのファイルパスをredmine側のリポジトリのパスに指定します。

やっとredmine側から見れるようになりました。
redminerep

作ったリポジトリへeclipseから強制PUSHするとこんな感じでgitbucketのホームディレクトリを変える前にコミットしたのも含めてredmineから参照出来ました。分散管理っていいですね。
redminerep2

後日、init.shを作って別途サービス登録しておきます。

JSF2でbootstrapのダイアログとアイコンを使う

 前に作ったJavaEEアプリの画面に機能追加の依頼があったのですが、既存画面に追加するのも新規画面を作るのも微妙な要件だったので、ダイアログ表示でなんとかしたいと考えてました。
 で、ちょうどbootstrapを使っていたので、調べてみるとダイアログ表示はbootstrapで簡単に出来そうです。なおバージョンは2.3を使用しています。
http://bootstrapdocs.com/v2.3.2/docs/javascript.html#modals
JSF2のel式をダイアログに埋め込む為にはh:form内に書けばよいようです。ダイアログにはdatetimepickerをinputを2項目入れ下記のようになりました。

呼び出し箇所は下記です。

これで「期間指定」を押すと下記のようなダイアログが表示されます。
fromto

次にアイコン表示も
http://bootstrapdocs.com/v2.3.2/docs/base-css.html#icons
の通りやってみましたが、なかなか表示されません。なんでかな??と思いながらブラウザの開発ツールを見ていたら、pngファイルは404 Not Foundとの事。ここでやっと気が付き、bootstrap.cssのpngファイル名に「.xhtml」を付け、やっとアイコンが表示されました。

プロジェクトの7割では何が失敗しているのか?

 システム構築プロジェクトの約7割は失敗すると一般的に言われています。ここで失敗と言っているのはQCD(品質・予算・納期)の3点が計画に対し達成できなかったという事みたいですが、失敗と判定しているのはいったい誰でしょうか?
 予算と納期は明確なので、成功・失敗は明確に線引きできそうですが、作り手側では途中で納期に間に合わせる事が無理だと判断したその時点でユーザー側と予算と納期の調整をするはずです。この場合、調整を開始する時期にもよりますが、大抵の場合で要件追加はあるものですし、要件追加に対してはそれを盾に予定よりも時間が足りないと主張するのは当然と言えば当然で、ユーザー=発注者側が了解すれば、結果として予算と納期は変更されます。なので、作り手側からみると当初の予定というよりも最終的なコスト・納期で判断している事が多いように思います。でもユーザー側は計画通りではなくなったと考えるでしょう。ここで作り手側とユーザー側で基準にズレが発生している事になります。
 また、品質というのは何を基準にしているか曖昧ですが、品質が計画通りでないというのは基本的にユーザー視点でしょう。作り手側は品質的に問題無いという判断できる段階で納品しているはずなので、そのズレが大きいのでしょうか。カットオーバー後にちょっとした不具合でもあれば、品質が良くないと強く感じてしまうものですし、そもそも要求を全て実現する事なんて殆ど無いのに、いざ動かしてみたら、実現出来ていない点が目立ってしまい、要件外であったとしても一番使うエンドユーザーは大抵そんな経緯は知らず、不満な思いを持ってしまいます。
 作り手である開発者側も発注者であるユーザー側のどちらも経験している筆者の経験上、開発者の立場から失敗だったと感じたプロジェクトはあまり無いですが、発注者側の立場では当初の予定通りに行くプロジェクトは確かに多くはなかったと感じます。途中から担当することになったプロジェクトなどでは既に失敗してないか?というのもありましたので、7割のプロジェクトが失敗したという判定は発注者側、さらに、当初の計画を知っている人、発注者側のシステム部門長の判定と思われます。
 でも、正確に言うとシステム構築プロジェクトの失敗ではなく、プロジェクトを計画する企画段階が失敗しているケースが多いのではないでしょうか?計画に問題があれば、それを実行するのが難しいのは当然です。ヒマラヤ登山の計画がずさんだったらそりゃ大事故が起こるのは当たり前です。でも、登山だったら目的は明確だし、登山道の選択肢も限られているし、過去の経験と照らし合わせて計画ができます。対してシステム構築プロジェクトは、お題目的な目標はあれど、たいていは明確ではありません。例えば業務コストを何%カットというのが目標だったりすると、その為に何をするかは限りなく選択肢があります。極端な話システム開発しなくても達成できる事だってあります。
 数年前に話題になった小惑星探査機はやぶさのプロジェクトですが、あれって期日を何年も超えてるし、恐らく予算もかなりオーバーしていると思いますが、誰もが成功と思っているのではないでしょうか?実は、はやぶさプロジェクトの評価は加点方式で、何のミッションを実現したら何点という評価方法自体をプロジェクト計画時点で明確にしていたので、一般的な減点方式の評価とは違うらしいのです。
 とは言え、前人未踏のはやぶさプロジェクトとは違い、殆どのプロジェクトは減点方式です。計画に対して未達なら減点されてしまうのですが、計画が計画通りにいかないリスクを感じ取るのは不可能、というか、そもそもリスクヘッジした結果として計画が出来上っているはずなんです。時間経過に伴いリスクが顕在化した場合を見越して、要件定義後に計画を再見直しするという前提を設けるとか、曖昧なバッファ期間・バッファ予算を設けるくらいしかできませんが、それを他へ説明するのも難しいものです。細かい機能要件の漏れとかインフラ・ビジネス・他システム連携の前提条件が当初想定したものと一致していない事が判明するのは設計フェーズでよく発生しますが、極端なケースだと実際に他システムと接続できた後の導入開始後だったりもします。当然それらは計画時点では盛り込まれていませんので、計画を変更せずにそれらを受け入れる時、いわゆるデスマーチが始まるのです。もちろん、作り手側の力量不足という理由だけでマーチが始まってしまう事も確かにあるでしょう。とは言え、例えそうであったとしても、失敗という言葉を現場のメンバーのいる場で聞こえるように言わない方がいいですね。

Zend_Dbの微妙な相違にハマる

今、ZendFrameWorkを使ったphpアプリをDB2からOracle接続へ変える対応をしています。
phpは数年前に少し触った程度でしたが、基本的にアプリケーションスペックは何も変えないという前提なので、DB接続部分を変え、DB2独自のSQL部分を変えればそんなに時間は掛からないだろうと思ってました。

接続部分は、
$conn = Zend_Db::factory(“db2”,$params);

$conn = Zend_Db::factory(“Oracle”,$params);

SQL実行部分は
$stmt = new Zend_Db_Statement_DB2($conn, $sqlString);

$stmt = new Zend_Db_Statement_Oracle($conn, $sqlString);
に、その他DB2独自のSQLをOracle向けにSQLを書き換えていく地味な作業です。。

開発環境は、
pleiades 4.6 Neon PHP にしてみました。
php/pearにZendを追加したり、Oracle接続の為にInstantClient12を入れ、
php.iniは、
extension=php_oci8_12c.dllやextension=php_pdo_oci.dllを有効に、
iconv.internal_encoding=UTF-8 でマルチバイト対応とし、
大体開発環境が整いました。

で、DB2のテーブルをOracleDBに作成し、XAMPPを動かして画面を動かしてみると下記のエラーが、
Invalid bind-variable position ‘?’
バインドがインバリッド?何でだろう??
何もまだ変えてない箇所なんだけど。。

でネットで情報収集していくと下記を発見
oci_bind_by_name
Oracle はクエスチョンマークをプレースホルダとして使いません。

との事。。

まったく変更する必要が無い箇所もたくさんあり、いろいろ継承している既存ソースを考慮し、
?を諦め、下記のように:0などに置き換えていこうと決断。

$sqlString = $sqlString . “? = COLUMN_NAME “;
というような箇所を
$cnt = 0;
$sqlString = $sqlString . “:” . $cnt++ . ” = COLUMN_NAME “;
に変えていきます。

変更箇所は当初想定した倍以上になりそうです。
幸い時間があるので、間に合うとは思いますが、参りました。。

決算前税務講習会に行ってきた

 法人設立からもうすぐ1年という事でしょうか、税務講習会のハガキが来ていたので松戸法人会に本日行ってきました。
 せっかく松戸に行くんだからという事で中華蕎麦とみ田で昼飯でも、と、11時過ぎについたら案内出来るのは2時過ぎですとの事・・・無理なので、近くの系列富田食堂でラーメン食べて、法務局へ登記取りに行ったり、税務署へeTaxで納税する為に「国税ダイレクト方式電子納税依頼書兼国税ダイレクト方式電子納税依頼書」を提出して、松戸法人会へ。なお、税務署に提出した方は1か月くらいで有効になるとの事。くらいっていつですか?と聞きましたが、明確な回答は無く、期初が8月=申告期日は9月末までなのでまあいいやと。
 税務講習会は13時半から16時まで、前半は税理士の話、後半は税務署員から直近における税法の変更箇所の説明と源泉徴収の注意事項という流れですが、税理士の方が元マルサで「ガサ入れ」の話とか「通帳のカミナリ型、逆L字型」とか結構面白かったです。講習とはあんまり関係無いですが、半分くらいそんな話でした。その後、タバコ吸いながらその税理士の方と話をしてましたが、漫画の監修もやったよと。最後にちゃんとまじめに記帳していれば大抵大丈夫だよと心強い一言。
 あとは、源泉徴収の注意事項で前回間違えていた箇所が発覚。納付書の「人員」は延べ人数を書くとの事。筆者の場合は特例なので納付は半年に1回、という事は1人なら半年で延べは6人なんですね。一応、税務署の人に聞きましたが、解りますから大丈夫ですよという事なので、次回は間違えないようにしよう。

8月22日 ダイレクト納付の登録完了通知がeTaxのメッセージに入ってました。

SSL証明書を入れてみた

 SSL証明書が欲しくなったので、出来るだけ安くという事で下記にしてみました。なお、サーバは別の所にあります。
http://www.sslbox.jp/
 サポートページにあるとおりに秘密鍵を作成し、格安証明書3年で税込み2,559円のCoreSSLを管理画面より申込&決済&証明書申請。数分で証明書をゲット出来ました。
 ゲットした証明書はこれまたサポートページを見ながらサーバに配置&ssl.confをセッティングし、リスタート。
 で、稼働確認も済んだとして、サーバ設定をもとに戻したら、見つかりません状態に。。
 何で??と思ったらiptablesで弾かれていました。。
iptablesのコンフィグファイルに下記を追加し、リスタートで作業終了!
-A INPUT -p tcp -m tcp –dport 443 -j ACCEPT

UWSCを使ってみた。

前回の続きで、Windows系のサブネットを一括変更するツールを作ろうといろいろ調べてみました。
まずは、コマンドプロンプトなどで、
netsh interface ip show addres
を打ち、その出力から変更対象のネットワーク設定を取得し、それを元に、
netsh interface ip set address “ネットワーク名” static 192.168.1.101 255.255.254.0 192.168.1.1
といったネットワーク変更コマンドを発行するスクリプトを作ります。
 それをリモートから実行するのには、そのスクリプトをリモートマシンに配置して実行するという事なりますが、まずやってみたのがPsExec。net use でスクリプトをリモートマシンへコピーしてPsExecで実行するという内容ですが、2012Serverだとデフォルトではnet useもPsExecもFirewallで弾かれてしまいます。Firewallを無効にするとうまくいくのですが、Firewallとかセキュリティポリシーとか変えなきゃいけないならそれは本末転倒になってしまいます。
 結果、行きついたのが、UWSC。大抵のWindows系サーバはメンテナンスの都合でリモートデスクトップだけは有効になっているので、リモデ経由の作業を自動化するにはと発想を変えてUWSCを見つけました。下記を参考にさせて頂きました。

UWSCによるリモートデスクトップの一括自動操作スクリプト

微妙に2012ServerR2用のGUI操作に変更して使ってみました。
でも、結果的にはコマンドのみで完結しない作業だし、実行結果の証跡確保や確実性を求められる内容なので、やっぱり手作業が必要になってしまいました。ダイアログを出して手作業が終わったらボタンを押すみたいな。。
Windows系OS作業の自動化はインフラ側でそれに合わせた設定が事前にされてないと無理ですね。