忍者ブログ

Javaの記事一覧: Javaってまだいけますか

Javaってまだいけますか

いっぱいいっぱいで無理なので学んだ事をいちいちメモっていくブログです。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

IBMとSunのJVMのリソース使用量の違いについて

のメモ。

《背景》
IBMのDB2をインストールしたサーバでJavaアプリケーションを動かす必要がありました。
DB2をインストールすると同梱のJavaが一緒にインストールされてたので、ちょうど良いと思いそっちにパスを通してアプリを起動するように設定しました。
ところが処理負荷の高い部分でOSがフリーズしたような状態になり、サーバの電源を落とすはめに。。。

《検証》
メモリ使用量などを出力するサンプルプログラムを作成し、IBMとSunの違いを見てみました。
サンプルプログラムの参考
PR

つづきはこちら

LDAP検索

LDAPサーバへ検索条件を指定して検索を実行する場合のメモ。
基本的には、

(属性名=条件値)

のような形式でフィルタ条件を指定します。

・AND検索
(&(objectClass=Person)(cn=Babs*))


・OR検索
(|(objectClass=Person)(cn=Babs*))


・NOT検索
(!(objectClass=Person))


条件値に特殊文字を含む場合はエスケープする必要があります。
public String escape(String str) {

if(str == null) {
return "\\00";
}

// 最初に\をエスケープ
if(str.indexOf("\\") >= 0) {
str = StringUtils.replace(str, "\\", "\\5C");
}

if(str.indexOf("*") >= 0) {
str = StringUtils.replace(str, "*", "\\2A");
}
if(str.indexOf("(") >= 0) {
str = StringUtils.replace(str, "(", "\\28");
}
if(str.indexOf(")") >= 0) {
str = StringUtils.replace(str, ")", "\\29");
}
return str;
}


サンプル。
public void search(String cn) {
String filter = "(cn=*" + escape(cn) + ")";

SearchControls ctls = new SearchControls();
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

Hashtable env = getEnv();
DirContext dirContext = new InitialDirContext(env);

try {
NamingEnumeration entries = dirContext.search([baseDn], filter, ctls);

while (entries.hasMore()) {
javax.naming.directory.SearchResult entry = (javax.naming.directory.SearchResult) entries.next();

// 省略
}

} finally {
dirContext.close();
}
}

public Hashtable getEnv() {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.provider.url", "ldap://" + [LDAPサーバホスト名] + ":" + [LDAPサーバポート番号] + "/");
env.put("java.naming.security.authentication", "simple");
env.put("java.naming.security.principal", "");
env.put("java.naming.security.credentials", "");
return env;
}

参考

catch (Exception e)でErrorの捕捉が漏れる

アプリケーションで、「ここが全ての例外をハンドリングする最後の関所だ!」みたいなところで

try {

} catch (Exception e) {
// 最終ハンドリング
}


のようにしてExceptionで一括捕捉しようとすることがあるのですが、今さらながらこの場合Errorの捕捉が漏れてしまうことに気づきました。
例えば、以下のようなError。

・OutOfMemoryError
・StackOverflowError

通常、上記のErrorが発生したらもうアプリケーションではどうしようも無いですが、外部システムと連携しているシステムで困ったことがありました。

要は、

・自分とこのシステムはぜんぜん平気
・外部システムを呼び出したらOutOfMemoryErrorが帰ってきた

というようなケースでハンドリングすべき処理ができなかった、といったバグです。

こういった場合、
「外部システムを呼び出す処理においては、ExceptionとError、もしくは一括してThrowableでキャッチして、システム共通例外などに詰め込んで再スローする」
といった考慮が必要だと思いました。

あと、Throwable、Exception、Errorなどについてはこちらのブログ記事がとても参考になりました。

Unicode対応 文字コード表

文字コードが分かりやすくまとめられているサイトを見つけたのでメモ。

Shift_JIS、EUC_JP、UTF-8、UTF-16でそれぞれどのコードになるかを対比して見ることができるのでとてもいい感じです。

貴重な情報を公開していただいてとてもありがたいです。

文字コードについて

ついでにこっちもメモ。
機種依存文字について

Java SE 5/6を勉強するなら

すごく参考になったのでメモ。

java in the box

Windows + DB2でダッシュ「―」や波ダッシュ「~」や全角マイナス「-」が文字化け

Windows環境でDB2から取得したデータをファイルに書き出すという処理で、ダッシュ「―」や波ダッシュ「~」や全角マイナス「-」が含まれていたときに文字化けがおきました。

調べてみると、
問題になることが多いのはShift_JISとそのサブセット(Windows-31Jなど)とのUNICODEのコンバータです。これらのコンバータにはSJIS、MS932、 Cp943Cなどの複数のコンバータが存在し、これらのコンバータ間で文字コードマッピングが異なるために一部の文字が文字化けを起こします。
DB2ではCp943Cのコンバータを使用すれば上記の文字について文字化けを回避することできます。

とのこと。

ということで、以下のようにしたら解消しました。
System.out.println(new String(ret.getBytes("Cp943C"), "MS932"));


参考にしたサイト

JavaでString⇔16進コードの相互変換

String target = "㍼"; // 文字コードは0x878f

// Stringからコードへ
char[] buf = new String(target.getBytes("MS932"), "8859_1").toCharArray();
System.out.println(Integer.toHexString(buf[0]) + Integer.toHexString(buf[1]));
// →878f

// コードからStringへ
buf = new char[]{(char)Integer.parseInt("87", 16), (char)Integer.parseInt("8f", 16)};
System.out.println(new String(new String(buf).getBytes("8859_1"), "MS932"));
// →㍼

参考にしたサイト

クラスタ環境とセッションとSerializableの関係

お恥ずかしながら、今までSerializableについてあまり意識してませんでした。
「RMIで受け渡すオブジェクトとかでは宣言しとけばいいのかな…」ぐらいの軽い気持ちでした。

しかし、従事していたプロジェクトでこれが原因の不具合が発生してしまいました。
要はクラスタ環境で稼動しているアプリケーションで、Serializableを実装していない属性がセッション情報に格納されており、セッションレプリケーションが行なわれないという現象でした。
ローカルや検証環境ではクラスタ構成を組むことが無いので気づきづらいですよね…。

開発規約として「Serializableを実装しましょう」では弱いので、こんな感じで専用クラスを作って利用を強制する方がよいでしょうか。
(EclipseでHttpSession.setAttributeを検索すればチェックできますし。)

public class SessionManager {

/**
* セッションにSerializableを実装したオブジェクトを格納します。
*
* @param request
* @param name
* @param value
*/
public static void setAttribute(HttpServletRequest request, String name, Serializable value) {
request.getSession().setAttribute(name, value);
}

/**
* セッションからSerializableを実装したオブジェクトを取り出します。
* @param request
* @param name
* @return
*/
public static Serializable getAttribute(HttpServletRequest request, String name) {
return (Serializable) request.getSession().getAttribute(name);
}
}

テストフェーズにクラスタ環境を意識したテストをしておくことも重要ですよね。
反省。

SerializableなクラスのメンバもSerializableな必要があるようですがjava.lang.Stringやプリミティブ型のほか、Java標準のコレクションなどであれば問題ないようです。(ArrayList.subList()の戻り値など、一部例外有り)

その他参考にしたサイト

Serializableについて
Serializableについて(java API)

Tomcat5でのクラスタリングについて

ググってみるといろんな方がブログで取り上げてるので、結構みんな一回は通る道っぽいですねw

Navigation

Copyright ©  Javaってまだいけますか  All Rights Reserved.
  • 忍者ブログ
  • [PR]

menu

ブログ内検索

カテゴリー

カウンター

忍者アド

リンク

最新CM

[07/17 セバ]
[12/27 NONAME]

最新記事

(10/15)
(10/01)
(08/12)
(08/12)
(08/11)

プロフィール

HN:
takacy.k
年齢:
44
性別:
男性
誕生日:
1979/08/13
趣味:
自己紹介:
個人的なメモですので、投稿内容について真偽を保証するものではありません。また、当ブログの内容をご利用になったことによる(以下略)

最新TB

RSS

アーカイブ

アクセス解析