JSF試行錯誤
思ったこと。
- セッションスコープでデータを持ちたいときに@SessionScopeをつけたbeanをInjectするとエラーになる
- これで解決
- glassfishの変なバグ:トランザクション境界を越えてExceptionを投げられると、どんなエラーでもRollbackExceptionが上位にわたってくる。
- 馬鹿でしょ。@Versionでのロック判別できない
- これでググろう!GLASSFISH-21172
- Javascriptをあまり書かなくて済むから楽。Ext JSではどんなに苦労したことか・・・
- dataExporterとかマジ便利
- JPAはバカ
- LEFT JOINすると基本は別々にSQL実行される。毎回QueryHints.LEFT_FETCHとかsetHintsしないと行けない。
- NamedQueryで済むなら定義しとけばいいけど。条件文の個数とか動的に変えたいでしょ普通は
- デフォルトがキャッシュが効く設定。shared-cache-modeのデフォルトはキャッシュなしでいいだろ
- Faceletを使ったRESTなURLのページが作りづらい
- だいたいxxxx.xhtmlを呼び出すものだからね
うんこ
うんこ
PythonでPACSにdicomファイルを送る方法
CONQUEST DICOM Serverをインストールしているサーバのfsckが失敗してlost+foundディレクトリに
大量のdicomファイルがあったので、それをCONQUEST DICOM Serverに再登録するためのスクリプト
easy_installでpydicom,pynetdicomをインストールすること
#!/usr/bin/env python import sys from netdicom.applicationentity import AE from netdicom.SOPclass import * from dicom.UID import * import dicom import os import traceback remote_host = "xxx.xxx.xxx.xxx" remote_port = 5678 def OnAssociateResponse(association): print "Association response received" MyAE = AE("自分のAEタイトル", 9999, [ StorageSOPClass, VerificationSOPClass],[], [ImplicitVRLittleEndian]) MyAE.OnAssociateResponse = OnAssociateResponse RemoteAE = dict(Address=remote_host, Port=remote_port, AET="CONQUEST") print "Request association" assoc = MyAE.RequestAssociation(RemoteAE) print "DICOM Echo ... ", st = assoc.VerificationSOPClass.SCU(1) print 'done with status "%s"' % st for dpath, dnames, fnames in os.walk("lost+foundにあったdicomファイル置き場のパス"): for fname in fnames: full = dpath + "/" + fname print full d = dicom.read_file(full, None, False, True) print "DICOM StoreSCU ... ", try: st = assoc.SCU(d, 1) print 'done with status "%s"' % st except Exception as inst: print "problem -> ", inst print "trace -> ", traceback.format_exc() print "Release association" assoc.Release(0) MyAE.Quit()
あー、PACSぐらい商用のもの導入してほしい。。。
ドキュメント管理ソフトを探す
会社の先輩のお姉さんにドキュメント管理ソフトが欲しい。と言われて、すっかり忘れて1ヶ月ほど放置してたけど
昨日、今日といろいろ探していた。で、試したのは順番に以下の3つ。
- OpenKM
- NemakiWare
- alfresco
今回はCentOS6.3にインストールすることにした。
OpenKM
これは、最新版が6.4だったかな?日本語にローカライズされていない。
5.1はローカライズするSQLファイルがここでダウンロードできた。
http://wiki.openkm.com/index.php/Language_Packs
これは、インストール自体は簡単。ここにあるファイルをダウンロードして実行するだけ
http://www.openkm.com/en/download-english.html
だけど、実際動かしてから基本機能を使えるようにするまでに至らなかった。
文書のプレビューを表示するのにLibreOfficeをデーモンで立ち上げるようにするとかの設定とか
何やらがうまく行かず面倒でやめた。UbuntuでOffice文書をPDF化するJODConverterのWebサービス環境を
作った時は、うまく行ったんだけどなー。
半日悩んだので諦めた。PDF文書をOCR読み込みできる機能があるみたい。OpenKMが一番よさげだったんだけどなー
NemakiWare
国産ソフトなんだそうで。ドキュメントが揃ってそうで期待していたんだが。。。
インストールで躓いた。
Select target path [/root] /var/nemakiware Tomcat configuration Tomcat port [8080] Tomcat port(shutdown) [8005] Tomcat port(AJP) [8009] press 1 to continue, 2 to quit, 3 to redisplay Repository configuration Repository ID(main) [bedroom] Repository ID(archive) [archive] press 1 to continue, 2 to quit, 3 to redisplay CouchDB configuration CouchDB host [127.0.0.1] CouchDB port [5984] press 1 to continue, 2 to quit, 3 to redisplay Rails configuration Choose your Ruby bin path [C:\RailsInstaller\Ruby1.9.3\bin] /usr/bin press 1 to continue, 2 to quit, 3 to redisplay [ Starting to unpack ] [ Processing package: (1/9) ] [ Processing package: Tomcat (2/9) ] [ Processing package: NemakiWare CMIS サーバ (3/9) ] [ Processing package: CouchDB初期データのインポート (4/9) ] [ Processing package: Solr (5/9) ] [ Processing package: NemakiShare CMIS クライアント (6/9) ] [ Processing package: NemakiShareの初期設定 (8/9) ] [ Processing package: (9/9) ] [ ERROR: The installation was not completed ] [ Unpacking finished ]
何が原因のエラーか全くわからんし。もっと詳細なエラーログだしてくれー
対処しようがない。
事前にRubyもインストールしないといけなくて、やたら面倒だったし。
1時間で諦めた。
alfresco
ここでダウンロードした
http://sourceforge.net/projects/alfresco/
こんな感じでインストール。事前に準備するソフトもなし。(多分)
chmod a+x alfresco-community-4.2.f-installer-linux-x64.bin
./alfresco-community-4.2.f-installer-linux-x64.bin
対話形式でやっていって、何の問題もなくインストールできた。
以下のURLでアクセス
http://host/share
使ってみたが、フリーのソフトにしてはよくできてるな。と思いました。
EXCELとかPDFとかアップロードして、文書中の文言の内容で検索とかできちゃうし。(あたりまえ?)
しかもSharepointプロトコルを喋ってOffice連携できるのはすごい!!
ただ、メニューをログインユーザのグループとかで切り替えできない。
どんな権限、グループでもサイト(ポータル画面みたいなやつ)を作れてしまう。
まあどうせ、リポジトリしか使わないだろうから無視して使ってもらえばいいんだけど。
Ext JS4.2のform部品にapplyToがない件
今までは院内Webシステムを作るときは、見た目の良さからExt JS3.4を利用していたが、
新しいシステムを作るにあたって新しいバージョンの4.2を使ってみることにした。
Webシステムは、SeasarプロジェクトのSAStrutsとS2Daoを使っている。これすごい便利。
Javaで作るなら、これがないともう無理。私アンチPHPですし。自分だけでやるならこれ一択
まあそれはいいとして、Ext JS3.4のときはJSPに書いたhtml:textとかhtml:selectとかのタグに、
こんな感じでExt JSのスタイルを当てていた。
new Ext.form.DatePicker({ applyTo: "inputタグのid" });
Ext JS4使ってみると、applyToのコンフィグがない!!
コンボボックスだけはtransformのコンフィグでできたけど、日付選択とか、
ただのテキストボックスとかをExt JSスタイルにする方法が見当たらなかった。
うーん、サンプルみたいにExt JSだけでフォームの入力部品を作っていくと
アクションフォームの値をフォームに反映するのがひじょーに面倒だ。
JSPファイルの中でExt JSのフォームを作るjavascriptを書けばいいんだろうけど、それはしたくない。
他の人はどうしているんだろか?と思ってググってみたが、日本語の情報は皆無だった。
Ext JSって、そもそもどういう使い方を想定しているのか全然わからん。
PHPファイルとかJSPファイルにはinputタグを書かないのがセオリーなの?グリッドはすごい便利なのにその辺が優しくないなー
まあ、外国には同じことで困っている人がいたようで。
これを参考してみた。
http://www.sencha.com/forum/showthread.php?158065-add-applyTo-to-Ext-4.1&langid=14
/** * An abstract base class which provides shared methods for Components across the Sencha product line. * * Please refer to sub class's documentation. * @private */ Ext.define('Ext.AbstractComponent', { /* Begin Definitions */ // --------- 省略 ------------------ me.loader = me.getLoader(); // ここから if(me.applyTo) { me.name = me.applyTo; var elem = Ext.get(me.applyTo); me.setValue(elem.getValue()); me.setReadOnly(elem.dom.readOnly); me.setDisabled(elem.dom.disable); me.render(elem.dom.parentNode); var id = elem.id; elem.dom.parentNode.removeChild(elem.dom); me.inputEl.dom.setAttribute("id", id); }else // ここまで if (me.renderTo) { me.render(me.renderTo); // EXTJSIV-1935 - should be a way to do afterShow or something, but that // won't work. Likewise, rendering hidden and then showing (w/autoShow) has // implications to afterRender so we cannot do that. }
これで、Strutsタグで書いたフォームにExt JSスタイルを当てることができた
Ext.create("Ext.form.field.Date", { applyTo: "inputタグのid" });
Linux(Ubuntu14)版PHP5.5でImage_Graphを使うと透過色やアルファチャネルが使えない件
前回やっとこさ、PHPのSQL Server接続がうまくいったんで、移行する予定のシステムを検証した。
やはり手を加えないと正常に動作しなくって、前の上司が作ったコードが
めちゃくちゃ汚いコードだからか全然動かない。ホント汚い。
scriptタグ内のjavascript部分にphpタグがそのまま出力されてたりするし。
しかも<?phpが勝手に<?で出力される!!ウケるんだけど!!
まあ、どういう対処したか忘れたけど、こういう仕様もない修正を繰り返しながら作業していた。
あるシステムでグラフを表示する機能があって、そのソースはpearでインストールするような
外部モジュール?を使っていた。
それが、Image_Graphというやつ。
今稼働中の/usr/share/phpから使ってそうなやつをrsyncでごっそり新サーバへコピー。
それでグラフ表示するページを動かしたら、gdとかいうエクステンションが必要らしい。
まあよい。手っ取り早くaptでgetする
apt-get install php5-gd
service apache2 restart
gdが入りました。これでどうや!!とページをリフレッシュすると折れ線グラフの各点の
値を表示する部分とか、グラフ内の最大、最小のエリアを表示する部分が透けてないの!!
なにそれー。意味わかんない。前回といい、何で同じコードで同じように動かないの?
JavaでもPOIとかではあったけど、そんなになかったけどなぁ。あーうっとおしい。
普通はこういうコードで透過色になったり、アルファチャネルのついた色を付けたりできるらしい。
$Marker->setBackgroundColor(''); // 透過色 $Marker->setBackgroundColor('green@0.2'); //透けた緑
@移行の数値を0.0とかにしてみたりしたけど何も変わらず。
とりあえずImage_Graphの透過色を扱う部分を、ざらっと見ていった
そしたら、このソースの部分で透過色が使える条件が書いてあった。
/usr/share/php/Image/Canvas/GD/PNG.php
60 if ((isset($param['transparent'])) && ($param['transparent']) && 61 ($this->_gd2) 62 ) { 63 if ($param['transparent'] === true) { 64 $transparent = '#123ABD'; 65 } else { 66 $transparent = $param['transparent']; 67 } 68 $color = $this->_color($transparent); 69 $trans = ImageColorTransparent($this->_canvas, $color);
Canvasを作る時のコンストラクタのパラメータのmapにtransparent=>trueで追加して、
_gd2がtrueでないといけないと。
transparentのパラメータはドキュメントになかったから無視した。高さと幅の指定しかなかった気がする。
_gd2がtrueになる条件はここ
/usr/share/php/Image/Canvas/GD.php
145 function Image_Canvas_GD($param) 146 { 147 include_once 'Image/Canvas/Color.php'; 148 149 parent::Image_Canvas_WithMap($param); 150 151 $this->_gd2 = ($this->_version() == 2);
修正したのはここ
1761 function _version() 1762 { 1763 $result = false; 1764 if (function_exists('gd_info')) { 1765 $info = gd_info(); 1766 $version = $info['GD Version']; 1767 } else { 1768 ob_start(); 1769 phpinfo(8); 1770 $php_info = ob_get_contents(); 1771 ob_end_clean(); 1772 1773 if (ereg("<td[^>]*>GD Version *<\/td><td[^>]*>([^<]*)<\/td>", 1774 $php_info, $result)) 1775 { 1776 $version = $result[1]; 1777 } else { 1778 $version = null; 1779 } 1780 } 1781 1782 // ここ 1783 if ("1" == substr($version, 0, 1)) { 1784 return 1; 1785 // ここ 1786 }elseif ("2" == substr($version, 0, 1)) { 1787 return 2; 1788 } else { 1789 return 0; 1790 }
まえのバージョン判断はこんな感じ。「2.1.1」とかはバージョン1と判断されてしまう。
if (ereg('1\.[0-9]{1,2}', $version)) { return 1; } elseif (ereg('2\.[0-9]{1,2}', $version)) { return 2; } else { return 0; }
gd_info()で取得したgdのバージョンが、うちの環境でインストールされたものと
合ってなかった。うちでのバージョン表記はこんな感じ。
これの修正で透過色はアルファチャネルが使えるようになった。
Linux版PHP5.4以降のODBCエクステンションがsegmentation fault
院内独自開発システム用のサーバがDebianでPHP5.2を使ってる。PostgreSQLも入っている。
俺の前の上司が一人で作った環境。
前にサーバトラブルがあってPostgreSQLのデータファイルが壊れているらしく自動バキュームが
全く働いてない。
どうもpostgresデータベースというかシステムデータベースの、忘れたけどpg_xxxxxxとか
いうテーブルが開けないみたい。
そのせいか、PostgreSQLのディレクトリの容量がデータ量に見合ってないぐらいデカい。
まあ、そのサーバのVMイメージをコピーして、ググっていろいろやったが全くダメ。
なんか壊れている領域を強制的にゼロで埋めるコマンドとかもやったが全く改善しない。
これは、サーバ移行せんといかんかなー。と考えたのが先週の月曜日。
仮想サーバにCentOS7サーバを準備して、apache/php/pgsql/unixODBC/FreeTDSなど
いろいろインストール。画像やphpファイルはrsyncで持ってきた。さあ動作確認。
あるシステムの最初のページは表示された。
が、次のページに行くと「受信したデータが・・・」みたいなエラー。
apacheのerror_logを見るとsegmentation faultでPHPが落ちてるじゃないですか。
調べてみると、たわいもないコードのところで落ちている。
こんなコードでも落ちる。
<?php $con = odbc_connect("xxx.xxx.xxx.xxx", "xxx", "xxx"); if(empty($con)) { echo "error"; die; }else{ echo "connecting success"; } echo "\n"; // STAFFはテーブルでもビューでも落ちる $sql = "SELECT KANJINAME FROM STAFF"; $result = odbc_exec($con, $sql); while(odbc_fetch_row($result)) { echo "test:"; echo odbc_result($result, "KANJINAME"); echo "\n"; }
SQL Serverのデータを取りにいくところで落ちる。稼働中のサーバでは動いているし、
このSQL ServerはJavaのシステムでも使っているのでデータが悪い訳ではないと思う。
ちなみに、PDOでやってみると落ちはしないがodbcで落ちるデータを取ると空文字になる。
いろいろやってみると、SQL ServerでカラムがVARCHAR(24)に全角8文字入れると落ちないが
VARCHAR(23)に全角8文字入れると落ちることに気づいた。けど、ググっても全然情報出てこない。
しょうがないから、PHP5.5、5.6とかubuntu14でも試したけど状況かわらず。
これは、PHPのODBCのレイヤが悪いんじゃなかろうかと。
どうせ暇だし、PHPのソース改造してでもやるかい。あー、けどすごいめんどくせー。
とりあえず、gdbでトレースとった結果がこれ。
#0 __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:116 #1 0x00000000006c8d58 in _estrndup () #2 0x00007f7bbbcd0f4f in zif_odbc_result (ht=<optimized out>, return_value=0x7f7bbeea3630, return_value_ptr=<optimized out>, this_ptr=<optimized out>, return_value_used=<optimized out>) at /root/php_dev/php5.5-201409112230/ext/odbc/php_odbc.c:2186 #3 0x00000000006dd9bb in dtrace_execute_internal () #4 0x000000000079da15 in ?? () #5 0x0000000000717748 in execute_ex () #6 0x00000000006dd8b9 in dtrace_execute_ex () #7 0x00000000006ef340 in zend_execute_scripts () #8 0x000000000068f225 in php_execute_script () #9 0x000000000079f9ee in ?? () #10 0x0000000000461de0 in main ()
あー、なんかメモリ破壊してる。まあ、どこでアロックするサイズ間違えてるか知らんが
多めに取れば問題ないでしょ。と思って、メモリアロックしてる箇所を探すことにした。
ソースは適当にこれを使った
http://snaps.php.net/php5.5-201409112230.tar.gz
メモリ破壊している部分はここ(修正後の行数だから大体の目安で見て)
RETURN_STRINGLマクロで_estrndupが使われていた。そこで落ちる。ちなみに_estrndupで
アロックするサイズは第2引数だった。
2189 if (result->values[field_ind].vallen == SQL_NULL_DATA) { 2190 RETURN_NULL(); 2191 } else { 2192 RETURN_STRINGL(result->values[field_ind].value, result->values[field_ind].vallen, 1); 2193 }
アロックしている部分はここだった
989 case SQL_CHAR: 990 case SQL_VARCHAR: 991 #if defined(ODBCVER) && (ODBCVER >= 0x0300) 992 case SQL_WCHAR: 993 case SQL_WVARCHAR: 994 colfieldid = SQL_DESC_OCTET_LENGTH; 995 #else 996 charextraalloc = 1; 997 #endif 998 default: 999 rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), colfieldid, 1000 NULL, 0, NULL, &displaysize); 1001 /* Workaround for Oracle ODBC Driver bug (#50162) when fetching TIMESTAMP column */ 1002 if (result->values[i].coltype == SQL_TIMESTAMP) { 1003 displaysize += 3; 1004 } 1005 1006 if (charextraalloc) { 1007 /* Since we don't know the exact # of bytes, allocate extra */ 1008 displaysize *= 4; 1009 } 1010 /********* ここから *************/ 1011 #if 1 /* 修正後 */ 1012 result->values[i].value = (char *)emalloc(displaysize + 4); 1013 rc = SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value, 1014 displaysize + 4, &result->values[i].vallen); 1015 #else /* 修正前 */ 1016 result->values[i].value = (char *)emalloc(displaysize + 1); 1017 rc = SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value, 1018 displaysize + 1, &result->values[i].vallen); 1019 #endif 1010 /********* ここまで *************/
1008行目で(カラムサイズ×4)バイト分のメモリを取ろうとしているけど、修正前の1018行目では
1バイト分しか余分に取ってなかったが、修正後は4バイト余分に取るようにした。
この修正後、ビルドしてodbc.soだけ入れ替えたらテーブルのVARCHAR(24)は落ちなくなった。
ちなみに、phpソースからphp_odbc.soを作成する方法は以下のコマンド
./configure --with-unixODBC=shared --enable-so make cp -f modules/odbc.so /usr/lib/php5/20121212/
が、ビューではやっぱり落ちる。まあ、今考えたら当たり前か。この修正では_estrndupに渡される値は
何もかわらないし。
テーブルの時はSQLBindColの第6引数のvallenにカラムサイズが入ってくるけど、ビューの時は-4が
入ってくる。-4はSQL_NO_TOTALを指すが何のこっちゃさっぱりだわ。
ビューだからカラムサイズとれないのかなー?
まあ、RETURN_STRINGLマクロの第2引数に−4(SQL_NO_TOTAL)が指定されているから
落ちるということがわかった。
で、このように修正した。
2189 if (result->values[field_ind].vallen == SQL_NULL_DATA) { 2190 RETURN_NULL(); 2191 /********* ここから *************/ 2192 }else if (result->values[field_ind].vallen == SQL_NO_TOTAL) { 2193 RETURN_STRINGL(result->values[field_ind].value, strlen(result->values[field_ind].value), 1); 2194 /********* ここまで *************/ 2195 } else { 2196 RETURN_STRINGL(result->values[field_ind].value, result->values[field_ind].vallen, 1); 2197 }
めちゃくちゃ姑息!!でもこれ以外の方法が思いつかなかった。
configure/makeしてodbc.so入れ替えたら落ちなくなった。まあいいや。
どうせ同じ職場の人間しか使わないし。
けど、この調査ホントに疲れた!!近くに相談できる人でもいればなー。
けど、この現象ってうちの会社の環境が特殊だからなのか?Windows版PHPでは試してないけど、
Linux版PHPでSQL Server使うことが珍しいの?
PHPerの人は、こういうこと普通にしとるんだろうか・・・。誰か教えてください