エンジニア的なネタを毎週書くブログ

東京でWebサービスの開発をしています 【英語版やってみました】http://taichiw-e.hatenablog.com/

XP祭り2015 に参加してきました 1 (講演・ワークショップ) #xpjug

今年もXP祭りに参加させていただきました!

http://xpjug.com/xp2015/

 

7月まで仕事もプライベートもバタバタだったのもあって、久しぶりにまともな勉強会に参加した感じ。

たくさん刺激を頂きました。

基調講演

角さんの基調講演。

一番ググっときたのはこれ。

TDD - ときめき駆動開発!
語呂が良かったからか、このあと一日バズワードみたいになっていましたが、ここにこんまり先生のトキメキという言葉を持ってきたのすごい。
 
このスライドで上がっている、「プラクティスの選定」にしても、ときめくかどうかって非常に重要だと思うんですよね。何かしらの課題を抱えていて、それを解決してくれるかもしれないものに出会った瞬間にときめく!はずなので。
 
ときめきっていう言葉の選定にときめきました。
 
ところで、「エクストリームプログラミング」。昨年のXP祭りで これも読まずに何を俺はXP祭りに参加してるのだ… と思って購入したのに(第2版が出る前だったのでAmazonで売ってた古本を購入した)、未だに浅くしか読めてない… 読まないとなぁ…。
 

ワークショップ ”共感”でつながるアジャイルチーム

ゴゴイチはワークショップに参加。裏も気になるものばかりだったのですが、こういうの選ぶあたり、現状で自分の興味が強いところは、チームビルディングとか人と話すとかそういうところなのかなぁ…。

共感コミュニケーション とは、マーシャル・ローゼンバーグ博士によって提案された、相互理解を深め、自分や相手とより繋がるためのコミュニケーション「プロセス」 で、次の4段階のプロセスからなるそうです。

4つのプロセス
1.観察
 ビデオカメラのように事実のみを観察する
2.感情
 自分/相手が感じていること
3.ニーズ
 何を必要としているか
 例えば、イラッとしていたら何か満たされないものがあるのではないか
4.リクエスト
 具体的なお願い。かなわなくてもいいのでしてほしいことをクチに出して言う。

 

今回のワークショップでは、2の感情 と 3のニーズ の部分について行われました。

f:id:taichiw:20150912130229j:plain

左側の「感情」と右側の「ニーズ」を結びつける練習。

例えば

  • 私は基調講演を聞いて「ワクワクした」。なぜなら、「刺激がほしい」というニーズが「満たされた」からだ
  • 私は基調講演を聞いて「ショックを受けた」。なぜなら一部理解できない話があり、「情報や知識がほしい」というニーズが「満たされなかった」からだ

というように、どのように感じているか、という感情から、その感情の元となるニーズを探ることで、自身/相手が欲しているものは何か ということを探っていくことをしました。

一般的に、ポジティブな感情の裏には、なにかニーズが満たされた という事実があり、逆にネガティブな感情の裏には、なにかニーズが満たされなかった という事実があるそうです。

初めは自分自身の感情に対してこれを行い、次に、他の人の話を聞いて、その裏にある感情とニーズを探る という訓練を行いました。

さらに、ふりかえりも、「◯◯と感じた。なぜならば◯◯だからだ。」の形式で行われました。

こういったことは、普段からある程度無意識にやっていると思うのですが、プロセスとして体系立てて学ぶことで、改めて自分の中で手法が整理されると感じました。

NVCの本、アマゾンの書評を見るとなかなか骨のある本のようなのですが、読んでみたいなぁ…

 

ユーザーストーリーマッピング入門

弊社アジャイルコーチ、川口さんのセッション。

川口さんが監訳された『ユーザーストーリーマッピング』について。

スクラムのプロダクトバックログには、
 ・今どこにいるかがわかりにくくなる
 ・チケット間の関連性が見えづらい
 ・長めマイルストーンが見えづらい

などの弱点があり、それを解決する方法としてJeff Patton氏がユーザーストーリーマッピングを考案したという話。

この弱点、私も感じる所あるのですが、何より、ここ数年一緒に仕事をさせていただいている、自分よりベテランな方数名が、こういうことを言われている気がする… というところでググッと惹かれました。

周りの皆さんが読んでいる中、取り掛かれていなかったのですが、読まないとなぁ…

モデリングもしないでXPとは何事だ

モデリングというものをちゃんと勉強したこと無いながら、ここ数年間、ちゃんと勉強したほうがいいんだろうなぁ… と思っている昨今。

モデリングとは?」のような話はなかったので、自分にはちょいハードル高めだったのですが、最近会社でよく先輩から教えられている、「issue driven」な考え方にとても通ずるものがあると感じました。

なにか新しい機能を考える際に、いきなり「方法」にいくのではなく、そもそもの問題から考える流れです。

普段なかなかできていないので、もっとこういう考え方を身に着けていかなくてはと感じました。
そしてモデルそのものも、知識としてもっと知りたい…

 

ということで あの本ちゃんと読まないと とか ここちゃんと勉強しないと とか 自分の不勉強さばかり気になった一日でした。

 

ちょっと辛くなりかけましたが、ちょっと寝ぼけていたところにたくさん刺激を頂いたということで、早速エクストリーム・プログラミングを読み返すところから始めました!

今日は、チーム9人全員で「プライベートメソッドのユニットテストは書くべきなのか? ディスカッションができた」記念日

今日はとても素敵な一日になりました。

私を含めたチームメンバー9人が、一つの技術的な話題に対して30分話し合う会を開けた日。

何より嬉しかったのは、この会そのものが、メンバー間でのやり取りからほぼ自然に出てきたことなんです。

回想:本当に「スモール」だった時期

私の今のチームは総勢9名のチームなのですが、大まかに分けても4種類くらいののサービス(検索から予約、管理画面も。)を担当している、プロダクト的にはかなりマッチョなチームです。

これらのサービスはどれも「似ている」のですが、歴史的にバラバラに作られてきたため、アーキテクチャフレームワーク、コードの思想は全部バラバラです。

以前は、このバラバラなプロダクトを、チーム内でもバラバラに担当がついていて、2~3人の少人数チームが3つ、という状態でした。

「似ている」ものをバラバラに作っているので、同じようなものをお互い作っていたり、同じようなことでお互い困っていたり。
しかも1つ1つに対して、到底足りない人数で必死にサービスを回している。

なんとかこの状況を変えたい、という思いで、少しずつ少しずつ、バラバラだった組織を混ぜ始めました。

初めはデイリースクラムも、振り返りも、3回ばらばらでやっていたのを、ちょっとずつくっつけてみたり、隣のを覗いてもらったり。

お仕事も、少しずつ隣のプロダクトを触ってもらったり、コードレビューしてもらったりしていました。

いい感じで衝突し始める

さて、気づけばすっかり一緒にやるのが当たり前になった我がチームのふりかえりミーティング。一昨日のミーティングでこんな意見が出ました。

ユニットテストで使うライブラリや、書き方を統一したい。人によって違いがあることで、問題が起きた」

キターーーーーーー!!

以前は2~3人でキレイに分担されていたのが、どんどん混ぜこぜににされている昨今。当然こういう衝突は起こりますよね。
解決すべき問題なので、Tryとして、改めてみんなで話し合う場を後日持ちましょう! ということにしていたのですが…

コードレビューでもぶつかる!

その翌日、さらなる『事件』は起こりました。ある案件のコードレビューで、「プライベートメソッドユニットテストは書くべきではない」というレビューがつけられ、これに対してレビューイから「自分は書くべきだと思う」という『反撃』がありました。

おそらく自分がこのチームに来てから、コードレビューで『反撃』を見たのは初めてだったと思います。

これ以外は
「◯◯に直してください」→「直しました」
しか本当に見てこなかったような。

 

ユニットテストについて話し合う場を持ちましょう といっている矢先に こんなホットなトピックが起こったのですから放っておく手はありません。
第一回ユニットテストについて議論する会 という会議依頼を勝手にメンバーに送信。
議題は、「プライベートメソッドユニットテストは書くべきなのか?」です。

みんな意見は持っている

きっと落とし所は見つからないだろうな と思っていたので、今日の私の目標は、とにかくみんなに意見を出してもらって、お互いの考えを知ってもらうことでした。

はじめに、皆さんどっち派ですか?と聞いたところ、ちょうど半々くらいに。いい具合に、コの字型の素敵なソファーのオープンスペースでミーティングしていたので、左と右で別れて座ってもらいました。
とっさの思いつきでしたが、各自の立ち位置が可視化されて(そしてちょっとテレビのバラエティ的なおもしろさもあって)、これは良かったと思います。

f:id:taichiw:20150905022954p:plain

はじめは言い出しっぺの彼に「なぜプライベートメソッドユニットテストを書くべきではないと思うのか」を話してもらいました。
それに対して、「賛成でも反対でもいいけど、彼の言っていることの意味はわかりましたか?」と確認したうえで(+私からちょっと補足したうえで)、意見がある人に、自由に発言してもらいました。

そこからは、賛成も反対もどんどん意見が出る出る。

どうしても声の大きい人と物静かな人がいるので、さり気なく全員一回は話してもらえるようにちょっと振りつつ、皆さんに意見を出してもらうと…

 

・あれ、賛成派も反対派も同じ事言ってない?

・そもそもPrivateメソッドって何よ?

・俺のPrivateメソッドとお前のPrivateメソッドと、サイズが違う…?

・実はPublicとかPrivateとかが問題では無いのでは!?

 

という感じになってきたところで30分終了。もっとまとまらないと思っていたのですが、いい感じで次に繋がるトピックが出たところで終了したのでした。

 

なるべく自分の意見は入れずにファシリテータに徹してたつもりなんですが…

すげー楽しかったなぁ!

チーム異動があって、「ふりかえり」が自分の中では一番大事だと気づいた話

2月の半ばに組織改編があり、新しいチームにリーダーとして異動しました。新しい環境で試行錯誤する中で、自分がチームビルディングにおいて大切に思っているものが見えてきたので、それを書き残しておきたいと思います。
数回に分けて書く予定ですが、そう宣言しておいて続いた試しがこのブログでは無い…

ふりかえりのためにタイムボックスをセットした

異動してチームメンバーに初めにさせてもらったことは、二週間のスプリント切りでした。

今日から2週間で一旦区切らせてください、というお願いです。

アジャイルな開発」をするため?  多分違います。
計画を立てて実施しきるため?  それも違います。
理由は一つ。「ふりかえりをするため」です。

私は、チームが自分たちのやり方やスキル、チーム力を高めていくために、短いサイクルでの定期的なふりかえりが、最も大切と考えています。
ですので、私の新しいチームのメンバーには、定期的な間隔でふりかえりがあること、そしてその場では、自分たちの問題を自分たちで発見し、自分たちで解決までのプロセスを考えてよいことを知って欲しかったのです。
そのためのスプリント切りでした。

一方で、最初のスプリントの”計画は”、ややゆるめに、「今までの流れで、もともと、むこう2週間でやろうと思っていたことを、この2週間でやってください」と伝えるに止めました。
今回の異動では、もともと存在していたチーム・案件に、私一人が新参として入った状況です。一番プロダクトのことも案件のことも分かっていない私があーだこーだ言うよりも、基本的にはもともとみなさんがやられていたやり方を継続してもらう方がいいと考えました。

たくさんKeepやProblemが出てきたふりかえり

ふりかえりミーティングでは、「全員に参加」してもらうために、Keepと Problemのパートでは順番に一人一人思っていることをあげてもらう手法を取りました。また、私が強めのファシリテーションをし、あげてもらったものに対して深掘りすることもしました。
「○○ができてよかった」→「それができた要因ってなんでしょう?」
「○○で困った」→「本質的には何に困ってたんだろ?」「そういうことが起こった要因はなんだろう?」
という具合です。

嬉しかったのが、みなさん、たくさんのKeepやTryを上げてくれたことでした。初回は一人当たり、2つ以上のKeepとProblemが上がったような気がします。
私が異動してから5回ほどふりかえりを行いましたが、今でもこの傾向は続いていて、嬉しい限りです。

また、ProblemからTryに落とし込む際も、真剣に考えてアイディアを出してくださっている印象があります。

このチームはこれからどんどん、自分たちを自分たちで良くしていって、強いチームになっていくと思います。

テストを整備するよりもアーキテクチャを変更するほうが効果が高そうと思った話

2月の半ばに、これまで3年弱携わらせてもらったプロダクト/チームを離れて、新しいプロダクトを担当することになりました。

プロダクト面での一番大きな違いは、これまでは主にデータ更新/参照系のAPI(HTTPでコールして、JSONとかXMLとか返す)ばかりを担当してきたのですが、今回担当させていただくことになったプロダクトはいわゆる普通のWebアプリケーションで、「画面」があります。

これまでは担当プロダクトがAPIだったので、EndToEndテストの整備もある程度いい感じにできてきていて、リグレッション系の不具合はほぼ0!という素晴らしいプロダクトとチームを作ってくることができました。

しかし今回、テストすることが難しい「画面」をサービスとして受け持つことになり、どうやって品質を保っていこうかなぁ… と思っていた矢先、早速、リグレッションにあたってしまいました。

ちょっと前の案件で、直さなくていいところまでJSPを直してしまっていたそうです。

ロジック周りがどれだけちゃんとしていても、最後の最後にViewでバグられたら回避方法無いじゃん… と悩みました。

エンドツーエンドテストで細かくテストできるか

ここで一旦、Seleniumなどのツールでで細か目のエンドツーエンドテスト(=イメージ的には画面レベルのユニットテスト)と思いました。

ちょうど一ヶ月ほど前にGebというものを覚えたこともあり、GebというかSpockのデータテーブル機能が、いろんな組み合わせのテストケースを並べるにはイケそうじゃん!と思ったのですが…

 

ダメだこれ、遅すぎる。

 

メンテナンス性がー とか HTMLが古くてタグにIDすら振られてねー

 

とか言う以前に、自分のやろうとしているテストをやろうとしたら、どれだけハイスペックなマシンを使っても埒が明かねーなこれ、という結論に至ってしまいました。

そんなのよりアーキテクチャ変更なんだろうな

結局Viewに近いところのバグを減らすためには、Viewにロジックを持たせないことなのだろう
という結論に至りました。

複雑なロジックはAPI化してそこのE2Eテストを充実させるとか、JSPなんぞ使わないでテンプレートエンジンを使うとか。

CROSS2015 に参加してきました #cross2015

CROSS2015というイベントに参加してきました!

パネルディスカッションに参加した!

今回の主目的は、パネルディスカッションへのパネラーとしての参加。

旅行ECサイト各社に聞く成長の秘訣とこれから と題された、異色のパネルディスカッションに参加してきました。

f:id:taichiw:20150130001315j:plain


一休.comさん、Reluxさん、そして楽天トラベルと、オンライン旅行サイトのエンジニアが集まってパネルディスカッションをするというもので、
正直、始めにお話を頂いた時は、「それ、誰か聞きに来てくれるの…?」という感じだったのですが…

会場に対しては少し少なめではあったものの、多くのお客さんに来場していただけました!


旅行ECサイト各社に聞く成長の秘訣とこれから #cross2015a - NAVER まとめ


私自身は初めてのパネルで、
常に回答を考えながら、そして「これ言っていいんだっけ?」も考えながらで、
結構表情がひきつりながら話していたんじゃないかと思います…。
「子供料金あるある」など、諸々の話題で盛り上がれて楽しかったです。
お互い話し足りなかったようで、ぜひ近いうちに居酒屋で延長戦を!ということで本日は別れました。
もともとこの企画の目的の一つが、エンジニア間での横のつながりを作る という話だったので、その点は成功だったのかな、と思います。

ただ、お客さんになにか持ってかえってもらえたのかは微妙…。パネルディスカッション難しいですね。

 

アウトプットを意識する → とりあえず喋ってみた! → いいことあった

代わって、聴講したセッションのお話。

先達に聞くこれからのエンジニア像というタイトルのセッション。
Googleの及川さん、テコラス技術研究所の伊勢さん、そして楽天の吉岡さんのお三方のパネルディスカッションでした。

90分に渡るディスカッションでしたが、特に印象に残ったやりとりを抜粋させていただきます。

自分が成長した、ターニングポイントはどういう時だったか
 → 転職や異動など、環境が変わった時が多い (3名とも)
 → 自分は自ら環境を変えてしまう。怠け者なので自ら仕事を取りに行って必死に勉強する。IPv6の担当になった時もそうだった。(及川さん)

自らを成長させるための方法
 → 思ったことをやればいい。ただし、やりたいことをやるために、やりたくないことを倍くらいやる必要あり(伊勢さん)

これは俺、似たようなことをつい今朝FBに書いてたな…と思ったり。

f:id:taichiw:20150129231121p:plain

 

そして面白かったのが、
 → (40歳以降の人は)若い人と話す。若い人にあってもらいたいと思われるような人間で無くてはならない(及川さん)
 → 若い人と一緒に飲んだ時に説教モードにはいってはいけない(吉岡さん)
 → 自分はむしろ説教される(伊勢さん)

このエピソード、途中から酔っぱらいの戯言みたいになっていたのですが、すごく皆さんの学びに対する意識が現れているように感じました。
皆さん年齢も、経験も重ねているのに、いろんな人から貪欲に新しいことを吸収したいのだという姿勢の現れかと!


そして、はっとさせられたのがこの一言。
 → アウトプットを意識する。呼吸は吸うのを意識するのではなく、吐くのを意識するのが大事。
   勉強会に出るのがゴールになってしまってはもったいない。「質問したり」「LTしたり」「ブログを書いたり」
   して、いろんな人からフィードバックをもらい、そこから良い所を取り入れる姿勢が重要。(及川さん)

今日のカンファレンスでは、夜の部で1時間半ほども、アンカンファレンスという、野良LTの枠が用意されていました。
気にはなっていたものの、今日はまとまったテーマもないし準備もしてないし… と敬遠していたのですが、
この及川さんの一言で一念発起。
5分程度の枠ならどうにでもなるわ! と、とりあえず枠を取らせていただきました。


結局話したのが、以下の話。

f:id:taichiw:20150129231325p:plain


俺、7人位の開発チームのリーダー。
チームのタスクのプランニング/アサインについて悩んでます。
リスク分散や、スクラム的な理由では、「アサイン」をしたくない。全員がすべてのタスクを理解して、自主的にタスクを取って行って欲しい。
一方、「あなたのタスクはこれ!」の方が、よりそのタスク/プロダクトに対して責任感が生まれ、モチベーションは上がる。
悩ましいのだけれど、どっちがいいと思う?

と言うもの。
5分枠のうち、1分半ほどで上の話をさせてもらって、残りはひたすら会場に意見を求めるという、
俺も会場の人も酔ってるからどうにかなるだろ! 的な酷いセッションでしたw

幸い、お仲間のメンバーが盛り上げてくれたこともあり、
・2人組にすれば両者のいいところがとれるのでは
・3ヶ月位でのローテーション制
・そもそも会社に自分しかエンジニアがいないのでそんな状況ではない
などの素晴らしい回答を頂きました!


さらにさらに結果的にここで話したことがきっかけになって、この後及川さんともお話させていただくチャンスが。
おそらく、先ほどのパネルディスカッションの後に話しかけに行っても人だかりにまみれて対して話せなかったのではないかな、と思います。
やはり、アウトプットあるところにインプットありだと感じました。

なんでアジャイルなんだっけ

グループの後輩が二人、James O. Coplien氏の認定スクラムマスター研修を受けてきました。

昨年私が受けた時と同様に、たくさんの刺激を受けて、いろんなことを考え、やりたいこと、悶々としていることがたくさん湧き出ている状態のようです。

当然のことながら(?)、じゃあAgileしたいんだっけ? Scrumしたいんだっけ? やりたいことはそれなんだっけ?
というところに一度彼は行き着きました。
その様子を見ていて、「自分はどうだったんだっけ?」と、少し振り返ってみたので、書き記してみたいと思います。
 
自分が最初にScrumに興味をもったのは、タスクボードで皆のタスクを見える化できる点でした。
Scrumとの出会いはほんとうに偶然で、「特にAgileには興味がなく、海外もそこまで興味がなかったんだけど、とにかくプチ移動して他の環境で自分の実力を試してみたかった」という理由で申し込んだ、短期海外異動Agile研修で、Scrumらしきものと出会いました。
そこで、チーム内のタスクを自分だけが把握していることに抱いていた違和感への回答を見つけたのです。
このへんのくだりは昨年、社外で発表させていただく機会を頂きました。

 
さて、上記資料を作ったのは、今から一年ちょっと前です。
この時から、「アサインするのって違うと思うんだけどな-」と悶々としていたのですが、この後、認定スクラムマスター研修をうけて、
「群がる」スクラムのイメージがようやくハラオチします。


私、スクラムを分かってませんでした 〜Jim Coplien氏のScrum Master 研修を受けて 1〜 - エンジニア的なネタを毎週書くブログ

これがちょうど今から一年前です。
 
そしてここから一年間、「群がる」スクラムを試していたのですが、
これはこれで若干の違和感を感じ始め、今年の夏ころからもう一度「個人」にフォーカスした仕事の進め方の検討を始めてきました。

XP祭りでこのLTをした9月の段階では、一人一タスクアサインってサイロを作りがちだしやっぱり微妙かなぁ… という思いが強かったんですが、
この後きっかけがあり、現在は、さらに各チームメンバーが「自分のタスク」に責任を持ってフォーカスをしてもらう形をとっています。
 
一見すると元に戻ってしまったようにも見えるのですが、自分なりに模索しながら進み続けてきた結果、たまたま一年ちょっと前と似たようなところに立っているのであって、
決して戻ったわけではないと思っています。
今の取組みについては、年末くらいに改めて振り返りたいと思っています。

U+FFFF以上の文字ってなんや → サロゲートペアってなんや → Spring Web Services が言うことを聞きません! とかで一日潰れた話

表題のような感じなのですが、これまで理解が曖昧だったUnicodeとか何とかが今までよりわかったのでメモ。

尚、こちらのサイトを非常に参考にさせていただきました。

Unicodeについて

コードポイントとは 文字コードとは

今日覚えた単語その一。Unicodeに限らず、文字をコンピュータ上で表現する際、1つの文字に1つの数値を対応させるわけですが、この文字に対応する数値をコードポイントというそう。
いままでASCIIコードとか呼んでました。

そして、文字と数値の割り当てのルールのことを「文字コード」と言うんだそうです。

Unicodeとは から UTF-XXは何が違うんじゃ という話へ

Unicode誕生

文字コードが乱立したため、あるコードポイントで表現される文字が、文字コードによって、てんでばらばらという状況に。

ややこしいから、ひとつの統一した文字コードをつくろう! ということで「Unicode」が作られることになりました。

Unicodeを使うときは、U+12ABのように16進数の先頭にU+をつけて表すことにして、
U+0000~U+FFFFの216パターンで世の中の文字を表そう!ってことでUnicode1.0が生まれたそうです。

サロゲートペアの誕生

ところが、特にアジア圏の文字を表そうとしたらこれでは全然足りなくて、U+10FFFFまでUnicodeを拡張することになりました。

しかしこれだと1文字表現するのに21bit必要で、2nじゃないのでとっても切りが悪いという事態に。

そこで、もともとUnicode1.0で使われていた16bitでなんとか表現するために、

たまたま未使用だったD800H~DFFFHを2つ組み合わせ、32bitを使ってU+10000以上を表現するという、むりくりな方法が発明されたそうです。これが「サロゲートペア」。

で、U+0000~U+FFFFの文字をBMP(Basic Multilingual Plane, 基本多言語面)、U+010000~U+10FFFFまでの文字をSMP(Supplementary Multilingual Plane追加多言語面)と呼ぶことにしたそうです。

UTF-XX

上記のような経緯を踏まえ、実際にデータ上でどう表すかという、エンコード方式がいくつか考えられたそうです。

UTF-16 → 上の通りのサロゲートペアをそのまま実装した、一文字に16bit使うエンコード方式。一番正直。

UTF-32 → サロゲートペアはややこしいので、すべての文字に対して32bitを割り当てた方式。一番わかり易いけど、一番無駄が多い。

UTF-8 → 文字に合わせて、8bit, 16bit, 24bit, 32bitのどれかを使うようにしている。Unicodeの中では無駄が一番少なく、最も普及している。

JavaでのSMP

少し話変わってJavaのお話。

突然ですが、Javaのプリミティブ変数のchar型は、上限が (char) 0xFFFF なので、なんとSMPに割り当てられた文字が表現できないそうです!

そこで、Java5.0以降、上記のサロゲートペアの考え方を流用して、SMPは、char2つで1文字を表すようにしています。

Javaでのサロゲートペアの扱いについてはこの記事がわかりやすかったです。

Java とサロゲートペアについて - にょきにょきブログ

Spring Web Serviceが言うことを聞きません!

…と、ここまで説明してようやく私の身に起こったことを。

いろいろありまして、XML上にU+1F6ADのようなSMPを出力する必要がありました。

XMLの仕様的には単純で、数値文字参照を使って 🚭 とか 🚭 と表現できればOKです。

一方、私達のサービスではSpring Web ServiceというSOAPアプリのためのフレームワークを使っています。

こいつ、普段はなかなか便利な子でして、EndPointのレスポンスとしてBeanをReturnすると、そのBeanの階層構造をそのまま反映したXMLを作ってくれるのです。
また、XML上必要なエスケープも自動で行ってくれて、たとえば「&」が文字列の値として含まれていたら、XMLを出力する際にはきちんと「&」と出力してくれる、という具合です。

では、このSpring Web Serviceを使った時に、
レスポンスのBeanに含まれる hoge フィールドに、🚭(U+1F6AD)が入っていたらどうなるか!?

<hoge>&#55357;&#57005;</hoge>

なんじゃこりゃぁ!?

55357 = D83DH, 57005 = DEADHで、サロゲートペアに分解された上で実体参照として表現されています。

おそらく、String hoge 内のcharの配列を頭から順に1文字ずつ処理してるんだろうなぁ… と推測されます。

更に良くないことに、D800H~DFFFHはUnicodeでは単独で存在できない文字なので、上記&#55357;や&#57005;はXML上使えない文字で、これらが含まれたXMLは正しくパースされません。

 

結局現状で、XMLを破壊しないためには、Character#isSupplementaryCodePoint methodを使って、SMPを除外する以外方法がなさそう。

うーむ…。

おまけ Oracle上では

じゃあこの禁煙マークがOracleUTF-8エンコードで)に入ってた場合どうなるか

select ascii(hoge) from hoge_table;

-> 4036991661

おうふ。

これは、4036991661 = F09F9AADH でして、SMPをUTF-8で表現する場合、やたらややこしいルールで、やたらでかい数値に変換されるため…みたいです。