- PR -

Antでテストを実行すると、Class.forNameでClassNotFoundException

投稿者投稿内容
かりあげ
会議室デビュー日: 2004/06/24
投稿数: 6
投稿日時: 2007-06-26 17:40
Java初心者です。
MySQLに接続するアプリケーションを作成しています。
JUnitで作成したテストケースを、Antから実行したところ、
次の行を実行した際に、java.lang.ClassNotFoundExceptionの
例外が発生します。
Class.forName("com.mysql.jdbc.Driver").newInstance();

JUnit単体ではテストは成功するので、Antの設定(もしくはEclipseの設定?)
が悪いと考え、MySqlのjarファイルをいくつか置き場所を変えて試しましたが、
問題が解決できません。
分かる方いらっしゃいましたら、ご教授お願いします。

環境は下記のとおりです。
eclipse 3.2.1
jdk 1.5.0.0_09
junit.jar junit-3.8.1.jar ←プロジェクトのビルドパスと[Ant]→[ランタイム]のクラスパスに設定済み
mysql-connector-java-5.0.3-bin.jar ←プロジェクトのビルドパスと[Ant]→[ランタイム]のクラスパスに設定済み

---------build.xmlの抜粋です---------
<project name="jcoverage.examples" default="main" basedir=".">
<property name="build.dir" value="${basedir}/build"/>
<property name="build.classes.dir" value="${build.dir}/classes"/>
<property name="build.instrumented.dir" value="${build.dir}/instrumented-classes"/>
<property name="build.coverage.dir" value="${build.dir}/coverage"/> <property name="build.reports.dir" value="${build.dir}/reports"/>
<property name="dist.dir" value="${basedir}"/>
<property name="lib.dir" value="${dist.dir}/lib"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="cobertura.dir" value="D:/Program Files (x86)/_java/cobertura-1.9" />

<target name = "main" depends="clean,init,compile,instrument,test,coverage" description = "clean build, instrument and unit test"/>

<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>

<taskdef classpathref="cobertura.classpath" resource="tasks.properties"/>

(中略)

<target name="test" description="Unit test the application">
<junit showoutput="true" fork="yes" dir="${basedir}" errorProperty="test.failed" failureProperty="test.failed">
<classpath location="${build.instrumented.dir}"/>
<classpath location="${build.classes.dir}"/>


<classpath refid="cobertura.classpath" />

<classpath path="${basedir}/cobertura.jar"/>
<formatter type="xml"/>
<test name="${testcase}" todir="${build.reports.dir}" if="testcase"/>
<batchtest todir="${build.reports.dir}" unless="testcase">
<fileset dir="${src.dir}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
</target>

-----エラーの発生するコード部分です。-----------
public void open() {

String url = "jdbc:mysql://localhost/book";
String param = "?useUnicode=true&characterEncoding=sjis";
String usr = "mysqluser";
String pwd = "mysqluser";

// JDBCドライバーをロードする
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
// 接続を確立する
con = DriverManager.getConnection(url+param, usr, pwd);
// ステートメントを取得する
stmt = con.createStatement();
} catch (InstantiationException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
} catch (SQLException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}

}
かりあげ
会議室デビュー日: 2004/06/24
投稿数: 6
投稿日時: 2007-06-26 17:54
正確な例外メッセージを載せ忘れました。
com.mysql.jdbc.Driverが分からないと言われているため、mysqlのjarの配置の問題かと判断しています。

[junit] java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
[junit] at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
[junit] at java.security.AccessController.doPrivileged(Native Method)
[junit] at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[junit] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
[junit] at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:164)
[junit] at mybook.MySQLManager.open(MySQLManager.java:73)
 以下省略。
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2007-06-26 18:19
build.xmlの内部で定義が必要なんじゃないでしょうか。
そもそも、Ant自身の実行環境とプロジェクトの要件は、依存していない方がいいでしょうし。

配置だけで片付けたいなら、Javaランタイムのlib\extにライブラリを放り込めば、
ビルド・パスの設定すら必要なくなります。
本番環境ならともかく、開発環境ではお勧めはしませんが。
かりあげ
会議室デビュー日: 2004/06/24
投稿数: 6
投稿日時: 2007-06-26 18:31
回答ありがとうございます。
lib/extにJARを放り込んで実行しましたが、結果は同じでした。
引用:

配置だけで片付けたいなら、Javaランタイムのlibextにライブラリを放り込めば、

Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2007-06-26 18:50
SDKを入れてるんだったらsdkとjreとふたつ、ディレクトリが作られますよね。
jreに入れましたか?
引用:

lib/extにJARを放り込んで実行しましたが、結果は同じでした。


私としては、build.xmlに記述することをお勧めします。
かりあげ
会議室デビュー日: 2004/06/24
投稿数: 6
投稿日時: 2007-06-26 19:29
jdk1.5.0_09/lib
jre1.5.0_09/lib/ext
のみにファイルを入れていました。
jdk1.5.0_09/jre/lib/ext
にファイルを追加すると、エラーがなくなりました。
ご丁寧に指摘していただきありがとうございました。

build.xmlの設定のほうはこれから勉強します。
よろしければ、何をどうする設定を定義すべきなのかヒントをいただけないでしょうか?
Antも初めてなのでよろしくお願いします。

引用:

SDKを入れてるんだったらsdkとjreとふたつ、ディレクトリが作られますよね。
jreに入れましたか?

朝日奈ありす
大ベテラン
会議室デビュー日: 2007/05/02
投稿数: 189
お住まい・勤務地: 最北の地
投稿日時: 2007-06-26 19:34
他所でひろったjarは jreにいれずにクラスパス指定をし、実行しましょう。
基本は作成アプリケーション側梱包にしないと、
Javaの「一度書いたらどこでも動く」という思想がなくなってしまいます。

Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2007-06-27 10:47
自前で用意したbuild.xmlじゃなかったのか・・・。
まあ、私が勝手に決めつけただけですが。

ヒントなんて、何もしないうちから欲しがるものではありません。
junitタグもclasspathタグも、もう書いてあるんだから、すぐにわかるでしょ。
始めたばかり? んなもん関係ありません。
それよりも、最初から人頼みかそうでないかは、それこそ大違いですよ。
できるようになったら、lib\extに入れたライブラリは削除しておきましょう。

>杏氏
lib\extへ放り込むことの是非については、私は本番環境なら有りだと思っています。
システムの環境変数に追加するよりも、そちらの方を選ぶでしょう。
jarに固めてしまう場合など、ライブラリは環境の属性として扱う場合もありますし。

ただし、あくまでも本番限定です。開発環境ではお勧めはしません。

今回は、確かに軽率だったかも。今後は気を付けたいと思います。

スキルアップ/キャリアアップ(JOB@IT)