■
[Java]JSP実行時のエラー
Tomcatのバージョン:5.0.28
JDKのバージョン:1.5.0_02
J2EE1の課題2を終わらそうと思い、まずは教科書に掲載されている簡単なloop.jspを動かそうとしたらエラーが出てしまいましたorz
TomcatのJSPサンプルプログラムは動くのですが、loop.jspが動きません。下のエラーメッセージによるとC:\jdk1.5.0_02\jre\lib\ext\checkmmx.exeのファイルが壊れたのかも?
結局同じバージョンのJDK(1.5.0_02)を再インストールしたら直ってしまいました。再インストールする前のcheckmmx.exeをバックアップしておいたから、再現テストを行ってみよう。
ところが!
JDKを再インストールしたら、C:\jdk1.5.0_02\jre\lib\extの下にcheckmmx.exeというファイルはありませんでした。
あったのは以下の4ファイルのみ。
2005/03/04 02:43 8,176 dnsns.jar
2005/03/04 03:53 802,502 localedata.jar
2005/05/28 13:05 153,036 sunjce_provider.jar
2005/05/28 13:05 173,235 sunpkcs11.jar
何をやったときにcheckmmx.exeファイルが追加されたのだろうか。謎です。
JDK再インストール前にloop.jspを実行させたときに表示されたエラー
ype 例外レポート メッセージ 説明 The server encountered an internal error () that prevented it from fulfilling this request. 例外 org.apache.jasper.JasperException: JSPのクラスをコンパイルできません 生成されたサーブレットのエラーです: エラー: C:\jdk1.5.0_02\jre\lib\ext\checkmmx.exe の読み込みエラーです。java.util.zip.ZipException: error in opening zip file エラー 1 個 org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:84) org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:332) org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:412) org.apache.jasper.compiler.Compiler.compile(Compiler.java:472) org.apache.jasper.compiler.Compiler.compile(Compiler.java:451) org.apache.jasper.compiler.Compiler.compile(Compiler.java:439) org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:511) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:295) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236) javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
そしてloop.jspの中身
<!-- loop.jsp --> <%@ page pageEncoding="Shift_JIS" contentType="text/html; charset=Shift_JIS" %> <html> <head> <title>JSP: for 文を使ったサンプル</title> </head> <body> <% for (int i = 1; i <= 5; i++) { %> <p>サンプル<%= i %></p> <% } %> </body> </html>
抽象性をまったく考えないDBへアクセスするコード
DBの検索、挿入、更新そして削除をメインメソッドに放り込んだメンテナンス性が低いコードを書いてみた(笑)それも処理毎のメソッドも書いていない。これを元に抽象度が高いコードを書いてみたいと思います。
package jdbc3;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import static java.lang.System.out;public class DBAccess1 {
public static void main(String[] args) throws Exception {Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
PreparedStatement prst = null;try {
// HSQLDBドライバのロード
Class.forName("org.hsqldb.jdbcDriver");// DBへ接続
connection = DriverManager.getConnection(
"jdbc:hsqldb:hsql://localhost/", "sa", "");// トランザクション自動設定解除
connection.setAutoCommit(false);// 第一引数が1の場合は指定したIDで検索
if (args[0].equals("1")) {// SQL文作成
String sql_str = "SELECT id ,name FROM student where id = ?";// 第二引数をint型にしてidへ代入
int id = Integer.parseInt(args[1]);// PreparedStatementオブジェクトを作成
prst = connection.prepareStatement(sql_str);// パラメータにidを設定
prst.setInt(1, id);// idで検索した結果をresultSetに代入
resultSet = prst.executeQuery();// 検索結果を表示
if (resultSet.next()) {
out.printf("id = %d : name = %s", resultSet.getInt("id"),
resultSet.getString("name"));
} else {
out.println("idが" + id + "のデータはありません。");
}// 第一引数が2の場合は全検索
} else if (args[0].equals("2")) {// SQL文の組み立て
String sql_str = "SELECT id,name FROM STUDENT";// PreparedStatementオブジェクトを作成
prst = connection.prepareStatement(sql_str);// resultSetに検索結果を代入
resultSet = prst.executeQuery();// 検索結果を表示
while (resultSet.next()) {
out.printf("id:%d,name:%s\n", resultSet.getInt("id"),
resultSet.getString("name"));
}// 第一引数が3の場合は新規に行を登録
} else if (args[0].equals("3")) {// SQL文の組み立て
String sql_str = "INSERT INTO student VALUES(?,?)";// 第二引数をint型に変換して変数idに代入
int id = Integer.parseInt(args[1]);// 第三引数を変数nameに代入
String name = args[2];// PreparedStatementオブジェクトを作成
prst = connection.prepareStatement(sql_str);// 一番目のパラメータにidを設定
prst.setInt(1, id);// 二番目のパラメータにnameを設定
prst.setString(2, name);int result = 0;
try {
// 行を挿入
result = prst.executeUpdate();// 変更確定
connection.commit();} catch (SQLException e) {
out.println("id" + id + "既に登録済みです。");
}// 結果状況表示
if (result == 1) {
out.println("新規データ登録成功");
} else {
out.println("新規データ登録失敗");
}} else if (args[0].equals("4")) {
// SQL文の組み立て
String sql_str = "UPDATE student SET name=? where id = ?";// 第二引数を変数idに代入
int id = Integer.parseInt(args[1]);// 第三引数を変数nameに代入
String name = args[2];// PreparedStatementオブジェクトを作成
prst = connection.prepareStatement(sql_str);// 一番目のパラメータにnameを設定
prst.setString(1, name);// 二番目のパラメータにidを設定
prst.setInt(2, id);// 行を更新
int result = prst.executeUpdate();// 変更確定
connection.commit();if (result == 1) {
out.println("データの更新成功");
} else {
out.println("データの更新失敗");
}
} else if (args[0].equals("5")) {// SQL文作成
String sql_str = "DELETE FROM student where id = ?";// 第二引数を変数idに代入
int id = Integer.parseInt(args[1]);// PreparedStatementオブジェクトを作成
prst = connection.prepareStatement(sql_str);// 一番目のパラメータにidを設定
prst.setInt(1, id);// 行を実行
int result = prst.executeUpdate();// 変更確定
connection.commit();// 実行結果を表示
if (result == 1) {
out.println("削除処理成功");
} else {
out.println("削除処理失敗");
}
} else {out.println("第一引数には1から5の値を設定して下さい。");
out.println("第一引数が1の場合は、IDを指定して検索です。IDも指定して下さい。");
out.println("第二引数が2の場合は、全検索です");
out.println("第二引数が3の場合は、指定したIDと名前をデータベースに登録します。");
out.println("第二引数が4の場合は、指定したIDを持つ行の名前を更新します。");
out.println("第二引数が5の場合は、指定したIDを持つ行をデータベースより削除します。");
}} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {e.printStackTrace();
}
}if (prst != null) {
try {
prst.close();
} catch (SQLException e) {e.printStackTrace();
}
}if (connection != null) {
try {
connection.close();
} catch (SQLException e) {e.printStackTrace();
}
}}
}
}
WSDLに悪戦苦闘
definitions要素の各属性とその値
<?xml version="1.0" encoding="UTF-8"?> <definitions name="MyHello" targetNamespace="http://myhello/" xmlns:tns="http://myhello/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
definitions要素の各属性の意味がよく分かりません。特にtnsはどういう意味なのだろうか。
WSDL2JAVAの疑問
service要素のname属性の値をMyWelcomeにし、名前空間の一部を以下のように設定してWSDL2JAVAを実行したら、MyWelcome_pkgというフォルダの下にJavaのソースコードやWSDDファイルが吐き出されました。
targetNamespace="http://myWelcome/" xmlns:tns="http://myWelcome/"
targetNamespace属性とxmlns:tns属性の値をmyWelcomeと定義しているのだから、myWelcomeというフォルダの下にソースコードやWSDDファイルが生成されると予測しました。しかし実際は異なりました。
因みに出来たJavaのソースコードを開いてみるとパッケージ名がMyWelcome_pkgとなっていました。このpkgとは何なのだろうか?何故自動的にpkgと付くのだろうか?知っている人がいたら教えてくださいね。
今日のエラーその1
Welcome.wsdlファイルを作って、java org.apache.axis.wsdl.WSDL2Java -o . -s Welcome.wsdl実行後以下のエラーが発生
D:\>java org.apache.axis.wsdl.WSDL2Java -o . -s Welcome.wsdl java.io.IOException: 生成に失敗しました。 WSDLドキュメント内に未定義のbinding(WelcomeIFBinding)があります。 ヒント: <port binding=".."> が十分に適したものかどうか確認して下さい /
原因はWSDLファイルの冒頭に記載した名前空間の定義がほんの一箇所間違っていました。どこが誤りだか分かりますか?(^_^;)
ヒント:targetNamespaceのところを凝視すれば分かります。
(正) <definitions name="MyWelcome" targetNamespace="http://mywelcome/" xmlns:tns="http://mywelcome/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
(誤) <definitions name="MyWelcome" targetNamespace="http://mywelcome" xmlns:tns="http://mywelcome/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
正解:targetNamespace="http://mywelcome/"が正しくて、targetNamespace="http://mywelcome"が間違った例です。/をひとつ見落としていました(大汗)
AXISに悪戦苦闘〜結果はケアレスミス
以下のMyHello.wsdlファイルを元にしてWSDL2JAVAを実行しAXISでこのWEBサービスを実行するのに必要なファイルを生成して、deployしたらエラーが表示されました。
MyHello.wsdl
<?xml version="1.0" encoding="UTF-8"?> <definitions name="MyHello" targetNamespace="http://myhello/" xmlns:tns="http://myhello/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types /> <message name="HelloIF_sayHello"> <part name="String_1" type="xsd:string" /> </message> <message name="HelloIF_sayHelloResponse"> <part name="result" type="xsd:string" /> </message> <portType name="HelloIF"> <operation name="sayHello" parameterOrder="String_1"> <input message="tns:HelloIF_sayHello" /> <output message="tns:HelloIF_sayHelloResponse" /> </operation> </portType> <binding name="HelloIFBinding" type="tns:HelloIF"> <operation name="sayHello"> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://myhello/" /> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://myhello/" /> </output> <soap:operation soapAction="" /> </operation> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" /> </binding> <service name="MyHello"> <port name="HelloIFPort" binding="tns:HelloIFBinding"> <soap:address location="http://localhost:8080/axis/services/HelloIFPort" /> </port> </service> </definitions>
表示されたエラー
And now... Some Services
AXISエラー / [en]-(AXIS error)申し訳ありません, 何らかの誤りがあるようです... 詳細はこちら: / [en]-(Sorry, something seems to have gone wrong... here are the details:)
Fault - 名前付けされたサービスに対するクラスを見つけられませんでした: myhello.HelloIFBindingImpl
ヒント: 正しいロケーションにクラスファイル/ツリーをコピーする必要があるかもしれません(ロケーションは使用しているサーブレットのシステムに依ります) / [en]-(Could not find class for the service named: myhello.HelloIFBindingImpl
Hint: you may need to copy your class files/tree into the right location (which depends on the servlet system you are using).); nested exception is:
java.lang.ClassNotFoundException: myhello.HelloIFBindingImplAxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException
faultSubcode:
faultString: 名前付けされたサービスに対するクラスを見つけられませんでした: myhello.HelloIFBindingImpl
ヒント: 正しいロケーションにクラスファイル/ツリーをコピーする必要があるかもしれません(ロケーションは使用しているサーブレットのシステムに依ります) / [en]-(Could not find class for the service named: myhello.HelloIFBindingImpl
Hint: you may need to copy your class files/tree into the right location (which depends on the servlet system you are using).); nested exception is:
java.lang.ClassNotFoundException: myhello.HelloIFBindingImpl
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:XX-XXXXXXX
myhello.HelloIFBindingImplなのでmyhelloパッケージにHelloIFBindingImplクラスが無いですというエラー内容である。
myHelloパッケージにはHelloIFBindingImpl.classファイルはあることは確認する。
しかし動かない。
夜学にて、Yさんに以下のことを指摘される。
helloの「h」を大文字にしたディレクトリを%CATALINA_HOME%\webapps\axis\WEB-INF\classesに作っていませんか?
確かにmyHelloディレクトリーの下にHelloIFBindingImpl.classを置いていましたorz
myHelloではなくmyhelloディレクトリーの下に置いて問題解決。
ケアレスミスでした。夜学参加者の皆様お騒がせ致しました(^_^;)
WEBサービスの勉強中
WEBサービスの勉強のためにWSDLファイルを読んでいます。わかるようなわからないような。手を動かして体で技術を取得しなくては。
少々古い記事ですがAxisによるAmazon Webサービス活用記(1/4)というのを見つけました。以前かAmazon Webサービス(以下AWSと略)には興味があったのですが、どこから手をつけてよいのやら分かりませんでした(汗)
学校でもAxisを習ったことだし、それの復習のつもりでAxisとAWSを組み合わせたアプリを作るのも良いかも。
とりあえずWebサービスの課題が終わったらAxisとAWSを組み合わせて、サンプルプログラム程度で良いので作ってみたいと思います。