メイン

Java アーカイブ

2005年11月09日

JavaOne Tokyo 2005

技術調査と称してJavaOneへ

午前中の基調セッションを聴く。
意外と聴衆の年齢層が高かったのは驚き。

当然通訳なしで聞くでしょう!

大きなケーキでHappy Birthday Java 10thを祝ったのは
さすがアメリカの会社。歌手まで連れてきてましたからね。

もらったものリスト

続きを読む "JavaOne Tokyo 2005" »

2006年10月11日

逆コンパイルツール

JDKにも付属しているが使いやすいのは
DJ De Compilerである。

なんでこういうのが必要かといえばソースがなかったり、今あるバージョンとCVSのソースの整合性に自信が持てないケースだったりするから。

最終的には動いているのが最新バージョンということになるとこいつの出番である。

2007年07月13日

StrutsのActionがスレッドセーフでない証拠

検索キーワードを見ていると相変わらずStrutsのActionがスレッドセーフであるか否かを探していると見られるものが多い。

最近出たStruts2は知らんが、Struts1.x系においては一度作ったActionインスタンスはアプリケーションサーバー(Tomcat等)を再起動するまではずーとプールされる。

ためしにこんなコードをActionクラスのexecuteに入れてみれば一発だ。

System.out.println(this.hashCode());

なんどリロードしてもハッシュコードは一緒。つまり同一インスタンスなので読取専用以外のフィールドは持たせないほうがよいということになる。ユーザー固有の情報(たとえばHttpSessionなど)をフィールドにもたせてActionクラスを作ってしまうと自分一人のテストでは問題が発覚しなくても、結合テスト時などの複数人同時に利用したときに問題が発覚して大慌てになるので注意。

Actionがスレッドセーフでない理由はパフォーマンス的にリクエスト毎にActionをnewするのはよろしくないという設計者の思想があるからしょうがない。

ActionをスレッドセーフにするためにSpringなどのDIコンテナを利用してActionインスタンスをリクエスト固有で生成するようにしていたやり方もある。

2007年07月19日

NoClassDefFoundErrorの原因を探る

本番環境にUPする時など環境が変わったときに遭遇しやすいこのエラー

開発時は問題なかったのにいざ本番で出るとびびる上にだいたいそういう時はテンパリモード1000% なので冷静な判断ができないだろう。

しかし結局のところクラスパスの設定が間違っているというのがほとんどなのでクラスパスを列挙させてみるといい。 たとえばjspなら以下のコードを入れてみる。

<%
//クラスパス表示
String classpath = System.getProperty("java.class.path");
java.util.StringTokenizer st = new java.util.StringTokenizer(classpath,";");
while (st.hasMoreTokens()){
out.println(st.nextToken() + "<br>");
}

%>

そしてきちんと動く環境のクラスパスと比較してみる。 クラスパスがまったく一緒なのに動かない場合はJARファイルなどのライブラリがきちんと存在しているか? コンパイル環境ではコンパイルエラーとなるので気づくが、実行環境ではクラスをロードするときまでエラーが出ないので厄介だ。

たいていの場合において開発環境にはたくさんJARファイルが入っていてどれがどれに依存しているかわからなくなって、 必要なJARを本番環境にコピーし忘れてこのエラーに遭遇するというケースも多い。

 

2007年07月21日

Windowsで複数のバージョンのJDKをインストールする

JDKはすでに6.0が出ているというのに、いまだアプリケーションサーバー各種での採用があまりなく(特に商用)利用例が少ないのが実情ではないだろうか?

各いう自分も今やっているプロジェクトはJDK1.4系である。しかしTomcatなどのオープンソースプロダクトの最新版はもうJDK5.x以上しかサポートしていない。というわけで複数の別バージョンのJDKを入れるというニーズもあるだろうからそのやり方を書いておく。

Linuxと違いJDKのWindows版はインストーラーしかない。しかしデフォルトではバージョン名がフルに入ったディレクトリにインストールされるので別バージョンを入れたとしても上書きされるような事態にはならない。なので後は使うアプリケーションごとにJAVA_HOMEの値を切り替えて置けばよい。

Linuxではアーカイブ版があるので違ったディレクトリに解凍し、こちらも環境変数の値を使うバージョンにあわせて設定すれば共存ができる。

ちなみになんでJDK6を入れたかというとTomcat6を試してみたかったからなのである。

2007年07月26日

Apache2.2のmod_proxy_ajpでTomcatと連携する

ApachetとTomcatといえばmod_jkで連携するのがこれまでの定番であった。 Apache2.2からはApacheの組み込みモジュールで連携することができる。

実験はVineLinux4.1で行った。 Apache2.2はaptでいれるとmod_proxyやmod_proxy_jspは入っているはずである。

Tomcatのバージョンは6.0.13だが、Tomcat側はajpプロトコルが使えればいいので5だろうと4だろうと多分大丈夫。

下の例は同じマシンで動くTomcatのexampleコンテキストに/exampleでアクセスできるように設定したものである。

#Tomcat Connect Setting
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Location /examples/>
  ProxyPass ajp://127.0.0.1:8009/examples/
</Location>

Apache2.2が出て間もないのと、mod_jk並に細かい設定ができるかわからないので、 JKによる連携が急激に廃れることはないと思うが、 コンパイルする必要がなく設定だけで連携できるのは個人のテスト環境としては楽でいいのではないだろうか?

2007年07月30日

Javaで日付妥当性チェック

PHPに比べるとめんどくさいのね。

入力はString型とする。

入力日付フォーマットをチェックしつつ日付の妥当性も検証する。 なお内部的にはCalendarクラスのsetLenientメソッドを呼んでいるので引数がintの場合はCalendarクラスを利用したサンプル (そっちは世の中にありふれてる)を使うといいだろう。

 String dateString = "2007-07-30";
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     // 日付解析を厳密に行う(2/31などはNG)
     sdf.setLenient(false);
  try {
   Date date = sdf.parse(dateString);
   return sdf.format(date);
  } catch (ParseException e) {
   // 不正な日付のときはこのブロックに到達
  }

JavaScriptとかASPでも同種の処理を作った覚えがある。 たしかフォーマットをかける前とかけた後を比較して同じだったら正常日付、違ったら不正日付とみなしていた。

2007年09月27日

JDBCドライバーの4タイプを理解する

JDBCドライバをダウンロードする時に困るのが複数タイプのドライバがあってどれをダウンロードすべきかということである。とりあえずどんなタイプがあるのかだけでも抑えておこう。


タイプ1 ODBC経由。windows環境でお手軽に試す場合。JDBCドライバが用意されていなくてもODBCドライバがあればよい。最近ではSQLServerもJDBCドライバを提供しているので本番環境での出番はなさそうである。

タイプ2 クライアント側にネイティブライブラリ必要。OracleのJDBC接続はまだこれが主流ではないだろうか?Oracleクライアントの設定とさらにJDBCの設定が必要なので面倒だ。

タイプ3 ミドルウェアサーバー経由。というだけでほとんど実利用されているのを聞いたことがない。絶滅寸前か?

タイプ4 100%JavaでJDBCドライバのみで接続可能。一般に重い商用DBクライアントをインストールしなくていいので便利。OracleやDB2など主要なDBMSではドライバが提供されている。

2007年10月10日

UnsupportedClassVersionError

はじめてみたこのエラー

コンパイルされたのが5.0で実行したのが1.4なのが原因のようだ。

5.0でコンパイル→古いバージョン1.4では認識できずにエラーとなった。
ちゅー感じ

動かそうとしたアプリは1.4対応と書いてあったのでJDK1.4環境でコンパイルしなおせばよいのだが、もうJDK5.0が当たり前の時代なのかと思わせる出来事なのであった。

2008年09月30日

CentOS5.2 JDKセットアップ

特に難しいことはない

SunのサイトよりRPMファイルのJDK(原稿執筆時点ではjdk-6u7-linux-i586-rpm.bin)をダウンロードして、 実行権限を付与して、ライセンスに同意するのみ

CentOSではパスの通っているところにシンボリックリンクが作られるので特段設定は必要ない

なおwgetを使ってダウンロードするときにファイル名が長すぎる時は以前のエントリーを参考に対処してほしい

wgetでファイル名が長すぎると出た時

http://rutake.ddo.jp/blog/techmemo/2007/07/wget.html

mod_proxy_ajpでApache Tomcat連携

前のエントリーに続きCentOSでJava環境構築シリーズ

Apache2.2になってmod_proxy_ajpを使うようになり、mod_jk(もはや非推奨)の時代より格段に楽になった。

通常CentOSのApache2.2にはモジュールがすでにインストールされた状態なので後はTomcatのインストールと連携の設定をhttpd.confに加えるだけとなる。

Tomcatのインストール

公式サイトからダウンロードして解凍する。/usr/javaに解凍してstartup.shを実行したらそのまま実行できた。 環境変数の設定いらないんだ・・・

一応ブラウザで単体で動くことを確認しておこう

http://サーバIP:8080/

httpd.confの設定

以下の設定をhttpd.confに加えるだけ、LoadModuleの設定は不要だが、 VineLinuxでやるときは必要だったのでコメント行として残しておいた。

#Tomcat Connect Setting
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Location /examples/>
  ProxyPass ajp://127.0.0.1:8009/examples/
</Location>

連携確認

http://サーバIP/examples/

Tomcatのサンプルが出てくればOK

 

2008年12月17日

Struts2のActionクラスはスレッドセーフ

相変わらず
Struts Action スレッドセーフ
のキーワードが多いことから、Struts1が使われていることが多いんだろうけどもStruts2になるとリクエストごとにオブジェクトを生成するようにアーキテクチャが変わった。

ほかにもActionクラスはPOJOオブジェクトでよいなど、1のバージョンアップというより別アーキテクチャのフレームワークと考えた方がいいだろう。

というか1もまだ精力的にバージョンアップされているのである。

2008年12月22日

UnsupportedClassVersionError 再びでた

このエラーに遭遇するのは二回目。

原因としては6.0でコンパイルしたものを1.4で動かそうとしたからなんだけどもね。
いろんな変更を同時にやってしまった場合は、いきなりエラーが出てあせるかもしれない。


ソースをもってきて、1.4環境でコンパイルしなおせば解決する。

2008年12月29日

Java JDK 過去バージョンを手に入れる

いくら6.0が出てるとはいえバージョンアップしたことによるアプリによっては、不具合報告を聞いているのでまだ5. 0の需要はあるのではないか?

もしくは既存プロジェクトのためJDK1.4.2を使わざるを得ないとかね。

というわけでいざとなると見つけづらい過去バージョンのURLは以下になる。

http://java.sun.com/javase/downloads/previous.jsp

2009年01月15日

SAStrutsのActionはスレッドセーフ

SeaSar2プロジェクトのSuperAgileStruts

設定ファイルを書かなくていい&HotDeploy対応なのでほんとさくさくと開発が進められる。

HelloWorldを出すのに何ステップも手順が必要だった従来のStrutsよりはるかに使いやすい

そして公式ドキュメントにも記載があるが、リクエストごとにActionインスタンスを生成するのでスレッドセーフである。

2009年01月27日

UnsupportedClassVersionError対処法その2

昨日も出た。

前回のエントリーでは以前のバージョンでクラスのコンパイルし直しだったが、今回の根本原因はJDKが複数はいっており、古いJDKで実行しようとしていたことであった。

なのでJDK6にJAVA_HOMEを向けてやれば再コンパイル不要。
たまに行儀悪いアプリケーションが勝手にJDKのパスを書き換えて、知らない間に動作しなくなることもあるので、どのアプリを実行するにしても個別にJAVA_HOMEを設定しておくことをお勧めする。

Tomcat起動時のエラーメッセージ「以前のエラーのためにコンテキストの起動が失敗しました」が出たときの対処法

こちらもより詳細にエントリーを書き直しました。リンク先を御覧ください。

http://blog.rutake.com/techmemo/2009/01/27/tomcat%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%ae%e3%82%a8%e3%83%a9%e3%83%bc%e3%83%a1%e3%83%83%e3%82%bb%e3%83%bc%e3%82%b8%e3%80%8c%e4%bb%a5%e5%89%8d%e3%81%ae%e3%82%a8%e3%83%a9%e3%83%bc%e3%81%ae%e3%81%9f/

これもよく遭遇するといえば遭遇するエラー

エラーメッセージの日本語訳が微妙なのと、該当コンテキスト以外はTomcatが正常に動いており、404を返すのでなんで??と思ってしまいがち。

根本原因はweb.xmlやfilterなどの設定がおかしいためこのコンテキストの初期化に失敗しており、その場合Tomcatはそのコンテキストが存在しないものとして扱う。というわけで404エラーがでていたらちゃんとTomcatのログを見よう。特にweb.xmlを大幅に編集する場合は、事前に動いているweb.xmlのバックアップを取得しておくべきだろう。

2009年02月19日

Strutsの同期トークン

二重送信を防いでくれる同期トークン。いろいろ議論はあるがCSRF対策にもなるだろう。

お手軽にできるのだが、タブブラウザ全盛時代には使用上の注意がある。

同期トークンの仕組みはHIDDENの値とセッションの値が同一であることを比較する。
つまりセッションに入った値が空もしくは別のトークンであればエラーとなる。

ここに問題があり、同一セッションを持つブラウザで別のトークンを発行した時点で、以前発行されたトークンはセッションから追い出されて処理が継続できない。

これが作られた時点ではあまり問題にならなかったのだろうけど、今はタブブラウザ全盛だからな。

改良の余地あり。

2009年03月11日

ClassNotFoundExceptionの原因

エントリーを新たにわかりやすく書き直しました。
リンク先をご覧ください。

ClassNotFoundExceptionの原因と対策

NoClassDefFoundErrorなどに比べるとわかりやすい。

ClassForNameしているところが原因なのでたいていはスペルミス。

スペルが正しいのならNoClassDefFoundErrorと同じ対処法でjarのライブラリをチェック!

2009年03月12日

Mavenでテストスキップ

テストクラスが外部リソース(DBや外部サイト)に接続している場合、単なるコンパイルだけでテストしてしまうのは非常に時間がかかり生産性が落ちる。

2時間かかっても終わらなかったのでテストなんてやってられるか!最後に一回やればいいんじゃというわけでテストをスキップするオプション

-Dmaven.test.skip=true

2009年03月24日

Hudsonのお勉強開始

ゲームソフトメーカーぢゃないよ。

HudsonというCIツールを仕事で使うことになり、必死で勉強してますわ。

2009年04月01日

Tomcatで404エラーが出る時の原因と解決策

404は要求したリソース(≒ページ)が見つからない時に出るエラー

一番最初に確認すべきはURLが正しいか?

ピリオドがカンマになっていたりとか、パスが間違っていたりとか。テンパっている時こそ落ち着いて確認すべき。

次に仮にURLが正しい場合で404エラーが出る場合は、HTMLなどのスタティックコンテンツを同じディレクトリにおいてみる。 そして404エラーが出ないようであれば設定漏れ(web.xmlを更新して再起動してないとか)

最後にHTMLコンテンツですら見えない場合は、コンテキストの起動に失敗している可能性が高い。 たとえばweb.xmlが不正であったり、filterの設定でクラス名を間違えて、 ClassNotFoundExceptionが発生している場合そのContextは無効になる。 他のコンテキストは大丈夫なので一見エラーではないと勘違いしがちであるが、 Tomcatの起動ログではエラーのスタックトレースが発生しているはずである。

web.xmlの大掛かりな変更をする場合は、バックアップをとるのは必須といえよう。

2009年04月26日

\65279 は不正な文字です。

Javaコンパイル時に発生したエラー

UTF-8で先頭に特殊文字が入っていると出る可能性がある。

とくにメモ帳で開くとかならずこのエラーが出てしまうので注意。

BOM除去で検索すると対処法が見つかるかも

2009年05月08日

NoClassDefFoundErrorの原因を探る Tomcat編

自分が遭遇することも多いので必然的に検索ランキング上位に位置するようになった前回の 「NoClassDefFoundErrorの原因を探る 」 エントリーでは特にWebアプリの対応を挙げていなかったので今回はTomcatに焦点を絞ってみたい。

Tomcatの場合共通系のライブラリにjarファイルを置くことはあまりしない(JDBCドライバぐらい)はずなのでjarファイルを置く場所としては下記の場所になる。

コンテキストベース/WEB-INF/lib

ここに目的のjarファイルがないとNoClassDefFoundErrorが実行時にでてしまう。 難しいのは実行時にしか起こらないことと、コンパイル時には判明しないjar同士の依存関係があること。

あわてることは無いので一つ一つ出るたびにjarファイルを探してきて、 上記ディレクトリに配置してTomcatあげなおすの繰り返しで解決するしかない。

実行時エラーとはいえコンパイルエラーと同様本来起こってはいけないエラーなので、 設定系を担当している人はこれが出てしまったら自分が怠けているってことだぜ!

2009年05月26日

TomcatのバージョンとJDKの対応表

TomcatがどのJDKで動くのかというバージョン対応表

http://www.rutake.com/wiki/Java/Jakarta/Tomcat/#k323cf8d

2009年06月15日

jdkのバージョンを調べる

超基礎レベルだけど意外と検索キーワードが多いので

コマンドラインで

java -version

これだけ。

そもそもそのコマンドがどこにあるのかはちゃんと起動スクリプトなり、JAVA_HOMEをみるなりして確認しないとだめですぞ。

環境によっては複数のJDKを入れていて、共存させるためにJAVA_HOMEはき同スクリプトで指定させる場合もあるので、 自分がどのパスのJDKを使っているかをはっきりさせるのが第一。

NoClassDefFoundErrorの原因を探る jarファイル競合編

すでにおなじみとなったこのシリーズ。

基礎編

Tomcat編

続きましては結構はまりがちなjarファイルの競合によるもの。

同じクラスを含むjarファイルがある場合は基本的に先に読まれたものが優先となる。本来あってはいけないことだが、 新旧バージョンが混在している場合などに古いjarが優先して読まれるケースが起こりうる。

特にTomcatのWEB-INF/libにあるjarはどんな順番でクラスパスが通るかは制御できないので、 jarの競合が起こりやすい。

違ったバージョン並存して入れている場合は一つに絞るべきだろう。

2009年06月17日

Tomcat 監視ツール

http://www.lambdaprobe.org/

結構よさげ。家帰ったら試そう

2009年06月22日

Javaの一時ディレクトリ場所を指定する。

なにも指定しないとOSの標準の一時ディレクトリ場所になるが、指定したほうがよい。

というわけで起動オプションに下記の文字列を指定する

-Djava.io.tmpdir=/hoge/tmp

 

2009年07月06日

SJC-WC

Javaの資格試験の一つ

正直なところ最近はフレームワークばかりなのであまりServlet,JSPなどを直接触ることもないし、 多少APIを覚えたところで、google様に頼れば仕事はできるからこの手の資格はあまり重要視しない。

世の中的にはどのぐらいニーズがあるのか知りたいけど。

2009年07月10日

BOM問題

UTF-8を表すためのバイナリが先頭3バイトに入るのだが、見た目ではぜんぜん気づかないので厄介。

バイナリエディタで該当ファイルを開き、EF BB BFの順番で始まっていればBOM付

XMLの読み込みなどでエラーが出る可能性が高い。混じっても実行時までわからないのが厄介どころ。

Byte Order Markの略でBOMだが実際には爆弾の意味と等しいかと。

2009年07月14日

ClassファイルはあるのにNoClassDefFoundErrorが出る時

今日始めて遭遇。

コンストラクタで例外が発生してしまうと初期化に失敗する。以後そのクラスは無いものとして扱われる。

NoClassDefFoundErrorの前に初期化に失敗している旨のメッセージが出ているはずである。

 

2009年07月16日

jarファイルを作り直す

jarファイルにすると当然一つのファイルにまとまる利点がある反面そう簡単に中身を更新はできない。 故にリソースファイル系にちょっと修正を加えて実行したい時にまたjarを作り直すのも面倒な話。

本来こういう場合はリソースファイルだけを切り出して、 クラスパスの優先順位を上位にすればそちらのリソースがjarの中身より優先して読まれるのだが、 残念ながらそうなっていないプロジェクトもある。

というわけでその場でjarファイル解凍して、再び作成するテクニック

1.作業用ディレクトリ確保

mkdir -p /tmp/jartmp

2.作業用ディレクトリに移動


cd /tmp/jartmp

3.解凍

jar xvf 目的のjarファイル

4.リソースファイルを変更する

5.jar再作成

jar xvf 新しいjarファイル名 *

これでOK!

Tomcatの設定ファイルに環境変数を使う

へー使えるんだといまさら発見

下記のように使う。

<Context>
    path="/Sample"
    docBase="${catalina.home}/webapps/Sample">
</Context>

 

2009年08月04日

hudson subversionの差分更新はやめたほうがよい!

hudsonでsvnを利用する場合、過度に負担をかけないように「アップデートの使用」というオプションがある。

これだと前のファイルが残るのだが、圧倒的に早いためこれを使い出したところ、 コンフリクトを起こしたファイルはいくら直してもコンフリクト状態のままという現象になる。 おそらく前の衝突ファイルが残っているためだと思われる。

ソースがほぼ衝突しないような安定したプロジェクトでない限り、このオプションの利用はお勧めできない。

2009年08月05日

一定ルールを持つファイルの一括ファイル名変換

antを使ってみた。もっと他に楽なやり方があるかもしれない。 用途としてはSeasar2のdiconファイルの一括リネームだった。

  <move todir="対象ディレクトリ" includeEmptyDirs="no">
   <fileset dir="対象ディレクトリ"/>
   <mapper type="regexp" from="(.*)_dev.dicon" to="\1_ut.dicon"></mapper>
  </move>

 

2009年08月11日

tomcatのserver.xmlの設定を動的に置換える

起動時の引数を利用してserver.xmlの内容を置換えるようにできる。

これは目からうろこだった。

たとえばクラスタリングにつかうjvmRouteの値などはほとんど同じ設定の二台でjvmRouteだけが違うのに二つのファイルを用意するのはミスの元。

というわけでjava起動時の-Dオプションで指定しておけばあとはシェルでおなじみの変数表記で置換えてくれる。

Tomcat起動引数に以下のようにして起動

-DjvmRoute=a

server.xmlでは以下のように記述

<Engine name="Catalina" defaultHost="localhost" jvmRoute="${jvmRoute}">

そうするとjvmRoute="a"と記述したのと同じことになる。すばらしい!

2009年12月16日

NoSuchMethodErrorの原因をさぐる

NoClassDefFoundErrorよりは出現頻度が低いけど、出たら焦ってしまうエラー。

根本原因はコンパイル時に使ったjarファイルと実行時のjarファイルが違うこと。
jarファイルが同じものか確認することと、同じクラスを含むjarファイルが混在していたりしないかチェック。

一度あったのが、アプリをバージョンアップした後に古いjarがworkディレクトリに残っていたためにこのエラーが出たというケース。

2010年02月03日

Java ME SDK 3.0ではじめる携帯アプリ開発

CLDCやらwireless Toolkitやら

どれをインストールすればいいんじゃー!と思っていたら、オールインワンの開発パッケージがSUNからでてた。

今後はこれを使っていくのがいいのかな。eclipseはJ2ME分野ではまだ情報が少ないし。

早速インストールしてみる。

開発環境とエミュレータセットですぐ開発開始できる!

すばらしい。

About Java

ブログ「技術メモ」のカテゴリ「Java」に投稿されたすべてのエントリーのアーカイブのページです。過去のものから新しいものへ順番に並んでいます。

前のカテゴリはHardwareです。

次のカテゴリはLinuxです。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。