Skip to main content

9 posts tagged with "Exception"

View All Tags

Android: "Unable to open sync connection!" の対処例

· One min read
Yu Sasaki
Enterprise Security Manager / Advisor

上記のメッセージはAndroidアプリをEclipseから実機でデバッグする際にDDMS上に出力されたエラーです。

[2010-06-05 15:16:21 - pokeca] Failed to upload pokeca.apk on device '11223344'
[2010-06-05 15:16:21 - pokeca] java.io.IOException 発生: Unable to open sync connection!
[2010-06-05 15:16:21 - pokeca] Launch canceled!

根本原因は不明ですが、対処として下記の手順を試みると解決しました。

  1. コマンドライン上でadb kill-server
  2. Android端末の接続を解除する(USBケーブルを抜く)
  3. コマンドライン上でadb start-server
  4. Android端末をUSBで再接続する。
  5. DDMSで端末が正常に接続されているか確認する。
  6. アプリのデバッグを開始→正常に実行される(OK!)。

コマンド

C:\Users\yukun>adb kill-server
C:\Users\yukun>adb start-server
* daemon not running. starting it now *
* daemon started successfully *
C:\Users\yukun>

5の実行結果

Android端末のUSB接続確認

参考サイト

  • anddev.org • View topic - Unable to open sync connection!

Java, Servlet: No suitable driver found for "~" の原因と解決法

· One min read
Yu Sasaki
Enterprise Security Manager / Advisor

事象 - NullPointerException on java.sql.Connection

JDBCを用いてServletからMySQLのテーブルへアクセスする過程で、DriverManager.getConnectionメソッドの呼び出しの後、NullPointerExceptionが送出された(アプリケーション・サーバーはTomcat)。

<前略>
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("<sql文>");
<後略>

tomcat_error_nullpointer

原因 - No suitable driver found for "~"

デバックトレースを行ったところ、No suitable driver found for "~"というメッセージが出力されていた。JDBC Driver のクラスパスを設定していなかった為、今回のエラーが発生した。

対策 - JDBC Driverのクラスパス設定

JDBC Driver ファイル(.jar)をクラスパスに追加する。Eclipse上での設定方法は「実行」→「実行の構成」から「クラスパス」タブ内の「ユーザー・エントリー」を選択、「外部JARの追加」ボタンから、Driverを設定する。

雑感

ありがちー、なミスをしてしまったー。

Python: ファイル読み込み時の例外の扱い例 - try、except、else、finallyブロック

· 4 min read
Yu Sasaki
Enterprise Security Manager / Advisor

ファイルのパスや名前のミス、パーミッションの権限が無い等が原因でファイルを読み込めない場合がある。そのような場合、すなわち例外が発生した際にそこで処理を中断して、発生した例外に合わせた処理ブロックにジャンプする構文が、try:~except Error:~構文。 今回は、コマンドライン引数で英文テキストファイル名を指定し、スクリプト内でファイル内容を読み込み、単語数をカウントし出力するスクリプトを以って、オプションのelse、finallyブロックを含めた例外ブロックの扱いを確認する。 ただし、ここでの「単語」とは、簡単に考える為、1つの空白文字で区切られた文字列とする。

ソースコード

# -*- coding: UTF-8 -*-
import sys
script_name = sys.argv[0]
try:
arg = sys.argv[1]
f = open(arg, 'r')
except IndexError:
print 'Usage: %s TEXTFILE' % script_name
except IOError:
print '"%s" cannot be opened.' % arg
else:
print arg, 'contains', len(f.read().split(' ')), 'words.'
f.close()
finally:
print 'n"%s" process end.' % script_name
quit()
print 'Not reach this line.'

コードの説明

tryブロック

まず、例外を発生させる恐れのある行は、tryブロック内に書く。 ここで発生する可能性がある例外はコマンドライン引数が格納されているリストへのアクセス部分であるsys.argv[1]。[]演算子で存在しない要素を参照する例外。また、ファイルを開くopen(arg, 'r')も冒頭の理由で例外発生の可能性もある。

exceptブロック

exceptブロックは、tryブロックで例外が発生した場合にのみ実行されるブロックです。その為、例外が発生しない場合は実行されない。 発生する可能性のある例外のタイプ毎にexceptブロックを書けば、そのタイプ毎の例外への対処処理を書くことが出来る。

except TYPE_AError:
TYPE_AErrorが発生した際のとある処理...
except TYPE_BError:
TYPE_BErrorが発生した際のとある処理...

elseブロック (オプション)

elseブロックは全てのexceptブロックの後に書く(任意なので書かなくても構わない)。 elseブロックはtryブロックで例外が発生しなかった場合にのみ実行されるブロック。今回は、ファイルの読み込みとクローズに使用している。

finallyブロック (オプション)

finallyブロックはtryブロックで例外が発生するしないに関わらず実行されるブロック(任意なので書かなくても構わない)。

実行結果

読み込むテキストファイルを以下の_aLine.txt_とする。 aLine.txt

Unless I set the standard where I am in any level, I'll be puzzled about what I should do from now on.

コマンドラインで適切な引数を与えた場合

$ python excp01.py aLine.txt
aLine.txt contains 22 words.
"excp01.py" process end.

存在しないファイル名を引数を与えた場合

$ python excp01.py texfile.tex
"texfile.tex" cannot be opened.
"excp01.py" process end.

コマンドライン引数を与えなかった場合

$ python excp01.py
Usage: excp01.py TEXTFILE
"excp01.py" process end.

例外オブジェクト名をpython処理系に聞いてみる

どんなメソッドや関数、演算子が、どのような例外を投げるのか予測が付かない場合もある。そんな場合、一旦はスクリプトを実行してエラーを確認する。 SyntaxError: invalid syntax以外のエラーがある場合、例えば、

$ python excp01.py
Traceback (most recent call last):
File "excp01.py", line 5, in
arg = sys.argv[1]
IndexError: list index out of range

のような場合は、最終行の行頭のIndexErrorが例外名となる。

何でも例外任せにしていいの?

計算量が増える為、良くない。今プログラムのコマンドライン引数の確認を、 if len(sys.argv) != 2: ホニャララ とすると整数の比較ですむが、例外のキャッチに任せると、例外インスタンスを生成し送出という計算量の大きい処理が掛かる。ネットワーク接続やファイル読み書きなどのIOでは例外はイベント駆動で発生する為、例外制御が必須ですが、それ以外では使用しない。

ドキュメント

java.io.StreamCorruptedExceptionが発生した原因とその解決策の一例

· 3 min read
Yu Sasaki
Enterprise Security Manager / Advisor

以前というかこの頃Javaで簡単な分散処理サーバ・クライアントシステムのモデルを実装中にこのjava.io.StreamCorruptedExceptionという例外が発生。

StreamCorruptedExceptionの発生原因

結論から言えば、恐らく実行中のスレッドの数がマシンスペックに対して多すぎたのではないかと推定(推定どまり)。 サーバが複数のクライアントを受け付けるので、クライアントのソケット接続(accept時)毎にスレッドを生成する方法を採った。この時はブロッキング型のモデル(この頃ノンブロッキング型は知らなかった)。 例外の発生状況はサーバプログラムをテスト動作時、絶えず約1000クライアントからのリクエストを受け付け、かつレスポンス等を行った場合。なお送受信データはシリアライズされたオブジェクトで、サイズは平均5KB。その時テストマシンで走らせたスレッド数が約5000。 シリアライズの復元の問題かと考えたが、送受信するオブジェクトのクラスとそのserialVersionUIDは揃えており、500クライアント位ではこれといった異常なく動作していた。 実際にある時間のクライアントの送信データ数とサーバの受信データ数を確認してみたら、両数値の差が生じていて、約200リクエストがソケット部分で溜まったところでダウンしました。 スレッド数が多いと、その分スレッドの切り替えが頻発したり、待たされるスレッドが出てくる。その為、ソケットの部分で受信データが許容量以上に溜まって、I/Oのどこかがオバーフローか変になった可能性もある。

例外発生時のスタックトレースの一部抜粋

java.io.StreamCorruptedException: unexpected reset; recursion depth: 1
at java.io.ObjectInputStream.handleReset(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.skipCustomData(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)

また、これ以外にOptionalDataExceptionという例外も併発しましたが、これも同じ原因かと推定。

java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)

試した解決策

スレッド数を抑える

これは解決策とは言えないが、マシンスペック(CPU[コア]数やクロックなど)に対してスレッド数が多すぎるのが問題だと推定したので、ある程度スレッド数を抑えて運用したところ例外は発生しなくなった。

もう一度接続しなおす

例外をtry-catchブロックでキャッチできるので、それに合わせて接続しなおしてリクエストorレスポンスを再送することで一時対処した。

ノンブロッキング型にする

nio(New I/O)ライブラリが用意されているので、それを用いたノンブロッキング型の機構にして、スレッドプールを用意することでスレッド数やコンテキストスイッチ、オーバヘッドをある程度抑えることが可能と考えるが、まだ未検証。 どちらにせよ、根本原因の究明にはkernel dump等の情報を取って解析していく必要がある。。。

Python: 文字列の検索 - index()、reindex()メソッド

· 2 min read
Yu Sasaki
Enterprise Security Manager / Advisor

ソースコード

#!/usr/bin/python
# coding: UTF-8
# 文字列の検索 | index(), reindex()の使い方
s1 = 'Hello, Jan !'
# 引数(パターン)が1文字の文字列
try:
i = s1.index('l') # 引数で与えられた文字列を先頭から探索した場合の出現位置を返す
except ValueError:
i = None # 存在しない場合は例外ValueErrorがなげれられる
print i, s1[i]
try:
i = s1.rindex('l') # 末尾から探索した場合の最初の出現位置を返す
except ValueError:
i = None
print i, s1[i]
print
# 引数(パターン)が2文字以上の文字列
str = 'lo'
try:
i = s1.index(str)
except ValueError:
i = None
print i, s1[i]
try:
i = s1.rindex(str)
except ValueError:
i = None
print i, s1[i]
print
# 引数で与えられた文字列(パターン)が存在しない場合
try:
i = s1.index('Max')
except ValueError:
i = None
print i

実行結果

2 l
3 l
3 l
3 l
None

リファレンス

チュートリアル

Python: モジュールにテスト関数を定義 - 重複のない乱数(整数MIN以上MAX以下)の生成

· 2 min read
Yu Sasaki
Enterprise Security Manager / Advisor

ソースコード

#!/usr/bin/python
# coding: UTF-8
import random
def make_randint_list(min, max, cnt, sortflag=False, revflag=False):
"""
重複のない乱数(整数min以上max以下)を要素としたリストを返す
"""
list = []
i = 0
while cnt != i:
r = random.randint(min, max)
try:
list.index(r) # 既にリストに存在するか
except ValueError, e:
list.append(r) # 無い場合はリストに格納
i = i + 1
if (sortflag): list.sort(reverse=revflag)
return list
def _main():
"""モジュールのチェック関数"""
print 'makerand0.py [_main()]'
print make_randint_list(10, 99, 10)
print make_randint_list(10, 99, 10, True) # 昇順ソート
print make_randint_list(10, 99, 10, True, True) # 降順ソート
if __name__ == '__main__' : _main()
#

モジュール変数__name__の中には通常はモジュール名が入っています。しかし、このモジュールファイルを直接実行した場合は__name__に'__main__'という名前が入ります。その為、if __name__ == '__main__' : は真となり_main()が実行されます。

実行結果

$ python makerand0.py
makerand0.py [_main()]
[62, 18, 55, 44, 97, 67, 87, 16, 59, 43]
[11, 13, 30, 42, 46, 52, 71, 75, 81, 92]
[88, 81, 65, 60, 57, 53, 41, 34, 27, 23]

モジュールテスト用スクリプト

makerand0_test.py

#!/usr/bin/python
# coding: UTF-8
from makerand import make_randint_list
print make_randint_list(10, 99, 10)
print make_randint_list(10, 99, 10, True)
print make_randint_list(10, 99, 10, True, True)

実行結果

$ python makerand0_test.py
[52, 44, 63, 61, 50, 66, 88, 45, 99, 57]
[15, 26, 29, 53, 56, 69, 89, 91, 94, 95]
[96, 95, 93, 88, 79, 75, 64, 62, 33, 11]

リファレンス

チュートリアル

java.lang.OutOfMemoryErrorが発生する原因とその解決法の一例

· One min read
Yu Sasaki
Enterprise Security Manager / Advisor

JVMがGCを行えるように、開放するインスタンスへの参照を切っていたのだけれど、なぜか例外が投げられ続けていました。色々調べてみたら、java.io.ObjectOutputStream#writeObject(Object obj)の部分で、書き出されたobjの状態が保持され続けるので、いつまでたってもGCが始まらなかったのが原因でした。 解決法は、java.io.ObjectOutputStream#reset()メソッドでストリームが保持している状態を無効にすることで、不要インスタンスをGCの対象に入れることでした。

JavaとRubyで文字列の終端の扱いの違い

· 2 min read
Yu Sasaki
Enterprise Security Manager / Advisor

RubyのコードをJavaに書き直す際に注意する相違点が幾つかあったので、そのうちの一つを挙げてみます。特に文字列関係は色々やりにくいです。

a = "4321"
p a[4] #=> nil

Rubyでは文字を[]で指すとき終端文字の次の添え字を指すとnilを返します。これをCで言う文字列の終端文字'\0'のように考え、if文などの判定に用いることが出来ます。

対して、Javaで同じような書式で書こうものなら、

public class Test {
public static void main(String[] args) {
String str = "abcdef";
char[] arr = str.toCharArray(); // String型をchar型の配列に変換
System.out.println(arr);
System.out.println(str.length()+ " == " + arr.length);
try {
System.out.println(arr[6]);
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.out.println("キャッチ:" + e);
- }
try {
System.out.println(str.charAt(6));
} catch (java.lang.StringIndexOutOfBoundsException e) {
System.out.println("キャッチ:" + e);
}
// 最後の文字を知るためには
System.out.println(str.charAt(str.length() - 1));
}
}

のように例外でキャッチしなければなりません。

実行結果

6 == 6
abcdef
キャッチ:java.lang.ArrayIndexOutOfBoundsException: 6
キャッチ:java.lang.StringIndexOutOfBoundsException: String index out of range: 6
f

まぁ、str.length()を用いて文字列長でcharAtで指す文字が文字列の末尾かどうかを判定することで制御すればよいまでの話かもしれません。

今回はとあるアルゴリズムを移植上、気づきが色々あったのでこうした機会に言語仕様に対する理解を深めていきたいです。