weblogic 12cR2にバージョンアップしたらJAX-RSが動かなくなった。

5年前に作ったweblogicで動かしているアプリですが、一部の機能でエラーが出ているとの連絡。よく聞くと、weblogic12cから12cR2にバージョンアップをした後に発生しているとの事。

そりゃ、何かしら影響あるよね。。

どうも、JAX-RSが下記のように2.0に変わったという事で、jerseyも2.Xにしないといけない模様。
https://docs.oracle.com/cd/E92951_01/wls/NOTES/whatsnew.htm

pom.xmlを

    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-bundle</artifactId>
      <version>1.19.1</version>
    </dependency>

から

  <dependency>
    <groupId>org.glassfish.jersey.bundles</groupId>
    <artifactId>jaxrs-ri</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </dependency>

に変更

web.xmlを

 <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 

から

 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

に変更して再ビルド、概ね事無きを得ました。

対象のアプリは2,3年何も手を加えていなかったので、依存ライブラリのバージョンアップをするのは止めました。トラブル対応だし、必要以上の事はしない方はよいかと。
JavaEEって、oracleからEclipse Foundationに移管されてJakarta EE 8になってたんですね。知らなかった。。
でも、まだ全く別の問題が発生していて対応中です。。

VS CodeからGitbucketへリモートプッシュする

対応していたredmine独自プラグインのredmine4移行が終わり、また別に独自プラグインを入れて業務システムとして使っているredmine2.5のredmine4移行を始めましたが、前回はeclipseからVSCodeへ途中で変えたので、Git周りについてはeclipseからそのままでVSCodeからコミットもリモートプッシュも問題無く動いてました。

今回、VSCode(+GitLensエクステンション)側でGitリポジトリを作成し、Git: Add Remoteで社内で立ち上げているGitBucketをリモート先として登録し、プッシュしたところうまくいきません。。
なお前回と今回のGitBucketリポジトリは別ですが、privateでユーザー、パスワードの認証が必要な構成は同じです。

リモートURLにユーザーを入れたりいろいろしましたが、認証が出来ずにエラーになってます。eclipseならユーザー認証のダイアログが表示されるのですが、VSCodeではエラーメッセージのダイアログのみ。。

で、いろいろ試行錯誤してたら突然プッシュが成功、何がうまくいったか解らないままでしたが、もしかしたらChromeで認証してGitBucketを開いたのがきっかけかもしれませんがそんな事ってあるのでしょうか。。
もう一度やり直すのも面倒なので、今回は謎のままで。。

何か試行錯誤するときは何でうまくいったかちゃんと解るように手順を踏んでやらないといけませんね。。

Oracleからpostgresへの移行でCREATE SEQUENCEにハマる

OracleDBからpostgresへ移行しているのですが、シーケンスをOracleSQLDeveloperからDDLを生成して、そのままpostgresにCREATE SEQUENCEしたところ、下記エラーでそんなのないよと怒られます。。

test_db=# select * from tran_id
test_db-# ;
ERROR: relation tran_id does not exist

実行したDDLは下記の内容です。

CREATE SEQUENCE “TRAN_ID” MINVALUE 1 MAXVALUE 99999999 INCREMENT BY 1 START WITH 1 CACHE 20 CYCLE ;

権限周りを見直しても何も変わらず、試しに

 CREATE SEQUENCE TRAN_ID MINVALUE 1 MAXVALUE 99999999 INCREMENT BY 1 START WITH 1 CACHE 20 CYCLE ;

を実行したところ、CREATE出来た?普通にSQLでシーケンスが取れた。あれ?

postgresはダブルクォーテーションを付けると付けないでは別ものになるのですね。。

WindowsのRedmineプラグイン開発をVisualStudio Codeに移行してみた

 前にやろうとしていたRedmineのバージョンアップ対応ですが、バージョンが決まり(Redmine2.5.1&Ruby2.0&Rails3.2 → Redmine4.0.4&Ruby2.5&Rails5.2)、インフラ含めスケジュールされたので、ぼちぼち対応に入ろうとした所、Rubyのバージョンを2.0から2.5に変えた影響か、Windowsローカル環境のAptanaStudio3では、実行は出来てもデバッグしようとすると、


と出て動かなくなりました。

 これまで3年くらい、Redmineプラグインの開発用に使っていたAptanaStudio3ですが、原因調査を早々に諦めて、、VSCodeに開発環境を移行する事にしました。
 使っているWindows端末にはRuby系の環境は既にインストール済みなので、Rubyのみ最新にします。

C:¥temp>ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x64-mingw32]

C:¥temp>rails -v
Rails 5.2.2

 VSCodeを普通にインストールして、既存のAptanaStudio3で対応していたフォルダをワークスペースに追加するだけで、準備が出来ましたが、デバッグ設定が一苦労。。ググるといろいろ情報があり、思いのほか試行錯誤しましたが、こちらが一番参考になりました。デバッグ用のGemをインストールし、設定を試していきます。

 最終的にlaunch.jsonは下記となり、ブレークポイントも止まるようになりました。

"version": "0.2.0",
"configurations": [
    {
        "name": "Rails server",
        "type": "Ruby",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "pathToRDebugIDE": "C:¥¥Ruby25-x64¥¥bin¥¥rdebug-ide.bat",
        "env": { "RAILS_ENV": "development", "GEM_PATH": "${workspaceRoot}/vendor/bundle/bin/ruby/2.5.0"},
        "program": "${workspaceRoot}/bin/rails",
        "args": [
            "server"
        ]
    }
]


 VisualStudio Code ネットの評価に違わずいい感じです。新しいツールを使うのは少し手間が掛かりますが、気分的にもリフレッシュできますね。

Mybatis自動生成SQLからスキーマ名を除外

 既存のWebサービスをマイグレーションしようという事で、Springboot&Mybatis3で実装を開始し、開発端末上のOracleDBに接続してMybatisの自動生成機能を使用してみました。

 かなり便利で、簡単なSQLで済む範囲ならSQLを書く必要が無いようです。が、自動生成されたxmlを見てみると、SQL内のテーブル名にスキーマ名が付加されてしまいます。。
 実際に使用するサーバ上のDBはどんなスキーマ名になるか現段階では解らないし、スキーマ名をカットしてくれる設定が無いか、下記を読み込みます。

http://www.mybatis.org/generator/configreference/table.html

それっぽいのを何個か試して、結果、ignoreQualifiersAtRuntime をつける事でsqlMap.xmlに自動生成されるSQLからスキーマ名が無くなりました。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
    <context id="MyDb" targetRuntime="MyBatis3">
 
        <!-- スキーマ情報を取得する DB への接続設定 -->
        <jdbcConnection
            driverClass="oracle.jdbc.driver.OracleDriver"
            connectionURL="jdbc:oracle:thin:@localhost:1521/dev.local"
            userId="testdb"
            password="password"
        />
        <!-- javaModelGenerator等は割愛 -->
        
        <table schema="testdb" tableName="%"> 
            <property name="ignoreQualifiersAtRuntime" value="true" />
        </table>
    </context>
</generatorConfiguration>

でも、既存システムはかなり複雑なSQLが多数有り、DB設計はそのままとなると、自動生成の恩恵も一部の限られた範囲になってしまいます。

カテゴリー: Java

算定基礎届等の提出のお願いが来た

 先月ですが、「社会保険関係書類提出に関する重要なお知らせです」と書かれた書類が届き、なんだとろう?と中を開けると「算定基礎届等の提出のお願い」という書類が入ってました。
 昨年から厚生年金等に切り替えていたので、この書類が来たのは今回初めてです。

 内容的には、今年4月から6月までの3か月間の給料を記入し7月10日までに提出するというもので、予め去年の額等が記入されており、記載例も添付されているので、特に難しいものではないようです。適用年月が9月と書かれているので、9月から今回記入した給料に沿って保険料が変わるという事なのでしょう。ま、しょうがないですが、保険料自体が今年4月から微妙に金額が増えているし、保険料が変わると給与計算が面倒です。保険料の労使折半というのも簡単そうな計算を複雑にしてくれます。

 提出には、郵送かCD等での電子媒体、または電子申請と3つ方法があるようですが、社員が何人もいる会社でもないので郵送で済ませますが、切手は必要です。

MacBook Proをアップデートしたらログインが撃遅になった

 たまに開発用に使っているMacBook Pro(13-inch,2017,Mojave,TouchBar無し)ですが、先月発生したMacOSのアップデートを適用した途端に、ユーザーのログインが撃遅になりました。。

 事象としては、起動後にユーザーを選択して、パスワードを入力するとずっと待ち状態。測ってませんが、10分以上でしょうか、忘れた頃にやっとデスクトップ画面が開きます。

 その他、Safariの立ち上がりも異常に遅い状態です。Safariのパスワード設定をみる時にパスワードを入力しますが、パスワードを入力すると殆ど応答無し状態になります。逆に言うとそれ以外は問題無いのですが、使いたい時にすぐ使えないので、暫く別の端末を使っていました。
 セーフモード立ち上げや、その他ネットで見つけた対策を色々してみますが、一向に改善しません。

 で、色々やってみてやっと復活出来た方法が、別ユーザーを作る事でした。別ユーザーを作成し、そのユーザーでログイン、一応、AppleIDとの紐付けまでやってからログアウトし、元々使っていたユーザーでログインすると、やった!治りました!

 作ったユーザーは使わないので削除しましたが、その後も問題ありませんでした。AppleIDとの紐付けは不要だったのかな、、
 解決はしましたが、拙速にアップデートしたりせずにちゃんとバックアップを取っていざという時に備えて置かないといけませんね。

Visual StudioでC++再配布可能パッケージ不要のDLLをビルドする

 結構前にちょっと触ったDLLですが、新しい端末に導入したところ動作しないので、何でだろ?と思ったらC++再配布可能パッケージ系が何も入っていない状態でした。
 再配布パッケージを入れるかどうか検討していたところこちらを発見。

 VisualStudioのプロジェクトの設定を見てみると、こんな感じです。

さらにコード生成の箇所を見てみます。

 ランタイムライブラリの箇所では<別オプション>としか表示されていないので、よく解らなかったのですが、消してから確認した所、<親またはプロジェクトの既定値から継承>が選択されていた事が判明。
 その為、全般設定側で指定されているプラットフォームツールセットに依存して再配布パッケージが必要な状態になっていたようです。2年近くもその事に気が付いていませんでした。。
 コード生成のランタイムライブラリを消してビルドした所、DLLのファイルサイズが大きくなりましたが、再配布可能パッケージ無しでも動くようになりました。

springboot AOP でリクエストパラメータをログに出力する

かなり前から稼働しているWebサービスをspringbootで再構築をしているところですが、リクエストとレスポンスをログに出力するという既存仕様の踏襲にAOPを使ってみました。
 対象のWebサービスは、昔ながらのフォームのポストでリクエストを受け付ける仕様なので、application/x-www-form-urlencodedに対応する形になります。
AOPについては、こちらを参考にさせて頂きました。
リクエストとレスポンスなので、@Aroundでメソッドの前後にログ出力をします。

Controllerのメソッド引数にHttpServletRequestとHttpServletResponseを入れる事で、Advicer側でパラメータが取得出来ました。

@Controller
public class XXXContoller {
	
    @RequestMapping(path={ "/online/XXX.do"}, method = RequestMethod.POST)
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
		//サービス層で処理
    }
}

Adviser側です。

@Aspect
@Component
public class ControllerAdviser {
    private static final Logger logger= LogManager.getLogger();

    /**
     * Controllerメソッドの前後処理
     * */
    @Around("execution(* jp.esoro.application.controller..*.*(..)) && args(request,response,..)")
    public void Around(ProceedingJoinPoint joinPoint, HttpServletRequest request, HttpServletResponse response){
        try {
            String logMessage = request.getRemoteAddr() + ":" +request.getRequestURI() + ":";
            Map<String, String[]> map = request.getParameterMap();
            if(map != null) {
                boolean firstFlg = true;
                for (Iterator<Map.Entry<String, String[]>> it = map.entrySet().iterator(); it.hasNext();) {
                    Map.Entry<String, String[]> entry = it.next();
                    String[] value = entry.getValue();
                    if(value.length > 0){
                        if (firstFlg) {
                            logMessage = logMessage + entry.getKey() + "=" +value[0];
                            firstFlg = false;
                        }
                        else{
                            logMessage = logMessage +"&" + entry.getKey() + "=" +value[0];
                        }
                    }
                }
            }
            logger.info(logMessage);

            //実処理の実行
            joinPoint.proceed();

            //レスポンスログ(未実装)

        } catch (Throwable e) {
            logger.warn(e.getMessage());
        }
    }
}

下記のようにログに出力されました。
2019-05-21 11-38-39.002:0:0:0:0:0:0:0:1:/online/XXXX.do:Id=9999999&Password=ggggg&Action=regist

 でも、今回の要件にはこれ以外にログ出力要件があり、Controllerの引数ではちょっと無理っぽい。。
 他にも、同じクラスから呼ばれたメソッドには適用されないようなので、ビジネスロジック側の影響は避けられないようでした。
 また、戻りがあるメソッドに適用するにはjoinPoint.proceed()の戻りを返す必要があったりと、色々ハマりどころがあるようです。

Selenideでブラウザ操作専用のRPAっぽいのを作ってみた

 とあるWebサイトのデータが欲しいとか、主にブラウザ使って仕事してますとかで、ブラウザの操作を自動化したいという要求は結構あると思います。RPAと謳った製品はあるのでしょうが、そんな大袈裟にやる訳でも無いレベルなものが欲しいなと。昔であれば、エクセルVBAでIEを自動操作とかしてましたが、今回はSeleniumの利用を検討してみました。

 Seleniumといえば、開発者がWebサイトのテストとして使うケースが多く、業務利用的な話はあまり聞きませんが、ブラウザの自動操作なら同じ話、Seleniumを調べていくとjava実装ではSelenideが使いやすいようでした。
 対象となる操作の自動化要求だけ対応するのもつまらないので、いろんな操作を自動で出来るRPAクラス1っぽいものを目指します。

いろんなタイプのブラウザ操作に対応する為に、まず操作テーブルを定義します。今回は、操作対象となるものをWEB、ファイル、プログラムと3種に分類し各操作を定義、実装していきます。
WEBならURLオープンや要素から値を取得したり、要素に値をセットしたり、ファイルならファイルから読込とか出力といった操作です。プログラムは加算や変数に入れる、次に行う処理に飛ぶ判断等です。

で、次は操作対象とするWebページの要素を調べて操作テーブルを作成するのですが、CSSセレクタで指定するのが安定してました。Chormeのデベロッパーツールから要素を右クリックCopyでCopy selecterして、「>」を取ったり最後だけ切り取ったりで指定してます。idやnameがあればそちらの方が良いかも知れません。

実際にWebページからテキストを取得するのは下記のようなソースです。
Selenide.$(By.cssSelector(“span.tlid-translation.translation span”)).getText();

で、大体操作テーブルが出来たので動かしてみます。下記はテストとしてGoogle翻訳ページの操作テーブルです。

結構動かないので操作内容等を微調整していきます。。PAUSE入れたり。。

Selenideというか、Seleniumのはまりどころでしょうか、
・clickは問題無い(画面が遷移するまで待ってくれる)が、JavaScript実行で画面遷移する時は考慮が必要→直前の画面のどこかの要素を取得して、それが変更されていないなら待つみたいな小技が必要
・現時点、Windows環境上ではChromeで動かない→Windows+ChromeだとChrome本体とChromedriverのバージョンが合わない(Macでは動く)、Firefoxは動いた
・Windows+FireFoxドライバで動かしっぱなしにするとかなりのメモリを消費する→対象のページによるのかも知れませんが、数時間動かすような処理だと定期的に落し上げ(close&open)した方がよさそう

使ってみたいという方がいらっしゃいましたら、コメントからお問い合わせ下さい。
なお、このサイトではコメントの公開はしておりません。