おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

父が亡くなりました

Facebookに書いたらクソ長文になっちゃって、私はFacebookというサービスというかメディア*1 をあんまり信用してないんで、ちょっとアレンジしてこっちにもおくことにしました。

TLDR

このギョーカイ(特にOSSな世界)独身で年老いた両親がいるって人も増えてるかもしれないので手短に我が家がラッキーだったことを書いとくと、事前にやって置けることとしては:

  • 生前に葬儀屋の会員サービスに申し込んでたこと
  • 同じく空っぽだけどお墓を持っていてお寺が決まってたこと

で、自力では何ともできないけどラッキーだったことは:

  • 言語障害を患って施設に長いこと入っていたので、プライベートの付き合いがほぼなく家族葬だと事前に決められていたこと
  • 一度事業に失敗して自己破産をし、不動産は私の所有になってたので、遺産は普通預金しかなく、また兄弟仲も悪くないので遺産相続がもめそうにないこと

ですね。やっておけばよかったなあってことは:

  • 生活インフラの名義人変更は、生前時間があるうちに
  • 亡くなったときに連絡を取るべき人たちを一覧にしておいて、常にカバンにいれておくなり、非常持ち出し袋的にイザというときに持ち出せるようにしておくこと
  • 親戚としてお通夜や告別式に参列する人でもお食事に出てくれるとは限らない、けち臭いことをいえばお食事に参加いただけるかちゃんと確認しといたほうがお財布にはやさしい

ってな感じでした。

disclaimer

  • この記事は人が死ぬということに伴うバタバタを描いて、あわよくば皆さんがそこから得るものがあればなという意図で書いてるものです。
  • ご愁傷さまとかそういうご挨拶だけのコメントはいらないです。自分の体験を踏まえて自分のときはこうで大変だったなあとか、こんなことは参考になったなあというコメントは大歓迎です。

では、クソ長本文の始まり始まり~~。Facebookからのコピペにちょっと加筆した程度なので、それFacebookで読んだよ、という人は記事ごと飛ばして大丈夫です。

……以下、Facebookからのコピペアレンジ……

11/8、月曜日に父が亡くなり、疾風怒濤で昨日通夜、本日告別式と初七日の法要と火葬を終えてお骨になった父を抱えて帰宅しました*2。 いやーーーーくたびれたーーーーー。

週末明けた月曜日、朝ごはんたべるかー、それと並行してコーヒーでも淹れよう……と、準備してるところに唐突に入電。 父の入院先からで、もうすぐ心臓が止まりそうなのですぐ来てくれと。とりあえず家族LINEにその旨だけ入れ、 会社に今日は休むことになるので打ち合わせ対応などお願いしますの連絡を入れて、猛ダッシュで病院に向かいましたが、 到着したときには心停止のアラートが鳴りっぱなしになっている父が。 その場でお医者様が死亡宣告出していただき、臨終ということになりました。死亡時刻は7時47分だったかな。 でも、まだ体が暖かいうちにお別れできただけでも幸運だったと思います。

もともと2回の脳梗塞を経て言語障害と左半身のマヒを抱えており、施設に入ってもらっていましたがそこの施設とは相性がよかったらしく、 本人も機嫌がよさそうでしたし、施設の職員さんからも(リップサービスかもしれないですが) 小笠原さんはやさしい、ほかの入居者さんのことをいつも気にしてくれている、と言ってもらっていて、穏やかに暮らしていました。

公務員を長くやったあと事業を始めて大やけどをして(わたしの父親ですからね、商売ができるわけがない)自己破産をして、 実家を父親から私が住宅ローンを組んで買い取ることにより抵当から抜くみたいな荒業をしたりしました。 そこからはしょぼくれた日々を送って、病気にもなり苦労もしたし老々介護で母親もメンタルが死にそうでしたが、 施設入りしたことでQoLが上がって、ああ、こういう穏やかな日々が来て本当によかった、と思っていた中。

コロナ禍で施設に面会にもいけない日が続くなか、今年の1/3に誤嚥性肺炎で入院したとの連絡が。 あわてて駆け付けたものの病院ももちろん面会不可なのでなにもすることはできず。 唯一できたことは、「万が一のことになっても延命措置はしないでください」というお願いをしたことぐらい。

そこからどうしても痰が切れなくて飲食ができない状態になって経鼻栄養になりましたが、 数か月経って家族で取った励まし動画を見せたらにっこり笑う程度に回復して、 このまま回復してまた口からモノ食べられたらいいなあって言ってたんですが(食べることがホントに好きな人だったので)。

夏場に一度悪化したときから酸素吸入も取れなくなって、 秋からビデオ面会が可能になったんですがそのときにはこっちの呼びかけにも反応しなくなっていて、 ああ、もうこのままこの病院で最期を迎えるんだな、という覚悟はしました。

ただ、11/10って父の誕生日で、今年で米寿なんですよね。なので次の面会は11/10にして、 家族でビデオメッセージ取って差し入れでもしようか、って話をしていた矢先のことでした。 あと二日頑張ってくれたら米寿だったのに……とは、言えないですね。 本人苦しそうなのずっと見てきたので、あれ以上頑張れとはとても言えない。 とりあえず頑張ったね、おつかれさまだね、といって、はてこれからどうしよう、と……。

幸いなことに生前に、 某葬儀屋グループの前払い会員的なものになっていたのですが、 なにしろ慌てて出てきたのでそこの会員向け書類なんかもぜんぶ置いてきたわけで。 私も母も、そもそもなんて葬儀屋さんと契約したのか覚えてない。

一方で病院からは霊安室を使える時間は限られてるのでなるはやで葬儀屋がいつ来るかを知らせろといわれ、 記憶を手繰って検索して出てきたところに電話をして「ウチってそちらの会員ですか?」から始める始末。 結果としては一発目からアタリで、すぐに人を寄こしていただくことになりました。 会員に入ってなければまず葬儀屋さんを決めないことには遺体の引き取りもできないので (いや、ウチの車なら普通に運べるしウチに置いておけるよ?って人は除く)、 事前に会員になってたことで、決めるべきことが一つ減ってよかったです。

で、遺体を引き取ってホールで安置いただいた上で、お葬式の段取りを相談することに。 わたしは一応長男なので(末っ子ですが)、母とどっちが喪主やる?って話になったのですが、 わたしは親戚やご近所とのお付き合いがほとんどないので、 母にはそちらの対応を任せるとなるとわたしがやるのがまあ合理的なので、喪主ってことになりました (我ながら頼りなさそうな喪主だ)。

でも喪主ってなにやんの? よくわからん。(幸いなことに)経験ないし身近で葬式を出した経験もない。 でも、事前に入っていた会員制度は、基本はパッケージになってて、オプションを足していくだけというわかりやすいサービス構成。 しかもスケーリングも考えて香典返しなどは多めに用意して使った分だけで後日清算、という便利さ。 お通夜の後のお食事会も近親者以外は会食で提供する食事の代わりになるお米をお渡しすることができる(これも使った分だけ)とか、 いやーサービスとしてよく考えられてるわ。 そして「一生に一度のことだから」といってついついオプションを足してしまうお気持ちをうまく利用したご商売が巧みですね(誉めてます)。

でまあさっき書いた通り11/10は父の米寿なので、単なるお別れの会じゃなくてできなかったお祝いの会にもしたい、可能なら11/10、11の日程だとうれしいと。 それは葬儀屋さん的には可能だけど、お坊さんの手配次第で、 ウチは(中身空っぽだけど)いちおうお寺さんにお墓持ってるのでそこの住職さんに聞いてほしい、とのことで、電話かけてもずーっと留守電。 どうしようか……と考え込んでたら葬儀屋さんが

「10、11で決めましょう! 米寿のお祝いを兼ねるってことは大事にしたいです。お坊さんは、もし都合がつかなかったら同じ宗派のお坊さんに相談してくれるとかもあるので何とかなりますよ!」

と言ってくれたのでハラを決めて、10日お通夜、11日告別式という日程にしました。

でもお坊さんが捕まらないの困るな……よし! お寺に直接うかがってみよう!30分もかからないところだし! ということでクルマに飛び乗り向かって、あと5分で作ってところで入電。 「すみません電話遅くなりまして……」 「あ、今そちらに向かってて、直接お話ししていいですか?」 「え、そうなんですか??ではお待ちしてます」ということでお寺に到着。

「えっ、日程決めてきちゃったの? まあ、それならなんとか都合はつけますよ……」と戸惑ってた住職さんですが、 父の出身が青森の奥入瀬渓流の近くだって話で「あそこは私も行きましたけどほんとにいいところですよね」みたいな話で盛り上がって、 「じゃあ奥入瀬から字を取って戒名作れないか考えてみます」ってことになって、結果的には襲撃してよかった。 最終的にはやっぱり会ってご相談したほうが、電話よりもずっといいと思います。 私初めて住職さんとお話ししたんですけど、さばけたよい人で、あーこの方なら任せても安心だなと。

翌11/9は友引なので何もない日なので勤務日にしたんですが、 我が家は電気ガス水道CATVなどの契約が全部父名義だったし父の口座からの引き落としなのでこれをなんとかせないかん。 もっと早くやっておけばって感じだったんですが、なんか父の死が近いってことを予期して動くのが気持ちよくなくてズルズルと引っ張ってきちゃったんですよね。 でもさすがにまずい。ということで仕事の隙間で、こういう関係とか保険とか年金とかそういうたぐいのところに電話をかけまくる必要があり仕事が進まない。 その予感はあったので朝5時起きして頑張ってたんだけどそれでも進捗出ない(そういう日に限ってチャットの問い合わせ対応が多かったりしてね……)。 私の仕事ってほぼ私一人でやってることが多いので、金曜までにやっておきたいことは火曜日までに終わらせなきゃいけないので、夜も12時まで仕事して3時間睡眠で、 お通夜当日の10時近くまで仕事してようやっと終わりました。やれやれ。

あともう一個あって、じつは日曜日に若くして亡くなった知人の告別式に行ってて、そのあと礼服クリーニングに出しちゃったんですよね。 で、これを取りに行かないといけない(クリーニングだしたのが日曜当日でよかった)。

あとさすがに喪主が二日続けて同じYシャツってのはどうかなと思いつつも白いワイシャツは1枚しかアパートから持って帰ってこなかったので買ってこないといけない。 そんなわけでこれも火曜日の夕方回収したり調達したりしました。綱渡りだな。

それ以外にも、例えば父の遺影と会場投影用の思い出写真を選んだりフィルム時代のやつはスキャナで取り込んだり、 家族LINEで相談したり、そういう写真データや、保留にしてた注文の類を葬儀屋さんに連絡したり、 まーいろいろと忙しすぎて、悲しいとか寂しいとか思う暇がなかった。うーん親が死んでもこんなもんか、自分案外つめたいやっちゃな、そんな風に思ってました。 で、お通夜までは時間があったので、屋根にカヤック積んだあんまり汚いクルマで喪主が乗り付けるのもなあと思って、 カヤックおろして久しぶりに洗車して、あと葬式ってカード払いとかダメで現金一括が多いので銀行行ったりして。 お通夜の15時ぐらいまではそんなことをギリギリまでやってました。 ほんとバタバタやな。

んでお通夜なんですが、長いことOSSのイベント手伝ったり主催したりしてたせいで、どこか手すきのところがあると気になってしょうがない。 受付頼んだ姉貴が、プチカメラ趣味なので張り切って写真撮ってるなか(思い出になるので写真撮ってもらうこと自体はありがたい)、 なぜかわたしが受付に立って受け取ったお香典を抱えてドキドキして、喪主なのにろくに会葬者に挨拶もしてないというですね。喪主ってなに……概念? まあでも祭壇のお花はすごいいいチョイスだったし、 「米寿なので赤いちゃんちゃんこをイメージしてポイントで赤を入れてほしい」「青森県人なのでリンゴが好き」みたいな要望にもばっちり、応えてもらって、 遺影の写真も素敵に仕上げてもらって、あーすごいよい式になりそうだなって。

f:id:naruoga:20211116062809j:plain
祭壇。まだ準備中なので仮位牌載ってないけど

で、お願いして、最後に喪主の挨拶をさせてもらうことにしました。 ぶっちゃけそれで緊張してて手汗がすごくて、ご焼香のときに手にお香がくっついちゃって閉口しましたw

で、台本もなしに「ぜひお別れの場だけではなく、父の米寿を祝う気持ちで見送ってほしい」みたいなことをしゃべってたら段々こみあげてきて、 あれ? さっきまで全然悲しくなかったのになんで? うそでしょ? もう涙が止まらくなってマスクの下は鼻水だらけだわ、お見苦しい挨拶でしたが、よいスピーチだと褒められてホッと一息。 その後、お食事してホールに泊まって、母と、普段は離れて暮らしてる姉と、父との別れを惜しんで話したりしました。

開けて翌11日、お葬式。今日は全然こみあげてこないし大丈夫、あー昨日はびっくりしたなあ、と思ってたんだけど、 最後にお棺にお花いれるときに、家族といろいろ話しながらやってたらまた涙がドバドバ出てきて……マスクしながら泣くと、 ぱっと鼻がかめないで困るということを学んだ二日間でした。

それから火葬場にいって最後にお見送りをして、火葬の間お食事をして、お骨拾って、ってときにはもうさっぱりしたもんで、 へー人間の骨って焼くとこんな感じになるんだー、こんな大きさの骨壺に入っちゃうんだなあ、そんなことを純粋に感じてました。

で、お骨になった父を連れて帰宅。青森から来てくれた叔父さんと姉貴も交えて話をいろいろしつつ、 最後に二人を駅まで送って、またまた礼服をクリーニングに出して、帰ってきて、経過をFacebookに投げたって感じです。

葬儀屋さんが届けてくれた花とかも飾ったら祭壇がすごい豪華になって、父も心なしかうれしそう。 施設に預けてから、正月に一時帰宅することはあってもず~~~~っと家にいなかったから、久しぶりに父がいる生活が四十九日までは続くことになりますね。

へーしゃの場合は1親等だと忌引三日なんですが(一般的かな?)、金曜日はもう行事的なことは終わったので比較的のんびりで、 午前中は水道料金の支払い請求の切り替えのために銀行に行き、ついでにインフルの予防接種も打って。 午後は役所にいって、葬儀屋さんが市からもらってきてくれたチェックリストをもとに各種手続きを済ませて、 その足で「手の皺と皺を合わせて」で有名な某仏具店に行き、仏壇や仏具の選定も済ませて。 いまの仏具っていろいろ便利? に進化してるんですねえ。 仏壇は母の寝室に置くことになってるので、母が気に入ったものを買えてよかった。

あとはおっかけで来るお香典も含めて収支弾いたり、まあ大イベントである四十九日の法要関係の手配と相続関係が残ってるけど、 とにかく喪主終えてほっとしました。よかったよかった。 もちろん父が死んでさみしいし悲しいけど、最後はホントに辛そうだったから、楽になってよかったという気持ちが大きいです。

今は朝晩、お線香は省略してお水換えてリンを慣らして、 「長いこと刻み食と経鼻栄養だったから、ご飯とかおやつとか食べられるようになってよかったねえ」 「お父さんは外面はいい人だったから、きっと常世の国に行ってもみんなに愛されるんじゃないかな」 「家族にはけっこうな人だったけどねw」 みたいな会話をしつつ日々すごしております。初七日は一緒にビールで乾杯しました。

ま、そんなわけで、人が亡くなるってのは大変だなあ、というつまらない述懐でしたよと。おしまい。長文読んでくれてありがとうございました。

f:id:naruoga:20211116063059j:plain
ウチに安置されてる父(の遺骨)。お花たくさんで本人も心なしかうれしそう。四十九日の法要まではこうやっておうちでお骨守ります

*1:最初「会社」って書いてたんだけど、今Facebookって会社はないじゃんねえ……。

*2:注;これをFacebookに書いた11/11木曜日時点のこと。

LibreOffice Conference 2021雑感

naruoga.hatenablog.com

前の ↑ 記事でも予告したように、LibreOffice Conference 2021(以下LibOCon、りぼこんと読んでね)参加してきました。

libocon.org

LibreOfficeのコミュニティ活動辞めたっていってたのに何で年次カンファレンス参加してるの? といわれるかもだけど、LibOコミュニティには知人が多いし応援したいプロジェクトでもあるし、ただメンタル弱ってるので「継続的に価値がある貢献を、周りと議論しながらやっていく」みたいなのは約束できないしそれを求められるのは正直苦痛だけど、イベント参加したりそれをTwitterにメモったりこういうブログ書くことは、誰ともかかわらずに一人でできますので。はい。

つーてもおおむね当日の内容はTogetterに書いてしまったのでそっちを見てください*1

togetter.com

また、発表のビデオについては順次YouTubeに上がっているので、上のTogetterをみて「へーこの話面白そう」って思った方は、そちらを直接見ていただくのもいいかもしれません。

www.youtube.com

なのでこの記事は、個別のセッションがどうとかではなく、全体的になんとなく感じたことを雑にまとめたいと思います。

ちなみにクソ長いです。分割しようかなとも思ったけどそれも大仰なので適当に流し読みして、気持ちがひっかかったところだけきっちり読んでくださいませ。

イベントのスケジュール

今回、イベントはハンブルグのLUGとの共同開催ということになってて、イベント自体はハンブルグタイムゾーンで企画されてたんですが、その時間は12:00-17:30と、割と短めに設定されていました。 その理由は明確には確認してないのですが、もしかしたらタイムゾーンが離れた我々極東の民のことも考慮してくれてたんでは……って、ちょっとだけ思いました。 日本時間だと19:00-00:30で、去年朝5時まで起きてなきゃいけなかったことを考えると天国のようにラクショーでしたし。 もしそうだとしたらうれしいなあ。 オンラインイベントは参加こそ容易ですが、時差だけはなんともならないですからね。

また、イベントのスケジュールページ:

https://events.documentfoundation.org/libocon2021/schedule/events.documentfoundation.org

にて、ブラウザのロケール設定を見て? タイムゾーンが選択できるようになってたのもありがたかったです。これまでだと、聞きたいプログラムをチェックして、それをGoogleカレンダーに現地タイムゾーンに登録する、っていちいちやってたので……。

公式アプリの存在

ほかのイベント(COSCUPとか)だとよくあったんですが、今回、LibOConにも公式アプリがリリースされてました。Androidだけですけど、Play Store だけじゃなくて F-Droid でも公開されてたのがそれらしい。

タイムゾーンを端末設定で選べること、興味があるセッションにマークすると時間にアラームで知らせてくれること、スケジュール変更があればリアルタイムで通知が来ることなど、なかなかよくできていました。これはいろんなイベントで取り込んでほしいなあ。

コミュニティ、エコシステムの関係と「LibreOffice Technology」「LibreOffice Enterprise」

今年の大きなテーマの一つは、この部分だったのかなあと思ってます。

ここでいう「エコシステム」っていうのは、すごい大雑把にいえばLibreOfficeのフルタイムの開発者を雇用する組織のことです。多くはLibreOfficeに関するなにか(例えば長期サポート版などの派生した有償のプロダクト、導入支援、サポート、教育など)を顧客に提供して対価を得る企業であることが多いですが、昔のミュンヘンのように自分たちが使うための問題を解決するために開発者を雇用していた組織もあります。

LibreOfficeコミュニティが、「エコシステムの金銭的利益(さらに言えば持続可能性)とコミュニティの関係や利益にどう折り合いをつけるか」って議論は結構重要です。やはり多くの開発行為はエコシステムからなるものが多く、特に特定のバグ対策ではない大きい機能改善は、フルタイム開発者でなければ実現できないことも多いですし、フルタイム開発者は霞を食べて生きていくわけにはいかないですから。もちろんエコシステムはコミュニティの重要な一部であり、彼らのコードやその他(イベントのスポンサーシップやGSoCのメンタリングなど)の貢献なしにはLibreOfficeプロジェクトは継続していくことは困難です。

一方で、LibreOfficeを取り巻く状況としては以下のようなものがあります。

  • そもそもデスクトップでアプリを使う、というユースケース自身が縮退しつつあるのでは
  • OSSを単にサポートするというビジネスの成功例はほとんどなく、新たな展開が必要
  • 派生版を提供するエコシステムにとって、「LibreOffice」というブランド力に頼りたい半面、それを前面に出してしまうと自組織のブランドイメージが向上しない
  • 各OSベンダーが提供するStoreシステムからLibOをインストールしたいという要望に対して、Storeの要求に合わせるコストをだれがどう負担するか、その負担分をどう回収するか

それから、今までは「Poorman’s MS Office」でやってこれたとしても、MS OfficeがOffice 365のライセンス費用を相当抑えてきており、Googleも個人利用では無償、商用でも競争力のある価格設定をしている現在、エコシステムへのサポート込みでLibreOfficeを使うことは決してコスト的に有利にならない、したがって「安いMS Officeの代替品」という立ち位置ではない、LibreOfficeならではの魅力を強力に発信していく必要があるわけです。

そこでLibreOfficeコミュニティとして旗印として立てているのが「コアの共通性」と「ODF」の二本柱です。

コアの共通性というのは、前から紹介している通り、LibreOffice OnlineはサーバーサイドでLibreOfficeを動かし、そこでレンダリングした結果をビットマップタイルとしてクライアントに送信するということで、クライアントの状態によらない統一した、デスクトップ版と変わらない(例えば、ほかのクラウド系オフィスソフトでは実現できていない縦書きなどもサポートした)レンダリング結果を実現しています。またCollaboraが開発しているCollabora Office for iOS/Androidは、基本的にはLOOLサーバを内蔵して、アプリはWebViewでLOOLクライアントとしてふるまうという実装をしています。つまりデスクトップ、クラウド、モバイルにて、統一したレンダリングエンジン、統一したコア実装を用いており、ユーザーはどのプラットフォームでも、同じレンダリング結果と、ほぼ共通の機能を得ることができるというわけです。

もちろんこの実装には利点も欠点もあるわけですが、それはおいておいてもこの「共通性」を強みとしてしっかりアピールしていきたい、と、LibreOfficeコミュニティは考えています。

そしてODFは、LibreOfficeの標準ファイルフォーマットであるだけでなく、オフィスドキュメントの相互運用性ということに真摯に向き合った国際標準でもあります。アプリケーションから利用するにも、ZIPファイルをほどいて中のXMLを人間が見ても、プログラムから操作するにも優れたフォーマットです(詳しくは過去記事を参照)。イギリス政府が「編集可能な文書ファイル形式」をプレーンテキストとODFに限定しているのは、このような優位性を認められてのことです。その優れた点の一つが、ワープロ表計算、プレゼン、図形描画と同じスキーマを持っていることです(OOXMLが、スキーマはおろかXMLファイルのディレクトリ配置すら異なるのとは対照的ですね)。これが二つ目の「共通性」というわけです。

この二つの「共通性」を基盤とし、ワープロ表計算、プレゼンといったアプリ、そしてPC(デスクトップ)、クラウド、モバイルが同じ基盤に乗っていること、これをLibreOfficeの優位性として積極的にアピールしていこう、というのを表すのが「LibreOffice Technology」という用語、だという理解です。

f:id:naruoga:20211010231024p:plain
LibreOffice Technologyの説明図

そして、エコシステムベンダーは、自社ブランドを冠したプロダクトに「LibreOffice Technology」を使っている、というアピールをすることができる、というわけです。

また、LibreOfficeに対して「大きく革新的な機能開発」を行うには、やはりボランティア開発者だけでは利用できる時間的に難しく*2、フルタイム開発者の力が必要です。このような場合、①そのような機能を求める顧客の要望に求めてエコシステムが対応する、か、②LibreOfficeを資金面で支える非営利法人The Document Foundation(以下TDF)が資金を供給して開発者を公募し、それを受けた開発者やベンダーが開発を担当する、の二つの方法があります。顧客にとってわかりやすい魅力的でない改善であっても重要なものというものがあり、それを解決するには②の手段を取る必要があります*3

その場合、資金の出どころはTDFということになるのですが、TDFにおける収入の大部分は実は寄付によっており、そして寄付は個人やSMB(中小企業)によるものがほとんどで、大規模な組織、つまりエンタープライズ(大企業、政府機関、自治体、学校法人など)からは行われていないというのが現状です。そして彼らがエコシステムにもお金を払っていないのであれば、いわばそれはエコシステムを含むコミュニティの成果にフリーライドしている、ということになります。

したがって、エンタープライズが寄付を行うつもりがなければ、積極的にエコシステムに対価を払うべきである、というのがLibreOfficeコミュニティからのメッセージで、それを表す言葉が、TDFからリリースされているバージョンに対する「LibreOffice Community」と、それに対してエコシステムが提供する「LibreOffice Enterprise」です。

このように、エコシステムの持続性をコミュニティの持続性と積極的に結び付け、エコシステムがより多くの利益を得ることでLibreOfficeがより良い方向に発展していく、というメッセージを強く発信したカンファレンスであった、と、感じています。

これは非常に重要なことで、当然意見は一様でなく、ここ数年の間、さまざまな議論を経て今回のメッセージを出すところまでようやっとたどり着いた、そういう風に考えています。 丁寧に議論を重ねてきたコミュニティメンバーたちには敬意を示すところです。

が……。

TDFメンバー・コミュニティメンバーに対する調査と取り組み

この手の議論はもちろん大事で、オープンな場で透明性を持った形で議論するのは望ましい……と、理屈ではそう思うのですが、この手の議論は紛糾するとひたすら長文の英語のメールが延々と流れることになり、そしてあまり英文読解が得意でなく、かつ議論のすべてを機械翻訳に通すほどの元気もない私は、「なんか対立関係が表面に出てきている」という印象だけを受け取ってしまいがち、ということがありました。

前にも書いたけど私がつらくなった一つの要因に「なんかグローバルなコミュニティでもギスギスした雰囲気を感じてた」ことがあるんですが、それは、こういう議論がとにかく紛糾しているけど詳細を追い切れるほどの気力も能力も欠けていた、ただ紛糾している雰囲気だけが見て取れてそれがつらかった、ということがあります。

その中の一つには、エコシステムの一つであるCollabora Productivity(以下単にCollabora)が一強になりすぎたってこともあると思います*4

エコシステムに開発の多くを依存しているLibreOfficeプロジェクトにおいては、エコシステムのビジネスが健全に発展し続け、十分な利益を得ることができ、それにより多くの貢献者が開発だけでなくその他の活動で生計をたてられる、あるいはサイドビジネスとして十分な利益を得られることは非常に望ましいです。

一方でSun Microsystemsという一組織に依存していたことからプロジェクトが継続できなくなったOpenOffice.orgの反省から、エコシステムとの距離感に対して警戒感を持つ人も少なくなく、ボランティア貢献者の中には「今のTDFは過剰にエコシステム方向を向きすぎている」とか「ボランティアによる貢献をエコシステムがタダ取りしている」などと考える人もいるようではあります。

先に書いたとおり私はそういう議論を逐一追えてはいないのですが、とにかく一種の緊張関係があるのは事実。私の目から見ると、今回のカンファレンスは、そういう緊張関係に対して、なんらかの解決を目指そう、という姿勢を感じました。それはTDFとして目指していくところをより丁寧に説明しようという点もそうですし、TDFのメンバーシップ委員会が企画した「コミュニティインタビュー」に対する振り返りとディスカッションというセッションの存在についてもそうです。

コミュニティは当然いろんな思惑がある人がいろんな動機で参加してくるところなので、「全員の思いや行動を揃えよう」とするのではなく「違いを尊重しつつ一緒にできることをやっていこう」というふうになればいいなと感じます。そしてそう思っている人はTDFのコアにも確実にいる、そういう思いを感じたカンファレンスでした。

LPIやUdemyと協業した新しい認定プログラム

このブログやTwitterなどで紹介したことがあるのでご存じの方はいるとは思いますが、TDFにはその公式の認定制度があります。

この認定制度は、例えばMicrosoftOracleCISCOといったベンダー認定と違い、「LibreOfficeに対して十分な知識と専門性を持っており、貢献の実績がある」ことを示すもの……という側面が強いものでした。なので、例えば移行専門家であれば「過去にこのような移行を推進した・支援した実績がある」といった証拠となるドキュメントを提出し、認定委員会による面接を経て認定される、というものでした。認定専門家には移行(マイグレーション)、トレーニング、開発が存在します。

もちろんこれらの認定制度は、どの企業にも属しないコミュニティベースのプロジェクトであるLibreOfficeでは重要な役割を果たしてきましたが、一方で以下のような課題がありました。

  1. 「利用者がLibreOfficeの使い方を正しく把握しているか」といった、例えばMOSOracle MasterCCNAのように「履歴書に書ける」資格が存在しない。たとえばLibreOfficeやODFを政府機関で採用している国や自治体においてはこのような資格は就職に有利に働く
  2. 認定専門家(特に移行とトレーニング)は当然、LibreOffice/TDFからのメッセージを正しく使える「代弁者」としての責務を担うことになるが、認定専門家が正しくその理念を伝えているとは限らないし、認定専門家の品質が悪いと逆にプロジェクトやコミュニティにネガティブな印象を与えうる
  3. 失効期間が曖昧で、アクティビティが低下している人でも資格持ち、という状態になりうる

このような問題意識のなかから、今回はいくつかアナウンスがありました。1. の解決手段として、LPIとの協業による新たな資格を用意するとのことです*5。すばらしいニュース! ただ、まだ検討を始めた段階であり実際のローンチには少し時間がかかりそうです。

また 2. と 3. については24か月ごとの活動状況の再チェックと、活動的でない認定専門家については再認定などを検討しているとのことです。そして「LibreOffice認定済(LibreOffice Certified)」的なポジションが用意され、これは基本的な面接を受けた後にUdemyから提供されるビデオ講座を受講してなることができるそうです。その資格を受けてから12か月以内に今の認定試験同様の基準を満たすことで(つまり移行やトレーニングの実務を行ったことを示すことで)、初めて今の「認定専門家」になれると。ただしTDFメンバーである場合は「LibreOffice認定済」を経ずに直接移行専門家の試験を受けられることにすることのこと。

まだ詳細決まってないことはあれど、いずれにせよ認定制度としては正常な進化だし、こういう方向でよりLibreOfficeの認定がカジュアルに取得でき、かつその利益が取得者にとって得られる社会に近づけばいいなと感じました。

LOOL(COOL) vs. WASM

ここの vs. は煽り気味です、はいw

開発についてのトークについてはこれというテーマがある感じではなく、これはもちろんデスクトップオフィスソフトとしてのLibreOfficeの成熟度を示しているってことはあるとは思うのですが、その中でしいていうならこのテーマですかね。

LibreOffice Online(LOOL)はブラウザベースでLibreOfficeを動かす仕組みで、なおかつCollabora Office for iOS/Androidはこれを応用して実現されているので、クラウド時代におけるLibreOfficeの新たな地平を開く、LibreOffice Technologyの鍵となる技術です。しかしLOOL自体はTDFのリポジトリに存在して一部外部の貢献者もいたものの、本体の開発および、LOOLの機能のためのLibreOfficeのコアの開発の多くはCollaboraのメンバーによりなされていました。そのためTDFリポジトリのLOOLは更新が凍結されて、Collabora Online(COOL)としてCollaboraのGitHubプロジェクト配下で管理されるようになりました*6

もちろん、COOLは相変わらずOSSでありCollaboraメンバー以外のPRやその他の貢献も受け付けていますし、GitHubベースになったことによって「モダンな」開発者にとっては参加の敷居が下がったと思われますし、さらに言えばCollaboraとビジネスパートナーになればCOOLをベースにした自社商品もリリースできる(想像です)と思うのですが、前述のようにLibreOffice Technologyの重要なキーが特定のエコシステムベンダーのものとなったことに嫌悪感や危機感を持ったコミュニティメンバーも少なくない、というのが私の感じているところです。

また技術的には、LOOLはいわゆるクライアント・サーバーモデルなので運用が結構大変ですし(個人やSMBで立てるのと、エンタープライズでごりごり使うにはノウハウが必要)、またCOOLとLibreOfficeコアのリポジトリが分かれているにもかかわらず密結合なところがあるので双方を見られる人じゃないと大きな機能追加は難しく、またメモリ使用量も比較的大きい重量級のシステムです。

と、いうことで、新たに注目されているのがWASMベースのLibreOfficeのポーティングです。2015年ごろにも構想されたもののWASM自体もツールチェーンのemscriptenも問題が多く挫折したのですが、W3Cの標準となり多くのブラウザで実装された現在、再びチャレンジすることになったということです。 これは、もちろん前述の技術的問題へのカウンターであることもそうですが、主に牽引しているのが、ドイツCIB社から分社したばかりの若いエコシステムベンダーであるallotropia社であることから、単純に技術的な挑戦だけではないのではと邪推しています。

とはいえWASMへのポートは相当いばらの道のようで、今年2月のFOSDEM 2021ではまだまだ戦いは始まったばかり、という感じでしたが、今回のカンファレンスのトーク聞きそびれたのでビデオ公開が待たれるところです。

WE WANT YOU!

長くなってきたので残りはなるべく手短に。

TDFの雇用メンバーに新たに加わったHossein Nourikhah氏は「Developer Community Architect」という役割で、これから新たな開発者を開拓していこうという取り組みをいろいろしていますが、氏による「Getting Started with LibreOffice Development」という90分のセミナーをはじめとして、LibreOffice SDKのサンプルを再構築しましょうとかLibOのソースはこう読めとかデバッグをこうやれとかそういうトークが多かったとします。日本からの参加者、案浦さんのGraphQLのエクステンション作ったよな発表もこの枠かな。

その中の一つ、Ilmari Lauhakangas氏によるセッション「A legendary bug reporter」がめちゃくちゃ面白かったので、ぜひYouTubeで公開されてるビデオ見てください。

日本でCJKバグを直すためのハンズオン的なものやりたかったらTDFは協力してくれるかな?と、マーケティング担当のMike Saunders氏を経由してHosseinさんに伝えてもらったらメールもらって「LibOConで講演するからまずはそれを見てね、手伝えることがあったら連絡ちょうだい」と言われてるんだけど、いまだに返事を返せていません……興味ある、参加したいって人は私のSNSなりなんなりで反応ください。個人的にはビルドやってなにやってって話もそうだけど、CJKバグに対する単体テストを書く、見たいなハンズオンをやってみたい。

って、継続した貢献はお約束できない、って言ってるぼくがいうのも変な話だな。まあ、単発のイベント回すぐらいならできるんで……。

終わりに

去年の似たようなエントリ

naruoga.hatenablog.com

で、来年は参加するかわかんない的なことを書いたけど、やっぱり参加したしやっぱり楽しかった。 あとはなあ、知り合いともっと話できるチャンスがあるといいんだけどなあ。ビール片手に。でもそれは時差がある分難しいですね。

来年の開催は「現在状況を見ながら慎重に議論を重ねていて、今話せることは何もない」だそうです。 オフライン開催になればいいけど、それでも日本から私が行けるかどうかはわからないしね(そもそもまだLibreOfficeコミュニティの一員として活動を復帰するとは言っていない)。

まあともかく、いろいろな中イベント開催に尽力してくれたみんなには感謝感謝です。ありがとでした!

*1:Togetterは公開期間にリミットがあるから、ずっと残したいコンテンツは別の手段を取った方がいいという説もありますが、まあ、イベントログ自体生モノなので、そこのところはあまり深く考えない方向で。

*2:可能な「すごい人」がいないとは限りませんが。

*3:もちろんエコシステムベンダーが「自発的に」そのような改善を行うこともありえますが。

*4:ここについてはあんまり大っぴらに書きにくい話も聞いたことがありますが、それは直接聞いてくれればお話ししますw

*5:今年のLibOConはLPIがスポンサーになってて、ありがたいことだけどちょっと意外、と感じてたんですが、このアナウンスを聞いてなるほどと。

*6:この説明はかなり雑なので、うのみにしないで詳細はCOOLのFAQなどを参照してくださいね。

【個人的メモ】LibreOffice Conference 2021 Onlineでどの発表を見るか

いよいよ近日開催、LibreOffice Conference 2021(以下長いのでLibOCon)。

libocon.org

今年のロゴ、なかなかかっこいいですね。

https://libocon.org/assets/libocon2021/libocon-2021-logo.png

カンファレンスグッズも各種取揃っており、イベントに向けて気持ちを盛り上げるには十分です*1

www.freewear.org

そんなわけで、今やLibreOfficeに関するいかなる組織にも属してないけど、市井のLibreOffice愛好家であり、一応日々LibreOfficeを使って仕事してる人間として、どんな発表に着目していてどれを見るかって個人的メモをここに書いておくという誰得エントリーを今回もやります。つーてももうコミュニティワークをしなくなって1年以上経つし、貢献もなにもしてない*2 人間のメモなので、「これを見た方がいいよ」とかそういうオススメではありませんので、そこらへんは踏まえてお読みいただけますと。

はてさて。グローバルなイベントがオンラインで気軽に参加できるようになったとはいえ、時差がつらい*3 という問題はあるわけですが、なんと幸いなことに、今年わたくしの勤務先はシルバーウィークで今週ぶち抜きお休みなんですよね*4 なのでヨーロッパ時間で行われるイベントに出ても昼寝すればオッケー。なんて楽勝なんだ……。

あともう一つうれしいのが、カンファレンスのスケジュールページでタイムゾーンが選択可能になってること!

f:id:naruoga:20210920160242p:plain
Asia/Tokyoが選べる! ブラウザの設定などによりほかの場所も選べるのかな?

これで、Googleカレンダーに聞きたいトークを全部入力して、実際には何時に始まるんだかを把握する、超めんどくさい作業から解放される……。

まあそんなわけで、昼寝をすればいいってのはチートですけど、現地でも開催時刻を少し遅らせて、終了も早めることで(現地時間12:00-17:30)、我々日本からの参加者でも、19:00-24:30というまあまあ人間的な時間帯に参加することができるようになりました。なので、全部通して聞けとは言わないけど、よかったら少し早めの面白そうなトークを狙って聞いてみると得るものも多いんじゃないかな。

では始めましょー。前回は超長くなってしまって3分割にしましたが今回は手短になるといいな。

Day 1(9/23(木))

現地午前中はオープニングアワーということで迷う必要がなくていいですね。

ここらへんはオープニングやスポンサートークで、LibOConにおいてはLibreOffice自体の大きな機能開発がやはりイベントのスポンサーである2企業(Collabora Productivityおよびallotopia)の主導で進んでいることは間違いないので聞いても損はないですね。最後のCertificationはあんまり興味はないんだけど、わざわざここにアナウンスを持ってきたってことは何か大きな変化があるかもしんないし。

21:30-22:00の休憩をはさんでからは3ルームに分かれるので悩ましいですがこんな感じで考えてます。

時刻 トーク 一言コメント
22:00 I feel the need... The need for speed..... :: LibreOffice Conference 2021 :: pretalx パフォーマンス向上の話は技術者として純粋に面白そう。裏番組は榎さんだけど、ごめんなさい :)
22:30 The Crashreporter Service used by LibreOffice :: LibreOffice Conference 2021 :: pretalx 実はCrashreportの仕組みちゃんと知らないので。会社でも死んだときにはこうやってレポート送ってね、ってことを推奨するようにもしたいし
23:00 LibreOffice Calc Survey: User Characteristics, Usability, and Future Enhancements :: LibreOffice Conference 2021 :: pretalx SVGエクスポートフィルタの話とも悩んだけどこちら。ソフト屋としてUXにも関心持たないと
23:30 Improved document searching with LibreOffice :: LibreOffice Conference 2021 :: pretalx 内容見てみたらヘッダやフッタ、図表のキャプションも含めて検索できるようにするよという話で面白そう
24:00 Multi-column support in LibreOffice 7.2 :: LibreOffice Conference 2021 :: pretalx 多段組サポートもうあるじゃん、って思ったけどなんか違うんでしょうね。CJKへの影響も含めて興味がある

Day 2(9/24(金))

時刻 トーク 一言コメント
19:00 openSUSE maintenance, when several projects cooperates for making LibreOffice a solid productivity suite :: LibreOffice Conference 2021 :: pretalx Marinaの話だという理由も大きいんだけどw、ディストロと上流プロジェクトの関係を考えるよさそうなセッションなので。ま、私はどっちの人でもないですけどね、どっちにも知り合いはいますし……。
19:30 COOL performance :: LibreOffice Conference 2021 :: pretalx こういっちゃなんだけど消去法でこっち。スペルチェック大事だけど我々日本人には、もっと手前でやることあるからね……
20:00 PPTX footer export & import interoperability :: LibreOffice Conference 2021 :: pretalx
Edit LibreOffice files directly from Nextcloud web interface :: LibreOffice Conference 2021 :: pretalx
Color Filter in Calc :: LibreOffice Conference 2021 :: pretalx
案浦さんのGlaphQLの話 とすごい悩んだんだけどLTっぽいこちらに。PPTXの相互運用の話とCalcのカラーフィルタの話が聞きたいので
20:30 ODF Status Update 2021 Edition :: LibreOffice Conference 2021 :: pretalx ODFの動向はちゃんと追っておきたいです。LibOはPoormans MS Officeとしてはもう負けが込んでるので、技術屋としてはODFの機械加工性の良さとかを推していきたい感があり。裏番組のDaeHyunさんにはごめんなさい。
21:00 Update about ODF Advocacy :: LibreOffice Conference 2021 :: pretalx 同上。Xrayの話もすごい興味があるけど、まあこれは後で録画で追いましょう
22:00 How to debug Writer, forwards and backwards (Epsiode 2) :: LibreOffice Conference 2021 :: pretalx 去年のセッションが面白すぎたので……。今年も聞かないわけにはいかんかなと。90分長いけど……
23:30 LibreOffice SDK Examples Overhaul :: LibreOffice Conference 2021 :: pretalx LibOのExtension周りは詳しくなさすぎるので土地勘持ちたいということも。って、一度実践してみたらいいのにね(セルフ突っ込み)
24:00 Converting LibreOffice Guides into Web Pages :: LibreOffice Conference 2021 :: pretalx こんな議論があるんだ、という新鮮な気持ちとともに。まあ確かにWebベースのほうが時代にあってるとはいえ

Day 3(9/25(土))

関係ないけどこの日から 2021.ubucon.asia が始まるため一部イベントの時間被っちゃうの*5で自分にはプチ残念。まあ、しょうがないね。

この日はマルチトラックなのはごく一部で表形式である必要はないんだけど、まあ、そのまま

時刻 トーク 一言コメント
19:00 LibreOffice in the browser, live and in color! :: LibreOffice Conference 2021 :: pretalx LibOのWASM実装の話、聞かないわけにいかないでしょ。おかげでUbuCon Asiaのソーシャルイベント出られないんだけど……発表の合間でちょっと顔出してみるかな
19:30 Building (and using) LibreOffice Online... again :: LibreOffice Conference 2021 :: pretalx タイトル見るとCollabora Productivityにコード移譲された 元の LOOLを動かそうって試みかな?
20:00 JSDialogs improvements over the past year :: LibreOffice Conference 2021 :: pretalx COOL(旧LOOL)で使われてるLibOの各種ダイアログをJSで実装するコンポーネントの説明と思われる、前にこれに関する発表聞いたけど面白かったので
20:30 LibreOffice Community Survey - retrospective feedback :: LibreOffice Conference 2021 :: pretalx 誤解を恐れずに言うとぼくがLibOの活動を一時休止してそのまま(組織的にはいくつかのところから)辞めるきっかけになったのは、グローバルのメーリングリストでもなんかギスギスした議論が目立つようになってきて、それをコロナ禍でよわったぼくの気持ちが受け止めきれなかったからなので、LibOコミュニティとして現状をどう受け止めているかというのはちょっと気になります
22:00 A legendary bug reporter :: LibreOffice Conference 2021 :: pretalx よいバグレポートをしよう!とかそういう啓蒙は大事だけど、個人にフォーカスしてるのは面白いすね
22:30 Introduction to TDF Membership :: LibreOffice Conference 2021 :: pretalx 今んとこまだTDFメンバーに戻れるにふさわしい活動をできる自信はないですけどねえ……
23:00 Introduction to TDF Membership :: LibreOffice Conference 2021 :: pretalx プロジェクトの継続性・健康性(一部の人間が病みながら頑張る、とかじゃなくて)ってどうやって担保すればいいんですかねえ、と、ドロップアウト組としては気になる
23:30 Q&A Session with BoD and MC :: LibreOffice Conference 2021 :: pretalx 今のBoDはMinutes見る限りだとコミュニティからの質問に答えようと機会を設けているけどうまく活用されているように(残念ながら)見られないので、オンラインイベントならそこらへん変わるのかなあと
24:00] Closing Session, with closing address by Lothar Becker :: LibreOffice Conference 2021 :: pretalx クロージングですしね、見ないわけにはいかないでしょう!

ま、そんなわけで。気が向いたらTwitterでSpace作ったりして、そこで話しながらセッション聞いたりしてもいいかも(私と話したい人がいれば、ね)。

*1:私発注したの2週間前ぐらいなので、イベントには間に合わないけどねw。

*2:https://github.com/naruoga/jOpenDocument が進捗したらODFエコシステムに対してのなにがしかの貢献になるだろうとは思ってるけど、まーーーーったく進んでないもんね。モノグサはよくないね。

*3:とか、ビール飲みながらじゃないとやっぱ英語での雑談がつらい(特にぼくみたいなコミュ障は、アルコールの力を借りないとなかなか人に話しかけられなかったり)とか。

*4:厳密には、弊社にはたぶん全日本人の9割ぐらいが既に忘れているプレミアムフライデーという制度がまだ生きており、ただ在宅勤務化で金曜日だけ早く終わってもあんまりうれしくないという理由で数か月分をくっつけてお休みを増やす方向にしているのです。なので9/21、9/22はその休暇、9/24は有給取得奨励日ってわけ。ぼくは弊社の創立メンバーではあるけど組織運営には一バイトもタッチしてない平社員だけど(その方が嬉しい)、こうやって従業員の働きやすさに向き合ってくれている経営層には本当に感謝しております。ですよ。はい。

*5:&昼寝ができなくなる……のは、まあ、いいか ;)

jOpenDocumentを2021年にリブートしてみる その4:GitHub ActionsでJDKを振って自動テスト

前回の記事はこちら。

naruoga.hatenablog.com

やはり2021年にもなって、手元でテスト回したりするのは犯罪でしょう。普通にpushしたりPull-Req作ったりしたらビルドのチェックとテストぐらいはしたい。

ということで、恥ずかしながら今まで使ったことがないGitHub Actionsを使ってみることにしました。

とりあえずActions登録

今更なのですがQuick Startを読みます。

docs.github.com

で、実は今やってる作業は締め切りがある話で、めちゃくちゃ締め切り迫ってるので、真面目に調べてる暇ない!って感じで、 こういう付け焼刃ホントよくないんですけど、このリポジトリにサンプルがいっぱいあるよってことで即見に行きました。

github.com

はいはい、顧客が本当に必要になったものありました。Mavenでビルドするための情報。

github.com

さくさくパクりまして、 .github/workflows/mvn-build-actions.yml というファイルをこんな風に書きました*1

name: Java CI with Maven

on:
  push:
    branches: [ $default-branch ]
  pull_request:
    branches: [ $default-branch ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'adopt'
    - name: Build with Maven
      run: mvn -B package --file pom.xml

で、こいつを master ブランチに入れて、push時のトリガを強制的にかけるために

touch foobar
git add foobar
git commit -m "GitHub Actions test"
git push

とかやったんですが動かない……なんぞ? なんかスキーマの書き間違い? でもサンプルのコピーだしなあ。

Actionsがトリガされない問題のチェック

Actionsの画面を見ると、手動実行のUIっぽい奴も特に存在しない……ううむ。

これは調べてみたら、

docs.github.com

ちゃんと答えが書いてあって、 workflow_dispatch ってトリガを追加すればいいらしいですね。で、こんな感じにした:

on:
  workflow_dispatch:
  push:
    branches: [ $default-branch ]
  pull_request:
    branches: [ $default-branch ]

ら、手動実行のボタンが出てきました。よしよし。ということはスキーマが全然違ってて認識できてないみたいなことはないらしい。

やれやれということで手動で実行してみたら、一回目は

Error:  Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project jOpenDocunentNg: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test failed: Plugin org.apache.maven.plugins:maven-surefire-plugin:2.12.4 or one of its dependencies could not be resolved: Could not transfer artifact org.apache.maven.shared:maven-common-artifact-filters:jar:1.3 from/to central (https://repo.maven.apache.org/maven2): transfer failed for https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/1.3/maven-common-artifact-filters-1.3.jar: Connection reset -> [Help 1]

とかなんとか言われて、えっ、手元ではビルドできてるんだけどな……なんでや……ってなったのですが、 ダメモトでもっかい再実行したらうまく行って、あとはずっと成功してます。 なんじゃそりゃ……と思いますが、まあ、いいでしょう。

それとは別にいくつかのサンプル見たら、そもそも push とか pull_requestbranch 指定してないのが普通っぽいので、それを取り除いて

on:
  workflow_dispatch:
  push:
  pull_request:

こうしたら、普通に push した場合でもActionsがキックされるようになりました。めでたしめでたし。

複数のJDKでビルドする

こういうときってジョブを割るのがいいのかActionを割るのがいいのか、たぶんちゃんとどこかにどうすればいいってプラクティスがあるんでしょうけど、 前述のように時間がない中付け焼刃でやってるので、雑にActionを割りました。 こういうときも共通部分をどこかに記述して差分(今回の場合はJDKのバージョン)だけを記述する方法が絶対あると思うのですが、 それはあとで考えるとして、いったんはJDK11側のファイルはこんな感じにしました。

name: Build with JDK11

on:
  workflow_dispatch:
  push:
  pull_request:

jobs:
  build-on-jdk11:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          distribution: 'adopt'
          java-version: '11'
      - name: Build with Maven
        run: mvn -B package --file pom.xml

JDK8のファイルは11って書いてあるところが8ってなってるだけです……お恥ずかしい。

まあでも、いちおうこうやって二つ並んで、テストがそれぞれ走るようになりました。よかったよかった。

f:id:naruoga:20210716182138p:plain
JDK8とJDK11の両方でCIできるようになった

テストレポートがGitHubの画面から見たい

ここまででまあ一応「pushやPRのたびに自動テストをする」目的は達したんですが、Jenkins + JUnit プラグインを使ってた人間としてはやっぱり非常に寂しい。 ダッシュボードの上からテスト結果が見たいなあと思って、雑にググったらこういうプラグインがヒットしました。

github.com

で、各yamlファイルにこんな感じで書いてみました。

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          distribution: 'adopt'
          java-version: '11'
      - name: Build with Maven
        run: mvn -B package --file pom.xml
      - name: Publish Test Report
        if: ${{ always() }}
        uses: scacap/action-surefire-report@v1
        with:
          check_name: JDK11 result

結果は……ちょっと期待と違って、

f:id:naruoga:20210716182649p:plain
片方のActionに両方の結果が出ちゃう

こんなふうに、片方のActionに両方の結果が出ちゃってます。中身もこんな感じで、ちょっと寂しい。

f:id:naruoga:20210716182822p:plain
履歴とかはなくてその時の結果の数しか見られない

Failしたときの結果も見てみたいけど、このプラグインの設定をもっと詰めるか、ほかのプラグインを探すかも含め、後日ですねー。

READMEにバッジをはる

つまらないことですがCIの結果をREADMEにバッジとして貼ると、なんか今風じゃないですか。ので貼ることにしました。

それぞれのActionの画面の右上の「…」ボタンを押して、「Create status badge」を押すと、

f:id:naruoga:20210716183133p:plain
メニューからバッジ作成

こんなダイアログが出てきて、README貼り付け用Markdownスニペットが得られます。

f:id:naruoga:20210716183252p:plain
バッジのMarkdown記法が得られる

これをREADMEにぺったんすると、

f:id:naruoga:20210716184021p:plain
バッジが並んで今風(そうか?

これでなんかモダンな開発をしているような雰囲気を醸し出すことができた……かな?

まあそんなわけで、まだまだやり残したことはありますが(というかまだ目的全然果たせてないですが)今回の短期集中連載はここまで。

今後の宿題としては:

  • XMLのValidatorをちゃんと動かす(最優先)
  • マトモなサンプルでちゃんと動くかを確認する(具体的には私の所属先のツール)
  • テストをきれいに直す
  • 会社名義でMaven Centralにpublishする
  • ODF 1.3対応をする
  • 下回り(ODF操作部分)を独自実装ではなくODF Toolkitに乗り換え

あたりかなー。協力者も募集ですよ。

*1:今回、JAR配布の予定はないので -B test でも十分なんですけど、まあ、もしかしたらするかもしれないし。

jOpenDocumentを2021年にリブートしてみる その3:落ちてるテストを成功させる

naruoga.hatenablog.com

のつづき。おつむの出来がしょぼいのでXMLスキーマValidationがコケてる理由がわからないため、ほかのテストのFailを潰していきます。

幸いなことにValidatorはテスト内部でしか使っていないので、これでもアプリ側から使う分には問題ない……はず*1

落ちてるテストを拾う

でも、実はValidation以外で落ちてるテストって二つだけなんですよねえ……。

f:id:naruoga:20210716112037p:plain
落ちてるテストは日付と時刻関係だけ

しかも落ち方が……あやしい。これはテストのGlobalization対応が不十分なんじゃないか?

f:id:naruoga:20210716112213p:plain
落ち方がいかにも怪しい

DataStyleTest.testFormat() を直す

まずは簡単そうなほうから。

junit.framework.ComparisonFailure: 
Expected :0,500
Actual   :0.500

これは絶対、Locale関係だろ……と思うので、見てみましょう。

落ちてるところまでコードを引用するとこんな感じ。

    public void testFormat() throws Exception {
        final ODPackage pkg = new ODPackage(this.getClass().getResourceAsStream("/cellFormat.ods"));
        final Sheet sheet = pkg.getSpreadSheet().getSheet(0);

        // * test that the framework format as OpenOffice
        final int lastRow = sheet.getCurrentRegion(0, 0).getEndPoint().y;
        for (int i = 0; i <= lastRow; i++) {
            final MutableCell<SpreadSheet> cell = sheet.getCellAt(0, i);
            final String byOO = cell.getTextValue();
            final ODValueType origType = cell.getValueType();
            final Object cellValue = cell.getValue();
            // like OO, we should allow any value without removing the data style
            cell.setValue("string");
            cell.setValue(12.3);
            cell.setValue(new Date());
            cell.setValue(true);
            cell.clearValue();
            if (origType != null)
                cell.setValue(cellValue, origType, false, false);
            assertEquals(byOO, cell.getTextValue()); // <---- ここで落ちてる
            assertEquals(origType, cell.getValueType());
        }

こら! テストコードで for 文書くなって教わらなかったのか! と怒りたいところですがそれはおいといて。

まずは読み込んでるファイルは cellFormat.ods というCalcファイルですね。 中身はこんな感じ。

f:id:naruoga:20210716130933p:plain
cellFormat.odsの内容

で、この1列目を各行ぐるぐる回ってセルの各要素のテキスト文字列を取り出した後、セルに書式指定を無視していろいろ値をセットして(表計算ソフトでは例えば数値書式のセルに文字列を突っ込んだりもできるので)、元の値と書式をセットしなおして結果が変わらないかを見る……って、いうのがテストの意図っぽいですね。

そして、expected が 0,500 で actual が 0.500 なので、元のドキュメントの標準言語はまあ、想像したとおりフランス語なので小数点は , で、だから取り出したセルの値は 0,500 で、cell.setValue() したときには私の動いてる環境の標準ロケールだから日本語で小数点が変わっちゃう……って、ことじゃないかな?

ん? じゃあ、これ、テストの問題じゃなくてプロダクトコードの問題じゃないですかね……。

ともかく、問題になってるのは2行目(セルの表記的には (0,1))なので、そこに条件付きブレークポイントを貼って調べますと、……あれ?

f:id:naruoga:20210716134246p:plain
contentがTextで0,500ってなってる!

テキストじゃん!

あーでも、attributes はこうなのか……。

f:id:naruoga:20210716134601p:plain
attributeでは確かにtype:floatになってる

ふむふむ、ODFの仕様をちゃんと読んでないことがバレバレなのですが、どうやらODFでは

  • セルに文字列で表示するための要素( cell.localElement.content[0]
  • セルに実際に入っている値( cell.attributes

を二重管理してて、前者は少なくともLibreOffice上では使われてない(セルの値と書式から動的に表示結果を作ってる)ってことなのでしょうか……。

で、

cell.setValue(cellValue, origType, false, false);

すると、「ドキュメント」のではなく「セル」の言語が使われて、0.500 になっちゃう、ってこと……みたいです。

……いや、違うかな。違いそう。何が違うかというと

「ドキュメント」のではなく「セル」の言語が使われて

です。というのはなぜかというと、cell.setValue() の実装をおいかけてくと、最終的に NumberStyle.format() ってメソッドに来るんだけど、

    @Override
    public String format(Object o, CellStyle defaultStyle, boolean lenient) {
        final Number n = (Number) o;
        final Namespace numberNS = this.getElement().getNamespace();
        final StringBuilder sb = new StringBuilder();
        @SuppressWarnings("unchecked")
        final List<Element> children = this.getElement().getChildren();
        for (final Element elem : children) {
            if (elem.getNamespace().equals(numberNS)) {
                if (elem.getName().equals("text")) {
                    sb.append(elem.getText());
                } else if (elem.getName().equals("number") || elem.getName().equals("scientific-number")) {
                    sb.append(formatNumberOrScientificNumber(elem, n, defaultStyle));
                } else if (elem.getName().equals("fraction")) {
                    // TODO fractions
                    reportError("Fractions not supported", lenient);
                    sb.append(MutableCell.formatNumber(n, defaultStyle));
                }
            }
        }
        return sb.toString();
    }
}

この中で呼ばれている formatNumberOrScientificNumber(elem, n, defaultStyle)defaultStyle に保持されてるセルのロケール情報見てないっぽい……ですね。 なのでこれはプラダクトコードの問題。

だけど、LibreOfficeというアプリケーションで使うことだけを考えると、テキストは付帯情報であって実際の値やフォーマット情報は適切に扱われているので、ここに不具合があってもすごくシリアスではないし、まあいいかなあという……FIXMEフラグだけつけときますか。

こういうこと考えると下周り(ODFを実際に操作する部分)をごっそりモダンなライブラリ……例えば:

github.com

に差し替えたくなりますね。

ということで乱暴ながら、

  • testFormat() の今落ちてる assert はコメントアウト
  • それ以外の assert は、期待値が即値なのが問題なのでいったん String.format() を利用するように書き換え(将来はセルのロケールに従った動きをしないとだめですが)

としました。

DataStyleTest.testDays() をどうするか

先ほども書いたけど、このテストでは期待値と実際の値が1時間ずれてるというもの。

Expected :27/10/2013 09:30:00
Actual   :27/10/2013 10:30:00

1時間ってことはタイムゾーンというか夏時間(DST)がおかしいんじゃない?と思うんですが、なんかコード見るとまさに夏時間向けの処理がごちゃごちゃと書いてある……。 これを直さなきゃいけないのかー。

と、思いましたが、 このテスト、ちらっと見た感じだと jOpenDocument 自体のテストをしてるように読めないんですよねー。

なので、えいっと無視することにしました。

mavenでdependsしてるのは JUnit4 なので、 @Ignore って書くだけじゃん、と思ってそう書いたら 「これはJUnit3形式のテストだから @Ignore じゃ無視されなくて、メソッド名を test で始まらないように _test ってすればいいよ」とIntellij IDEA君に教えてもらいました。 なんと、まあ。

JUni4 形式に移行することもIntellij IDEAの機能でできるらしいのですが(優秀)、 個人的には将来はJUnit5でもちょっとましなテストを書こうと思ってるんで*2 、 雑に _ をつけて無視する方法にしました。

動かないXMLのバリデーション

ここまで来たら毒皿なので、ここらへんも無視することにしちゃいましょう。

主にバリデーションがテストしたい部分で、これを通さないと落ちるテスト

  • OOXMLTest.testValidation()
  • SheetTest.testCreate()

についてはやはりIgnore(FIXMEつけて)。

それ以外のテストで、テストメソッド内にて SheetTest.assertValid() を呼んでいるテストについては、システムプロパティ jopendocument.test.validationtrue を指定しない限り無視するようにしました。 これも後々は直すつもりですが、まずは先に進みたいので。

ま、そんなわけで、テストは全部バスするようになりました*3

次はCI的なところをやっていきます。

*1:もちろん、スキーマをぶっ壊す可能性があるようなODF操作ライブラリとか怖くて使いたくないので、いずれは直しますよ、もちろん。ただ、優先度をいったん置くってことです。

*2:for文書くな、一つのテストメソッドで延々違うassertを繰り返すんじゃない、的な意味で。

*3:これは品質を満たしているという意味ではないので、まったくよろしくないけど。

jOpenDocumentを2021年にリブートしてみる その2: テストを動かす

前回の記事

naruoga.hatenablog.com

のつづき。今回は目標が低くてテストを動かすところまで。 これが全然苦戦して、ほとんど進捗がないんですねえこれが。

テストの位置をMaven標準に動かす

その前に前の記事の落穂ひろいですが、

To compile you need to put iText ( http://www.lowagie.com/iText/download.html ) and junit4 ( http://www.junit.org/ ) into the lib/ dir.

って書いてあるので、iText と Junit4 が必要ですね。ということで pom.xml に次の二つを追加しておいてました。

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.2</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
</dependency>

(なんで最初からlibディレクトリに入ってないんでしょ、再配布制限的な何かあるのかな)

それとこれも前回からの書き漏れですが、 src/product.properties を参照できなくてコケるので src/main/resources に移動しておきました。 ここまでは前回の落穂ひろい。

で、ここからが今回の本題ですが、junit4が必要だよと言ってるってことは当然テストコードがあるわけで、 Maven的には src/test/java 以下にソースがないとたぶんだめですよね。

まあこれはきっと @Test アノテーションがあるファイルはテストコードだと見極めをつけて移動しました。

$ grep -rl "@Test"
src/main/java/org/jopendocument/dom/ODSingleXMLDocumentTest.java
src/main/java/org/jopendocument/dom/OOXMLTest.java
src/main/java/org/jopendocument/util/cache/ICacheTest.java

こいつらをまるっと test に(同名のフォルダを掘って)移動。 すると Intellij IDEA上でテストコードが実行できるようになりました。やった!

で、まあテストはrunできるようになったんですが結果を見ると真っ赤っ赤。 あとはぼちぼちこれを直していけばよかろうと。

リソースの移動

まずはテストコードの中で指定されてる .odt がないとテストコード内でファイルが読めないので移動します。これは簡単。 diff見るとこんな感じですね。

diff --git a/src/main/java/org/jopendocument/dom/empty.odt b/src/test/resources/org/jopendocument/dom/empty.odt
similarity index 100%
rename from src/main/java/org/jopendocument/dom/empty.odt
rename to src/test/resources/org/jopendocument/dom/empty.odt
diff --git a/src/main/java/org/jopendocument/dom/styles.odt b/src/test/resources/org/jopendocument/dom/styles.odt
similarity index 100%
rename from src/main/java/org/jopendocument/dom/styles.odt
rename to src/test/resources/org/jopendocument/dom/styles.odt
diff --git a/src/main/java/org/jopendocument/dom/test.odt b/src/test/resources/org/jopendocument/dom/test.odt
similarity index 100%
rename from src/main/java/org/jopendocument/dom/test.odt
rename to src/test/resources/org/jopendocument/dom/test.odt

で、よく見ると、普通に src/main/java にもいかにもリソースなファイルがあるので移動しとかないとですね。 具体的には src/main/java/org/jopendocument/dom/oofficeDTDs/ にあるやつを丸っと src/main/resources/ 以下に移動します。

ほかにも getResource(AsStream)() で参照されてるファイルを探してはリソースに放り込む日々。

XML関係のテストがそもそも動いてない

これで結構テスト通るようになってきたんですが、問題は、XML関係のテストでスキーマによるバリデーションを試みてるところで落ちてる。 具体的には

private Schema createSchema(final String name) throws SAXException {
    return SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI).newSchema(getClass().getResource("/oofficeDTDs/" + name));
}

こんなコードが、

Caused by: java.util.ServiceConfigurationError: javax.xml.validation.SchemaFactory: org.iso_relax.verifier.jaxp.validation.RELAXNGSchemaFactoryImpl Unable to get public no-arg constructor

こういう例外を吐いて落ちるんですな。

なぬ?スキーマに対する適切なコンストラクタがない? いやいや、XMLConstants.RELAXNG_NS_URIJava標準なんだからそんなわけないだろう……と、Java力(ちから)がないわたくしは考えておりました。

しかし色々調べると「java.xml.validation のデフォルトの実装に含むべきなのはW3Cなソレだけで、それ以外のスキーマを利用したい場合は自分で何とかしなさい」ってことらしいじゃーないですか。おうふ。なるほど……。ここでしばらく停滞、袋小路にハマってました*1

でもよく見るとREADMEにこんな記述がありました。

To validate XML (needed for JUnit tests) you need to download http://java.net/downloads/msv/releases/msv.20090415.zip and put msv.jar, relaxngDatatype.jar, xsdlib.jar and isorelax.jar in the classpath.

いや、だったらなんで最初から入れといてくれないの……というのはともかく、これらをMavenの依存関係に足せばよいのですね。足しましょう。足しました。

<dependency>
    <groupId>msv</groupId>
    <artifactId>msv</artifactId>
    <version>20050913</version>
</dependency>
<dependency>
    <groupId>msv</groupId>
    <artifactId>relaxngDatatype</artifactId>
    <version>20050913</version>
</dependency>
<dependency>
    <groupId>msv</groupId>
    <artifactId>xsdlib</artifactId>
    <version>20050913</version>
</dependency>
<dependency>
    <groupId>msv</groupId>
    <artifactId>isorelax</artifactId>
    <version>20050913</version>
</dependency>

これで行けるだろ!と思ったんですが、いざValidationをしようとするとコケるのです……しくしく。

@Override
public Validator getValidator(final Document doc, final boolean ignoreForeign) {
    final Schema schema;
    try {
        if (doc.getRootElement().getQualifiedName().equals("manifest:manifest"))
            schema = this.getManifestSchema();
        else
            schema = this.getSchema();
    } catch (SAXException e) {
        throw new IllegalStateException("relaxNG schemas pb", e);
    }
    return schema == null ? null : new Validator.JAXPValidator(doc, ignoreForeign ? UNKNOWN_PRED : null, schema);
}

こういうコードで、 this.getSchema() したところで

Caused by: org.xml.sax.SAXParseException; systemId: file:/C:/Users/naruhiko/gosrc/src/github.com/naruoga/jOpenDocument/target/classes/oofficeDTDs/OpenDocument-schema-v1.1.rng; lineNumber: 123; columnNumber: 36; 同名のパターンが既に定義されています。combine属性を使って結合するか、パターン名を"office-meta-content"以外のものに変更してください

って例外が出ちゃうのです(しかし上のコードの "relaxNG schemas pb" ってどういう意味なんだろう。pbってスイスの工具屋さんじゃないよね)。

うーん。わからん。言葉通りだとすると元のスキーマに問題があるっぽく読めるけどスキーマは何にも変えてないしなあ(当たり前)。

office-meta-contentgrepしてみると

 grep -r "\"office-meta-content\""
src/main/resources/oofficeDTDs/OpenDocument-schema-v1.1.rng:            <ref name="office-meta-content"/>
src/main/resources/oofficeDTDs/OpenDocument-schema-v1.1.rng:<define name="office-meta-content">
src/main/resources/oofficeDTDs/OpenDocument-strict-schema-v1.1.rng:        <define name="office-meta-content">

となってるのは確かにそうなんだけど、これがいいのか悪いのか……何も変えてないので悪いってことはないと思うし、そもそもスキーマなんだから標準から引っ張ってきてると思うんで、なにがなんやらさっぱりです。

わからないので後回しにして*2落ちてるほかのテストを調べることにします。次回へ続く。

*1:関係ないけど、そして昔からJavaやってる人なら当たり前すぎることなんですが、RelaxNGについて調べたらJenkinsの創始者で現Launchableの川口さんが出てきて、あー世界はこんな風につながっておるのだなと思いました(?)。

*2:こうやって書いておくと優しい人が誰かSNSで教えてくれたりしないかなとかすかに期待しつつ……。

jOpenDocumentを2021年にリブートしてみる その1:Maven化

LibreOfficeの標準フォーマットであるOpenDocument Format(以下ODF)*1 は、XMLの標準化団体OASISのOpenDocument TCが標準化しISO標準にもなっている公開された文書フォーマットです。アプリケーションの進化に伴い標準が改訂されていく「真の国際標準」である唯一のオフィス向けドキュメント形式であるとともに、スキーマの構造が透明で見通しがよく、なおかつLibreOfficeの出力するODFは意味が明瞭(機械も人間も読みやすい)という特徴があります。

そのため操作・加工ライブラリも豊富にあり、さまざまな言語でODFを簡単に、しかも結構複雑な操作を行うことができます。

さて、私の勤務先はとあるセキュリティベンダーでございまして、日々顧客のためにシステムやアプリを診断して、それを報告書にして提出するということやっております。で、スプレッドシートの形式になった診断結果から見やすいPDF形式の報告書を作成するために、社内製のツールにてODFファイル(Writer向けのODT)を生成して、それに考察などを記入してWriterでPDFエクスポートして提出するという作業を日々行っております。

このために使っているライブラリが

www.jopendocument.org

といいまして、専用の拡張機能で埋め込んだタグをプログラムで置換したり表形式で埋め込んだりするというなかなか使いやすいライブラリであります。こいつ便利ですよという発表は去年の台湾のOSSイベントCOSCUPでしました。

speakerdeck.com

で、この資料でも書いたんですが、jOpenDocumentいいんですけどなにせ最後に出たバージョン1.4-rc2が 2014年 でして、java8で動作させると「この言語機能はdeprecatedだから使うのやめた方がいいよ」という警告がバリバリ出る。それはまあいいのですが、ODF 1.2 extended までしかサポートしてないので、今のLibreOffice(7.0以降)で普通に生成したODF(1.3 extended)だと正しく扱えない。 しかし今更これらの問題が治るとはとても思えない。思えないんだったら、自分で直せばいいじゃん! と、トライしてみることにしました。

ちなみにわたくし齢50にして細々と今でもコードを書いてますが(会社で書くのは ↑ のスライドでも述べた通りScala)、職業プログラマーとしての黄金期?はC/C++(言語仕様的には98)、C++は組み込み用途だったのでメモリフットプリントを抑えるためにRTTI禁止、という制限があり、Javaを書くようになったのは前職のソフトウェア第三者検証会社(今の所属の親会社)に入ってからで、世の中にはGradleとIntellij IDEAがすでに存在し、クラスパスがどーとか javac でビルドして *.class から JAR 作るとかそういう経験はゼロなのであります。ゼロ。antも知らない。mavenもほぼわからない。

そんなレベルの人間が、2014年で開発が止まっちゃった、まったくの他人が書いたライブラリをモダンにしてみようという、まあうまく行くんだか行かないんだかという試みを紹介してみたく。 意味も分からず試行錯誤で進めてるところがあるので、「そんなやり方はよくないよ!」という突っ込みは大募集なのです。

もとのソースを取ってくる

ソースは公式のダウンロードページ にてZIPファイルでおいてあるので、まずはこれを取ってきて手元に展開します。

まずは最初にライセンスを確認。LICENSE.txt を見たら GPL v3 だったので大手を振ってフォークできます。オープンソース万歳。

で、中身を見てみたら、 build.xml というファイルと libs というフォルダに JAR ファイルがゴロゴロ転がっています。さっき言った通り私はJavaのビルドシステムはさっぱりわからんのですがきっとこれはantなんだろうなと。で、さすがに今リブートのであればせめてビルドシステムはモダンにしたいよねということで、Maven化することにしました。

これも繰り返しになりますが、わたくし別にMavenにも詳しいわけではありません。なので、何も考えずにIntellij IDEAの新規プロジェクトでMavenを選んで、こんな感じの pom.xml をスクラッチで作りました。

<?xml version="1.0" encoding="UTF-8"?> 4.0.0

<groupId>jp.shiftsecurity.tech</groupId>
<artifactId>jOpenDocunentNg</artifactId>
<version>2.0-SNAPSHOT</version>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

依存関係の解決

わからないなりに、たぶん元プロジェクトの lib にあるJARをMaven Centralで探してその設定を pom に書いていけばいいんでしょ、ということにしてやってみることにしました。なにせ2014年のソースなので依存関係も2014年で止まっておりますが、そこは何も考えずに最新化して、動かなかったら考えようと……。

探し方としてはまあひたすら https://search.maven.org/ で検索するだけなんですが、

ファイル名でartifactが想像できるものはそれで いまいちわからないものは jar を unzip してパッケージ名から推察 って感じです。結果以下の通りになりました。

元のjar maven central で見つけたバージョン 備考
commons-collections-3.2.1.jar org.apache.commons:commons-collections4:4.4 この名前なら多分Apache Commonsでしょう。3と4で非互換あるかもだけどなんとかしましょう
fb-annotations-2.0.0.jar com.github.spotbugs:spotbugs:4.3.0 もとのはfindbugsらしいけど死んだので後継プロジェクトのspotbugsに
isorelax-jaxp-bridge-ILM.jar org.jopendocument:isorelax-jaxp-bridge-ILM:1.1 どうもjOpenDocumentの一部を切り出しただけで凍結されてるけど、動かなかったら考えることでいったんはそのまま取り込み(実際問題あったんだけど)
jaxen-1.1.6.jar jaxen:jaxen:1.2.0
jcip-annotations.jar net.jcip:jcip-annotations:1.0 いろいろforkがあるけどいったんは公式っぽいもので
jdom-1.1.1.jar org.jdom:jdom:1.1.3 たぶん1系の最新を選んどけばよいのだろうと
jdom-2.0.5.jar org.jdom:jdom2:2.0.6 同名のJARのバージョン違いがあるのがなんだけど、まあ2系の最新を選べばよかろうと
js-1.7R1.jar org.mozilla:rhino:1.7.13 ZIPファイルをほどいたパッケージ名から判断
ognl-2.6.9.jar ognl:ognl:3.2.21 これは素直に名前から。
ognl-engine.jar org.jopendocument:ognl-engine:2.6.9 これも名前から

で、これらのdependencyをpom.xmlに追加してビルド……するも、jaxenがmaven centralに見つからないと怒られてしまいました。 よくわからないし、必要なら依存関係で引っ張ってこられたりするかな……と、えいっと指定自体はずしてしまいました。 いまのところ特に何も起きてない、ような……。

ソースコードの場所を移動

Mavenなのでソースコードの位置を src/ 直下から src/main/java 以下に丸っと引っ越しました。 テストコードも混じってるんですがそれはあとで……。

ライブラリ更新に伴うソースコードの修正

ライブラリのバージョンをばしばし上げたので、当然非互換な部分も出てきます。 動作の部分はあとで考えるとして、とりあえずコンパイルエラーをつぶしていきます。 細かに書いても退屈なだけでしょうから下記リンクからdiffを見てください。

https://github.com/naruoga/jOpenDocument/compare/af77a4b09e7fea72ceff9f325919bc463ddc7414..92982f10d37a9cf230720246fa2d23692cdd8e3f

コミットコメントから引用しておきます。英語へぼいのは勘弁してね。

commit 92982f10d37a9cf230720246fa2d23692cdd8e3f
Author: Naruhiko Ogasawara <ogasawara@shiftsecurity.jp>
Date:   Fri May 7 21:08:00 2021 +0900

    avoid to use deprecated PdfTemplate#createPrinterGraphics

    the implementation is just call PdfPrinterGraphics2D constructor,
    so it could be migrate easily

commit 75caf0495319ab02c60d0e5b7524d85808b31893
Author: Naruhiko Ogasawara <ogasawara@shiftsecurity.jp>
Date:   Fri May 7 21:05:28 2021 +0900

    OGNLDataModel: remove previous code comment, because we use Git

commit d2855abc7f01d43b8b0dd30b33bb1d4b96c655ed
Author: Naruhiko Ogasawara <ogasawara@shiftsecurity.jp>
Date:   Fri May 7 20:48:49 2021 +0900

    follow updated APIs of libraries

    general: avoid useless FQCN

    several: migrate to org.apache.commons.collections4
      - CollectionUtils
      - ExnTransformer
      - ICache
      - IPredicate
      - ITransformerWrapper
      - ODSingleXMLDocument
      - Transformer

    CollectionMap2Itf:
      remove() should have Object args, not type parameters to override Map

    OGNLDataModel:
      Ognl.getMemberAccess() has been removed, then change
      Ognl.addDefaultContext() without it

    SimplePDFGenerator:
      migrate to com.itextpdf.text from com.lowagie.text (this was obsoleted)

pom.xml にビルドの設定とプラグインの設定を追加

これでビルドできるようになっただろ! と IntellijMaven画面から build を叩いても何も起きない。ふむぅ。

これは私が素人だからあんまり意味も分からずに書いてますが、以下のようなビルド用の設定書かないとだめっぽいですね。

        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.2.1</version>
            <type>maven-plugin</type>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>${project.basedir}/src/test/resources</directory>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

maven-resource-pluginはJARの中にリソース取り込むためのプラグインmaven-soruce-pluginはsource jarを作るときのプラグイン(これがないとJARで取り込んだプロジェクト側でソースコードレベルでバッグができない)、あとビルド時にどこからリソース参照するかの設定を追加。この時点でのpom.xmlはこんな感じです。

jOpenDocument/pom.xml at 6497e9f279bb8d6184b8994a452865e040b0bc5d · naruoga/jOpenDocument · GitHub

これで、IntellijMaven 機能でbuildすると依存関係をちゃんと抱いたjarと、source jarの両方ができるようになりました。よかったよかった。

取り込んで基本的な動作確認

前述のCOSCUPでデモしたときのサンプルにできたJARを食わせて、ちゃんと動くことを確認しました。 おお、ここまでは結構順調。

github.com

jitpackにて仮公開

毎回毎回JAR差し替えるのは面倒くさいので、みんな大好きjitpackにて公開することにしました。

jitpack.io

こんな風にGitHubの公開リポジトリ登録するだけで、Mavenなどで参照できる形で公開してくれる上に、それを各バージョン管理システムmaven, gradle, sbtなど)でどう設定するかまで教えてくれる超便利サイトです。

f:id:naruoga:20210711171733p:plain
Jitpackでの公開画面。ブランチやタグ、コミットハッシュでも参照できるのが嬉しい

これで公開して、先のデモプログラムもそっちを参照するように(ローカルで)変えて、ちゃんと動くじゃーん、、と確認して、いい気持になって放置してたのが、ここまでのいきさつです。

ほぼ1か月の放置の末、大急ぎで続きをやろうというのが次の記事になります。あまり期待せずにお待ちあれ。結論を言うと、サンプル動いたくらいで安心してちゃいけなかったですw

*1:公式の宣伝サイト http://opendocumentformat.org が死んでいるっぽい……。