2009年06月29日

[java]恐怖文字コード

javaでもっとも怖がられているものが文字コード。
初心者キラーでもあり、見えない悪魔となって熟練者にも襲いかかる。

面白い事象を発見した。
SJISのbyteデータをStringコンストラクタを使ってデコード時、
未割当のコードポイントを使うと動作が( ゚Д゚)ハァ?

前提知識として、
 ・"SJIS" エイリアスは Shift_JISにマップしなおされた
  (JDK1.4〜)
 ・普段使っているコードはMS932(windows)、これは
  Windows-31Jからマップされている。
 
 http://www.ingrid.org/java/i18n/encoding/shift_jis.html

 ・Shift_JISの2バイトコードの空間は、
  第1バイトが81-9FならびにE0-FC、
  第2バイトが40-7Eならびに80-FCである。

 http://ja.wikipedia.org/wiki/Shift_JIS

これらをふまえた上で、コードポイントの外の文字を変換してみる。
例えば8B7F。MS932でも未割当である。
http://www.microsoft.com/globaldev/reference/dbcs/932/932_8B.mspx

しかし、結果はおぞましいことになる。
code1.jpg

エイリアスがShift_JISに相当してしまうとマトモな文字になる( ゚д゚)
しかもこれは次のコード(8B80 朽)

もっとおぞましいこともある。
上図はSunJDKだが、
code1_java.jpg

これを、IBMJDKで実行すると・・・
code2_java.jpg
code2.jpg


(´Д` )イェァイェァイェァイェァスーン( ゚д゚)ハッ!
HPとかのでも試してみたいが環境が無い。
てゆーかね、このSunの挙動はバグっぽくないか?

環境お持ちの方は続きにソースを貼り付けしておくので
その目でお確かめくださいな。

 ソースコード
posted by koteitan at 14:58| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2009年06月03日

JVMの時刻

ややこしいのでメモ

・普通OSは起動時に時計チップから時刻をもらい、
 以後CPUのticktimeをつかって時刻を計算する。(OS依存)
 毎回、時計のIOを叩くと重すぎるわけで。
時計の石の時刻=OS時刻
 ただし、OS起動後石の時刻とOSの時刻は合っているとは限らない。

・NTPデーモンや、Dateコマンドではその時計とIOして
 H/W上の時刻とOSの時刻が一致する(こともある)
 OS依存だと思う。極端な話、シャットダウン時に合わせるなど
 すきに実装できるとおもわれ。

これが大前提だとして、

・JVMは起動時にJVM内部時計を合わせる。
・System.currentTimeMillis()の内部ソースはJVMに依存している。

openなJVMソースを検索してみたところ以下がヒット
http://cacao.sourcearchive.com/documentation/0.97/builtin_8c-source.html


02624 s8 builtin_currenttimemillis(void)
02625 {
02626 struct timeval tv;
02627 s8 result;
02628
02629 if (gettimeofday(&tv, NULL) == -1)
02630 vm_abort("gettimeofday failed: %s", strerror(errno));
02631
02632 result = (s8) tv.tv_sec;
02633 result *= 1000;
02634 result += (tv.tv_usec / 1000);
02635
02636 return result;
02637 }


毎回APIコール=OSと同じ

・以下の確認プログラムを実行し、OSの時刻を変えてみたところ
 即反映される。(windows IBMJDK1.5 IBMJDK1.4 Sun 1.4.2 Sun5.0)



import java.util.*;

public class hoge{
public static void main(String[] s)
{
while(true)
{
System.out.println(new Date());
try{Thread.sleep(1000);}catch(Exception e){}
}
}
}



・HP-UXのJVMはOSのように起動時の時刻+CPUTickTimeで計算する。
 なぜなら、APIコールが減るため高パフォーマンスだから。
 ただし、NTPなどによりOS時刻とずれる可能性がある。

・従来(新式?)の方式(毎回APIコール)を用いるには
 -XX:+UseGetTimeOfDay オプションを付ける。

 (´Д`) HP-UXのマニュアルの日本語が理解できない。
 おれはもうダメかもしれん。新か旧かどっちなんだよ。

 http://docs.hp.com/ja/5589/p02.html#50

・Sunのオプションには無いのでHP-UX固有じゃね?
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

・HP-UXは試せる環境ナッシングなのでよくわからん、と。

参考
■[program]java -XX:+UseGetTImeOfDay
http://d.hatena.ne.jp/nekora/20071113/p3

 
posted by koteitan at 16:42| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2009年02月17日

[Java]SSL通信のカスタマイズ

備忘録。

オレオレ証明書などで、
java.io.IOException : HTTPS hostname wrong:should be )
等と出る場合、証明書に記載されているhost名と通信先の名前が
異なるというわけだ。
この場合、クライアント側(Javaクライアント)を触れる環境なら、
ホスト名認証をバイパスさせることで、乗り切ることができる。
(セキュリティ的観点で見て、バイパスしても良いかは慎重に判断すること)
こんなコードを通信前に入れておく。

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String host, SSLSession ses) {
return true;
}
});

無名クラスで、デフォルトのホスト認証処理を書き換えてしまうわけだ。
カスタムな処理がしたければ、ここにロジックを入れればよい。

クライアント側がいじれない場合、そらー証明書が悪いんだから、
証明書を直すしかないな。

参考リンク→ http://www.iknow.co.jp/users/kenkenwalker/journal/2008/7/11/62985-sslde-shita-ni-suruera-no
posted by koteitan at 11:15| Comment(2) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2009年02月04日

[Java]ResultSet#getBigDecimal(int,int)

掲題のメソッドは非推奨メソッドなのである。
何故か? 非推奨だから非推奨なのだ! では説明にならん。

調べて参りました。合ってるかどうかわからんけど。

http://media.datadirect.com/download/docs/slnk/devref/devjdbc.html

Fetching BigDecimal Objects

JDBC 1.22 defines getBigDecimal() with a scale parameter. When the SequeLink for JDBC driver fetches a BigDecimal object from a database, it rescales it using the scale specified by the application. This additional processing can downgrade system performance, particularly when large numbers of BigDecimal objects are fetched by your application.

To eliminate this additional rescaling, JDBC 2.0 defines an overloaded version of getBigDecimal, without the scale parameter. This method allows the SequeLink for JDBC driver to return the BigDecimal object with the original precision.



意訳。
昔のJDBCは桁数なんか知るか!だったけど、2.0以降では
ちゃんとDBのカラム設定を使ってスケーリングして返してるから、
(DECIMAL(10,5) とかで定義する桁数で調整してと言う意味)
指定はイラン。指定すると2回スケーリングすることになるので
コストがかかる。よってこのメソッドは破棄する。

俺約
テーブルでちゃんと定義してんじゃねーの? 何で再スケーリング?
設計が変なんじゃねーの?( ゚Д゚)ハァ? ('A`)マンドクセ
イランだろこんなのwwww
ということさ、多分。
posted by koteitan at 10:56| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2008年12月02日

[java]続・HTTPS

証明書をどうにもできない環境でも何とかしようとしてる例が
結構ある件。同じような理由なんだろうか・・。
技術でごり押しするあたり、同じ魂を感じるねぇ。

[Java]証明書無視のHTTPSクライアント 1.3 & JSSE
http://d.hatena.ne.jp/stdcall/20060805/1154761291

オレオレ証明書のサイトにアクセスしてみるテスト
http://blog.livedoor.jp/applepedlar/archives/64664302.html

SSL証明書の信頼判定無視のHTTPSクライアント
http://apis.jpn.ph/fswiki/wiki.cgi?page=ScrapCode%2FJava%2FHttps#p3

無視SSLの処理を注入してHTTP周りの処理はライブラリに任せる方式が
いいのかねぇ。SSL周りのコードが勉強できるからまんざらでもないな・・。なんて前向き思考な俺。
posted by koteitan at 10:13| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

[Java]keytool memo

JavaでHTTPS。ライブラリがSSLをまるっと受けもってくれるので、
認証とか( ゚Д゚)ハァ?でも誰でも作れる。
しかし、問題がでると対処できんのでは恥だよな。

・keytool
 JRE が持つ 証明書関連の操作をするプログラム。
 ${JAVA_HOME}/jre/bin にある。
 使い方はJDKのマニュアルにあるんだぜ。

サンプル
 IBMJDKでベリサインの証明書が切れる件があったんだけど、
 それを確認してみる。

切れてる版(JDK1.4.1)
keytool1.jpg
大丈夫版(JDK5)
keytool2.jpg

デフォルトパスワードは 「chagneit」。
Was関連製品なら「WebAS」かもしれない。

で、証明書を拾って入れれば古いJREでもOKと言ったら、
そんな得体のしれないものは許可しないィィィィィ とか。
モウヤダ、ココの職場。
posted by koteitan at 09:44| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2008年05月09日

No suitable driver

これはハマる危険があるかもなぁ。
英語がわかる人ならなおさら。
「適当なドライバが無い」と、いわれるとLIBPATHとか
LD_LIBRARY_PATHとかを疑ってしまうじゃない?
まぁ、そっちであることもあるんだけどさ。

これは、大抵がJDBCのURLを書き間違いによるものが多い。
勘違いしてTYPE2方式で書いちゃったとかだな。
それなら、URL MissMatch とか Invaild DatabaseName とか
もうちょっとわかりやすいエラーメッセージでいいんじゃね?('A`)
と思うのは俺だけだろうか・・。
参考リンク
posted by koteitan at 14:07| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2008年05月01日

DNSキャッシュの制御

java上のDNSのTTL制御は

networkaddress.cache.ttl
networkaddress.cache.negative.ttl

をjava.plolicyファイルで制御する。
プログラマブルには変えられない。

起動オプション(-Dパラメータ)で制御は可能だが、
名前が変わるっぽい。(未検証)

・networkaddress.cache.ttl ⇒ sun.net.inetaddr.ttl
・networkaddress.cache.negative.ttl ⇒ sun.net.inetaddr.negative.ttl

デフォルトは-1で無限キャッシュ。
うろ覚えだが、DNS Rebindingを防ぐために無限になってたと思う。
不便を取ってでも、安全側に倒す設計思想であーだこーだと聞いた
記憶がある。

DNS-Rebinding については、
 http://yebo-blog.blogspot.com/2007/10/dns-rebinding-dns-pinning.html
http://www.tokumaru.org/d/20071126.html

等が詳しく解説されている。
posted by koteitan at 15:48| Comment(0) | TrackBack(1) | Java | このブログの読者になる | 更新情報をチェックする

java で HTTPS with proxy

あんまり需要が無いのか、調べてもあまり出てこないね。
結論だけ書くと、

https.proxyHost
https.proxyPort
https.proxyUser
https.proxyPassword

をSystem.setPropertyで設定すればおk
ただし、システムプロパティなので、全スレッドに影響する。
Dynamicに反映されるが、同期を取らないと影響はでる。
ClassLoaderを分ける裏技もある
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=16868&forum=12&start=8

user名とパスワードを毎回変えたいのならば、
BASE64Encoderを使って、
setRequestProperty( "Proxy-Authorization", "Basic " + encoder.encode( "user:password".getBytes() ) )

こんな設定もおkらしい。
Base64Encoderはsunパッケージなので、
sun以外のJVMでは動かないこともある。
そのあたりは、参考リンクを辿ってくだされ。


参考リンク
posted by koteitan at 15:32| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年11月05日

[Java]GETとPOSTの混在

久しぶりなんだな。ま、誰も見てないから(・ε・)キニシナイ!!

http://hogehoge/fuga?ugaaaa=ohhhh

というURLに対して、postdataにhagaa=noooo を入れて
Method POSTを行うと、Servlet内では

URI /fuga
QueryString ugaaaa=ohhhh
Parameter ugaaaa=ohhhh,hagaa=noooo

という解釈になる。QueryStringもパラメータとして処理される。
じゃあ、ひねくれてこうやってみたらどうなるか?

http://hogehoge/fuga?uhyo=hackhackhack
PostData uhyo=seacretData

なんとGETが勝つ。(これはWebSphereV6.1で確認)
超簡易CSRF方法とかにつかえたり…しないわな。

URI /fuga
QueryString uhyo=hackhackhack
Parameter uhyo=hackhackhack

コンテナ依存だったと思うんだが。
別コンテナでちがうわいー、とかRFC違反じゃいーとかあれば
情報キボンヌ。


posted by koteitan at 16:39| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年10月08日

[Java]DNS Rebinding

http://sunsolve.sun.com/search/document.do?assetkey=1-26-103078-1

某MLからの情報なんだけど、こりゃー企業内イントラで
運用されているシステムに相当なインパクトがありそう。
少なくとも私のかかわっているシステムでは影響するっぽい。

同一サーバーであれば、アプレットは通信できるという
制限がさらに厳しくなっている模様。

接続させるためには、DNSをいじくる必要があるっぽい。
まだSunからの詳しいアナウンスが
ないのでちょっとはアンテナを張っておく必要がありそうだ。
policyファイルで回避できるのか?など気になる点は多い。

URLの記事をさらっと見た感じではJDK6.0だけの
実装ではないっぽいのがいやな感じ。
posted by koteitan at 12:13| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年08月23日

[java] javacore (゚Д゚ )!!

javacoreつうと、IBMJDK専用っぽいけど、
別に、HPでもSunでもスレッドダンプは取れるんだよね。

kill -3 (windowsならctrl+breakとか)で。
こちらのブログ記事にそりゃあもう詳しく詳しく掲載されていますので
あたしなんぞがわざわざ書く必要もあるめぇ。
同ページにjavacore解析のユーティリティまであります。
IBJDKのjavacoreに限れば、専用のツールも公式にあります。

しかし、まぁ折角なので、IBMJDK(+WebSphere)での
ハングや、CPU100%なんぞの解析手順並びに取得すべき資料の
ガイドでも・・・と思ったんだが、既に公式ページがあるみたい。
http://www-1.ibm.com/support/docview.wss?rs=180&context=SSCMPB9&q1=MustGatherDocument&uid=swg21052641&loc=en_US&cs=utf-8&lang=en

(その他の資料ガイドはこちら

もはやjavacoreすら出力できない悲しい状態になった場合は
gencoreでcoreを出力させておけば、IBM秘密の専用ツールで
なんとかできるので、IBMの人に聞いてみよう。

posted by koteitan at 14:31| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年08月16日

[java] BigDecimalの仕様変更

なんと、JDK1.5ではBigDecimalのtoString()に変更が加えられている。

科学表記に対応しているのだ。

JavaDocより引用)
各表現の左側は [unscaled value, scale]、右側は結果の文字列を示します。

[123,0] "123"
[-123,0] "-123"
[123,-1] "1.23E+3"
[123,-3] "1.23E+5"
[123,1] "12.3"
[123,5] "0.00123"
[123,10] "1.23E-8"
[-123,12] "-1.23E-10"


表記がscaleのサイズによって自動で
科学表記と数字表記に分別される。

従来のtoString()(JDK1.4.2までの)はtoPlainString()に
置き換えられている。

しかし、Tiger の変更点にはあまりあがっていない。
なーぜーだー?しらべてみた。

続きを読む
posted by koteitan at 11:08| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年07月13日

[Java]全角半角変換

いや、同僚と昼飯食ってて、VB.NET(正確にはVB6)では
半角と全角の変換できるが、Javaではどうなんよ、と聞かれ

「そういや、できねーな。標準では」

とすごい敗北感を味わったのであった。まぁ、自力で文字コードとか
見ればまぁできるんだけど、それも('A`)マンドクセ-。
というわけて、IBMの開発したICUを使うワケなんだが。
(ICUは文字以外にもいろいろなグローバリゼーションに対応)

和暦西暦変換とかもできる。JDKも6でようやく対応したのだが
(java.util.JapaneseImperialCalendar)
これまた、NETだと標準装備(System.Globalization)。
(,,゚Д゚) ガンガレ!JCPの中の人

以下サンプルとか
posted by koteitan at 17:13| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年06月06日

[java]HttpSessionの有効範囲

んー、調べたので備忘録にφ(`д´)カキカキ

Servlet2.1
JVM単位

Servlet2.2以降
 War単位
 ただし別WarであってもSession IDは同じになることもある。
 (コンテナによる)
 同じIDであっても参照しているオブジェクトは異なるため、
 War1でsetAttribute("hoge",hoge)していても、
 War2でgetAttribute("hoge")はnullになる。
 そもそもそういう使い方をするものではなく、
 Warの分割方針が間違っているということである。

原文はこれ
Session information is scoped only to the current web application (ServletContext),
so information stored in one context will not be directly visible in another.


ちなみにWebSphere4.x以降では過去のバージョンとの互換性のために
セッションコンテキストを共有する機能がある。
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/topic/com.ibm.websphere.nd.iseries.doc/info/iseriesnd/ae/tprs_sharing_data.html

V3.5(servlet spec 2.1)との互換のためかのぅ。
しかし、使わない方がいい。J2EE規格じゃないし、
ClassLoaderの問題等々が起こる。
posted by koteitan at 08:56| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年05月29日

[Java] ブートストラップ ClassLoader

あるClassがどこからロードされているかを調べるには
Class.forName("クラス名").getClassLoader().getgetResource("ファイルパス")

で調べられる。(他の書き方もあるだろうけど)
例えば、hogeパッケージのfuga.classを探すのなら、

Class.forName("hoge.fuga").getClassLoader().getResource("hoge/fuga.class")

と言う風に書く。戻りはURL型でjar内のファイルでもきっちり帰ってくる。
しかし、動作しないものもあり、それはブートストラップクラスローダー
によってロードされているクラスである。
(例えば、java.lang.String など)

何故かというと、ブートストラップクラスローダーによって
ロードされているクラスの場合、getClassLoader()がnullを返すから。
javadoc参照のこと。

JNIとかでガン( ゚д゚)ガレば何とかなるのかも知れないが。
posted by koteitan at 16:31| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年05月01日

[java]数値を判定する

いや、もうイディオムなんかもしれねぇけど。

普通、こんなコード


long val = 0L;
try{
val = Long.parseLong(hoge);
}catch(NumberFormatException nme){
val = -1L; // 数値じゃないという意味をもった数字を割当
}

…。例外を例外じゃない使い方している典型。
配列の境界チェックを例外でやるのとかわんない希ガス。

で、どうすっか?
続きを読む
posted by koteitan at 15:36| Comment(1) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年04月06日

[IBMJDK]問題判別ガイド

diagガイドの場所。
よく見失うのでメモっておく。

http://www-128.ibm.com/developerworks/java/jdk/diagnosis/

まー、とにかく便利なんで。英語だけど。

これを読めばJDK5.0でいきなり登場した謎のsnap。XXXX.XXXXX.trc
とかいうファイルの詳細も解るってモンだ。

「バイナリなので読むときはFormaterしてね」とあるので
$java com.ibm.jvm.format.TraceFormat Snap0001.20070406.073803.51348.trc -overridetimezone 9

こんなカンジでテキスト化する。
最後のオプションはタイムゾーンの調整だが、31時とかでるのは
どうなんだ?(;´Д`)ハァハァ

まー、アプリとかでtrace pointをしこんでなけりゃ、製品系のが
でるだけなんで、あんまり役に立たないような…。
メモリマップぐらい出してくれてもいいのに。(-ε-

posted by koteitan at 14:02| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする

2007年02月07日

[Java]識別子の判定

javaでは、いや、他の言語でもそうだが、予約語と呼ばれる
数十種の単語は識別子(class名、package名、interfece名、
変数名…etc)には使えない。

その他にも
 ・1文字目には数字は使えない
 ・演算子等の記号は使えない
などの制約がある。詳しくは、Java言語規定の3.8を参照のこと。

で、だ。こういう〜名とかはそのプロジェクト毎で、
「〜推進チーム」とか普段何をしているかよくわからないような
チームがドキュメントの規定を決めるような感覚で、
あまりJavaに詳しくない連中が決めていたりするような
半泣きなプロジェクトは結構あると思う。

そこで、いちいち説明するの('A`)マンドクセなのでツール化してしまおう。

続きを読む
posted by koteitan at 11:12| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする