Windows環境からLinux環境にしたらJavaプロセスが動かない

 Windows上で動作させていた既存システムの開発環境を、今回Dockerで動かす形に変えていました。
既存システムの構成上、javaプロセスを2つ立ち上げる必要があり、これまでwindows上でバッチファイルで実行していたのを適当にシェルに置き換えて実行してみましたが、下記のようなメッセージが出てプロセスが動作しません。


See http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details.
/var/lib/apl/tools/lib/app-XXX-server.jar: line 1: $'PK¥003¥004': command not found
/var/lib/apl/tools/lib/app-XXX-server.jar: line 2: $'¥373^¥226P': command not found
/var/lib/apl/tools/lib/app-XXX--server.jar: line 3: ??e?y: command not found
/var/lib/apl/tools/lib/app-XXX--server.jar: line 4: syntax error near unexpected token )'
/var/lib/apl/tools/lib/app-XXX--server.jar: line 4:
?z?z?M)?^)? {,? ?MLy?x?P]?p?PK'

 なんじゃこりゃ?

JAVA実行コマンドとしては、
java -cp resource;lib/* jp.co.esoro.app-XXX.main
のような感じです。

 暫く試行錯誤していましたが、結果的にクラスパスを複数指定するところのセパレータ「;」はWindowsだけで、Linux環境では「:」じゃないとだめというオチでした。。

カテゴリー: Java

Springboot Securityのログイン画面がいい感じになっていた

 Springbootで作ったアプリを、そろそろユーザーに渡そうかというタイミングになりましたが、Springbootのバージョンが結構更新されているので、今更ながら最新に入れ替えてみました。
 それまでフレームワークは、spring-boot-starter-parentの2.0.1.RELEASEを指定していましたが、今見ると2.1系の次に2.2系が既に出ています。
 コードに影響があれば、そこまで最新にしなくてもいいかととりあえず2.2.4を試したところ、特に問題が無かったのでチェンジ。
 今回のアプリはsecurityのデフォルトログイン画面を使っていたのですが、更新したところ画面が変わりました。どうやら2.1から既に変わっていたようです。

2.0系はこれ

2.1系overはこれ

2.0系の見ためがしょぼいのでカスタマイズしようか考えましたが、中央寄せのいい感じのUIに変わってました。これならそのままでも違和感無いですね。

アプリの動作確認は終了、最後に、バージョンアップでこんな警告が出るようになったみたいなので、
2020-02-27 14:09:12 WARN JpaBaseConfiguration$JpaWebConfiguration spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

出ないようにapplication.ymlに追加

受け渡し準備OKです。
でもjarのファイルサイズはどんどん肥大化してます。。

カテゴリー: Java

Mavenインストールが失敗するようになった

SpiringBootで作成中のツールにちょっと機能が漏れていたので、pom.xmlにライブラリを追加したところ、ダウンロード出来ませんとの事。

mavenリポジトリから501が応答されているのですが、何か変わったのでしょうか?
試しに、ブラウザ越しに上記のDownload URLをたたくと下記の応答

501 HTTPS Required.
Use https://repo.maven.apache.org/maven2/
More information at https://links.sonatype.com/central/501-https-required

httpsにしなくちゃいけないって事?

ちょっと調べると下記を発見。

今時当たり前なのですが、Mavenリポジトリがhttpsのみに変わったようです。

Mavenツールが古いからかな?とまずeclipse(marsを今でも使用中)から更新の確認を実行してもダメ。
インストールの詳細からm2e Eclipse用Maven統合 を更新してもダメでした。

上記リンクに、pom.xmlで設定するのは例が書かれていますので、有難くこれで一旦解決には出来ますが、プロジェクト個別設定でなくて全体的にどうにかならないの?と、.m2に置いてあるsetting.xmlの設定で対応してみます。

結果、リポジトリ設定ではうまくいかず、ミラーの設定をしてみると、ちゃんとライブラリをダウンロードしてくれるようになりましたが、
初回はミラーから全てのライブラリをダウンロードしようとするようなので、とりあえずはpom.xmlで個別に対応した方がいいかもしれません。

後日、別環境で使っているeclipseで確認したところ、比較的新しいeclipseでは特に問題が無かったようです。どうやら、古いバージョンのeclipseだけ対応出来ないようです。

カテゴリー: Java

w2uiでテーブルメンテナンス画面を作ってみる

SpringBootで作っているアプリに、テーブルメンテナンス画面が必要になったので、w2uiで作ってみる事にしました。


テーブルメンテナンス画面といえば、一覧表示があって、選択したら登録フォームが表示されて、とか基本的な構成はどのテーブルも似たようなものですよね。w2uiのグリッドとフォームを使い、使いまわし出来るようjavascriptに機能を纏め、html側にテーブル固有の個別設定を寄せる事で、いろんなテーブルに対応出来るような形にしていきます。
w2uiのformは、urlを指定するとthis.save()でフォームをPOSTしてくれるようなのですが、ちょっと扱いにくいのでsaveを使わずにjsonでPOSTするようにしました。

eclipse上のリソース構成はこんな感じです。

javascriptです。ちょっと変更後のUIの動きがアバウトではありますが。。

htmlにはjsで定義済の要素とか変数を載せます。メンテ対象のテーブルが増えた場合を考慮しツールバーも入れてます。なお、項目の設定はw2uiのドキュメントを見ながら調整していきますが、結構融通が利きますね。

最後にというか、本来なら最初にですがSpringBoot側は、w2uiの項目名と一致するエンティティクラス(ここではCustomer)と、CrudRepositoryを継承したインターフェースCustomerRepositoryを用意し、RESTコントローラーからアクセスさせるようにします。

で、出来た画面です。

なお、今回セキュリティ要件は考慮していません。。

カテゴリー: Java

msg形式のメールファイルをemlファイルに変換する

 数年前にjavamailで作ったメールを受信した後の業務を自動化するツールを、今でもいろいろ機能追加をしているのですが、機能を追加・変更する時に、利用者から対象のメールをemlで提供してもらってテストしています。
 でも、outlookユーザーはmsgでしか提供出来ませんというので、emlへ変換したいのですが、ネットに転がってるツールを使ってもイマイチ変換できません。。
 なら作ろうと調べた所、javaならjotlmsgというのがあったのですが、日本語が文字化けします。
 結局、apache poiでoutlookのmsgを扱えるようなので、msgファイルを読み込んでemlファイルへ出力するという形にしました。

 実行時の引数を、msgファイルを入れたパス、emlファイルを吐き出すパスで指定します。

 何件かのmsgファイルを試した所、htmlで取れるケースが無かった。。メソッド的にはあるはずなのに。。
 その為、完全にemlファイルで再現出来るというレベルにはなりませんでしたが、本文テキストと添付ファイルはemlファイルに出力できているので、まあここまででよいかと。

カテゴリー: Java

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

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

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

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

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

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

カテゴリー: Java

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

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

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

Adviser側です。

下記のようにログに出力されました。
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()の戻りを返す必要があったりと、色々ハマりどころがあるようです。

カテゴリー: Java

AWS CodePipelineでspringbootアプリをECSへデプロイしてみた

オンプレサーバで稼働しているシステムをAWSへ移行したいという話があり、AWS環境でCI/CDがどう出来るか確認してみました。
構成としては、開発用端末のIDE(IntelliJ IDEA)でコミット、CodeCommitのリポジトリにプッシュしたら、Mavenビルドを開始してECRへコンテナをプッシュ、ECSへデプロイという流れです。

下記AWS環境を用意します。
・ECSの設定(クラスタ、サービス、タスク定義)
・ECRにリポジトリを作成、springbootのアプリなのでopenjdkのイメージをプッシュ
・CodeCommitにリポジトリ作成
・CodePipelineを設定

ググれば、いろいろAWSに関する情報はあるのですが、なかなかうまく出来ません。
で、いろいろやってみた結果、ビルド用にbuildspec.yml、デプロイ用にDockerfileをリポジトリの直下に置くとデプロイが成功しました。

すいません、情報の参照元が解らなくなってしまいました。。
mvn install 結構時間掛かりますね。。

AWSは数年前にアカウントを登録してちょこっとだけ遊んでみただけだったので、ちゃんとAWS環境を理解した上で整理してからじゃないと実利用には遠い感じです。。

カテゴリー: Java

Swagger + SpringBoot で APIサイトを作ってみる

既存システムのDBへアクセスしてデータを参照するようなAPIを、って事で、
SwaggerでAPIを定義し、Swaggerから自動生成したソースを使って実装してみました。
なお、今回対象としているのは参照系がメインでRESTって雰囲気ではありません。
対象が既存システムのDBなので。。

とりあえず、ざっくりとした要求と応答の仕様を整理し、Swagger Editorにyamlを書いてみます。

なお、Swagger Editorは、別件で使っていた端末内のxampp/htdocsにGitHubからダウンロードしたZIPを解凍して使ってます。
ある程度、定義を書いた後、Swagger EditorからGenerate ServerでSpringのサーバソースを出力してみます。

自動生成されたJavaソースはこんな構成です。

Controllerとレスポンスエンティティのモデルが揃ってます。全体的なソース構成は、コントローラ層、サービス層、データアクセス層という3構成になりますかね。
コントローラ層は概ねSwaggerで生成したので、データアクセス層も自動生成しようと、Doma2を使ってみます。
doma-gen-build.xmlに接続先DB情報と出力先ソースの設定等を記述し、こちらもGenerate!

結果、ソースを手書きする必要があるのは、

・サービス層全体

・Swaggerで自動生成されたSpringBootApplicationクラスのComponentScanにサービス層のパッケージを追記
  @ComponentScan(basePackages = { “io.swagger”, “io.swagger.api”,”jp.esoro.api” })

・Swaggerで自動生成されたControllerにServiceをコールする箇所を追記

・DAOインターフェースに下記アノテーションを追記
@ConfigAutowireable
@Repository

・自動生成不可能なSQL文の作成し、それに合わせてDAOにメソッド追加

といったところで、とりあえずの動作確認が出来ました。

ただ、実用するには認証やページング等も必要なので、こんな単純な話にはなりませんし、APIの仕様をちゃんと整理してからSwaggerでソースを生成して着手しないと後が面倒ですね。

カテゴリー: Java

NTLM認証のサイトからファイルをダウンロードする

SpringBootで作成中のアプリに、企業内のWebサイトよりエクセルファイルをダウンロードする要件があったので、何となくBasic認証のサイトだろうなと思い込んで実装を始めましたが全然繋がりません。

wget ‘http://username:password@filestore.bbb.co.jp/web/download/downloadfile.xlsx’
でファイルは取れます。

でも、
curl ‘http://username:password@filestore.bbb.co.jp/web/download/downloadfile.xlsx’
では動きません。

試しにwgetをデバッグモードでやってみて気が付きました。。

WWW-Authenticate: NTLM

このサイト、NTLM認証ですね。。

下記を参考に認証箇所を変更
http://code-addict.pl/reporting-services-rest-url-client/

また依存が増えてしまいましたが。。

ダウンロードファイルが更新されていた時だけダウンロードするという対応も必要なので、サーバ内にダウンロードしたローカルファイルとサイト上のファイルタイムスタンプをチェックし、一致しなければファイルをダウンロードしタイムスタンプをサイト上と同じ時間に書き換えるという対応になりました。

で、タイムスタンプはどこ?ここに書いてました。

確かにhttpヘッダに
Last-Modified:Tue, 14 Aug 2018 08:53:30 GMT
と書いてあります。

結局、こんな感じのコンポーネントを用意しました。

テストしてみます。

とりえあず、動いたので整理してから実装します。

カテゴリー: Java