R6/R7からR8への移行
最終更新日: 2022年7月21日
R7.8 よりWagbyが内部で保持する複合キーの文字列表現が
この変更により、自動生成されるコードが変わります。これまでソースコード中にハードコードされていた"$"は、PrimaryKeyUtils.PKEY_SEPARATOR() になります。カスタマイズしたソースコード内にこの箇所があった場合、適切に置換してください。
R7.10 より、画面レイアウトにおいてグループの表示方法が未指定の場合の扱いが変わりました。
この変更により、自動生成される JSP ファイルが変わります。
R7.10より、変更履歴機能におけるファイル型項目は、実ファイル名のみが変更履歴ログに記録されるように仕様が変更されました。それまでは upload_dirを起点とする相対パス表記となっていました。
R8 へバージョンアップ後は、変更履歴機能のファイル型項目の表記が(実ファイル名のみが記録されるように)変更されます。
値部分(データ)に句読点や空白を含む文字列の場合は、折り返して表示されます。しかし区切りとなるポイントがないような文字列 (例 12345678901234567890...) は、折り返されません。
このようなデータが含まれているため折り返しが機能していないという場合は、スタイル指定で
background-color ではなく background を使うようにしてください。
R6/R7では Java 6/7 環境を利用できたため、サーバサイドJavaScriptエンジンに Rhino を利用できました。R8 では Java 8 以上となったため、サーバサイドJavaScriptエンジンはNashornのみとなります。Rhinoを前提にしていたスクリプトはNashorn用に修正する必要があります。
importClass 宣言を Java.type に置き換えます。
は次のようになります。
R7.10 より HSQLDB を 2.0.0 から 2.3.4 へバージョンアップしています。その影響で SELECT COUNT() の戻り値が、これまでは Integer でしたが、これが BigInteger へ変更されています。
いずれも java.lang.Number インタフェースの実装クラスですが、JavaScript での厳密等価演算子(===)利用時には注意が必要となります。
厳密等価演算子では同じ 0 という値を持っていても Integer と BigInteger は型が異なるため等価という判定とはなりません。
スクリプト内に記述した数値は Nashorn が自動的に java.lang.Double、java.lang.Long または java.lang.Integer オブジェクトとして解釈する仕様です。
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/scripting/nashorn/api.html#sthref22
このため、スクリプトに次のように記載したコードは影響があります。
ここで「if ( recordCount === 0 ) { 」の "0" は Nashorn 側で Integer と解釈されたため、HSQLDB 2.0.0 では SELECT COUNT(*) の戻り値が同じ Integer となり、厳密等価演算子でうまく動作していましたが、HSQLDB 2.3.4 では Integer と BigInteger との比較となり等価と判定されなくなります。
数字との比較では、厳密等価演算子を使わないことで回避できます。
R7 でメール送信のスクリプトで次のように $${{...}} と記述していた箇所を、${...} に変更してください。
R6 ではコントローラ層のフレームワークとして Struts を利用していましたが、R8 では Spring MVC に変わっています。このため次のような修正が必要です。
struts という表記は controller に変わります。
R6のコード:
R8のコード:
パッケージ名を変更したとき、保存先フォルダもこれにあわせて変更してください。
ActionForward は Struts のクラスであるため利用しません。そのため以下の行は削除します。
ActionMapping の廃止に伴い、従来生成されていた次のコードは利用できません。
代わって次のようになります。
メソッドの戻り値は ActionForward ではなく String となります。詳細は R8 で生成されたコントローラクラスのソースを参考にしてください。
BaseActionクラスは R7.10 で廃止されました。このクラスは Struts に依存していたためです。カスタマイズコードで直接、BaseAction を利用していた場合は、次の手順に従って書き換えてください。
JfcConfigクラスが代替します。次のコードをご利用ください。
JfcConfigクラスが代替します。次のコードをご利用ください。
BaseAction.getJFCErrorManager()は、applicationContextから取得してください。
ActionParameter クラスのインスタンス p が使える場合、次のように記述することができます。
ShowListXXXControllerなど、jp.jasminesoft.jfc.controller.BaseController を継承したクラスであれば、次のように記述できます。
HelperやProcessBeanなどSpringのbeanとして指定されている場合、下記のようにAutowiredでbeanが作成された際にセットすることができます。
jp.jasminesoft.jfc.controller.BaseControllerクラスのMultiPagemapNameフィールドを利用してください。
BaseAction に用意されていた定数は BaseController クラスが管理します。
HibernateUtil#getCurrentSession() を使って、HibernateSession を取得した場合に、HibernateUtil#unbindCurrentSession() の呼び出しが必要でしたが、R8 では HibernateUtil#getCurrentSession() が廃止となったため、unbindCurrentSession() の呼び出しも不要となります。
カスタマイズコードで unbindCurrentSession() を呼び出していた部分は、R8 では何もする必要はありません。
R8 では JFCDataAccessManager#clearCountAll() を呼び出す処理が不要となります。
例えば次のようなコードを記述していた場合、これをそのまま削除してください。
R8.0 よりフレームワーク内の DbActionParameter クラスが廃止され、ActionParameter となりました。R6/R7 で "p" というオブジェクトは DbActionParameter クラスのインスタンスでしたが、これが ActionParameter クラスのインスタンスになります。
カスタマイズクラスで DbActionParameter という表記はすべて ActionParameter に変更してください。例を示します。
R6のコード:
R8のコード:
この変更により、R6/R7 で利用できていた
p.con の実体はデータベースコネクションオブジェクトです。カスタマイズコードで p.con を使っていた場合、これに変わる方法として HibernateUtil.openSession() を使って Hibernate Session を取得し、HQL (Hibernate で利用できるSQL) を使うように変更してください。
HQL プログラミングの詳細は Hibernate のドキュメントをお読みください。Wagby R8 系に同梱されている Hibernate のバージョンは 5.1 です。
R8.0 に同梱される Hibernate は 5.1 となっています。旧版の Hibernate に依存していたコードがあった場合、これを 5.1 で動作するように修正してください。
プロセスビーンはデータベース操作用のクラスとして提供していましたが、R8 からは EntityService を利用するようにしてください。
R6のコード:
R8のコード:
R6のコード:
R8のコード:
R6のコード:
R8のコード:
更新用メソッド (update) の第一引数にはストアモデルを指定します。第二引数は更新対象モデルがロック済みかどうかを指定します。R6では未ロック状態のストアモデルを更新することができましたが、それと同じようにするためには第二引数に
「バッチ処理 > 自作クラスをジョブスケジューラに登録する」を行っている場合、applicationContext に登録する bean 定義ファイルに変更が生じます。Spring Framework のバージョンが 3 から 4 へバージョンアップされたため、org.springframework.scheduling.quartz.JobDetailBean クラスが廃止されました。代わりにorg.springframework.scheduling.quartz.JobDetailFactoryBean クラスを指定するようにしてください。[詳細...]
入力フィルタを管理するクラス JFCFilterManager を Spring の bean としました。この影響で FilterHelper クラスの次のメソッドが廃止されています。filter メソッドは必ず引数の最後に ActionParameter 型のインスタンス変数 p が必要となります。
開発者は customize/java/jp/jasminesoft/wagby/app/MyJFCFilterManager.java を用意することで、FilterManager クラスの getFilter メソッドをオーバーライドすることができます。
ServletContext は次のように取得してください。
Wagbyのコントローラクラスは BaseController を継承しています。この場合は次のコードを利用できます。
ヘルパクラスなどSpringのbeanとなっているクラスの場合、autowireでServletConfigを取得することができます。この ServletConfig から ServletContext を取得してください。
Wagby の内部変数 "p" (実体は ActionParameter クラス) が使える場合、次のコードを利用できます。
R7 と R8 では logon.jsp が異なっています。R7 でログオン画面をカスタマイズして使っていた場合、その logon.jsp を R8 でお使いいただくことはできません。同じようなカスタマイズを R8 に含まれる logon.jsp に対して行ってください。
一覧表示画面に用意する独自ボタンの追加パラメータに、検索条件部の値を渡すことができるようになりました。特別表記
これに伴い、これまで直接コンディション(のプレゼンテーション)モデルを指定してパラメータを渡していた箇所は、cond 表記に置き換えてください。
例えば、追加パラメータとして
R7 で設定していた "CAS" による LDAP/ActiveDirectory の設定は無効になりました。本設定は R8 方式として再度、改めて行なってください。
R7では REST API に v1 と v2 モードが存在していました。R8 では v2 モードのみとなりました。Designer で選択することはできません。
R7.10.3までの形式です。JSONオブジェクトのキー名はキャメルケース形式になります。
例えば項目名 "user_address" は、JSONオブジェクトのキー名が "userAddress" になります。
R7.11以降の形式です。JSONオブジェクトのキー名をキャメルケース形式から、項目名をそのまま出力します。
例えば項目名 "user_address" は、JSONオブジェクトのキー名も同じ "user_address" になります。
REST API を利用する際にHTTPヘッダ X-Wagby-RESTAPIVersion: v1 を指定することができます。この場合、モデルのREST API Version が v2 でも、このアクセスにのみ v1 を使うことができます。v1 を使う必要があるがモデル定義を変更したくない場合は、この方式をご利用ください。(ただし本方式は将来の Wagby で削除されます。あらかじめご了承ください。)
Wagby R8 は Spring Boot を組み込んでいます。この影響で R7 と変わった点は次のとおりです。
Wagby の Spring Boot 対応とは、Spring Boot 形式の War ファイルを作成できるようになったという視点で行なっています。STS でアプリケーションを作成できるという意味ではありませんので、ご注意ください。(Wagby を使うため、STS で Java コードを書くというプログラミングを行うことはありません。)
複合主キー
$
から $SEP$
に変更されました。
R7.8以前
R7.8以後
主キー1$主キー2$主キー3..
主キー1$SEP$主キー2$SEP$主キー3..
グループの表示方法
R7.10以前
R7.10以後
最初のレイアウト名は、グループの表示方法の指定にかかわらず四角で囲む。
最初のレイアウト名も、グループの表示方法の指定が有効となる。
変更履歴機能のファイル型項目の扱い
見た目の変更
長い文字列の折り返しルール
word-break: break-all
を明示してください。[詳細...]
CSSによる背景色の指定
スクリプトの変更
JavaScriptエンジンはNashornに統一
importClass 宣言の修正
importClass(Packages.jp.jasminesoft.util.ExcelFunction);
var ExcelFunction = Java.type("jp.jasminesoft.util.ExcelFunction");
HSQLDBのバージョンアップによる影響
var recordCount = session.createSQLQuery(
"SELECT COUNT(*) FROM \"model1\" WHERE \"pkey\" = " + pkey).uniqueResult();
if ( recordCount === 0 ) {
...
対応方法
if ( recordCount == 0 ) {
メール送信処理のスクリプト
旧表記
replaceMap.put("$${{message}}", "Hello Wagby");
新表記
replaceMap.put("${message}", "Hello Wagby");
カスタマイズコードの変更
Struts から Spring MVC へ (R6からの移行の場合)
パッケージ名
package jp.jasminesoft.wagby.struts.customer;
package jp.jasminesoft.wagby.controller.customer;
ActionForward,ActionMappingの廃止
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
p.mappingの廃止
return (p.mapping.getInputForward());
return (getInputForward(p));
BaseActionの廃止
BaseAction.getCsvEncoding()
p.appctx.getBean(jp.jasminesoft.jfc.service.JfcConfig.class).getCsvEncoding()
BaseAction.getJspEncoding()
p.appctx.getBean(jp.jasminesoft.jfc.service.JfcConfig.class).getJspEncoding()
BaseAction.getJFCErrorManager()
p.appctx.getBean(JFCErrorManager.class)
getJFCErrorManager()
import org.springframework.beans.factory.annotation.Autowired;
...
private JFCErrorManager errorManager;
...
@Autowired
public void setJFCErrorManager(JFCErrorManager errorManager) {
this.errorManager = errorManager;
}
BaseAction.MultiPagemapName
BaseAction.isDeniedNullForwardRequestName
jp.jasminesoft.jfc.controller.BaseController.isDeniedNullForwardRequestName
HibernateUtilクラスのunbindCurrentSessionメソッド
JFCDataAccessManagerクラスのclearCountAllメソッド
/* R8 では不要となったコード */
JFCDataAccessManager dam =
(JFCDataAccessManager)p.appctx.getBean(
"JFCDataAccessManager");
if (dam == null) {
logger.error("failed get JFCDataAccessManager");
} else {
dam.clearCountAll(p);
}
DbActionParameter は ActionParameter へ置き換える
型の変更
@Override
public ActionForward do_original(DbActionParameter p)
throws IOException, ServletException, SecurityException
{
...
}
@Override
public String do_original(ActionParameter p)
throws IOException, ServletException
{
...
}
p.con の廃止
p.con
というオブジェクトが廃止されました。
import jp.jasminesoft.jfc.app.HibernateUtil;
...
{
org.hibernate.Session session = HibernateUtil.openSession();
String hql = ...HQLで記述されたDML...;
Query query = session.createQuery(hql);
}
Hibernate のバージョンアップ
プロセスビーンは EntityService へ
データの取得
Customer[] customer_ary = null;
ProcessBean pbean = (ProcessBean)p.appctx.getBean("ShowListCustomerProcessBean");
pbean.setActionParameter(p);
CustomerC cond = new jp.jasminesoft.wagby.model.customer_c.CustomerC();
((CustomerCHelper)p.appctx.getBean("CustomerCHelper")).initialize(cond, p);
cond.setName(name);// ここでは顧客名を検索条件に設定した。
pbean.setParameter(ProcessBean.ConditionParamName, cond);
pbean.setParameter(ProcessBean.ReturnWrappedObjectParamName, Boolean.FALSE);
ResultBean rbean = new ResultBean();
try {
rbean.setProcessBean(pbean);
rbean.setSizePerPage(-1); // 無制限
rbean.processProcessBean(p, errorManager);
List coll = rbean.getCurrentPageItem(p, errorManager);
if (coll != null && coll.size() > 0) {
customer_ary = (Customer[])coll.toArray(new Customer[0]);
}
} catch (SecurityException se) {
logger.warn("jp.jasminesoft.wagby.app.customer.ShowListCustomerProcessBean failed.", se);
} finally {
rbean.release();
}
import jp.jasminesoft.jfc.service.JFCEntityService;
...
Customer[] customer_ary = null;
CustomerC cond = new jp.jasminesoft.wagby.model.customer_c.CustomerC();
((CustomerCHelper)p.appctx.getBean("CustomerCHelper")).initialize(cond, p);
cond.setName(name);// ここでは顧客名を検索条件に設定した。
JFCEntityService<Customer, String> entityService =
(JFCEntityService<Customer, String>)p.appctx.getBean("CustomerEntityService");
FinderContext<CustomerC> finderContext = new FinderContext<CustomerC>();
finderContext.setCondition(cond);
finderContext.setPageSize(-1);// 無制限
finderContext.setCriteriaConverter((CustomerCriteriaConverter)
p.appctx.getBean("CustomerCriteriaConverter"));
List<Customer> coll = entityService.find(finderContext);
if (coll != null && coll.size() > 0) {
customer_ary = (Customer[])coll.toArray(new Customer[0]);
}
データ1件の取得
Customer customer = null;
ProcessBean _pbean = (ProcessBean)p.appctx.getBean("ShowCustomerProcessBean");
_pbean.setActionParameter(p);
_pbean.setParameter("customerid", JFCUtils.decodePrimaryKey(customerid));//主キー
Object op = null;
try {
op = _pbean.process();
} finally {
_pbean.release();
}
if (op == null) {
return null;
} else if (op instanceof String) { // エラーメッセージの場合
Object[] ep = { (String)op };
p.errors.addJfcerror
(errorManager.getJfcerror("error.dbaccess", ep, p.locale));
} else if (op instanceof Customer) {
customer = (Customer)op;
}
import jp.jasminesoft.jfc.service.JFCEntityService;
...
Customer customer = null;
try {
JFCEntityService<Customer, Integer> entityService =
(JFCEntityService<Customer, Integer>)p.appctx.getBean("CustomerEntityService");
customer = entityService.findById(customerid, true);//主キー
} catch (Exception e) {
String errmsg =
DbBaseController.convertErrorMessage(e,
new String[][] {
{ "customerid", JFCUtils.getRValue("customer.customerid", p.locale) }
});
if (errmsg == null) {
errmsg = "";
}
Object[] ep = { errmsg };
p.errors.addJfcerror
(errorManager.getJfcerror("customer.error.dbaccess", ep, p.locale));
}
更新
ProcessBean pbean = new jp.jasminesoft.wagby.app.customer.UpdateCustomerProcessBean(p);
pbean.setParameter("customer", customer);
try {
pbean.process();
} catch (SecurityException e) {
throw e;
} finally {
pbean.release();
}
import jp.jasminesoft.jfc.service.JFCEntityService;
...
JFCEntityService<Customer, Integer> entityService =
(JFCEntityService<Customer, Integer>)p.appctx.getBean("CustomerEntityService");
// findById メソッドを経由してオブジェクトを取得、そのときにロックをかける。
Customer customer = entityService.findById(customerid, true);//主キー
// customer オブジェクトの内容を変更
// (省略)
// 更新
entityService.update(customer);
//entityService.update(customer, false); 未ロックのオブジェクトを更新する場合。非推奨。
false
を指定します。ただしこの方法は他ユーザによるロック取得を無視するため、推奨できません。R8へ移行時には、更新対象となるストアモデルを取得するときにロックをかけ、ロック済みのストアモデルをupdateメソッドの第一引数に指定するような見直しを行うとよいでしょう。
ジョブ定義の変更
FilterManagerのbean化8.0.3
ServletContextの取得
コントローラクラス
getServletConfig().getServletContext()
SpringのBeanとなっているクラス
import javax.servlet.ServletConfig;
import org.springframework.beans.factory.annotation.Autowired;
...
@Autowired
private ServletConfig servletConfig;
内部変数 p が扱える場合
p.request.getSession().getServletContext()
ログオン画面 (logon.jsp)
画面遷移パラメータ
condの導入
${cond.項目名}
を指定します。
${model1_cp.item1}
という表記があった場合、これを${cond.item1}
としてください。
CASの設定
REST API
バージョン
バージョン 1 (旧方式)
バージョン 2 (標準方式)
バージョン1を使う場合 [非推奨]
仕様変更
SpringBoot導入の影響
ワンポイント
動作環境