kuniku’s diary

はてなダイアリーから移行(旧 d.hatena.ne.jp/kuniku/)、表示がおかしな箇所はコメントをお願いします。記載されている内容は日付およびバージョンに注意してください。直近1年以上前は古い情報の可能性が高くなります。

タスクスケジューラからの起動でDLLファイルが読み込みできず、「NoClassDefFoundError」になる

事象

Windows2008serverでタスクスケジューラからtomcatを起動している。
Windowsのサービスは使っていない
・DLLは、「C:\Windows\System32」に置いている。
・tomcat4系(java1.4を利用)で、ServletからWindowsのDLLを使った場合に、例外になる
tomcat起動用のバッチファイルを手動で実行した場合は、問題ない(例外にならない)
・同じDLLであっても、tomcat8系(java8を利用)では、問題ない(例外にならない)。tomcat4とtomcat8の実行ユーザは同じ。
・タスクスケジューラは、最上位特権をチェックON(有効)にしても変わらず。
・DLLはSystem.loadLibraryを使って呼び出している

System.loadLibrary("Xxx"); ←dllファイルを指定(拡張子のdllなし)

tomcat4起動用バッチファイルが好ましくないんだろう・・・。

問題のあるtomcat4の起動バッチファイルの中身、抜粋

set JAVA_HOME=C:\j2sdk1.4.2_11
set PATH=%JAVA_HOME%\bin;
set CATALINA_HOME=C:\tomcat-4.1.30
set CLASSPATH=%JAVA_HOME%\lib\tools.jar;
set GC_LOG_DIR=%CATALINA_HOME%logs\

java.exe -server -Xmx512m -Xms512m -Xmn64m -Xloggc:%GC_LOG_DIR%\gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar -Duser.timezone=Asia/Tokyo -Duser.dir=%CATALINA_HOME% %CATALINA_HOME%\bin\bootstrap.jar start

エラー内容

root cause

java.lang.NoClassDefFoundError
at XxxServlet.doGet(XxxServlet.java:100)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
(略)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:199)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)

もしくは、以下のエラー


java.lang.UnsatisfiedLinkError: C:\tomcat-4.1.30\xxx.dll: Can't find dependent libraries

root cause

java.lang.UnsatisfiedLinkError: C:\tomcat-4.1.30\xxx.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at jp.co.hoge.(hogejni.java:29)
at XxxServlet.doGet(XxxServlet.java:100
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)

対処

例外のメッセージ( Can't find dependent libraries)にあるように、 tomcatのホームディレクトリからDLLをたどれていない。


set PATH=
set CLASSPATH=
に、「C:\Windows\System32」や「C:\Windows\System32\xxx.dll」を記載しても変わらずNG。


set CATALINA_HOME=C:\tomcat-4.1.30
・・・
java.exe ・・・ -Duser.dir=%CATALINA_HOME%
としているため、
C:\tomcat-4.1.30\xxx.dllにDLLファイルを配置すれば、回避できた。
けれど、これではDLLが2箇所(system32とtomcat4のホームディレクトリ)必要になる。
よって、

http://a4dosanddos.hatenablog.com/entry/2013/06/17/232839
http://qa.atmarkit.co.jp/q/2537
http://programamemo2.blogspot.jp/2008/09/javalangunsatisfiedlinkerror-xxxl-cant.html

上記のサイトを参考に、「-Djava.library.path」をjavaの実行時に指定するように
変更する


set CATALINA_OPTS=-Djava.library.path=C:\Windows\System32
java.exe %CATALINA_OPTS% -server -Xmx512m -Xms512m -Xmn64m・・・・

これで、解決。ただし、system32に、読み込ませてはいけないライブラリ等がある場合は、別の箇所に
DLLを置いて、そこをtomcat4もtomcat8も読み込む必要がでてくる。