Hatena::ブログ(Diary)

on the center line.

2008-12-29

WindowsのApacheでPHPを動かそうとしたときに、Cannot load mysql extension. といわれた

| 01:37

Windows 上に、Apache + PHP + MySQL の環境を構築していて、ハマった問題と解決策のメモ。

■事象

PHPからMySQLに繋ごうとすると、Cannot load mysql extension.というエラーが発生。Apache のログにも以下が出力されていた。
PHP Warning:  PHP Startup: Unable to load dynamic library 'C:/Program Files/php-5.2.6/ext/php_mysql.dll'
※PHPインストール&設定は、Webなどに掲載されているとおりに正しく実施している

■原因&対策

Windows上でPHPから、MySQLに繋ぐには、適切なバージョンのlibmysql.dll がパスの通ったところになければならない。
普通にWindows用のPHPインストールすると、インストールディレクトリにlibmysql.dll があるので(インストールディレクトリにパスを通していれば)問題にはならないが、この「適切なバージョンの」というところがポイント。
僕の環境では古いMySQLインストールされていて、かつ、そのMySQLがパスの前の方に指定してあったため、別の「libmySQL.dll」が読み込まれて、上記エラーが発生していました。パスの順序を修正して解決。

いやあ、悩んだ・・・orz

2008-10-03

Java1.6+Antを動かそうとすると、java.lang.NoClassDefFoundError: org/apache/tools/ant/launch/Launcher

| 10:26

LinuxFedora)に、Java1.6とAntインストールして、いざAntを動かそうとすると表題のエラーが発生。

Javaは、jdk-6u7-linux-i586-rpm.bin をダウンロードしてインストールAntyum install antインストールしたもの。

原因調査のために、まず、javaコマンドから実行

java -cp /usr/share/java/ant-launcher.jar org.apache.tools.ant.launch.Launcher --help

これは問題なく動いた。ということは、/usr/bin/ant の問題か。次に /usr/bin/ant の中身を見てみると "-execdebug" というオプションがあることを発見。これをつけて実行してみると、

error: JAVAVER_LIBDIR /usr/share/java-1.6.0 does not exist

こんなメッセージがでてきた。実際に /usr/share/ をみてみると、java-1.4.2/、java-1.5.0/ はあるのに、java-1.6.0/ はない。じゃあ、作ればいいのかな、と思って作って実行してみると、、、

error: JAVAVER_JNIDIR /usr/lib/java-1.6.0 does not exist

さっきのエラーは消えて別の同じようなエラーが発生。こっちも同様にディレクトリを作成してい再実行してみる。すると、、、

成功!

動きました。こんな解決方法で良かったのかどうかは分かりませんが、まあ、当面の作業には問題ないので良しとしよう。。。

世捨て人世捨て人 2017/09/05 22:22 「しかし、この方法は「"Content-Type"ヘッダが"text/html"である正常なレスポンス」があったら使えません。」??何故!?
サーバーがtext/htmlを返してきたのだから、そのままページを表示すればいいのでは!?

2008-06-27

java.util.logging.Loggerを使う上での注意点

| 12:06

java.util.logging.Loggerを初めて使ったのですが、ちょっとハマってしまった点などあったので紹介しておきます(主に設定ファイル=logging.propertiesまわり)。

○問題

  1. logging設定ファイルはシステムクラスローダによりロードされる
  2. logging設定ファイルでHandlerの設定をする際、クラス単位でしか設定できない
  3. ユーザコードで設定を変更しても、VM起動時に読み込んだ設定が有効になったまま
  4. ファイルにログを出力する際、Logger単位でファイルをロックしてしまう。

1. logging設定ファイルはシステムクラスローダによりロードされる

これは何が問題かというと、サーバ上で動かすアプリケーションで、Formatterを自作しようとしたとき問題となります(そして、こういった局面は結構あると思います)。

サーバ上で動かすアプリケーションの場合、通常、アプリケーションサーバが独自でクラスローダを持っています。そして、自分が作ったクラス(=ユーザクラス)というのはアプリケーションサーバのクラスローダによりロードされます。一方、logging設定ファイルは(デフォルトのものであろうと、起動パラメータで指定した場合であろうと)システムクラスローダによりロードされます。

このため、logging設定ファイルにユーザクラス(=Formatter)を記述している場合に、システムクラスローダがユーザクラスをロードできず、エラーとなってしまいます。ユーザクラス(=Formatter)をシステムライブラリに追加してやると、ロードできるのですが。

2. logging設定ファイルでHandlerの設定をする際、クラス単位でしか設定できない

例えば、FileHanderクラスを使ってログをファイルに出力する場合、logging設定ファイルに次のような指定をします。

java.util.logging.FileHandler.pattern = %h/application.log

これでは複数のファイルには出力できないですね、クラスに対して指定してしまってるので。

ちなみに、logging設定ファイルを使わずにアプリケーションコードから出力ファイルを指定する場合は、FileHandlerのインスタンスごとに指定できます(というかそれが普通ですね)。

○1. 2. の解決策

サーバアプリの場合は、設定ファイルは使用せず、コードで行う。

サーバ上で動作するコードで、ロガーのコンフィギュレーションをしましょう。そうすれば、クラスローダの都合でユーザクラスが読み込めない、といった問題もなく、また、Handlerの設定はインスタンスごとに行うことができます。

3. ユーザコードで設定を変更しても、VM起動時に読み込んだ設定が有効になったまま

JREを普通にインストールした状態だと、ルートロガーの出力レベルは、INFO以上となっています。そのため、ユーザコードでカスタムロガーのを作成したときに、うっかり出力レベルの指定を忘れていると、ルートの指定(=INFO以上)が有効になります。

僕はカスタムロガーの設定をする際に、Handlerの出力レベルはALLにしたのですが、ロガーの出力レベルを設定するのを忘れていたために、FINE以下のログが出力されず、2時間ぐらいハマってしまいました。

○3. の解決策

ロガーのコンフィギュレーションは注意深く行う。

期待した動作にならない場合は、デフォルトの設定が有効になっている可能性が高いです。そんなときはもう一度、自分が行った設定を見直してみましょう。

4. ファイルにログを出力する際、Logger単位でファイルをロックしてしまう

ロガーを複数定義し、それぞれから同じファイルにログを出力しようとすると、競合が発生してしまうみたいです。こうなった場合、ロガーは自動的に連番を振って、別ファイルにログを出力します。監視することを考えると、なるべくファイルに出力したいのですが。

回避策としては、ログを出力するたびに Handler.close() メソッドを呼び出すという方法もあるのですが、それはそもそもの使い方とは違っているような。

○4. の解決策

ファイルに出力するときは、共通親ロガーを使う。

複数のロガーから単一のファイルにログを出力することはできないので、代わりに複数のロガーの共通の親ロガーを作成します。そして、子の方のロガーでは何も指定せずに親に処理を委譲し、親の方では、通常どおりログをファイルに出力します。

こうすることで、ロガー:ファイルが1:1の関係になるので、競合を回避できます。ただし、複数のロガーに共通の親ロガーを作成できない場合は、いまのところ打つ手なしです。

2008-05-11

Rails2.0 + Lighttpd + CentOS5の環境構築での問題

| 15:51

Apache + lighttpd で Rails を動かす を参考にして、Railsアプリの実行環境を構築していたところ、僕の環境ではなぜか問題が発生したのでメモ。僕の環境は、以下のとおり。

  • CentOS 5.0
  • Ruby 1.8.5
  • Lighttpd 1.4.19
  • Rails 2.0.2

各アプリのインストールは上記サイトの通りにやって順調に行ってたのだが、いざlighttpdを実行しようとすると、

2008-05-11 15:37:35: (log.c.75) server started
2008-05-11 15:37:35: (mod_fastcgi.c.1029) the fastcgi-backend /var/lighttpd/demo/public/dispatch.fcgi failed to start:
2008-05-11 15:37:35: (mod_fastcgi.c.1033) child exited with status 9 /var/lighttpd/demo/public/dispatch.fcgi
2008-05-11 15:37:35: (mod_fastcgi.c.1036) If you're trying to run PHP as a FastCGI backend, make sure you're using the FastCGI-enabled version.
You can find out if it is the right one by executing 'php -v' and it should display '(cgi-fcgi)' in the output, NOT '(cgi)' NOR '(cli)'.
For more information, check http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI#preparing-php-as-a-fastcgi-programIf this is PHP on Gentoo, add '
fastcgi' to the USE flags.
2008-05-11 15:37:35: (mod_fastcgi.c.1340) [ERROR]: spawning fcgi failed.
2008-05-11 15:37:35: (server.c.908) Configuration of plugins failed. Going down.

こんなエラーを吐いてlighttpdが終了してしまう。ネットで調べてもイマイチ原因がわからない。ならば development モードでやったらどうかと思って、Railsのプロジェクトディレクトリで以下のコマンドをたたく。

  # ruby script/server lighttpd

するとあっさりと動いた。はて???

ということは、Railsで生成したconf/lighttpd.confを使えば良いのか、と思って /etc/lighttpd/lighttpd.conf を置き換えてみると、、、

動いた。

元のlighttpd.confと、Railsで生成したlighttpd.conf との違いは良く分からなかったが(設定内容はだいたい同じはずなのだが)、とりあえずやりたいことは実現できてるので良しとしよう。

2008-04-28

CentOS5からWindowsの共有フォルダを参照するには

| 13:18

LinuxからWindowsの共有フォルダを参照するには、sambaのクライアントツールである、smbmountコマンドが有名ですが、CentOS5のsamba-clientパッケージにはsmbmountコマンドが入っていない(インストールされない?)ので注意です。同様に、mount -t smbfs も使えません。正しくは、

# mount.cifs

or

# mount -t cifs

になります。まさか存在しないなんて事はないだろう、という思い込みをしてたせいでずいぶん時間を無駄にしてしまった。