ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Java質問&情報提供サイトコミュのはじめまして、質問させてください!

  • mixiチェック
  • このエントリーをはてなブックマークに追加
卒業研究でJava+MySQLのアプリを作るために
JDBCを使ってJavaからMySQLをいじれるものを作ろうとしています。
その準備段階のものとしてちゃんとMySQLをjavaから動かせるのか
確認するために作ったものがうまく動かず困っています。
出力されるエラーと環境は以下のようになっています。

以下がそのソースです。
『mysqltest.java』
―――――――――――――――――――
import java.sql.*;

public class mysqltest {
public static void main(String[] args) {
try {
// ドライバクラスをロード
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // ODBCの場合
Class.forName("com.mysql.jdbc.Driver"); // MySQLの場合

// データベースへ接続
// Connection con =
// DriverManager.getConnection("jdbc:odbc:helloworld"); // ODBCの場合
// MySQLの場合
String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url);

// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();
String sql = "SELECT * FROM HELLO_WORLD_TABLE";
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
// 検索された行数分ループ
while(rs.next()){
// NOを取得
int no = rs.getInt("NO");
// 言語を取得
String lang = rs.getString("LANGUAGE");
// メッセージを取得
String msg = rs.getString("MESSAGE");
// 表示
System.out.println(no + " " + lang + " " + msg);
}
// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
―――――――――――――――――――――――

コンパイルするときは以下のようなコマンドを使って
コンパイルしています。
『javac -cp /usr/local/jdbc/ mysqltest.java』
コンパイル時にはエラーは出ません。

/usr/local/jdbc/ の中には以下のものがあります。
mm.mysql-2.0.14-bin.jar
mysql-connector-java-3.1.11-bin.jar

この状態で
『java mysqltest』を実行すると
以下のようなエラーが出力されます。
―――――――――――――――――――
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at mysqltest.main(mysqltest.java:8)
―――――――――――――――――――
エラーの1行目の「java.lang.ClassNotFoundException: com.mysql.jdbc.Driver」は
クラスが無いことをあらわすエラーであることは
なんとなくわかっているのですが
パスも通しているしどうしてこのエラーが出るか
わからない状態にあります。

もしわかる方がいらっしゃいましたらご教授お願いします。
よろしくおねがします。m(_ _)m

他にもエラーの原因になりえる箇所があり
それに気付いてないこともあると思うので
「ここの設定はどうなってる?」というようなことがありましたら
それもよろしくお願いします。

コメント(19)

man javaに書いてあるクラスパスの記述は確かにわかりにくいので、
下記のようにいろいろ試してみると、通ると思います。
ディレクトリだけでなくjar本体を指定してあげないと読み込まれない事はよくあります。

java -cp /usr/local/jdbc/ mysqltest;
java -cp /usr/local/jdbc/:$CLASSPATH mysqltest;
java -cp /usr/local/jdbc/mysql-connector-java-3.1.11-bin.jar mysqltest;
java -cp /usr/local/jdbc/mysql-connector-java-3.1.11-bin.jar:$CLASSPATH mysqltest;
・・・
>きよさん
早速質問に答えていただきありがとうございます。
当方、JAVAのことはわからないことだらけなので
具体的にコマンドを書いていただけるととても助かります!

今、外に出ててるので家二帰ってやってみようと思います。
ありがとうございました!
>きよさん
実行の際に読み込むクラスのパスを通してあげないといけないことに
全然気付いていませんでした。。。

教えていただいた4つのコマンドの中の一番最後の
コマンドを実行したところクラスが無いという旨のエラーは
出なくなりました!本当にありがとうございます!!



教えていただいた4つのコマンドの中の一番最後の
『java -cp /usr/local/jdbc/mysql-connector-java-3.1.11-bin.jar:$CLASSPATH mysqltest』
を打ったとき、以下のようなエラーが吐き出されました
――――――――――――――――――――――――
java.sql.SQLException: null, message from server: "Host 'localhost.localdomain' is not allowed to connect to this MySQL server"
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:991)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2544)
at com.mysql.jdbc.Connection.<init>(Connection.java:1474)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:193)
at mysqltest.main(mysqltest.java:15)
――――――――――――――――――――――――

上に書いた「クラスが見つからない」というエラーではなく
「MySQL」との接続に失敗している旨のエラーが出ているようです。

そこで問題になってきているのが
ソースの中の
『 String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";』
の部分であると、推測しています。

しかし、この部分で書かれているものがいったい何を表しているのか
Googleで検索しても
細かく説明しているところがありません。。。

http://ueno.cool.ne.jp/shirokaze185/java-jdbc.html
↑にかろうじてOracleの場合の説明はあったのですが
mysqlの記述の方法が書いてありません・・・

『jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS』
をどのように記述すればうまく接続されるでしょうか。
ご教授よろしくおねがいしますm(_ _)m

上のURLのサイトで紹介されているOracleの記述方法では
ユーザー名とパスワードを使ってアクセスする記述方法が
紹介されています。
MySQLの場合にもそれがあるのでしょうか。
もしあるならその方法もぜひ教えていただきたいと思います。
よろしくおねがいします。

たびたび質問して申し訳ないです・・・
>「MySQL」との接続に失敗している旨のエラーが出ているようです。

みたいですね。
DBはどのユーザで作成したものなのか等詳細は分かりませんが、hellodbということで以下で作ったものなのかな。

mysqladmin -u root create hellodb

それであれば、

Connection con = DriverManager.getConnection(url,"root","");

にしてみてください。
mySql時もDriverManager.getConnection(url, user, pass)でよかったと思います。
String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS&user=接続するユーザ名&password=パスワード";
でいけるんじゃないでしょうか?どうですか、ちょっと自信ないですが
あと、MySQLのバージョンはいくつですか?
4.0だといけるんじゃないかな〜
がぶ飲みさん、テステスさん
とても親切に回答していただきありがとうございます。

>がぶ飲みさん
MySQLはセキュリティ面を考えてパスワードナシでMySQLを使えるユーザーを削除し
rootユーザーにパスワードをつけた状態になっています。
具体的には↓のサイトで紹介されている方法をやりました。
http://www.y-min.or.jp/~nob/FreeBSD/MySQL.html
ちなみにOSはFreeBSDではなくDebianを使っています。

なので『mysqladmin -u root create hellodb 』
ではなく
『mysqladmin -u root -p create hellodb 』を打って
rootのパスワードを入力して「hellodb」を作成しました。

そして以下のように教えていただいた通りソースを書き換えてコンパイルして実行したところ以下のエラーが出力されました。
―――――――――――――――――――――――――――
String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"root","****");
―――――――――――――――――――――――――――
java.sql.SQLException: null, message from server: "Host 'localhost.localdomain' is not allowed to connect to this MySQL server"
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:991)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2544)
at com.mysql.jdbc.Connection.<init>(Connection.java:1474)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at mysqltest.main(mysqltest.java:17)
―――――――――――――――――――――――――――


>テステスさん
mysqlのバージョンは『4.0.24』を使っています。
テステスさんに教えていただいた書き方で
――――――――――――――――――――――――――
String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS&user=root&&password=****";
――――――――――――――――――――――――――
↑のように書き換えてコンパイル後実行したところ
以下のエラーが出力されました。。。
――――――――――――――――――――――――――
java.sql.SQLException: null, message from server: "Host 'localhost.localdomain' is not allowed to connect to this MySQL server"
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:991)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2544)
at com.mysql.jdbc.Connection.<init>(Connection.java:1474)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:193)
at mysqltest.main(mysqltest.java:21)
――――――――――――――――――――――――――


初歩的な質問にもかかわらず親切に答えていただいてありがとうございます。
m(_ _)m

『jdbc:mysql:///hellodb』の記述はこれで正しいでしょうか?
ユーザー名とパスを入力してもエラーメッセージが大きく変わらないところを見ると
ここの記述が間違っていそうな気がします。
ご指摘よろしくお願いします。
MySQLは同じサーバで動作していて、ポート番号は3306でしょうか?その場合は下記のようにしてみてください。

jdbc:mysql://localhost:3306/hellodb?useUnicode=true&characterEncoding=SJIS
上記ですが、もちろん&user=root&&password=****も必要です
>きよさん
再度質問に答えていただきありがとうございます。
早速教えていただいた方法で実行してみました。

考えられるものとして3つの方法を試しましたがどれも同じでした。
以下がその試したソースです。

――――――――――――――――――――――――――
//方法1
String url = "jdbc:mysql://localhost:3306/hellodb?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"root","****");

//方法2-1
String url = "jdbc:mysql://localhost:3306/hellodb?useUnicode=true&characterEncoding=SJIS&user=root&password=****";
Connection con = DriverManager.getConnection(url);

//方法2-2
String url = "jdbc:mysql://localhost.localdomain:3306/hellodb?useUnicode=true&characterEncoding=SJIS&user=root&password=****";
Connection con = DriverManager.getConnection(url);
――――――――――――――――――――――――――

ポートに関してはデフォルトのままで
「my.cnf」内を確認したところ間違いなく3306でした。
パスワードも
「mysql -u root -p hellodb」コマンドを打って
パスワードを要求してくるので、そこにソース中に書いている
パスワードを打てばちゃんとMySQLのコマンドツールへと
移行します。なのでパスワードが間違っているということもなさそうです。

出力されるエラーは上で書いたものとまったく同じものが出力されてしまいます・・・


何が原因なのかまったくわからない状態です。
JDBCを利用する場合はMySQL側に特別な設定等が必要なのでしょうか?

当方まったくMySQLも初心者なので、当たり前のこともしていない可能性があります。。
「ここはどうなってる?」とういうような点がありましたら
どうかご指摘ください。

よろしくお願いします。
m(_ _)m
下記のように実行すると、正しく
| root | localhost.localdomain | |
という行はありますか?なければ
mysql> grant select on *.* to root@localhost.localdomain;
としてみてはいかがでしょうか。

[root@localhost ~]# mysql
mysql> use hellodb
Database changed
mysql> select User,Host,Password from user;
+------+-----------------------+----------+
| User | Host | Password |
+------+-----------------------+----------+
| root | localhost | |
| root | localhost.localdomain | |
| | localhost | |
| | localhost.localdomain | |
+------+-----------------------+----------+

http://web.arena.ne.jp/suitepro/support/manual/serveradmin/monitor.html
>きよさん
何度も質問に答えていただいて感謝しております。
本当にありがとうございます。

MySQLのコマンドも丁寧に書いていただいて
とても助かります。


上のコマンド
「mysqladmin -u root create hellodb 」
で作成したデータベース「hellodb」で
mysql> use hellodb
Database changed
mysql> select User,Host,Password from user;
『ERROR 1146: Table 'hellodb.user' doesn't exist』
というエラーが出力されてしまいました。。

なので、hellodbを使うのをやめて
もともとある「mysql」を使って進めていくことにしました。

なので、教えていただいたコマンドを使って
mysql> use mysql
Database changed
mysql> select User,Host,Password from user;
と打ったところ

上で示していただいた
| root | localhost.localdomain | |
が存在しました。

なのでソース中も書き換えて

――――――――――――――――――――――――――
//方法1-1
String url = "jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"root","****");

//方法1-2
String url = "jdbc:mysql://localhost.localdomain:3306/mysql?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"root","****");


//方法2-1
String url = "jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=SJIS&user=root&password=****";
Connection con = DriverManager.getConnection(url);

//方法2-2
String url = "jdbc:mysql://localhost.localdomain:3306/mysql?useUnicode=true&characterEncoding=SJIS&user=root&password=****";
Connection con = DriverManager.getConnection(url);
――――――――――――――――――――――――――

先のアドバイスで教えてもらった標記方法の
4通りを全てためしてみました。

しかし以下のようなエラーが出ました。

――――――――――――――――――――――――――
java.sql.SQLException: Access denied for user: 'root@localhost.localdomain' (Using password: YES)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2926)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:771)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1229)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2544)
at com.mysql.jdbc.Connection.<init>(Connection.java:1474)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
at java.sql.DriverManager.getConnection(DriverManager.java:525)
at java.sql.DriverManager.getConnection(DriverManager.java:171)
at mysqltest.main(mysqltest.java:22)
――――――――――――――――――――――――――

今までのエラーと違い
「コネクションしてるんだけど拒否される」という内容の
エラーが出力されるようになったので少しずつ前に進んでいることは
実感しているのですが、パスワードは違っていないのに
なんで接続を拒否されるのかわかりません・・・

まだMySQL側の設定に問題がありますでしょうか?

ご教授よろしくおねがいします。
m(_ _)m
上記はroot@localhost.localdomainがパスワードを使用しない設定で登録されているためだと思います。

mysql> set password for root@localhost.localdomain=password('****');

等として、パスワードを使用するように設定するといいのではないでしょうか。

http://www.atmarkit.co.jp/flinux/rensai/mysql03/mysql03b.html
>きよさん

ご指摘のとおりでした!
まさに上で教えていただいた
『mysql> set password for root@localhost.localdomain=password('****'); 』
を実行してみたらエラー文が
――――――――――――――――――――――――
java.sql.SQLException: Table 'mysql.HELLO_WORLD_TABLE' doesn't exist
――――――――――――――――――――――――
のように変わりました!

これはDBとのコネクションが確立しているが
テーブルが無いという趣旨のエラーですよね。

なので、あとはDBにテーブルを作る方法などは
いくらでもネットに出ているので、それを見ながら
がんばろうと思います。


初歩的な質問にもかかわらず
丁寧に最後までご指導いただきありがとうございました!

またこちらのコミュニティでお世話になるかもしれません。
そのときもよろしくおねがいします!
m(_ _)m

ほんとうにありがとうございました!!
再び問題に直面したので、また質問させてください・・・。


上で教えていただいたことを参考に
データベースからデータを持ってきて表示することに
成功しました。ありがとうございました。

しかし、新たなエラーが出てきてしまいました。。

以下のソースを実行したところ
―――――――――――――――――――――――
import java.sql.*;

public class mysqltest {
public static void main(String[] args) {
try {
// ドライバクラスをロード
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // ODBCの場合
Class.forName("com.mysql.jdbc.Driver"); // MySQLの場合

//「MySQL」へ接続
String url = "jdbc:mysql:///mysql?useUnicode=true&characterEncoding=SJIS";
Connection con = DriverManager.getConnection(url,"root","****");

//オートコミットの解除
con.setAutoCommit(false);

// ステートメントオブジェクトを生成
Statement stmt = con.createStatement();

//tableの内容を表示
ResultSet rs = stmt.executeQuery("SELECT * from list");
// 5.結果の出力
while (rs.next()) {
System.out.print("|");
System.out.print(rs.getString("NAME"));
System.out.print("|");
System.out.print(rs.getString("MAIL"));
System.out.print("|");
System.out.print(rs.getString("DATA"));
System.out.println("|");
}



//テーブルにデータを入力
String sql = "INSERT INTO list (NAME,MAIL,DATA) " +
"VALUES('tarou','tarou@mail.com','tarou_data')";

int recode_num = stmt.executeUpdate(sql);
con.commit();


// データベースから切断
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
―――――――――――――――――――――――


以下のような結果が出力されました・・・。
―――――――――――――――――――――――
|user1_name|user1@mail.com|user1_data|
|user2_name|user2@mail.com|user2_data|
java.sql.SQLException: Access denied for user 'root'@'localhost.localdomain' to database 'mysql'
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2926)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1666)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2972)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2902)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:929)
at mysqltest.main(mysqltest.java:44)
―――――――――――――――――――――――


ちなみにlistテーブルの中身は
―――――――――――――――――――――――
+------------+----------------+------------+
| NAME | MAIL | DATA |
+------------+----------------+------------+
| user1_name | user1@mail.com | user1_data |
| user2_name | user2@mail.com | user2_data |
+------------+----------------+------------+
―――――――――――――――――――――――



見ていただければわかるとおり
「select * from list」でDB内のものを参照できるのに
「INSERT INTO list」によるDB内への登録がなぜか
『Access denied』となります。。。


「Select * from list」のほうにもエラーが出るなら
設定がおかしかったりパスワードの設定の仕方が違うなどが
考えられますが。Selectがうまく動いてInsertが動かないのは
何が原因か検討がつきません・・・


だれかわかる方がいらっしゃいましたら
ご教授よろしくお願いします。。m(_ _)m

「ここの設定はどうなってる?」みたいなことがあれば
気軽に聞いてください!
MySQLのコミュニティで、教えていただき
解決することができました。

おさわがせしました・・・m(_ _)m
"jdbc:mysql:///mysql?useUnicode=true&characterEncoding=SJIS";
の部分を直したら直ったのではないでしょうか。気づくのが遅れてしまいました。
メッセージを送ってもらえれば早めに回答できると思います。
>きよさん
ホントに親切にしていただいてありがとうございます!

実はMySQLの勉強不足で

『grant insert on *.* to root@localhost.localdomain; 』

としていなかっただけでした・・・^^;


『grant select on *.* to root@localhost.localdomain; 』
のコマンドで全ての権限をroot@localhost.localdomainへ与えると
勝手に思い込んでたのがそもそもの間違えでした^^;

お恥ずかしい限りです。。


『"jdbc:mysql:///mysql?useUnicode=true&characterEncoding=SJIS";』は
明示的に「localhost:3306/」と書くことと「/」が
ローカルのDBに接続する場合には同じ扱いになるということも
いろいろ調べててわかりました。
(感覚的にそう理解したんですがもしかしたら違うかも・・・)

無知なので「localhost:3306/」とやってて良かったと思います。
おかげで雰囲気がわかったので。

また、何かあったらよろしくお願いしますm(_ _)m
ちなみに上記だとinsertとselectのみなので、普通はいきなり
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON...
とした方がよいかもしれませんね
なるほど!
>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON...
とすることで、一般的な権限を全て与えることができますね!

カナリ賢くなれた気がします(´ー`)
細かいところまでありがとうございます!

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Java質問&情報提供サイト 更新情報

Java質問&情報提供サイトのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング