Java HTML 5 WebSocket Avatar
-
Upload
oracle-fusion-middleware -
Category
Technology
-
view
25.616 -
download
1
description
Transcript of Java HTML 5 WebSocket Avatar
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.1
Yoshio TeradaJava Evangelisthttp://yoshio3.com, Twitter : @yoshioterada
Java HTML 5 & WebSocket &Avatar
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.2
以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することをコミットメント(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さい。オラクル製品に関して記載されている機能の開発、リリースおよび時期については、弊社の裁量により決定されます。
Oracle は、米国オラクルコーポレーション及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.3
Make the Future Java(Java の未来を創造 )
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.4
Java EE 7 : 2013 年 春頃提供開始予定
テーマ: HTML5 と開発生産性の向上
Java EE 7 SDK の提供開始
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.5
Java EE 7 へ含まれる予定の JSR 一覧
Connector1.6
JPA 2.1 JTA 1.2 JMS 2.0
Managed Bean 1.0 EJB 3.2
Common Annotations
1.1
Interceptors 1.1
CDI 1.1
PortableExtensio
ns Servlet 3.1
JSP 2.2JSF 2.2
JAX-RS 2.0
EL 3.0
Bean
Valid
atio
n1
.1
Java CachingAPI (JSR-
107)Batch
Application(JSR-352)
Java API forJSON
(JSR-353)
Java API forWebSocket(JSR-356)
新規追加 大幅な更新 通常の更新
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.6
Java EE 7 の注目技術
WebSocket ( 新 )JSON ( 新 )Batch ( 新 )Cache ( 新 )
JAX-RS 2.0JSF 2.2JMS 2.0EL 3.0
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.7
今日ご紹介する内容
WebSocket ( 新 ) JSF 2.2
HTML5 化に関するテーマ
そして、研究・開発プロジェクト
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.8
JSR 344 : JavaServer™ Faces 2.2
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.9
HTML5 マークアップ・サポート– Pass through attributes and elements
Faces フロー CSRF ( クロス・サイト・リクエスト・フォージェリ ) 対策 ResourceHandler 経由で Facelets のロード ファイル・アップロード マルチ・テンプレート
新機能の一覧
JSF 2.2
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.10
JSF : コンポーネント・ベース開発
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.11
JavaServer Faces
JSF フレームワークと開発の概要
DB
Webサービス
プレゼンテーション
• アプリケーションロジック
• コンバート ( 変換 )• バリデーション ( 検証 )• ナビゲーション ( 画面遷
移 )• イベント処理
ビジネスロジッククライアント Web アプリケーション
Web コンテナ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.12
デザイナーと開発者の共同作業が可能に (jsf:value=“”, jsf:action=“”)
デザイナーはテキスト&ブラウザで確認 プログラマーは JSP & Web コンテナで確
認 プログラム後のデザイン修正は困難
デザイナーはテキスト&ブラウザで確認
プログラマーは XHTML に要素を挿入 同一ファイルの為デザイン修正も容易
デザイナー(HTML)
プログラマー(JSP)
コード変換が必要
今までの開発スタイル
デザイナー プログラマー(XHTML)
同一ファイルを参照編集可能
JSF 2.0 の開発スタイル
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.13
HTML 5 マークアップ・サポート
JSF 2.2 からは素の HTML コードに
JSF 属性を埋め込みましょう !!
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.14
HTML 5 マークアップ・サポート
JSF のライフサイクルに適用可
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.15
HTML 5 マークアップ・サポート
HTML 5 の表現力をそのままに !!
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.16
HTML 5 マークアップ・サポート
<input type=“color” jsf:value=“#{colorBean.color2}”/><input type=“date” jsf:value=“#{calendarBean.date1}” /><keygen jsf:id jsf:value="#{bean.pubKey}"/>
標準の HTML 5 タグに jsf:value , jsf:action 等の要素を追加
<jsf:element p:elementName="keygen" id=”myKey" p:name="myKey" value="#{bean.myKey}"/>
直接要素を JSF ランタイムにスルーも可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.17
ファイル・アップロード
<h:form prependId="false" enctype="multipart/form-data"> <h:inputFile id="fileUpload" value="#{test.upfile}"/> <h:commandButton value="upload" action="#{test.doUpload}"/></h:form>
将来的には Ajax 対応( Java EE 7 の正式リリース時)のファイルアップロード機能も提供予定
ご参考 : http://yoshio3.com/2012/10/20/jsf22-env-on-gf3122/
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.18
ファイル・アップロード
@Named(value = "test") @RequestScoped public class TestManagedBean { private javax.servlet.http.Part upfile;
public String doUpload() { try { String fileName = getFilename(upfile); upfile.write(fileName); } catch (IOException ex) { ex.printStackTrace(); } return ""; }
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.19
マルチ・テンプレート同一コンテンツに対しテンプレートでデザイン切り替え可能
ご参考 : http://jsfmtsystem.appspot.com/
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.20
<ui:composition template="#{template}"></ui:composition>
デフォルトのスキニングファイル
サムネイルfacelets のテンプレートメタ・データ
テンプレートのディレクトリ構造
JSF タグ
マルチ・テンプレート同一コンテンツに対しテンプレートでデザイン切り替え可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.21
<template> <name>mytemplate</name> <version>1.1</version> <creationDate>11.22.2012</creationDate> <author>Yoshio Terada</author> <authorEmail>[email protected]</authorEmail> <authorUrl>http://yoshio.com</authorUrl> <copyright>Yoshio Terada</copyright> <license>GNU/GPL version 2</license> <description>Yoshio’s Original Template</description></template>
メタ・データの内容
コピーライト・契約等が可能
複数テンプレートの利用が可能
jar ファイルにパッケージ化
ご参考: http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-971
マルチ・テンプレート同一コンテンツに対しテンプレートでデザイン切り替え可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.22
JSR 356: JavaTM API for WebSocket
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.23
飛行機の事前座席指定
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.24
オークション
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.25
最新情報・更新情報を取得するために
今どうしていますか?
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.26
オークション・サイトで更新情報を取得する場合
データベースサービス
価格(空席)の最新情報をください
価格 ( 空席 )情報をください
接続
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.27
オークション・サイトで更新情報を取得する場合
データベースサービス
A の価格2000 円
<HTML> ヘッダー ボタン 1 の画像 ボタン 2 の画像 余分な広告 他へのリンク 製品情報:製品 A 製品価格: 2000円 製品詳細:これは フッダー</HTML>
切断
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.28
再度・更新情報を取得する場合
データベースサービス
価格の最新情報をください
価格情報をください
接続
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.29
再度・更新情報を取得する場合
データベースサービス
A の価格4000 円
<HTML> ヘッダー ボタン 1 の画像 ボタン 2 の画像 余分な広告 他へのリンク 製品情報:製品 A 製品価格: 4000円 製品詳細:これは フッダー</HTML>
切断
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.30
データベースサービス
1人あたり3回のアクセスで多数の接続・切断
接続
切断
接続
切断
接続
切断
接続
切断
接続
切断
接続
切断
…..製品価格: 4000円…..
…..製品価格: 4000円…..
…..製品価格: 4000円…..
…..製品価格: 4000円…..
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.31
システム全体に高負荷
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.32
本当に必要な情報は?
<HTML>ヘッダーボタン 1 の画像ボタン 2 の画像余分な広告他へのリンク製品情報:製品 A製品価格: 4000 円製品詳細:これは…フッダー</HTML>
4000 円
これだけ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.33
ネットワーク帯域も無駄
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.34
WebSocket の背景 – Server Push
Polling
Long Polling
Comet/Ajax
複雑・非効率・無駄
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.35
WebSocket を使えばどうなる?
データベースサービス
2000 円3 000 円3 000 円4 000 円5 000 円6 000 円6 000 円
切断
接続 接続
監視プログラムは1つのみ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.36
データベースサービス
1人辺り接続・切断処理は1度
受信 送信
送信
送信
送信 受信
監視プログラムは1つのみ
接続
切断
接続
切断
接続
切断
接続
切断
受信
受信
受信
受信
受信
受信
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.37
接続・切断数の減少不要なデータ配信の排除が可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.38
WebSocket とは
TCP ベース
双方向・全二重通信
RFC 6455JavaScript API by W3C
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.39
ブラウザの対応状況http://caniuse.com/websockets
現バージョンの対応状況
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.40
WebSocket の基本概念
コネクションの確立
双方向のメッセージ送信
コネクションの切断
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.41
コネクションの確立
HandShake リクエスト
HandShake レスポンス
クライアント サーバ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.42
HandShake リクエスト (RFC 6455 で定義 )
サーバクライアント
GET /mychat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: megachat, chatSec-WebSocket-Extensions : compress, muxSec-WebSocket-Version: 13Origin: http://example.com
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.43
HandShake レスポンス (RFC 6455 で定義 )
サーバクライアント
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chatSec-WebSocket-Extensions: compress, mux
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.44
コネクションの確立
クライアント サーバ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.45
WebSocket のライフサイクル
クライアント サーバ
Open Open
Close
MessageMessageMessageMessageMessageMessage
Error
接続確立
接続切断
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.46
WebSocket APIwww.w3.org/TR/websockets/
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.47
Java API for WebSocket (JSR-356)
http://jcp.org/en/jsr/detail?id=356http://java.net/projects/websocket-spec
仕様
ステータス: Early Draft
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.48
参照実装http://java.net/projects/tyrus
最新の GlassFish v4 開発ビルドにバンドル済
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.49
Java の WebSocket標準実装はとてもかんたん
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.50
アノテーション レベル 内容
@WebSocketEndpoint クラス WebSocket のエンドポイントを示す
@WebSocketOpen メソッド 接続確立時に呼び出すメソッドを指定
@WebSocketClose メソッド 接続切断時に呼び出すメソッドを指定
@WebSocketMessage メソッド メッセージを受信した時に呼び出すメソッドを指定
@WebSocketPathParam メソッドパラメータ
エンドポイントの URI 引数に指定されたパラメータを取得する際に仕様
@WebSocketError メソッド エラー発生時に呼び出すメソッドを指定
WebSocket アノテーション
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.51
WebSocket アプリケーション・ライフサイクル
@WebSocketEndpoint("/hello")var wsUri = "ws://HOST/foo/hello";var websocket = new WebSocket(wsUri);
@WebSocketOpenwebsocket.onopen = function(evt) { onOpen(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
@WebSocketMessage
websocket.onerror = function(evt) { onError(evt) };
@WebSocketError
websocket.onclose = function(evt) { onClose (evt) };
@WebSocketClose
JavaScript WebSocket API
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.52
import javax.net.websocket.annotations.*;
@WebSocketEndpoint("/hello")public class HelloBean {
@WebSocketMessage public void sayHello(Session session, String msg) { session.getRemote().sendString(“Hello” + msg); }}
HelloWorld アプリケーション (1 対1 )
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.53
デモ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.54
監視
サンプル・アプリケーションの構成 (多対1 )
Remote Endpoint
RE
RE
RE
Session
Session
Session
WebSocketEndpoint
Twitter4J
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.55
@WebSocketEndpoint(value= "/twitter")public class TwitterWebSocket { @WebSocketOpen public void initOpen(Session session) { TwitterClientSingleton.peers.add(session); } @WebSocketClose public void closeWebSocket(Session session){ TwitterClientSingleton.peers.remove(session); }}
Twitter Streaming アプリ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.56
@Startup @Singletonpublic class TwitterClientSingleton extends StatusAdapter { public static Set<Session> peers = null; static { peers = Collections.synchronizedSet(new HashSet()); } ...続く
Twitter Streaming アプリ
Session Session Session Session
クライアントの参照情報を保持
RE RE RE RE・・・・・・
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.57
public void onStatus(Status status) { User user = status.getUser(); String resStr = "@" +user.getScreenName() + " : " + status.getText() ; try { for (Session peer : peers) { peer.getRemote().sendString(resStr); } } catch (IOException ioe) { ioe.printStackTrace(); } }
データ送信コード ( ブロッキング )シーケンシャルに配信を実施 ( 大量のデータで待ち )
全ピア (RE) に対して配信
Session Session Session Session
RE RE RE RE
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.58
データ送信コード (ノン・ブロッキング
for (Session peer : peers) { Future<SendResult> futureSend = peer.getRemote().sendStringByFuture(resStr); while (!futureSend.isDone()) { // wait here ? } SendResult status = futureSendResult.get(); if (status.isOK()) { // ok } else { // whoops, send failed. }}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.59
こんな場合は Java EE で WebSocket を !!
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.60
OracleResearch Project !!
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.61
Project Avatar
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.62
先進的な HTML 5 アプリ構築フレームワーク– WebSocket, Server-Sent Event, RESTful に対応
モジュール化対応 JavaScript フレームワーク軽量なサーバ・アーキテクチャ (Thin-Server Architecture)
コンセプト
Project Avatar とは
Avatar のメリット– サーバ・サイド JavaScript と Java EE アプリの融合– Java VM 上で稼働する JavaScrip のスケーラビリテイ・信頼性・運用保守性
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.63
Thin-Server アーキテクチャ (TSA)
今まで アプリView
Modelサーバ側でマー
ジ
HTTP/JS
TSAView
Service
アプリ
クライアント側でマージ
HTTP/JS
JSON
View
Model
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.64
Avatar の概念 ( クライアント側 )
ブラウザ (JavaScript/DOM)
View (UI Node) Avatar(Controller)
Web コンポーネントと同様<a:page><a:form><a:input><a:textarea> …
• データ・ バインディング
• ナビゲーション• ローカル・
ストレージ
アクセス方法を提供• ローカル• RESTful• SSE• WebSocket
Model
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.65
Avatar の概念 ( サーバ側 )
Nashorn (JavaVM で稼働する JavaScript エンジン )
Service Avatar
アクセス方法を提供• RESTful• SSE• WebSocket
ルーティングJSON のシリアライズ
利用可能なデータソース• ファイル• DB(JPA)• インメモリ
Coherence
Data プロバイダ
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.66
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.67
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
① Avatar アプリの作成
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.68
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
② Avatar コンパイラで View サービス Data サービス を生成
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.69
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
③ View サービスの 「複数ページの一括」 ダウンロード (※プラグインは不要)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.70
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
④ WebSocket/Server-Sent Event/ RESTful で Data サービスを利用
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.71
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
⑤ サーバ側は Java EE のサービスも利用可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.72
Avatar のアーキテクチャ
UI
Avatar アプリ(HTML 5/JS/CSS)
Avatar 実行環境
HTML 5 DOM
ローカルストレージ
Avatar アプリ( XML/JavaScript )
Avatar コンパイラ
Nashorn (JavaScript エンジン )
ブラウザ App サーバ
Java EE アプリ
Viewサービス
Dataサービス
Java EEサービス
HTTP
HTTP/WebSocket
HTTP/WebSocket
⑥ クライアント側は HTML 5, DOM, ローカルストレージ 等を利用可能
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.73
アプリ View
Model
クライアントで動作するアプリ(Hello World)<a:viewModule …> <a:localModel> var NameModel = function(){ this.first = "Planet"; this.last = "Earth"; this.clear = function(){ this.first = this.last = ""; }; }; <a:/localModel>
<a:page> <a:model id="name" idref="NameModel"/> <a:form> <a:input label="First Name" value="#{name.first}"/> <a:input label="Last Name" value="#{name.last}"/> <a:output value="Hello #{name.first} #{name.last}"/> <a:button label="Clear" action="#{name.clear()}"/><a:/form><a:/page><a:/viewModule>ローカルのモデルを定義
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.74
WebSocket で動作するアプリ( Model の実装例 )
<a:socketModel> var ChatModel = function(){ this.message = ""; this.user = ""; var superSend = this.$send; this.$send = function(){ this.process(this.message); superSend.call(this); }; …. };<a:/socketModel>
ServiceJSON
Model
Model 用に用意されているプロトタイプ関数を上書き実装
• this.$onMessage• this.$send• etc.
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.75
WebSocket で動作するアプリ( Service の実装例 )
<a:socketService url="websocket/chat"> var SocketService = function(){ this.$onMessage = function(peer,message){ this.process(message); peer.getContext().sendAll(message); };};<a:/socketService>
ServiceJSON
Model
Service 用に用意されているプロトタイプ関数を上書き実装
• this.$onMessage• this.$onTimeOut• etc.
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.76
New Announcement2013 年 春頃Java イベント開催予定
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.77
Copyright © 2012, Oracle and/or its affiliates. All rights reserved.78