さわらブログ

さわら(@xhiroga)の技術ブログ

WASのディレクトリ構成

現場で学んだことの棚卸し。

背景

WAS(WebSphere Application Server)を使っていると、トラブルが起きた時にディレクトリ構成の知識が必要になってくる。
せっかくどのディレクトリにどんな役割があるか少し知ったので、自分の言葉で整理する。
いずれもWindowsが前提。

ディレクトリ構成

RAD(Rational Application Developper)のインストール・ディレクトリー以下、
runtimes¥base_v7¥profiles¥{プロファイル名} を参照。*WAS7の場合

bin

startServer.bat, stopServer.batがある。普段はRADから直接起動しているが、WASはコマンドラインから起動できる。
メモリが少ないマシンで開発していると、eclipseを立ち上げずにサーバーを起動したい局面で重宝しそう(ほんとに2017年かよ...)

config

サーバーの設定ファイルがあり、管理コンソールの設定内容が反映されている。
config¥cells¥{cell名}¥nodes¥{node名}¥servers¥{アプリケーションサーバー名}/server.xml

Tomcatの場合はconf直下にある。
{tomcat}¥conf¥server.xml

installedApps

サーバーをサーバー上のリソースで実行している場合、ワークスペースからコピーしたクラスファイルが配置されるフォルダ。
Tomcatの{tomcat}¥webapps に当たると思われる。
ソースの修正がどうしても反映されない時に、クラスファイルを強引に置き換えて直したい時などに使う(そんなことあるのか)

logs

サーバー起動時のログがある。ここを確認してOutOfMemoryだったら、JVMのヒープサイズを大きくする(その前に、同時に起動しているプロセスを減らす)
logs¥{アプリケーションサーバー名}以下、server.log など。

temp

JSPのクラスファイルがある。サーバーを再起動し、かつブラウザをスーパーリロード(キャッシュを無視した再読み込み)してもJSPファイルの変更が反映されない場合、このフォルダの対応するクラスファイルを削除するとよい。
Tomcatの場合、{tomcat}¥workにある。

行値構成子とテーブル値構成子:なぜSELECT結果を直接INSERTしたり、WHERE句で複数列を同時に比較できるのか

背景

現場で見かけてもやもやしていたSQLに、次のようなものがある。

INSERT INTO my_db.animals SELECT * FROM your_db.animals; --例1.

SELECT結果を直接INSERTしている。INSERT文と言えば INSERT INTO xxx VALUES xxx の形式だと思っていたので驚いた。
同時に、今までINSERT文の文法だと思っていたものが全てじゃないような気がしてきた。

こんな例もある。

SELECT * FROM my_db.animals WHERE (name, sound) = ('Cat', 'Myao'); --例2.
SELECT * FROM my_db.animals WHERE (name, sound) IN SELECT name, sound FROM your_db.animals; --例3.

WHERE句の左辺が複数要素ある。これは便利だ。
もし左辺に1項目づつしか指定できなかったら、例3.では比べる対象の列を項目に合わせて分けるため、SELECTを2回発行することになってしまう。

どうして例1.〜 例3.のような文法が使えるのか、ちょっと調べてみた。

前提

SQLの言語仕様はISOで定められており、これに各ベンダーが準拠している。
歴史的に統一標準規格がなかった時期が長かったため、ベンダーによって準拠の度合いはまちまちなんだそうだ。(Wikipediaより)
したがって、ISO(制定年ごとにバージョンがある)があればそれを参照し、ISOのドキュメントがなかったりベンダー固有仕様ならベンダーのサポートサイトを参照しよう。

これから調べることは文法の基本っぽい雰囲気だし、何よりISOのドキュメントが見つかったのでそれを読んで理解しよう。

行値構成子とテーブル値構成子

ぶっちゃけ自分で考えたことで事実確認はしてないんだけど、どうして例1. 〜例3. の文法が使えるのかの結論から行こう。
- INSERTが値に取るのはテーブル型の無名オブジェクトと思われる。VALUESはテーブル型のオブジェクトを生成するコンストラクター(テーブル値構成子)にすぎない。
- WHERE句では左辺が行値構成子の場合、右辺に対応する列があるものとして要素ごとに評価する。

それでは、行値構成子とテーブル値構成子とは何なのか。
SQL92の規格によれば以下の通り。
※例示と訳語のチョイス、翻訳は私自身によるものです。


row value constructor(行値構成子、行値コンストラクタ、RVCとも。)
値のセットを行または行の一部を構成するようにするもの。

('Cat', 'Myao') -- 行値構成子
('Dog') -- これも行値構成子
'Lion', 'Gyaoo' -- ()で囲わない場合、行値構成子リスト
'Beer' -- 単体だと行値構成子エレメント

要するに、()で囲うとそこが行として見なされるわけだな。

table value constructor(テーブル構成子、テーブル値コンストラクター、TVCとも。)
行値構成子をテーブルを構成するようにするもの。

VALUES ('Cat', 'Myao'), ('Dog', 'Bao'), ('Bird', 'Piyo') -- テーブル構成子

ということは、こんなこともできるのである。

SELECT * FROM ( VALUES('Cat', 'Myao'), ('Dog', 'Bao'), ('Bird', 'Piyo') ); -- VALUESを使い、手打ちの値をテーブルに見立てる。  
VALUES(1); -- 1をSELECTで取得したテーブルと同じように見立てる。

いや〜知らなかった。

まとめ

INSERT文は必ずVALUESを使わなければいけないのではなく、値がテーブル型のオブジェクトなら良さそうだ。
こういう例は他にもありそうだから、SQLを使う時は何のオブジェクトを扱っているのか気にしてみよう。

参考文献

SQL - Wikipedia
そもそもSQLについて調べるにあたり、何を見ればいいか分からなかったので。

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
Wikipediaのリンクから発見した、SQL 92の仕様書。カーネギーメロン大学のサーバーに置いてくれてあるようだ。

テーブル値コンス トラクター (TRANSACT-SQL) | Microsoft Docs
T-SQLMicrosoftによるSQLの規格)のドキュメント。

SQL Server 2008 から記述が短くなったもの の紹介 - お だ のスペース
個人ブログ。テーブル値構成子の使い方が例示されており、分かりやすい!

i am BEST : VALUES コンストラクタは必ずしも INSERT INTO とだけ用いられるわけではない!?
上に同じく。

sqlのwhere in って、複数条件(カラム)を指定できるんですね - end0tknrのkipple - web写経開発
上に同じく。

【備忘録】iBatis、log4j、依存性注入

現場で使っていて理解したことの棚卸し。

iBatis

JavaのO/Rマッパー。
勘違いしていたが、iBatisとDAOオブジェクトは直接関係ない。
iBatisは「if文などでカスタマイズ可能なSQLを」「入出力のパラメータをDTOオブジェクトにまとめてマッピング可能にし」「JDBCを意識しないで発行する」ためのライブラリーである。そうした機能は、iBatisが提供するsqlmapインスタンスのメソッドから利用可能。
ただし、アーキテクチャの問題として、SQLDTOオブジェクトをマッピングしたXMLファイルごとにデータアクセスのためのオブジェクト(内部でsqlmapインスタンスを使用)を定義することは考えられる。
そのせいでiBatisとDAOが依存していると勘違いしていた。

SqlMapConfig.xmlの設定を読み込み、アプリケーション内で一つだけのインスタンスを持つ(これは強制ではなくパターンの問題かも?)ただし、複数のDBにアクセスできるよう、SQL発行に使用するコネクションはアプリケーション起動後に変更可能である。
使用するSQLはSqlMap.xml内に定義するが、複数のXMLファイルに分散して記載することもできる。

普段生のSQLを触るので、PythonでSQLAlchemyを触った時よりも使いやすかった(そちらはSQL文をプログラマが設定することはなく、代わりに基本のSQLに相当するメソッドを組み合わせて利用する)

log4j

Javaはじめクロスプラットフォームで使用できるログ出力ライブラリー。
ログの重要度や出力先、形式を属性として持つLoggerインスタンスをアプリ内で生成し、ログを出力させる。
出力先、形式をそれぞれAppenders、Layoutsクラスとして定義しており、複数のLoggerインスタンス間で共有できる。
ログの出力先となるフォルダとその識別のためのIDをクラスパス直下のlog4j.xmlで管理しており、これをよく忘れて先輩に聞く(ログ出るのどこでしたっけ?)

依存性注入

クラス内で他のクラスのインスタンスが必要なときに、受け入れる変数の型をインターフェースで宣言し、肝心のインスタンスを呼び出し元に作らせたり、DIコンテナに作らせたりするパターンのこと。
他のクラスを直接参照しないことで、そのクラスのソースが完成していない状態でコンパイルをしても怒られないで済む。なので、複数人でプログラミングしているときに作業順を気にしないでよくなるそうだ。
(1機能のDelegateとServiceとDAOを別人がプログラミングすることってそんなにない気もするけど...逆に言えば部品の共有が進んでいないってことでもある。)
他にも、テストや開発環境の場合だけ参照する実装クラスを変えることが、ソースの修正なしにできる。これは嬉しいかも。

実装を見るとイメージが掴みやすいと思う。例はWikipediaより、DIコンテナを使った場合。

public static void main(String[] args) {
        IAutomatedStockTrader stockTrader =
            (IAutomatedStockTrader) DependencyManager.create(IAutomatedStockTrader.class);

参考資料

iBatis

iBATIS2/iBATIS3/mybatis各種アーカイブ・ドキュメント一覧 - Shinya’s Daily Report

log4j

Apache log4j 1.2 - Short introduction to log4j

依存性注入

依存性の注入 - Wikipedia

DI・DIコンテナ、ちゃんと理解出来てる・・? - Qiita

【備忘録】eclipseのエンタープライズ・アプリケーション・プロジェクトについて

eclipseのプロジェクトが何なのかしっくり来ていなかったので。

背景

現場でプロジェクトがサーバーに追加できない状態になり、解決策を調べるうちに「そもそもプロジェクトとは?」「もっと言うと、Java EEとは?」って状態になったので。

Java EEとは

Webアプリケーションの作成に役立つJava標準のライブラリ群。   サーバ・アプリケーション間のインターフェースであるServletPythonだとWSGI)、テンプレートエンジンのJSPPythonだとJinja2他)等々がある。   それだけでなく、アプリケーションサーバーが複数のアプリケーションを一つのアーカイブとして扱うための形式を定義している。その際のアーカイブがEARファイルである。

eclipseのプロジェクトとは

eclipseが複数のソースコードをデプロイやバージョン管理のための一つの単位として扱うためのフォルダ。
ただのフォルダではなく、離れたフォルダのリソースを参照するように設定することができる。

中でもJ2EE(Java EEの古いバージョン)で定義したディレクトリ構成に対応するフォルダをJ2EEモジュール・プロジェクトと称するようだ。
それらJ2EEモジュール・プロジェクトを一つのアーカイブとして扱うため、EARファイルの雛形となるのがエンタープライズ・アプリケーション・プロジェクトである。

エンタープライズ・アプリケーション・プロジェクトとプロジェクト・ファセット

J2EEに準ずるアプリケーションはxmlファイルにそのための設定を持つ(と思う、実際には見ていない...。)こうした設定を、GUIベースでプロジェクトに対する特性として設定できるのがeclipseのプロジェクト・ファセットである。
EARファイルの作成には親のエンタープライズ・アプリケーション・プロジェクトと、子のJ2EEモジュール・プロジェクト(特にサーバーに追加する場合は動的Webモジュールプロジェクト等)が必要になる。
こうした定義はプロジェクト・ファセットで行う。
モジュール間の依存関係は、本来はEAR > META-INF > application.xmlで設定する。eclipseの場合はプロジェクトのプロパティからJ2EEモジュール依存関係で設定可能。

プロジェクト・ファセットの特性のバージョン関係は依存性があるので、うまくプロジェクトが追加できないことがあれば設定を見直すべし。

その他現場で役立つこと

ソースの修正が反映されない場合、クラスファイルが再作成されていないか再デプロイされいていないかのいずれか。
前者の場合はクリーンビルド(クラスファイルを自動削除後にビルド)後者の場合はクリーンデプロイ(サーバーが参照するディレクトリ上のクラスファイルを削除してデプロイ)が効果あり。もちろん手動で消しても効果は同じ(ビルドし忘れなければ)

参考資料

Help - Eclipse Platform eclipse公式ドキュメント

IBM Knowledge Center IBMeclipse関連ドキュメント。↑の日本語訳があると考えてよさそう。

いまさら聞けないサーバーサイドJava 第1回 これだけは知っておきたいJ2EEの基本 | 技術トピックス | ウルシステムズ株式会社

【備忘録】Struts1系で調べたことまとめ

2017年にStruts1系を記事にしている人がいること自体がすごい?

背景

Struts1系を使ってアプリを作る機会があり、1画面を追加するに当たって調べたことの棚卸し。

調べたこと。

  • アクセスパスごとに呼び出されるActionを変更するには<action-mapping>のtype属性を指定する。
    validationが働くとimportで指定したページに遷移する。
    pathには.doを含めなくても構わない。web.xmlでそう設定してあるようだ。以下を参照。
    stackoverflow.com

  • actionクラスが受け取るformは、action-mappingのname属性<form-bean>のname属性/type属性の二段構えで設定する。

  • action後にフォワードする遷移先はaction-mappingの<forward>タグで指定する。<global-fowards>よりもそちらが優先。
  • Tilesの設定では、大枠となるファイルは<definition>タグのpath属性/extends属性で指定する。pathではjspファイルを指定するのに対し、extendsではTilesで作成したテンプレートの名前を指定する。
  • 上記<action-mapping>, <global-foward>, <form-bean>などは個別の.xmlファイルで管理できる。それぞれ複数あっても構わない。

まだ分からないこと

  • 各種xmlファイルがどこに配置されているのかの法則がよく分からない。
  • JSP内でJavaScriptCSSを指定する際のやり方が複数あるようだ。

参考資料

www.amazon.co.jp
まずはこの本を読んで調べる。

Index of /dist/struts/documentation
Struts1系はサポート終了しているが、Apacheのホームページからドキュメントを入手可能。そのリンク。

Webアプリの基本を整理してる

Webアプリの基本の勉強をしている。 前に20歳くらい上のエンジニアの人に基本が大事だって言われたのだけど、だんだん分かりつつあるような...

そもそもプログラムというのが何なのかしっくり来てない。 OSと自分が書いたJavaとかPythonのプログラムが物理的にどう違うのかいまいちわからん。

プロセスが何かしっくりこない。 僕の書いたPythonのプログラムはプロセス上で動いていると思うんだけど、それってOSの動作とどうやってCPUを分けあって使ってるの?とか。

一方で、Webサーバーが何なのかは地道に調べてわかって来た気がする。 まずはOSに頼んで、ソケットっていうファイル記述子の一種を払い出してもらうらしい。 この辺はAPIを叩くようなイメージだと思う!

そのあとでポートをバインドする。ポートの指定が先かと思ったけどそうではないっぽい。 で、リッスンする。これが具体的に何なのかよく分からない。そもそもプログラムが「待つ」という状態が分からない。 プログラムってズバズバ実行されるものだと思うんだけど...待つって何なんだ... どこかにファイルが書き込まれていないかを0.X秒間隔でチェックする、とかならまだ分かるんだけど。

で、このあとそれをHTTPリクエストとして読み取り、うまいこと文字列を区切ってパラメータを読み取って、処理に繋げるんだと思う。 (この辺は『Webを支える技術』が参考になった。)

www.amazon.co.jp

このあとまた分からないのがサーバーが僕の書いたコードを呼び出す仕組みなんだけど...どうやって繋ぎ込むんだろう? Tornadoとかはサーバーに直接プログラムを書き込んでる気がするんだけど、Tomcatみたいなサーバーはどうするのだろうか。

その辺は今この本で学習中。 www.amazon.co.jp

この本に限らず、基礎の勉強会とかしたいな。

Ajaxの使いどころと例外処理について考察

ぜひ意見をください( ´ ▽ ` )ノ
初めは「Ajaxが使えるぞ!」って意気揚々と調べてたんだけど、もしかしたら何にでも使うべきじゃないかも?

※親切なWeb系のお兄さんと話した内容を追記しました (2017/10/08)

そもそもの背景

現場のWebアプリでAjaxを使えることになりそうなので、新機能のうちAjaxを使えるところはそうしたい!
のだけど、Ajax/ 丸ごとリロードの切り分けとか、サーバー側で例外が起きた時の対応がよくわからない。
とりあえずは調べたことをまとめたい。

Ajaxの使いどころ

ちょっとした処理から決済まで重要度を問わずに使えるけど、DOMをゴリゴリ操作するのであれば生Javascript/JQueryはオススメできない。

2000年代の記事では以下のような必要最小限の使い方に抑えているのが多いイメージ。
1. 業務フローの本筋以外で通信が必要なところ
・チャット
SNSへのシェアや認証時のパズルなど
・検索結果など、リストに対するフィルターやソート
・自動補完
2. ダイナミックな動きが欲しいところ
インクリメンタルサーチ

その後フロントエンドのフレームワークが出てきて状況変わったってことかな?

この辺は現場のフロント事情を鑑みて決める(jspみたいなテンプレートエンジンの資産がたくさんあるなら、DOM操作にReactは導入できないよね?)のが良いと思われる。

サーバ側の例外の扱い

最初からやり直させた方がよければ例外ページ、続行させた方がよければページ内のアラートで警告

  1. 最初からやり直させた方が良いケース
    ・決済処理など重要な処理
    → エラーページにリダイレクトさせ、初めからやり直すことを促す。

  2. 続行させた方が良いケース
    ・入力補完やコンボボックスの選択肢など、表示されなくてもユーザーが処理を続けられる場合
    ・リトライしてほしい場合
    → ページ内にエラーメッセージを表示する(例:Twitterでツイートが投稿できない場合など)

参考サイト

Alex Bosworth's Weblog: 10 Places You Must Use Ajax
たくさん引用されているサイト。Ajaxを使うべき6ケースと使わないべき4ケース。ただし昔の記事。

おさかなラボ - 6 Places You Must Use Ajax
↑の記事の内容を間接的にわかりやすく引用してくれている日本語のブログ

How to use AJAX: 5 Real World Examples - Moz
割と最近のAjaxユースケース