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さんに質問できます」
明日のための殴り書き
非実在SEが、コード類の覚書を殴り書く場所。
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更新により反映される。