WildFlyでgetResourceするとパスが異なる事例と対処方法
GlassFishで動作していたSpringBootアプリを、サーバー移管に伴いWildFlyに切り替えました。
動作確認をしていくと、リソースの取得で404が返ってきて困っていました。
いろいろと調査すると、パスの取得方法がアプリケーション・サーバーによって異なることがあるらしく、その場合の対処方法をまとめました。
WilfFly上での問題の挙動
GlassFishでは、アプリをWAR形式でデプロイし動作させていました。
WildFlyでも同じようにして動作させていたのですが、Excelを出力する処理で、404が発生し原因を調査することにしました。
GlassFishでは、次のコードで正常に動作していました。
new File(this.getClass().getResource(srcFullPath).getPath());
このコードのままWildFlyで処理を行うと変なパスが返ってきます。
(ローカルでWARデプロイしたとき)
# getResourceで引数に「"."」を指定した場合 /Users/user_name/dev/eclipse/server/wildfly-15/modules/system/layers/base/org/jboss/as/ejb3/main/timers/ # getResourceで引数に「"report"」のパスを指定した場合 /content/Hoge.war/WEB-INF/classes/com/test/report/
いろいろと調べてみる
解決しないとマズイ問題なのでめちゃくちゃ調べました。
How to put an external file in the classpath |JBoss Developer
java - WildFly - getting resource from WAR - Stack Overflow
How to load a file in war file |JBoss Developer
How to load external property file in JBoss 7 classpath? - JBoss 7 Configurations
基本、英語のサイトしかヒットしないのでGoogle翻訳を駆使したり、コードから読み取ったりしてました。
サイトには、「それは解決できないよ」と絶望的な回答があったり、「この方法はどう?」と試すものの的外れだったりで、困り果ててました。
そんな中、「解決方法はこれ!」というのがあり、試すと問題なく動作するものがありました!!
解決方法
java - How to load resource files in jboss war - wildfly9.xV - Stack Overflow
getResource()
でFileを取得するのではなく、getResourceAsStream()
でStreamを取得して使えとのこと。
this.getClass().getResourceAsStream(path);
これですんなりExcelを出力できるようになりました。
Postfixで独自ドメイン用の送信メールサーバーを構築する
Webサービス等の開発でメールを送信することがあると思います。
リリースにあたり独自ドメインも取得してメールを送信すると思いますが、メールサーバーを構築したり、メールボックスを契約するのは手間や費用がかかり大変です。
それらのことをやらなくても、メールを受信したら転送するだけの仕組みがPostfixで可能だったので、それらについてまとめました。
メール送信するにあたり、キャリアメール(docomo、au、softbank等)の送信制限対策の設定も記載しましたので、ご活用下さい。
前提条件
独自ドメインを取得していること
今回構築するPostfixの仕様
・独自ドメイン宛のメールは、Postfixで受信し、それを指定のメールアドレスにそのまま転送する
・プログラムからのメール送信は、Postfixを経由してダイレクトに送信される
・プログラムからのキャリアへのメール送信は、Postfixで送信間隔を考慮して送信される
・プログラムからのメールは、暗号化して送信される(TLS設定をした場合)
独自ドメインにSPFレコードを設定する
SPFレコードとは?
独自ドメインのよるメール送信が、迷惑メール扱いとならないようにドメインの設定でSPFレコードを追加します。
SPFの詳細については以下のリンクを参考にして下さい。
salt.iajapan.org
ドメイン設定でSPFレコードを登録する
SPFレコードは、ドメインを取得したサイトにいって「DNSレコード設定」等のメニューで行います。
設定する値は、以下の表のようになります。
(独自ドメイン「hoge.com」メール送信するサーバーIP「192.168.0.1」の場合)
ホスト名 | TYPE | TTL | VALUE | 補足 |
mail.hoge.com | A | 3600 | 192.168.0.1 | すでにあれば不要 |
hoge.com | TXT | 3600 | v=spf1 a:mail.hoge.com ~all | 上記のホスト名を指定 |
TTLは任意の値で大丈夫です。
SPFレコードが有効か確認する
設定が終わったら、しばらく時間をおいて次のサイトでSPFレコードが有効になったか確認します。グリーンの表示ならOKです。
Sender Policy Framework (SPF) Record Lookup - SPF Check - MxToolBox
送信メールサーバーの設定
/etc/postfix/main.cf
# メール受信許可範囲(変更) inet_interfaces = all # 接続時に使うプロトコル(変更) net_protocols = ipv4 ## 配送設定 # 遅延メッセージの配送を試行する最小時間間隔 minimal_backoff_time=1m # 遅延メッセージの配送を試行する最大時間間隔 maximal_backoff_time=10m # 配送できないものとして送り返すまでに、メッセージがキューに入っている最大時間 maximal_queue_lifetime=1h # 配送できないと見なすまでに、バウンスメッセージがキューに入っている最大時間 bounce_queue_lifetime=1h # 遅延されたキューがキューマネージャによってスキャンされる時間間隔 queue_run_delay=30s # 配送経路ファイルパス transport_maps = hash:/etc/postfix/transport ## バーチャルドメイン # バーチャルドメイン virtual_alias_domains = hoge.com # バーチャルドメイン設定ファイルパス virtual_alias_maps = hash:/etc/postfix/virtual ## STARTTLSの設定(メールが暗号化される) # SMTP TLSセキュリティレベル smtp_tls_security_level = may # CAファイルのパス(Let's Encryptを使った場合) smtp_tls_CAfile = /etc/letsencrypt/live/hoge.com/cert.pem # TLS情報をログに出力 smtp_tls_loglevel = 1
/etc/postfix/virtual
hoge.com anything # 必須 # 独自ドメイン宛メールを別アドレスに転送する info@hoge.com hoge@gmail.com noreplay@hoge.com hoge@gmail.com
ハッシュ化する
postmap /etc/postfix/virtual
キャリアメールの送信制限対策の設定
キャリアメールの送信制限
キャリアメールの送信制限について調べたところ、表のような感じになりました。
内容が古いかもしれないので、間違っている場合はご指摘頂ければうれしいです。
1セッション同時送信 | 1日最大送信 | |
docomo | 100件 | 1,000通 |
au | 30件 | 1,000通 |
softbank | 20件 | 500通 |
Y!mobile | ???件 | 1,000通 |
キャリアにメールを送信する場合、独自ドメインにSPFレコードを設定することが必須となります。
キャリア毎の制限に引っかかった場合、迷惑メール扱いとなり、メールが届かなくなるので注意して下さい。
各キャリア規制についての参考情報
Postfixの設定
/etc/postfix/master.cf
docomo-smtp unix - - n - 1 smtp -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1 au-smtp unix - - n - 1 smtp -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1 softbank-smtp unix - - n - 1 smtp -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1 ymobile-smtp unix - - n - 1 smtp -o smtp_destination_concurrency_limit=1 -o smtp_destination_recipient_limit=1
/etc/postfix/transport
docomo.ne.jp docomo-stmp: ezweb.ne.jp au-smtp: softbank.ne.jp softbank-smtp: .softbank.ne.jp softbank-smtp: .vodafone.ne.jp softbank-smtp: ymobile.ne.jp ymobile-smtp: willcom.com ymobile-smtp:
ハッシュ化する
postmap /etc/postfix/transport
ポートを開ける
SMTPポート(25)を開けます。
sudo firewall-cmd --add-service=smtp --zone=public --permanent
上記設定がおわったらPostfixを再起動します。
sudo systemctl restart postfix
まとめ
今回、Webサービスをリリースするときに、独自ドメインをお名前.comで取得したところ、メールボックスは別で契約しないといけないことが分かり、メール送信をどうするか悩んでいました。
メールボックスを用意するのは、管理が面倒くさいので何か方法はないかと思って調べていると、Postfixだけでメール処理ができることが分かりました。
構築は簡単にできたのですが、できればこれらもしない方が手間も省けるので、独自ドメインを取得するなら、メールサーバー付きのサービスで取得する方が良いと思いました。
お名前.com以外にスタードメインでドメインを管理しているので、スタードメインだとメールサーバー付いてるので、そちらでメール転送設定をすれば、任意のアドレスでメールを受け取れるので手間いらずです。
PostgreSQLでDB間でデータをコピーする
PostgreSQLでDB間またはスキーマー間でpd_dumpを使ってコピーを試みたものの、うまくいきませんでした。
調べているとやり方はあるらしいですが、結局手間がかかり\copyの方が早いらしいのでこれで試してみました。
環境
PostgreSQL 9.4
CentOS 6
Mac 11
コピーの流れ
「コピー元DB:A、コピー先DB:B」とします。
1.AでCSVエクスポート
2.Bでデータ削除
3.BでCSVインポート
4.Bでシーケンス初期化
各項番の説明をしていきます。
1.AでCSVエクスポート
ターミナルで次を実行します。
# 通常接続 psql -h Aのホスト -U Aのユーザー名 -d AのDB名 -c "\copy テーブル名 to '/出力先フルパス/テーブル名.csv' (format csv, delimiter ',', header true);" # SSL接続 psql "sslmode=require host=Aのホスト user=Aのユーザー名 dbname=AのDB名" -c "\copy テーブル名 to '/出力先フルパス/テーブル名.csv' (format csv, delimiter ',', header true);"
2.Bでデータ削除
ターミナルでpsqlコマンドでDBに接続し、次のSQLを流してデータを削除します。
(psql -c "コマンド"で接続しなくてもできます)
TRUNCATE TABLE テーブル名;
3.BでCSVインポート
エクスポートの「to」を「from」に変えるだけです。
ターミナルで次を実行します。
# 通常接続 psql -h Bのホスト -U Bのユーザー名 -d BのDB名 -c "\copy テーブル名 from '/出力先フルパス/テーブル名.csv' (format csv, delimiter ',', header true);" # SSL接続 psql "sslmode=require host=Bのホスト user=Bのユーザー名 dbname=BのDB名" -c "\copy テーブル名 from '/出力先フルパス/テーブル名.csv' (format csv, delimiter ',', header true);"
超絶おすすめするPostgreSQL書籍!!
[改訂新版]内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)
- 作者: 勝俣智成,佐伯昌樹,原田登志
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: 鈴木啓修
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/16
- メディア: 単行本(ソフトカバー)
- 購入: 2人 クリック: 14回
- この商品を含むブログ (5件) を見る
Gradle 4.x で「Could not resolve all artifacts for configuration」のエラーが出たときの対処方法
個人的にGradleはよく分かってないので突っ込まれると回答できません。ご了承下さい。
※ 一概に「Could not resolve all artifacts for configuration」のエラーが出たら、ここの対処をすれば良いと言うわけではない点にご注意下さい。
環境
Mac
Spring Boot 1.3.6
Gradle 4.9 (Homebrew)
エラー内容
gradle eclipse
等を実行すると以下のエラーが発生する。
* What went wrong: A problem occurred configuring root project 'Test'. > Could not resolve all artifacts for configuration ':classpath'. > Could not find org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}. Required by: project :
build.gradle(一部抜粋)
buildscript { ext { springBootVersion = '1.3.6.RELEASE' } repositories { mavenCentral() } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}' // Gradle4対応 classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' } }
対処方法
build.gradle(一部抜粋)
buildscript { ext { springBootVersion = '1.3.6.RELEASE' } repositories { mavenCentral() } dependencies { // 変数ではなく固定値にする classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE' // Gradle4対応 classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' } }
Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築
- 作者: 綿引琢磨,須江信洋,林政利,今井勝信
- 出版社/メーカー: 翔泳社
- 発売日: 2014/11/05
- メディア: 大型本
- この商品を含むブログ (6件) を見る
Spring Boot 1.3.x で Gradle 4.x に更新してビルドするとエラーが出る場合の対処法
Gradleのバーションを久々に更新したら、一部のプロジェクトでエラーが出てました。
その時の対処を紹介します。
エラー内容
gradle eclipse
を実行するとbuild.gradleの15行目でエラーが発生と表示されます。
$ gradle eclipse FAILURE: Build failed with an exception. * Where: Build file '/Users/Applications/eclipse/workspace/Test/build.gradle' line: 15 * What went wrong: A problem occurred evaluating root project 'Test'. > Failed to apply plugin [class 'io.spring.gradle.dependencymanagement.DependencyManagementPlugin'] > Could not create task of type 'DependencyManagementReportTask'. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 0s
build.gradle
問題の15行目は、apply 'spring-boot'
の宣言です。
buildscript { ext { springBootVersion = '1.3.6.RELEASE' } repositories { mavenCentral() } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}' // Gradle4対応 classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' } } apply plugin: 'java' apply plugin: 'eclipse-wtp' apply plugin: 'spring-boot' // line: 15 以下略
対処法
buildscript { ext { springBootVersion = '1.3.6.RELEASE' } repositories { mavenCentral() } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}' // 追加 classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' } } apply plugin: 'java' apply plugin: 'eclipse-wtp' apply plugin: 'spring-boot' // 追加 apply plugin: 'io.spring.dependency-management'
WildFlyにJerseyアプリをデプロイするとエラーが発生するときの対処方法
WildFlyにSpring Bootで作成したJerseyを含むWebアプリをデプロイしようとすると、エラーが発生しデプロイができない現象に遭遇しました。
その時の対処方法をまとめました。
対処方法
Webアプリ側にjboss-deployment-structure.xmlを用意し以下のように定義する。
jboss-deployment-structure.xml
<?xml version="1.0"?> <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <deployment> <exclude-subsystems> <subsystem name="jaxrs" /> <!-- 追記する --> </exclude-subsystems> </deployment> </jboss-deployment-structure>
jboss-deployment-structure.xmlをwarに含める場合、WEB-INF配下に置くようにします。
Gradleで以下のように定義しwarビルドすると、自動的にWEB-INF配下にコピーされます。
war { from('src') { include 'jboss-deployment-structure.xml' into 'WEB-INF' } }
注意事項
すでにデプロイできない事象に遭遇している場合、上記対応を行ってもデプロイ時にエラーが発生します。
エラーなのにデプロイ時のゴミは残ったままなので、それらを削除する必要があります。
standalone.xmlを修正する
ファイルの場所:wildfly-root/standalone/configuration/standalone.xml
タグがある所を探し(ファイルの最後あたり)、デプロイに失敗したアプリ名の箇所を削除します。
<deployments> <deployment name="postgresql-9.4.1212.jar" runtime-name="postgresql-9.4.1212.jar"> <content sha1="38931d70811d9bfcecf9c06f7222973c038a12de"/> </deployment> <!-- 対象のアプリ名部分を削除する --> <deployment name="Test.war" runtime-name="Test.war"> <content sha1="fcb6ff1bf0777ce6b276f5067903db03c1addc3d"/> </deployment> <!-- ここまで --> </deployments>
MacでAndroid Studioを初回起動、新規プロジェクトを作成するまで
初めてAndroid Studioをインストールしてみました。
同じような方向けにどんな画面なのか、画像メインで記事を作成してみました。
アプリ自体開発したことないので、突っ込まれても回答できないのでご了承下さい。
セットアップ・ウィザード
1.ようこそ
2.インストールタイプの選択。分からなければ標準を選択しておけばOK。
3.表示色の設定
4.設定の確認。SDKのダウンロードなど必要なファイル群をさらにダウンロードされます。
5.各種ダウンロード中
6.ダウンロード完了