2014-08-23 に 関西WildFly 8(旧JBoss AS)勉強会 に参加したときのメモ。 * What's new in WildFly 8 - @nekop (slide @arunguputa) ** Arun Guputa -> OracleからRedhatに移った模様 ** WildFlyはJBossAS7の後継 ググラビリティが悪いので(JBoss.orgの他のプロダクトと被るので)改称 ** Undertow 内部的にはTomtcat使ってたけど、Tomcatのバージョンアップはさほど後方互換を重視していなかったので メンテが大変だった。 エンタープライズ用途に厳しいということでUndertowをフォークして作成。 今はそれを使っている。 ** 使用ポートを整理 アプリ用のポートは2本まで減らした。 - app: 8080 - mng: 9990 ※デフォルト値 ** What's new(Java EE7) *** WebSocet(JSR356) New *** Batch(JSR 352) New XMLで定義....だと?(仕様はIBMが策定) ※でかいバッチを本気で作ったらどんなXMLになっちゃうんだろう?と会場では話題に *** JSON(JSR 353) New *** Concurrency(JSR 236) New いままではThread扱えない Java EE自体が ThreadLocalをごりごり使う。 ユーザ記述ロジックで立ち上げたThreadにはそういうのがなくて管理できずに爆発する。 というのをどうにかして、管理可能な状態でThreadを作成する口が作られた。 Fork/Joinもできる *** JAX-RS(JSR 339) update RESTClientが誕生 Jerseyベース(not RESTEasy) *** JMS (JSR 343) update 呼び出しが簡素化(7行くらい -> 1行) *** JTA(JSR 907) update EJBによる管理だけではなく、CDI側で管理できるようになる *** CDI (JSR 346) update beans.xmlがoptional スキャンタイプを選べるようになる(前は全てのクラスをスキャンしていた) All scanは遅いことがある(今まではAll Scan) - All scanはくっそ遅い、となることがある - 自前のクラスとJar内部クラスがバッティングして Injection対象がわからないエラーになる、という現象の回避手段にもなる。 *** Undertow(新しい WebServer ) ハイパフォーマンスらしい。 TecgEmpowerというサイトがあらゆるWebServerに対してリクエストを投げてパフォーマンスを計測・公開していて、 そのランキングで上位に位置する。 embedded版がある *** Role based ACL JBossで操作できることを、ロールごとに管理できるようになる。 Paasで使用されることを意識して、管理系機能のためのよしなしをWildfly内で完結させようとしている動きの一環。 *** Automated paching update 今までは、このファイルを上書きして、あのコンフィグを調整して・・・・だったのを、 zipを持ってきて、バッチ当てコマンドでベタッとやると、完了する。 *** Hibernate search アノテーションで対象エンティティを指定すると、 勝手にDB内の全文検索用のindex貼ってくれる?(内部はLucene) 激しいLikeのSQLを自前で書くよりはお手軽とか。 *** clustering 監視リスナーを設定して、 落ちたサーバを検知し、それを生きてるやつに知らせたり、特定のメソッドコールするよう設定できたりする。 *** Paas提供しているところ OpenShift / CloldBees Java EEのFullProfile対応しているのは上記2つだけでは、とのこと。 *** クラスタリングするときのフロントエンド側のサーバのチョイス [3択]: 内部的には、コアなところで同じライブラリを使っているらしい - mod_cluster <- 一番新しい - mod_jk - mod_proxy *** jboss-cli XPath的なやり方でコンフィグ設定できる。 生兵法でXMLを触って、壊して怪我する、ということを減らせる。 *** クラスローディングの考え方の変化 http://www.slideshare.net/nekop/jboss-as-7-eap-6-modules-and-class-loading mavenの依存性推移のようなものを登録しておける。 -> 曰く「ランタイムで利用出来るMavenみたいなやつ」 Pros. 目的のjarをクラスローダが探しまわらなくていい Pros. 不要なものをロード市内で済むので若干早くなる? Pros. 依存性の推移先でバージョン違いのJarを使っている状態でも動ける。 *** slf4j のlog出力APIの可変長引数渡しているところで、最後の引数が例外系だったら例外としてログ出力してくれるらしい) 事故りそうではあるが、やりたいことはできる JBossのLogging Managerは、log4jやslf4j側の実装を全て差し替えたものを持っている。 アプリ側でそのライブラリを取り込んでいない状態で、logback塔を使った実装があると、 Log4jの処理を、JBossが差し替えた版に対してリダイレクトされる。 設定ファイルがアプリのクラスパスにあれば自動的にそれをJBossが解析して設定通りに出す。 *** その他 - SalesforceはResinを使ってる - 非圧縮jarにするとサーバの起動が早くなる(展開する手間がへるよ) - JVM_OPTIONSに -Xverify:noneすると早い クラスが壊れてないか検証する、という処理を切る。 Appletで謎のクラスを落としてきて使う、とかでなければ不要な処理だよ、という見解。 - TieredCompilation * Arquillianではじめるコンテナを使ったテスト (@backpaper0) ** 依存しているJarをアーカイブに含めるときは、ShrinkWrapのMavenResolverを使う方法がある org.jboss.shrinkwrap.resolver.api.maven.Maven drone - webdriverをinjectしたりできる graphere - droneとは違い、ajaxのテストするためにAPIを充実させたやつ warp - テストクライアント側の動作に加え、テスト対象のサーバ側の方で検証処理がかける。 DBのテストなんかにつかえる? * JSF アプリ作ったった ~EE サーバー載せかえ祭り~ (@shinsukeoda) * GC (@nekop) ** パラレルGC(UseConcMargSweepGC) - いっぱいになったら処理を全止めして、全なめしていらないものを消す -> APサーバみたいなランタイム環境で突然停止とかありえない -> 並列でやるよ - UseConcMargSweepGCのチューニングについて、世のブログにいっぱい嘘、古いのが書いてあるので気をつけようね。 ** JAVA_OPTSでのチューニングはデフォルトで大分いい感じなのでそれほど弄る必要はない。 ただ、GCを始めるしきい値(占有率)が92%なので、Hadoopのような大量のアロケーションを一度に行うようなものは 調整したほうがよい。 ** Java 8はCMSが早くなったので、G1GCを使わないといけないシチュエーションは減った ** G1GCはメモリが潤沢な環境でないと無理。でもあると、停止時間累計は半分ぐらいに減らせるかも。 ** GCは1GB - 1secを目安に考えておくとよい ** Zing: Azul社の有償のJavaVMでGCがちょっぱやい。(Pause less gcと呼ばれる) CPUコア数課金で、結構高いらしい。 Linuxでしか動かない命令セットを使ってる。 ** Shenandoah: Redhatがポータビリティの高い pause less gc を開発中 「Linuxの会社なのに・・・・」「ポータビリティを損なうやつは敵、という思想がある」とか。 * EAPとWildflyの違い (@nekop) オフィシャルはもちろん、だいたい@nekopさんのブログに書いてある話。 ** Wildflyがリリースされて、チェコのテストチーム60人が3ヶ月叩いて安定させたものが EAP ** Wildflyには大きな機能リリースは反映されることがある ** Wildflyにはセキュリティパッチは基本でない ** 「有償サポートに入ると nekopさんに質問できます」
2014/08/24
関西WildFly 8(旧JBoss AS)勉強会に参加したときのメモ
2012/12/02
「関西Javaエンジニアの会スペシャル! JavaOne2012」に行ってきた
2012/12/1に、 「関西Javaエンジニアの会スペシャル! JavaOne2012」(http://connpass.com/event/1261/) に参加してきました。 関西Javaエンジニアの会のイベントに参加させていただくのは、今回が初めてですすが、 他の勉強会で登壇されている方など、ちらほら見かけました。
勉強会の趣旨はSan Fransiscoで開催された JavaOne 2012報告会ということ、 現地の様子の展開と、その中で行われた発表内容のフィードバック、発表技術の 簡単なレクチャーといったものです。
以下、特に自分が興味惹かれたものを簡単に書いてみます。「StrutsとTomcatをやめようキャンペーン実施中です」
寺田さん(@yoshioterada)の、「Java EE プラットフォームにおける HTML5対応」にて 表題の発言がありました。
やべぇ、俺撲滅される側の人間だわ・・・。このセッションに限らず、登壇者の話や参加者の反応について、 技術と知識と意識の落差を感じることが少なくなかった。 浅学を恥じるばかり。
JavaEE 7でアップデートされる JSF 2.2では、ビューをxhtmlというものでかけて、 htmlとしてブラウザでそのまま表示できる形でモデルとのBindをバリバリかけるよ。 デザイナさんが作ったhtmlを頑張ってJSPに治すなんてナンセンスで無駄が多いでしょ、 xhtmlをデザイナとプログラマが両方かける形でやれてハッピーになるよ、 という話。 ↓みたいな感じで、htmlとしての解釈は可能な形で埋めると。
Lambdaは書きやすいだけでなく、早くなる
さくらばさん(@skrb)による「Lambdaへの道」セッションにて行われた、 Java SE8に盛り込まれる予定のLambdaの解説。
仕事でAjaxバリバリでビューを書くことがあり、Javascriptのmap関数などで使う無名関数の強力さに触れたあと、 Javaで同じことをやろうとして、匿名クラスをモリモリ記述することの面倒くささに 打ちひしがれていたので、javaのlambdaには興味津々でした。
このセッションで、シンタックスとしてはかなり簡易にかけるということがわかったが、 それ以上に、この無名関数部分を小さい粒度で書くことでCPUのマルチコアを有効に活用して 並列処理として実行されて、処理が早くなるというのが面白そう。 どうかけば、どれだけ早くなるのか? 学習コストを越えてどれほどのメリットが生まれるのか、というのが人の多い仕事で 採用するかの鍵になるかな。 検証資料を探さないと。
新Javascriptエンジン Nashorn(ナズホン?)
寺田さんの「JavaOne 2012 のアップデート」から。Rhinoに代わるJavascriptエンジン。 Invoke dynamicsを使うことでより高速に処理できるとのこと。
Invoke dyanamicというのは、Java仮想マシンにて動的型付け言語がサポート(...?) というように聞いたが、このあたり全く理解が追いついておらず。
これまで、私は入力バリデーションを、画面の入力チェックをJavascriptで、サーバでの検証をJavaで、 としていたけど、これがJavascriptで一本化できるだろうか、とか妄想するなどした。
NetBeansによるHTML5サポート
寺田さんの「JavaOne 2012 のアップデート」から。 NetBeans(IDE)での編集を、専用プラグインを入れたChromeに動的に反映させられる機能があり、 それがHTML5に対応するとのこと。 恥ずかしながら、NetBeansを使ったことはないので、これは試してみねば、と思っている。※ もちろん NecoBeansも知らなかった。
以下は、さらにメモからの細かい抜粋。
- 一時期勉強会といったらMBAの展示会みたいだったけど、タブレット + キーボードの人が結構いる
- Project SumatraでJavaからGPGPUがかけるようになる?学習コストは安くないとみるが、一部のボトルネック処理に対するアプローチにはなりうる?
- Jigsawは開発が遅れたため、Java SE9に順延するが、他の機能はこれを待たずに計画通りアップデートに載せていくとのこと。出来てるやつはリリースしてサイクルを早めていくという方向で進めていくということか。
- Websocketの処理が書きやすそう。Ajax - JSONIC RestServletで書いている部分の一部置き換えに使えるだろうか。DBのアップデートをpushするという応用は特に使えるシチュエーションを妄想できる。
- (fxmlの話を受けて)デザイナさんとの協業って今まであまりやってこなかったけど、インタフェースを使いやすくするところで質を上げたいし、タブレットスマフォだとUIへ配る意識の差は使用感が大きく変わりそう。 もっと積極的に考えないといけない。自分でもある程度UI/UXの知見がいるし、協力してやっていく場合の作業フローも考えないといけない。
- 会の最後に寺田さんご提供のプレゼント争奪ジャンケンで敗れた。JavaOne/Dukeグッズでドヤりたかった。
最後に
Javaと長く付き合うことになりそうな立場なので、 この先Javaにどんなものが出てくるかというのを人の口から聞いてみようということで参加しました。
その意味で大いに収穫ありです。 それに、外に出て他の人がやっているものを見聞きする刺激が、 忙しいなかでもオフで何かやろうという気持ちを起こしてくれることもあります。 普段書くJavaだけに、そういうところのモチベーションを維持する点でも有意義でした。
登壇者のみなさま、コーディネータのみなさま、参加者のみなさま、ありがとうございました。
2012/09/09
PATHの通っているディレクトリのファイルを全て出力するシェルスクリプト
環境
- OS: FreeBSD 9.0 STABLE
PATHのコロン区切り展開が sed なあたりが特に苦しまぎれだが、 スマートな解決はあるだろうか。
2012/08/21
JavaFX2を試しつつ gistを試す
Java FX2 を動かしてみたというのはもののついでで、 gistをBloggerに貼れるかどうか試したかったがためにできた記事。
環境
- OS: Ubuntu 12.04 (64bit)
- JDK: 1.7.0_06 64bit
Applicationクラス
アプリケーション全体の起動ポイントかつ各種制御。FXMLファイル
画面の構成、デザイン。CSSも適用できるらしい。Flashで言うところのmxmlか。コントローラクラス
FXMLの制御。Flashで言うところのmxmlに対するActionScriptファイルか。その他
- ビルド・起動時には、${JAVA_HOME}/jre/lib/rt.ja にパスを通す
- FXMLを相対パスで指定する場合のベースディレクトリはJavaの起動ディレクトリ。リソースファイルとかと同じ。
- "Control"って名前のクラスにしてしまっているけど、Oracleの名づけ的にはControllerですよ。
2012/07/08
jQuery MobileでGoogleMaps使う際の覚書(地図API動的ロードと地図サイズ最大化)
ライブラリ類のバージョン
- jQuery 1.7.2
- jQuery Mobile 1.1.0
- Google Maps API V3 (3.8)
覚書1: Google Maps APIの動的ロード
<div id="scriptArea"> <script type="text/javascript" src="http://www.google.com/jsapi"></script> </div>
// Maps API読み込み状態を管理するdeferredオブジェクトを作っておく。
_maps_loaded: $.Deferred()
// 地図の読み込み終了直後に行う初期化処理を登録しておく。
this._maps_loaded.done(this.initialize_map);
// 読み込み開始、完了時にDeferredを完了状態にする。
google.load('maps', '3', {
other_params: 'sensor=false',
callback: function(){
that._maps_loaded.resolve();
}});
覚書2: 地図を画面いっぱいに広げる
$('#map_canvas').css('width', $(document).width());
$('#map_canvas').css('height', $(document).height());
// ↓は実機では未検証。
// 画面回転についていくなら、orientationchangeメソッドについていけばよい(はず)。
$(window).on('orientationchange',function(e){
});
var store_map_page = {
_maps_loaded: $.Deferred(),
_map_options: {},
geos: {},
map_obj: {},
map_info_window: {},
_lazy_loaded: function(){
this.geos = {
station: new google.maps.LatLng(34.810538,135.494923),
yamada: new google.maps.LatLng(34.812141,135.494709),
oasis: new google.maps.LatLng(34.811155,135.494473)
};
var map_options = {
zoom: 17,
center: this.geos['station'],
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map_obj = new google.maps.Map(document.getElementById('store_map_canvas'), map_options);
this.map_info_window = new google.maps.InfoWindow(this.map_obj);
_map_options = map_options;
},
_initialize: function (){
var that = this;
this._maps_loaded.done(this.map_resize, this._lazy_loaded);
google.load('maps', '3', {
other_params: 'sensor=false',
callback: function(){
that._maps_loaded.resolve();
}});
},
map_resize: function(){
$('#store_map_canvas').css('width', $(document).width());
$('#store_map_canvas').css('height', $(document).height());
},
orientation_changed: function(e){
this.map_resize();
if(e.orientation =='portrait'){
} else {
}
}
};
$('body').on('pageshow', function(){
store_map_page._initialize.apply(store_map_page);
});
$(window).on('orientationchange',function(e){
store_map_page.orientation_changed.call(store_map_page, e);
});
$(window).resize(store_map_page.map_resize);
2012/04/04
JavaScriptオブジェクト⇔JSON文字列の変換処理時間
環境
- OS: Windows7 64bit
- CPU: Core i5 650 (3.2 [GHz])
- RAM: 12 [GB]
- Chrome: 17.0.963.83 m
- IE8(64bit): 8.0.7601.17514
- jQuery: 1.7.2.min
- jQuery.json: 2.3.min
動作
- Stringの配列を作成する。配列の長さは m であり、それぞれ n 文字のアルファベットからなる文字列がセットされている、
- 1.で作成したStringの配列をJSON文字列に変換する。JSON.stringify or jQuery.toJSONメソッドを用いる。
- 2.で作成したJSON文字列を、JavaScript文字列に変換する。JSON.parse or jQuery.parseJSONメソッドを用いる。
- n = 1, 2, 3, ... 10
- m = 20, 21, 22, ..., 219
結果
各シートの記述内容- Chrome: 17.0.963.83 m(JSON) JSON.parse, JSON.stringifyを使用
- Chrome: 17.0.963.83 m(jQuery) $.parseJSON, $.toJSONを使用
- IE8_64:8.0.7601.17514(jQuery) $.parseJSON, $.toJSONを使用
テストコード
$(function(){
function TestCondition(recordLength, recordNumber){
this.isCalculated = false;
this.recordLength = recordLength;
this.recordNumber = recordNumber;
this.spentTime = {
constructJsObject: 0,
serialize: 0,
deserialize: 0
};
}
TestCondition.prototype = {
execute: function(){
var recordString = "";
for(var i=0; i<this.recordLength; i++){
recordString += "X";
}
var rawJsObject = {};
var startTime = new Date();
for(var i=0; i<this.recordNumber; i++){
rawJsObject[i] = new String(recordString);
}
this.spentTime.constructJsObject = new Date() - startTime;
startTime = new Date();
var serialized = $.toJSON(rawJsObject, null)
this.spentTime.serialize = new Date() - startTime;
startTime = new Date();
var deserialized = $.parseJSON(serialized);
var deserialize = new Date() - startTime;
this.spentTime.deserialize = new Date() - startTime;
this.isCalculated = true;
},
writeResult: function(){
var resultTable = $('#resultTable');
var resultRecord = $('<tr></tr>');
resultRecord.append('<td>' + this.recordLength + '</td>');
resultRecord.append('<td>' + this.recordNumber + '</td>');
resultRecord.append('<td>' + this.spentTime.constructJsObject + '</td>');
resultRecord.append('<td>' + this.spentTime.serialize + '</td>');
resultRecord.append('<td>' + this.spentTime.deserialize + '</td>');
resultTable.append(resultRecord);
}
};
for(var i=1; i<11; i++){
for(var j=0; j<20; j++){
var test = new TestCondition(i, Math.pow(2, j));
test.execute();
test.writeResult();
}
}
});
JSON文字列変換後の文字長ぐらい、計算出しておけばよかった。
2012/04/02
svn:externalsをファイル単位・フォルダ単位で設定する
もしくは特定のファイルをミラーリングするために、svn:externalsを使う。
たとえば、
Subversionのリポジトリ上で複数のプロジェクトを管理している。
後発のプロジェクトBが、先発のプロジェクトAと同一のリソースを常に配置したい。
そしてそのリソースはどちらのプロジェクトでも更新するし、
その反映は常に両方のプロジェクトに対して行われる。
というような状態を作りたい場合。
(そんなシチュエーション、開発の初期フェーズしか通用しないと思うけど。)
ディレクトリの参照設定
[例]
http://localhost/svn/projA/resources
を常にprojBからも参照する。
http://localhost/svn/projB/resources
#参照設定 作成 ~projB$ svn propset svn:externals 'resources http://localhost/svn/projA/resources' . property 'svn:externals' set on '.' ~projB$ svn up Fetching external item into 'resources' A foo A bar Updated external to revision 2. #参照設定 削除 ~projB$ svn propdel svn:externals ./resources
特定の1ファイルの参照設定
※ Subversion 1.6以降に限る。※ 参照関係を張ることができるのは、同一リポジトリ同士に限る
subversion.apache.org subversion1.6のチェンジログ中、svn:externalsについて記述した項。
svn:forum "svn:externals" 他リポジトリへのファイル参照設定できないんだけど、というフォーラム記事。
[例]
/repo/trunk/libA/resources/shared_file.txt
を
/repo/trunk/libB/resources/
にから参照設定する。
libB/resources$ svn propset svn:externals '^/repo/trunk/libA/resources/shared_file.txt shared_copy.txt' . libB/resources$ svn uplibB/resources/shared_copy.txtを編集してコミットすれば、libA/resources/shared_file.txt更新時に反映される。
逆に、libA/resrouces/shared_file.txtを編集してコミットすれば、libB/resources/shared_copy.txt更新により反映される。
2012/03/22
[jQuery]テキストボックスへの「文字入力」の検知
- changeイベントを拾う…文字入力ではなくテキストボックスの入力終了でファイアするイベント。ざっくり表現すると、フォーカスアウト時。
- キー入力イベント(keypress, keyup, keydown)を拾う…キーボード押下時にファイアするイベント。テキストボックスに文字が入る前を取れる。
JavaScript Madness: Keyboard Events
キーボードからの、タブやカーソル移動、消去などを除いた「文字入力」だけを拾う手段として 下記の形で書いてみた。 ただし、ペーストや日本語変換入力などは検知できない。
// keypressイベントで発火させた後のコード
// @param event {Object} eventObject
// @return {Boolean} true:「文字入力」は行われていない、false:「文字入力」が行われた。
// キーコードの取得
var code = event.which ? event.which : event.keyCode ? event.keyCode : event.charCode ? event.charCode : 0 ;
//
if( (navigator.userAgent.indexOf('Gecko')) || (navigator.userAgent.indexOf('Presto')) ){
// Firefox and Opera send a code of special key whe user press it.
// below statements avoid prevented some codes sended.(arrows, delete, home, end, backspace, tab)
if( (code==37) || (code==38) ||(code==39) ||(code==40) ||(code==46) ||(code==36) ||(code==35) ||(code==8) ||(code==9) ){
return true;
}
}
if( (!code) || (code < 32)) ) {
event.preventDefault();
return false;
}
日本語変換を検知するのは無理か。 Enter確定やスペース確定を拾うとそれっぽい気がするしたけど でも、普通目的のEnterと変換のためのEnterを分離しきれる気がしない。 あと、日本語IMEをデフォルトから変更されたりしたらお手上げじゃない?
ペーストについては、pasteイベント拾いそうなものだが、 こいつは入力確定前でかつ、何が入力されようとしているかは検知できない。 なにやら、Flashを埋め込んで連携することで可能になるようだが。 まぁ、ブラウザでWeb閲覧するごときでクリップボードの内容なんか引っこ抜かれちゃ困る。 世の中に何人かはパスワード入力でコピペってる人がいるんじゃない?
理想的には、「ペースト操作が完了してブラウザが文字列受取」 ~ 「文字列をテキストボックスに描画」の間がとれればと思うけど、 それが可能な仕組みになってるのかどうかすらわからん。
2012/03/20
[jQuery.inplim]inputの入力文字制限
github:jquery.inplim.js
引数の名前やら中の制御やらについては、いろいろ潜んでいるので余暇でメンテしていきたい。 なんたってテストコードが入ってない体たらく。 jQueryプラグイン作成、githubの使用、gitなど慣れないもの満載だったので、徐々に覚えていきたいところ。
$('#numeric').inplim({regexStr:'[0-9]', jp:true});
$('#alphabet').inplim({regexStr:'[a-zA-Z]', jp:true});
$('#alphanumeric').inplim({regexStr:'[a-zA-Z0-9]', jp:true});
$('#mail').inplim({regexStr:'[a-zA-Z0-9-_\.@]', jp:true});
2012/03/04
Windowsから複数の端末を操作する環境(Cygwin + Cygterm + Putty + GNU Screen)
・ホストOSを一度シャットダウンしても元の作業状態に戻れる。
複数Windowを立ち上げる形式は、個人的に迷子になりがちなので回避。
- cygwin 1.7.1 http://www.cygwin.com/
- putty-gdi http://ice.hotmint.com/putty/ ターミナルエミュレータ。個人的に手に馴染んではいるが、今回の構成での必然性はない。
- cygterm http://www.dd.iij4u.or.jp/~nsym/cygwin/cygterm/ telentリスナーを空けたcygwinを立ち上げて、さらにこれに接続した状態のターミナルエミュレータを起動する。
- gnu screen 4.1.0 http://www.gnu.org/software/screen/ 画面の分割、作業状態の保存・復元(アタッチ・デタッチ)。こいつはゲストOS側に用意。
手順
[Windows]
1. cygwin
何も考えずに最新(Cygwin1.7)を入れる。
導入パッケージは下記を除いて随意に。
cygtermのビルドに必要なもの。
・tar
・make
・gcc
2. putty
GDIで描画してくれるバージョンを突っ込む。
http://ice.hotmint.com/putty/
Windows x64で使うので、putty/x64の*.exeで、putty/の実行ファイルを上書きする。
続いてcygwin実行時に使用するセッションを作成。
セッション名は"cygterm"で。
その他設定項目は、以下の形で設定。
- セッション>ホスト名: 127.0.0.1
- セッション>接続タイプ: Telnet
- 端末>ローカルエコー: 強制的にオフ
- 端末>ローカルライン編集: 強制的にオフ
- ウィンドウ>変換>文字セット: UTF-8
- 接続>データ>端末タイプを表す文字列 xterm
3. cygterm
http://www.dd.iij4u.or.jp/~nsym/cygwin/cygterm/
tarとgccとmakeが必要。全部cygwinに入ってるからよしなに。 からダウンロード、解凍、make, make install。
tar xvfz cygterm107.tgz cd cygterm make #今回は、cygterm.exeとcygterm.cfgを手動でcygwin/binに移動した。cygterm.cfgの内容
TERM = {puttyをおいた場所}\putty.exe -load "cygterm" telnet://%s:%d/
TERM_TYPE = xterm
PORT_START = 20000
PORT_RANGE = 40
SHELL = /bin/zsh -l -i
ENV_1 = MAKE_MODE=unix
ENV_2 = HOME=/home/{ユーザ名}
[CentOS]
# この辺は事前状態によりけり yum install git yum install autoconf yum install ncurses-devel yum install texinfo
git clone git://git.savannah.gnu.org/screen.git cd screen/src autoconf autoheader
./configure --prefix=/usr/local --enable-colors256
make
make install
vim ~/.screenrc
attrcolor b ".I"
term xterm
escape ^Zz
zombie ^[
altscreen on
shell /bin/zsh
defscrollback 5000
autodetach on
startup_message off
logfile "$HOME/.screen/screen-%Y%m%d-%n.log"
caption always "%{= Rk} %?%F%{b kr}%? %?%h%:%t (screen #%n)%? %{-}"
hardstatus alwayslastline "%{= Gk} %-Lw%40L>%{b kg} %n %t %{-}%+Lw%-040=%{b km} %l %{.b} %Y/%m/%d %C:%s %A "
sorendition "= Rk"
[ついで]
puttyの英文はConsolasにしておきたい。
けど、日本語がつぶれるのも困る場合。
ここでは、Consolasの日本を表示をOsaka-等幅にリンクさせる。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink 新規>複数行文字列値> "Consolas" 値>665ttc2.ttc,Osaka-等幅
まだ日本語が汚いのでどうにかしたいところ。
JavaScriptのモジュールファイル群の読み込み管理をどうしよう。(2)
- 画面全体は遷移しない。htmlを非同期ロードして一部のdivエリアの置き換えを行う。
便宜上最初に読み込まれるhtmlを親画面、非同期ロードされる側を子画面と呼ぶ。 - 親画面は、子画面の初期化に必要なものが何か知らない。どのhtmlを呼ぶかは知らない。
- 親画面1つに対して、子画面を複数ロードしない。
- test.html 親画面
- test.js 親画面初期化スクリプト
- screenManager.js 子画面置き換え処理スクリプト
- subscreen
- subscreen.html 子画面
- subscreen.js 子画面初期化スクリプト
- 子画面は必要とするjavascriptファイルのURLを値に持つhiddenフィールドを持つ
- 子画面置き換え処理スクリプトは、上記のhiddenフィールド値を参照して、javascriptファイルを取得する
- javascriptファイルのURLを相対パスで書く場合、その基準位置は子画面htmlではない。
- 子画面初期化スクリプトが、遷移の度にロードされる。
- CommonJSとかClosureを使えよ。
<html>
<head>
</head>
<body>
<div class="subScreenArea">
<p>initial contents</p>
</div>
<input type="button" id="changeScreen" value="screenChange" /> <br>
<input type="text" id="loginId" />
<input type="button" id="completing" value="completing" />
<div id="scriptDeclaration">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="module.js"></script>
<script src="test.js"></script>
</div>
</body>
</html>
var mymodule = mymodule || {};
mymodule.require('./screenManager.js');
mymodule.require('./completed.js');
$(function(){
$('#completing').click(function(){
$('#loginId').val(mymodule.compl.getCompletedScript());
});
$('#changeScreen').click(function(){
mymodule.scr.change('subscreen/subscreen.html');
});
});
<html>
<head>
</head>
<body>
<div class="subscreenArea">
<input type="text" id="subText">
<input type="button" id="subButton" value="Push">
<input type="hidden" class="requireScript" value="./subscreen/subscreen.js">
</div>
</body>
</html>
$(function(){
console.log('require script loaded.');
$('#subButton').click(function(){
$('#subText').val('clicked');
});
});
function ScreenManager(){
console.log('ScreenManager is loaded.');
this.screenClass = 'subScreenArea';
}
ScreenManager.prototype.change = function(url){
$('.' + this.screenClass).load(url + ' .' + this.screenClass, function(){
$.each($(this).find('input.requireScript'), function(){
console.log('loading ' + $(this).val());
$.getScript($(this).val());
});
});
};
var mymodule = mymodule || {};
mymodule.scr = new ScreenManager();
2012/03/03
JavaScriptのモジュールファイル群の読み込み管理をどうしよう。
そんなことしたら何もかけないのでとりあえず書いてみる方向に転換してみる。
- test.html テスト用画面
- test.js テスト用画面の初期化スクリプト
- module.js モジュール管理
- completion.js 管理されるモジュール
- 指定したURLのjsを読み込む
- 読み込んだURLを記憶して同URLのjsの読み込みを抑制する
- URLベースの指定なので相対でURL文字列自体がことなると意味なし
- 読み込みミスった場合のハンドリングがない
- アンロードはどうしたらいいの?
- 名前空間衝突への考慮
1. モジュールごとに識別名を割り振り、それで管理。どこかでモジュール名を集中管理することになるのでやりたくない。
2. URL指定させずに、ファイル名指定させる。ファイルの存在位置は、表示htmlのURLからの相対か、特定のディレクトリ群で決め打ちする。
<html> <head> </head> <body> <input type="text" id="loginId"> <input type="button" id="completing" value="completing"> <div id="scriptDeclaration"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="module.js"></script> <script src="test.js"></script> </div> </body> </html>
var console = console || {};
console.log = console.log || function(data){alert(data);};
function ModuleLoader(){
console.log('construtor worked.');
this.loadedModules = [];
}
ModuleLoader.prototype.require = function(url) {
var that = this;
console.log(url + ' is loading...');
if($.inArray(url, this.loadedModules) == -1){
$.getScript(url, function(data, status){
if(status === 'success'){
that.loadedModules.push(url);
} else {
console.log(status);
}
});
} else {
console.log(url + ' is already loaded.');
}
}
var mymodule = mymodule || new ModuleLoader();
var mymodule = mymodule || {};
mymodule.require('./completed.js');
mymodule.require('./completed.js');
mymodule.require('./completed.js');
$(function(){
$('#completing').click(function(){
$('#loginId').val(mymodule.compl.getCompletedScript());
});
});
function Completion(){
console.log('Completion loaded')
}
Completion.prototype.getCompletedScript = function(){
return 'completed';
}
var mymodule = mymodule || {};
mymodule.compl = new Completion();
2012/01/22
hashchangeイベントをjQueryUIのtabより発生させて、DOMを非同期に切り替える
ファイル構成
- js
- south-street (jQueryUIのテーマファイル群)
- index.js
- exvalidation.js (exValidation プラグイン http://5509.me/log/exvalidation)
- jquery.ba-hashchange.min.js (http://benalman.com/projects/jquery-hashchange-plugin/)
- css
- exValidation.css
- first.html
- first.js
- fourth.html
- index.html
- second.html
- third.html
機能
index.html上にdiv.contentsFrame要素を定義し、jQuery UIのタブ押下に応じて
内部のdiv.contentsを動的に切り替える。
コンテンツの切り替え処理はContentsManagerクラスが担う。ContentsManagerはDOMの摩り替えを行うが、hashchange自体は意識していない。hashchangeにかかる処理はhashchangeイベント内のみで処理をする。
div.contentsの中身は、リンク先のファイルからjQuery.loadで取得する。
遷移に際してはhashchangeイベントを用いて、history.back, forwardに対応する。
ファイルの取得成功時には、リンク先ファイル上の同名jsファイルを読み込む。
考慮不十分事項
エラーハンドリングがない
jsの名前空間がどうなっているのか分からない。
exValidationのエラーチップ初期化が#formError決めうち。
headにscriptをappendすることの危険性がよく分かってない。
URIはUItabがデフォルトでつけるハッシュURIのまま。
GETのためのクエリは考慮できていない。
処理の流れ
- 初期ページindex.jsでの初期化処理
- hashchangeイベントをトラップするためにjquery.hashchangeプラグインを導入し、初期化処理をする。
- UI Tabが生成するハッシュリンクを無視し、html上で指定したhref属性へのリクエストを発生させる。かつUI Tabの遷移先をhash化するようUI Tabのselectイベントを設定する。
- 上記によりUI Tabのリンク押下により '#' + href属性のhashchangeイベントを発火させる。
- hashchangeイベントの発火に呼応して処理されるコールバックに対して、ハッシュ化されたuriからハッシュを削除し、元々hrefに指定されていたリクエストからdiv.contensElementの内容を非同期ロードする
- 上記ロード完了に伴い、既存contentsの削除と新規contentsのappendを行う。ノリでfadeout/fadeinしているがそこはどうでもいい。
- ロード成功時に、リクエストしたurlをhtmlと仮定し、同パス上の同ファイル名のjsを読み込む。このときのscriptタグに特定の非同期読み込みされたスクリプトである旨を示すクラス名を付与する。
(#/hoge/first.htmlへのリクエスト発生時にhoge/index.jsを読み込むscript#contentsScriptタグをheadにappendする。)
jQuery.getScript(jsUri);する方がハンドリングがかけたりしてまだマシ。(追記: 2012/01/23)
- 上記処理によりjQueryのreadyイベントが発火する。(first.jsであればinputに対するexValidationの初期化が行われる。)
- 前回読み込んだscriptタグを削除する。(sciprt#contentsScriptをremoveする)
- 以上の処理によりfirst.htmlに単独で読み込んだ場合と同等の初期化が完了したコンテンツが表示され(ているといいな)
index.html
<div id="contentNavigation">
<ol>
<li><a href="#">HOME</a></li>
<li><a href="index.html">Index</a></li>
<li><a href="first.html">First</a></li>
<li><a href="second.html">Second</a></li>
<li><a href="third.html">Third</a></li>
<li><a href="fourth.html">Fourth</a></li>
</ol>
<div id="contentsFrame" style="height:500px;">
<div class="contents">
<div class="contentsElement">
<p>this is a index.html</p>
<p>http://fdays.blogspot.com/2011/01/jquery-ui-tabs.html</p>
<p>now</p>
</div>
</div>
</div>
</div>
first.html
<div id="contentsFrame">
<div class="contents">
<div class="contentsElement">
<form id='loginForm'>
<p id='first'>this is a first.html</p>
<div>
<label for='name'>Name:</label>
<input id='name' type='text'></input>
</div>
<div>
<label for='password'>Pass:</label>
<input id='password' type='password'></input>
</div>
<input id='regist' type='submit' value='Regist' class='button'></input>
</form>
<div id='registedName'></div>
</div>
</div>
</div>
first.js
$(function(){
// 検証処理追加
$('Form#loginForm').exValidation({
rules:
{
name:'chkrequired',
password:'chkrequired chkmin5'
},
errTipCloseLabel:'x',
errInsertPos: 'body',
customSubmit:function(){
var registedName = $('#name').val();
var registedPassword = $('#password').val();
var appendedHtml = '' + registedName + ':' + registedPassword + '';
$('#registedName').append(appendedHtml);
}
});
});index.js
// ContentsManagerClass
var ContentsManager = function(){
this.contentsFrameId = 'contentsFrame';
this.contentsClassName = 'contents';
this.contentsElementClassName = 'contentsElement';
this.contentsScriptClassName = 'contentsScript';
};
ContentsManager.prototype.preLoadInitialize = function(){
// exValidation初期化処理
$('.formError').remove();
};
ContentsManager.prototype.contentsReplace = function(uri){
var contentsManager = this;
if(uri){
var contentsTemplateHtml = '';
$('#' + contentsManager.contentsFrameId).append(contentsTemplateHtml);
var newContents = $('.' + contentsManager.contentsClassName + ':last-child');
newContents.load(uri + ' .' + contentsManager.contentsElementClassName ,function(){
var oldContents = $('.' + contentsManager.contentsClassName + ':first-child');
oldContents.animate({opacity:0.0},500,function(){
contentsManager.preLoadInitialize();
contentsManager.unloadScript();
oldContents.remove();
contentsManager.loadScript(uri);
newContents.animate({opacity:1.0},500);
});
});
}
};
ContentsManager.prototype.loadScript = function(htmlUri){
var jsUri = htmlUri.replace(/html$/g, 'js');
var className = htmlUri.replace(/\//g, '_');
//var scriptHtml = '';
//$('head').append(scriptHtml);
jQuery.getScript(jsUri);
};
ContentsManager.prototype.unloadScript = function(){
$('.' + this.contentsScriptClassName).remove();
};
var contentsManager = new ContentsManager();
//----------------------------------------------
$(function(){
$('#contentNavigation').tabs({
select: function(event, ui) {
var url = "#/" + $.data(ui.tab, "load.tabs");
if (url) {
location.href = url;
return false;
}
return true;
}
});
$(window).hashchange(function() {
var uriWithoutHash = location.hash.replace('#', '');
contentsManager.contentsReplace(uriWithoutHash);
});
$(window).hashchange();
});
2012/01/09
XS35GT V2にCentOS6.2をUSBインストールしてメディアサーバにする(2)
2012/01/07
XS35GT V2にCentOS6.2をUSBインストールしてメディアサーバにする(1)
起動してみると非常に静かなので、
やかましいデスクトップは休みに気合入れた作業をするときだけにして、
XS35を常時起動の普段使いにしようかと。
小型静音って、ステキやん。
デスクトップもSSD化したところなんだけど、それはそれ。
0. 環境
作業マシン: Windows7(64bit) SP1
1. 構成
ハードウェア
・XS35GT V2(http://www.shuttle-japan.jp/old/old-barebone/xs35)
- SSD 64GB
- SO-DIMM 4GB
・WLI-UC-GNHP(無線子機)
ソフトウェア
・CentOS 6.2 (CentOS-6.2-i386-bin-DVD1.iso)
その他使用したもの
・USBフラッシュメモリ (インストールメディアとして使用)
・Syslinux 4.04 (http://www.kernel.org/pub/linux/utils/boot/syslinux/)
2. 手順概要
2.1. USBメモリのFAT32フォーマット
2.2. USBメモリのインストールメディア化
2.3. CentOSインストール
2.4. USB無線子機の認識
/**** 本ポストは↑まで ***/
/**** ↓は残りの予定 ***/
2.5. DLNAサーバインストール
3. 使用状況
3.1. iPhoneからの使用
3.2. iPadからの使用
3.3. PS3からの使用
//--------------------------------------------------------------//
2. 手順概要
2.1. USBメモリのFAT32化
syslinux導入のため、USBをFAT32でフォーマット。
2.2. USBメモリのインストールメディア化
a. CentOS-6.2-i386-bin-DVD1.isoをそのままUSBメモリのルートディレクトリにコピー。
b. CentOS-6.2-i386-bin-DVD1.iso内のisolinuxディレクトリ直下のすべてのファイルを、
USBメモリのルートディレクトリにコピー。
上記ディレクトリ内の"isolinux.cfg"を"syslinux.cfg"にリネーム。
c. 続けてisolinuxを除くすべてのディレクトリ・ファイルをコピー。
d. syslinuxアーカイブ内のwin64ディレクトリに移動し、
syslinux -maf j:
を実行。(※ USBメモリは j:ドライブとして認識されています)
2.3. CentOSインストール
BIOSからUSBからブートするよう設定。
あとはいつもどおりのCentOSインストーラなので
流れでお願いします。
# CentOS5系で記述されている他記事では
デフォルトのgrubローダインストーラ先がUSBメモリ上となることでの
混乱について触れられています。
今回試行したCentOS6.2でも明示的にローダの位置としてSSDを指定しています。
2.4. USB無線子機の認識
当方は裸のD25HWしかないのでこれをwifiモードで起動し、
Linuxからwifi接続する。
# e-mobile端末をUSB直差しで使うモジュール化何かが入っているようだがうまく機能させられなかった。
D25HWをUSBで直差しすると、
"モバイルエリアネットワーク"として認識される。
さらに"ネットワーク接続"ウィザードから"e-mobile"を選択することで、
APSなどが設定された接続情報ができあがるが、
試みに接続してもすぐ遮断される。何か設定値が違うのか。
a. ドライバダウンロード
http://www.ralinktech.com/en/04_support/support.php?sn=501
よりドライバ(RT8070 /RT3070 /RT3370 /RT5370 /RT5372 USB)をDL
解凍し
# vim os/linux/config.mk
の2値を変更
HAS_WPA_SUPPLICANT=y
HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y
# vim common/rtusb_dev_id.c
の下記1行を追加
#ifdef RT3070引数は下記コマンドで確認しておくとなおよし
{USB_DEVICE(0x0411,0x0158)}, //追加行
# lsusb
あとはいつものメイキングでお願いします。
# makeこれで無線LANとしてアダプタとして認識される。
# make install
# insmod rt5370sta.ko
ref.
CentOS - USBデバイスからインストール!- mk-mode BLOG
http://www.mk-mode.com/wordpress/2010/01/11002001/
Ubuntu で Buffalo の WLI-UC-GNHP を使う - 試したことのメモ
http://ossan78.blog9.fc2.com/blog-entry-43.html
2011/12/24
UMTP L1, L2勉強用書籍
http://www.umtp-japan.org/
L1,については基本的に、各図の読み方、記号の意味などの基礎知識で対応できる問題が多い。
なので、下記の本くらいの知識を押さえておけば問題ない。
[改訂版] UMLモデリング技能認定試験<入門レベル(L1)>問題集 -UML2.0対応
http://www.amazon.co.jp/dp/4774132454
それでも不安になるという私のような小物諸氏には、
問題数が魅力の下記黒本。
[黒本]
徹底攻略UMLモデリング技能認定試験問題集―L1(T1/T2)対応
http://www.amazon.co.jp/dp/4844324829
徹底攻略UMLモデリング技能認定試験問題集 L2対応 (ITプロ/ITエンジニアのための徹底攻略)
http://www.amazon.co.jp/dp/4844326627
ただし、問題が洗練されていないところに難がある。
問題文が説明不足で、回答を一つに絞り込むことが難しいことがある。
難易度も、私見では高めに設定されている。
問題をこなして自分の知識を確かめて、
穏やかな気持ちで本番を迎えるためのもの、とのある種の割り切りで活用するのがいいのではないか
mx.Controls.AdvancedDataGridのヘッダソートフィールドを非表示にする
もちろんプロパティ名の通り、ソートフィールドの表示制御が元来の目的のプロパティではない。
sortExpertMode プロパティを true に設定すると、最初の列を選択した後に Control キーを使用して複数の列を選択し、ソートを実行できます。
ref. ActionScript3.0 リファレンスガイド
http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/mx/controls/AdvancedDataGridBaseEx.html#sortExpertMode
表示:

<mx:AdvancedDataGrid id="data" designViewDataType="tree" dataProvider="{contents}">非表示:
<mx:columns>
<mx:AdvancedDataGridColumn headerText="ID" dataField="id" draggable="true"/>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name"/>
<mx:AdvancedDataGridColumn headerText="City" dataField="city" labelFunction="labelCityFunction"/>
</mx:columns>
</mx:AdvancedDataGrid>

<mx:AdvancedDataGrid id="data" designViewDataType="tree" dataProvider="{contents}"
sortExpertMode="true">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="ID" dataField="id" draggable="true"/>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name"/>
<mx:AdvancedDataGridColumn headerText="City" dataField="city" labelFunction="labelCityFunction"/>
</mx:columns>
</mx:AdvancedDataGrid>
BlazeDSおぼえがき RemoteObjectのBoolean型のアクセサ命名
オフィシャルな情報はこちら。
http://help.adobe.com/ja_JP/Flex/4.0/AccessingData/WS2db454920e96a9e51e63e3d11c0bf69084-7fda.html
↑によると、AS3のBooleanとJavaのjava.lang.Booleanは普通に疎通できるが、
アクセサメソッドの命名について、他の型と若干の開きがある。
StringとIntegerでの命名対応は下記の通り。
//-----------------------------
Java:
private String param;
public String getParam() ;
public void setParam(String param);
AS:
public param:String
-------------------------------//
BooleanでJava側のアクセサをis形式で書いた場合。
AS側ではisをのぞいたメンバ名をターゲットにバインドしようとしてくる。
//-----------------------------
Java:
private Boolean isFoo;
public Boolean isFoo();
public void setFoo(Boolean foo);
AS:
public foo:Boolean;
------------------------------//
BooleanでJava側のアクセサをゲッターセッターで無理矢理
書けばisFooにバインドしにいってくれる。
アクセサ名で判断してんの?
//-----------------------------
Java:
private Boolean isFoo; (←冷静に考えてbooleanに対してこの変数命名がおかしかった 2011/5/11追記 )
public Boolean getIsFoo();
public void setIsFoo(Boolean foo);
AS:
public isfoo:Boolean;
------------------------------//
ちなみに、HibernateではいてくれるEntityで、
セッターに戻り値があったりすると認識してくれません。
//--------------------------
public String setFoo(String foo);
----------------------------//
上記理由等でRemote Objectの型変換に失敗した場合は、
デバッグ用のFlashを使っていればログにエラー出力が出ます。
AIR with RASCUT
mxmlcに下記オプションを付与することで、同等のことが行なえる。
mxmlc +configname=air
というか、amxmlcの実体は、上のようにmxmlcにオプションを付与して呼ぶだけ。
なので、rascutを使うときにも、
rascut --compile-config="+configname=air"としておくと、AIR向きコンパイルになる。
ref.電車で起動する男のブログ
http://hannaka.blog92.fc2.com/blog-category-1.html
AdvancedDataGridColumnのlabelFunctionのsetStyleはメソッド評価時のみ
AdvancedDataGridColumnは、labelFunction中でdataFieldの値を評価した結果で
表示スタイルを設定すると、他の要因でスタイルが変化されたときに打ち消される。
当たり前といえばそうなんだけども、はまったのでメモ。
たとえばGrid上のマウスオーバー等で色が変わったあとマウスアウトすると
スタイルが元に戻る。
1.初期状態

2. IDが赤色の列でマウスオーバー

3.マウスアウト

private function idLabelFunction(item:Object, col:AdvancedDataGridColumn):String{
var id:String = item.id as String;
if(id=="1"){
col.setStyle("color", 0xFF0000);
} else if (id=="2"){
col.setStyle("color", 0x00FF00);
} else {
col.setStyle("color", 0x0000FF);
}
return item.id;
}
]]>
</fx:Script>
<fx:Script source="scripts/testFlash.as" />
<s:VGroup>
<mx:AdvancedDataGrid id="data" designViewDataType="tree" dataProvider="{contents}"
sortExpertMode="true">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="ID" dataField="id" draggable="true" labelFunction="idLabelFunction"/>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name" color="0x0000FF"/>
<mx:AdvancedDataGridColumn headerText="City" dataField="city" labelFunction="cityLabelFunction"/>
</mx:columns>
</mx:AdvancedDataGrid>
