2017年10月17日火曜日

ADempiereのJasperで使うImageのパス

■Jasper内で使うイメージのファイルパス
JasperReportで、静的イメージファイルを貼り付けたときに注意することとして
そのイメージのパスの問題がある。

通常、JasperReportをデザインするのは、iReportというツールを使う。
iReportで、静的イメージを貼り付けるには、パレットからImageオブジェクトを選択して
デザイン中のレポートへドラッグすることで貼り付けることができる。

このときに、ダイアログが出て、静的ファイルを選択することとなる。
しかし、この動作によって、設定されるファイルパスは、使用中のiReportがある環境でのファイルパスとなる。
つまり、このJasperReportとImageファイルをサーバなどへ配置した場合、ここで設定されたパスでは、Imageファイルが見つからないことになってしまうことも多く、最終的な実行環境を想定したパスをここで設定しておかなければならない。


■ADempiereでのJasperイメージパスの設定方法
ADempiereでは、AP辞書で登録したJasperファイルやイメージファイルをReportStarterというクラスが処理して、JasperReportのアウトプットを作成する。
このときに、使用されるパスは、以下のようになる。

System.getProperty("java.io.tmpdir") + System.getProperty("file.separator")+"ABCDEFG.png"

つまり、システムプロパティの「java.io.tmpdir」に、Jasper関連のファイルが一時保存されて使用されている。
(C:\Users\ユーザ名\AppData\Local\Temp)

なので、iReportでデザインするときに、ImageオブジェクトのImageExpressionプロパティにも、上記のパスを設定しておけば、ADempiereでうまく表示することができる。


2017年7月26日水曜日

ADempiereのIEブラウザ対応


ADempiereは、FireFoxやChromeには対応しており問題なく動作するが
IEとなると少し問題がある。
グリッド表示やテキストボックスの表示がおかしくなったり、画面が真っ白になってしまうことがある。

ただし、これは、コミュニティ版のADempiereの場合で、SMBアソシエイツ社では、IEでも問題なく正常動作するように修正を加えている。

ADempiereをIEで正常動作させるためには、以下の対応が必要となる。


■Compatible対応のヘッダー出力をしない
 WebUIプロジェクトのindex.zulで、IE8へのCompatible対応タグが記述されているので、これを削除する。
 具体的には、index.zulの7行目あたりの以下の部分を削除する。
  <?meta http-equiv="X-UA-Compatible" content="IE=8" ?>

■拡大、縮小時のエラー対応
 上記の対応をすれば、IEでもほぼほぼ正常動作が可能になるが
 Ctrl+マウスホイールを使った拡大縮小時にエラーが発生してしまう。
 
 これに対応するには、以下のソースの修正が必要である。
 zk.jarの中にある「MouseCommand.java」に以下の修正をおこなう。
 processメソッドの中で、NumberForamtExceptionが発生しないように対処をおこなっている。
 
        // SMBA_CHG IE対応(NumberFormatExceptionの回避)
        MouseEvent event = null;

        if( data == null || data.length == 0 )
        {
            event = new MouseEvent(getId(), comp);            //no area, no coord
        }
        else if( data.length == 1 )
        {
            event = new MouseEvent(getId(), comp, data[0]);    //by area
        }
        else
        {
            BigDecimal bdVal1 = new BigDecimal(data[0]);
            BigDecimal bdVal2 = new BigDecimal(data[1]);

            event = new MouseEvent(getId(), comp,            //by coord
                bdVal1.intValue(), bdVal2.intValue(),
                data.length < 3 ? 0: Commands.parseKeys(data[2]));
        }

//        final MouseEvent event =
//        data == null || data.length == 0 ?
//            new MouseEvent(getId(), comp):            //no area, no coord
//        data.length == 1 ?
//            new MouseEvent(getId(), comp, data[0]):    //by area
//            new MouseEvent(getId(), comp,            //by coord
//                Integer.parseInt(data[0]), Integer.parseInt(data[1]),
//                data.length < 3 ? 0: Commands.parseKeys(data[2]));
        // CHG_END
 

  ちなみに、zk.jarは、通常はjarとして参照していることが多いが、ZK関連のjarもEclipseプロジェクト化しておくと、デバッグができるので便利である。



■メッセージの非表示
 最後に、ログインページで表示されるメッセージを非表示にする。
 IEでログインページにアクセスすると、「一部機能が正常に動作しない可能性がある」という旨のメッセージが表示されてしまう。

 これを表示しないようにしておくには、webuiプロジェクトのWLogin.javaを修正する。
 81行目あたりでメッセージを表示している部分を削除しておく。
 
        /*
        if (!AEnv.isBrowserSupported())
        {
//            String msg = "You might experience slow performance and user interface anomalies using your current browser to access the application. We recommend the use of Firefox, Google Chrome or Apple Safari.";
            String msg = "You might experience slow performance and user interface anomalies using your current browser to access the application. We recommend the use of Firefox, Google Chrome or Apple Safari."
                + "<BR>現在のブラウザはADempiereの一部機能が正常に動作しない可能性があります。ADempiereのすべての機能を使用するにはFirefoxやGoogle ChromeまたはSafariなどのブラウザをお勧めします。";
            browserWarningWindow = new Window();
            Div div = new Div();
            div.setStyle("background-color:#FFFFCC; font-size: " + (AEnv.getFontSize() - 1) + "pt");
            div.appendChild(new Text(msg));
            browserWarningWindow.appendChild(div);
            browserWarningWindow.setPosition("top,right");
            browserWarningWindow.setWidth("550px");
            browserWarningWindow.setPage(page);
            browserWarningWindow.doOverlapped();
        }
        */

これらの対応をしておけば、ADempiereにInternet Explorerでアクセスしても、正常に動作させることが可能である。


2017年7月25日火曜日

ADempiereのトランザクションとコネクション

ADempiereでは、基本的には、プロセスクラスがひとつのトランザクションクラスを保持し、
トランザクションクラスがひとつのコネクションを保持するという関係になっている。
プロセスクラスでひとつだけのトランザクションを使用する場合においては
プロセスクラスがトランザクションとコネクションを管理してくれるようになっている。

例外的には、スレッドなどを使うために、プロセスクラスで複数のトランザクションを使用する場合がある。この場合は、プロセスクラスに依存せず、トランザクションやコネクションの管理を適切におこなう必要がある。

プロセスクラスでひとつのトランザクションを使用する場合においては
プロセスクラスがトランザクションとコネクションを管理してくれるので
(プロセス開始時にトランザクション開始して、プロセス終了時にトランザクションを終了)
複数のトランザクションを使用しない限り、コミット漏れなどを気にする必要はないように見える。

注意が必要なのは、以下に説明するModelクラスを使用する場合とDB.javaのstaticメソッドを使用する場合である。


■Modelクラスとトランザクション
Modelクラスでのトランザクション管理は、少し複雑であるが
大きく分類すると
Modelクラスでトランザクションを作成してクローズするのか、
Modelクラスにトランザクションを外から渡し、トランザクション管理は呼び出し側でおこなうという2通りがある。

<Modelクラスにトランザクションを外から渡す場合>

まず、Modelクラスにトランザクションを外から渡す場合である。
ADempiereでは、通常このパターンでModelクラスを運用することが多いと思われる。
これは、Modelクラスをインスタンス化するときに、以下のようにトランザクション名を渡すことで、
Modelクラスに外からトランザクションを渡せるようになる。
    MPPOrder ppOrder = new MPPOrder(getCtx(), 0, get_TrxName());

通常は、Processクラスのget_TrxName()メソッドを使用して、プロセスクラスが保持しているトランザクションをそのまま渡すことで、ProcessクラスとModelクラスとのトランザクションを統一している。

この場合、Modelクラスのsave()メソッドを呼び出しても、コミットやトランザクションのクローズはされず、これらは呼出元に任されることになる。
つまり、呼出元で必ずコミットやクローズをするようにしないとトランザクションが残ってしまう。
☆呼出元でトランザクション管理をすることが必須となるので注意が必要。(プロセスクラスからの呼び出しであればプロセスクラスがやってくれる。)

また、この場合、エラーがおこったとき、ロールバックはされないが、SavePointを使用して、このModelクラスでおこなった更新処理だけを元に戻すようになっている。

<Modelクラスにトランザクションを外から渡さない場合>

Modelクラスにトランザクションを渡さない場合は、Modelクラス内部で新しいトランザクションが作成される。また、トランザクションは、Modelクラス内でコミットまたはロールバックがおこなわれ、クローズまでされる。Modelクラスないだけで利用されるいわゆるローカルトランザクションとなる。


■DB.javaのStaticメソッドとトランザクション
DB.javaでは、SQLを単発的に実行できるStaticメソッドがたくさん定義されている。
これらのメソッドでも、トランザクション名を外から渡せるようになっており
Modelクラスと同様に、トランザクションを外から渡すか、内部で作成するかを選ぶことができる。

ただ、コミュニティ版のDB.javaでは、コネクションのクローズ漏れがあり
これらのメソッドに、トランザクション名をNullで渡すと、コネクションが残ってしまう。
SMBアソシエイツ社では、これらのDB.javaのStaticメソッドのコネクション漏れを修正している。

また、さらに、SMBアソシエイツ社では、複数トランザクションの実装やコネクションプールを使わない選択ができるようにプロセスクラスを改造している。