OracleDBで文字化け発生

今構築中のPHP+apache+OracleDB構成のWeb業務アプリですが、
テスト環境を作ってもらったので動かしてみたところ、全角文字が??に化けて困ったことに。。

アプリケーションの要件上、2つのOracleDB(どちらも12c)に同時接続する必要があり、
一方の文字コードが
NLS_LANG=Japanese_Japan.JA16SJISTILDE で、
もう一方が、
NLS_LANG=Japanese_Japan.AL32UTF8 となっています。

とは言え、DBクライアントとなるphp側としては、Japanese_Japan.AL32UTF8でいいはず。

apacheのhttpd.confを見ると、
setEnv NLS_LANG Japanese_Japan.AL32UTF8
としているのですが、どうも有効にならない模様。

結果、apacheの起動シェルに
export NLS_LANG=Japanese_Japan.AL32UTF8
を入れてもらって解消。
念の為、はしご高とかを画面から入れてみましたが問題無し。

昔(Oracle8とか)は第2水準以上の漢字はトラブルの元だったとの記憶がありますが、今は便利になりましたね。

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
この業界初と思いますが「士」が付く資格が出来るとの事で、セキュリティスペシャリストに合格していれば、登録とか更新とかいろいろすれば名乗れるそうです。でも、他の「士業」と違って資格が無いと出来ない仕事がある訳でも無いし、維持するには結構お金が掛かるみたいだし、出来たばっかりで知名度無いし、、、暫く様子見ですかね。

Oracle DB のダンプファイルがインポート出来ない

 今やってる案件で、別ベンダーさん側がメイン部分を作って筆者はその周辺を作っているのですが、そろそろデータが欲しくなったので提供を依頼したところ、ダンプファイルが送られてきました。
 さっそく開発端末のOracleDB11Expressにインポートしてみようとしたところ
>imp
Import: Release 11.2.0.2.0 – Production on 火 10月 4 10:48:15 2016
・・・中略

IMP-00401: ダンプ・ファイル”data_20160928.dmp”
は、データ・ポンプ・エクスポート・ダンプ・ファイルの場合があります
IMP-00000: エラーが発生したためインポートを終了します。

ん?何でかダメみたいとググっていくと、どうやら今時はimpdpを使うらしい。。
筆者はOracle8から9辺りまでは実際の開発に従事してましたが、10以降は社内SEであまり具体的な作業をやる機会が無かったので知りませんでした。

で、impdpとやらでインポートしてみます。
>impdp
・・・中略

接続先: Oracle Database 11g Express Edition Release 11.2.0.2.0 – Production
ORA-39006: 内部エラーが発生しました。
ORA-39065: DISPATCHでマスター・プロセスの予期しない例外が発生しました
ORA-04063: package body “SYS.DBMS_METADATA_UTIL”にエラーがあります。
ORA-06508: PL/SQL: コールしているプログラム単位が見つかりませんでした: “SYS.DBMS
_METADATA_UTIL”

ORA-39097: データ・ポンプ・ジョブで予期しないエラー-6508が見つかりました

あれ?パッケージが無いの?
じゃあ、探そうとOracleインストールディレクトリより、GREPで上記のUTILを探すと下記を発見。
早速実行

>sqlplus sys/**** as sysdba

@C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\dbmsmetu.sql

続けてINVALIDのパッケージをしつこくコンパイルしたり、データ・ディクショナリ系SQLを実行したり・・・
http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05771-04/scripts.htm

気を取り直して再度impdp実行
>impdp
・・・中略

ORA-39000: ダンプ・ファイル指定が無効です
ORA-31640: ダンプ・ファイル”C:\oraclexe\app\oracle\admin\xe\dpdump\expdat.dmp”を
読取りのためにオープンできません
ORA-27041: ファイルをオープンできません。

まだダメ。。
下記をちゃんと読んでディレクトリを確認し、既存の設定箇所にダンプを置いて実行。
https://blogs.oracle.com/oracle4engineer/entry/data_pumpexpdpimpdp
>impdp
接続先: Oracle Database 11g Express Edition Release 11.2.0.2.0 – Production
ORA-39001: 引数値が無効です
ORA-39000: ダンプ・ファイル指定が無効です
ORA-39142: 互換性のないバージョン番号4.1が、ダンプ・ファイル”C:\temp\data_20160928.dmp”内にあります

結局、ダンプを作成したOracleのバージョンが12なので無理っぽい。
こちらにもXE特有の問題があるとの事なので、開発端末へのインポートは諦め、テストサーバを作ってもらうまで待つことにします。。
http://freespeedo.blog.fc2.com/blog-entry-1.html#comment3

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を作って別途サービス登録しておきます。

法人の確定申告を終えて

 今日、法人の確定申告をしてきましたので、その経緯マトメです。
7月末が決算期末なので、8月中に帳簿系を弥生会計にひととおり纏め決算書が出せる状態になり、今月から確定申告という感じに流していたのですが、eTaxで試みるも全く訳が解らず。。最初は弥生会計からeTaxデータ書き出しでeTaxにアップロードするもエラーで終了「読み込んだ申告・申請データの本税が1円以上でないため、納付情報登録依頼が作成できません」
 個人の青色申告はこんな感じで終わっていたと思うのですが、どうやら法人はソフトで税金計算をしてくれなくて、自力で税金を計算した上じゃないと無理らしい。。って、どう計算するの??と、こちらのニーズにぴったりな下記本を発見。
新版 ひとり社長の経理の基本

 Amazonで購入し、それを参考に税金を計算、その後弥生会計に税額を仕訳入力し、再度eTaxリトライするも、今後は帳票が出力できるようになるもエラーとしか出力されていない。。上記の本にもeTaxの利用が現実的では無いとの記述有、これは素人には無理です、諦めました。。

 そんで、その前に税務署から送られて来てた書類から必要そうな書類に手書きを開始。資産も無いし、初年なので消費税も関係無いしなので、書類の用意は上記の本を参考に下記の書類を用意。
 ・法人税申告書
  ・別表1(1)+次葉  法人税額の計算
  ・別表4(簡易方式)  所得の金額の計算に関する明細書(簡易方式)
  ・別表15       交際費等の損金算入に関する明細書
 ・法人事業概況説明書
 ・決算書
 ・勘定科目の内訳表
    勘定科目内訳明細書を使って作成
 ・事業年度分の適用額明細書
他に地方税を県税事務所へ提出する
 ・第六号様式
市役所へ提出する
 ・第20号様式

用意が出来たので、申告前日に税務署へ電話し、始めてなんで見てくださいと事前予約、午後一ならOKと、これで全て準備が整いました。
 当日、1日で全部済ませたいのでハンコや登記、eTaxの番号とか現金を持って税務署へ。
 税務署の担当の人に書類を提示し、下記も必要ですとその場で書き方を教えてもらって手書き。
 ・別表2    同族会社等の判定に関する明細書     一人法人でも必要らしい。。 
 ・別表5(1) 利益積立金額及び資本金の額の計算に関する明細書 
 ・別表5(2) 租税公課の納付状況等に関する明細書   別表5は初年度は要らないと思ったら必要らしい。。

 一か所、「事業年度分の適用額明細書」で 第42条の3の2第1項第1号で金額が当期利益ではなく、所得金額だと訂正しましたが、30分程度でチェックは完了、その後申告書を提出、その後納付書を書いて現金で税務署ダイレクト現金納付、ついでに納税証明書も銀行口座追加したら使うかもなんで取得して約1時間で終了。

 その足で県税事務所へ、上記の第六様式という申告書を提出。ここで、一か所間違っていると指摘有。事業開始年月日が3日からになっているので、均等割は12か月でなく11か月との事。。金額を書き直して提出し、その場で納付書を書いてこちらも現金納付完了。

 さらに市役所へ、上記の第20号様式という申告書を提出。特にチェックしているような感じも無かったですが、受付ハンコを押されたのでOKらしい、こちらも納付書を書いてその場で現金納付。

 県税で訂正されたのがちょっと気になりますが、市では何もなかったし、とりあえず終わりましたという事で。。

PS 翌日、市役所の方から電話があり、県税に指摘された箇所と同じ箇所で税額違うとの事、差額を振り込んでくれるみたいでした。

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 “;
に変えていきます。

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