そこに仁義はあるのか(仮)

略してそこ仁!

OSS X Users Meeting #31 ~オープンソースプロジェクトを支える言語たち~ に参加しました!

OSSをテーマにしたイベントの OSS X Users Meetingに参加してきたので、その参加レポートです!

oss-x-users-meeting.connpass.com

基調講演『改めて学ぶオープンソースの秘密』まつもと ゆきひろ氏 / 一般財団法人Rubyアソシエーション代表理事

プログラミング言語が誕生してからどういった経緯・歴史を経て現在利用されているプログラミング言語になっていったかというお話をされていました。
「今までコンピューターでできなかったことが出来るようになると、それが人工知能って呼ばれる」など、発表の中で面白い表現が使われていて楽しくお話を聴けました!

特に印象に残ったお話

ソフトウェアはもともと自由なものだったのが、商品化されて制限が厳しくなってきた、そんな中で再び自由を手に入れるためにフリーソフトウェアの考え方と、著作権を守るライセンスという考えが整理されていった。

オープンソースはソースコードはコードが公開されているだけでなく、自由なライセンスをつける必要がある。

オープンソースの定義という10項目がある。

  1. 再頒布の自由
  2. ソースコードがある
  3. 派生ソフトウェア
  4. 作者のソースコードの完全性(integrity)
  5. 個人やグループに対する差別の禁止
  6. 利用する分野(fields of endeavor)に対する差別の禁止
  7. ライセンスの分配(distribution)
  8. 特定製品でのみ有効なライセンスの禁止
  9. 他のソフトウェアを制限するライセンスの禁止
  10. ライセンスは技術中立的でなければならない

↑はメモが間に合わなかったので、こちらから引用しました。後で読む。
オープンソースの定義 (v1.9) 注釈付 – Open Source Group Japan – オープンソース・グループ・ジャパン

オープンソースの定義は素晴らしいが、開発者が生活出来るようにどうすればいいかをこれからは考えていかなければならないという課題がある。

オープンソースはここ20年で出てきた新しい世界で、オープンソースがないときに比べて遥かに良くなっている
オープンソースをこれから守っていきつつ、貢献していきましょう。

講演『オープン化が進むC++の現状と展望』高橋 晶氏 / cpprefjp(C++)コミュニティ コアメンバ

私はC++を触ったことがないので、こういうライブラリがあるんだ〜・こういう状況なんだ〜と初見のお話が多かったです。

質疑応答のところであったGitHubスポンサー、知りませんでした。
開発者を経済的に支援できる仕組み。
GitHub スポンサーについて - GitHub Docs

資料はこちら
speakerdeck.com

特に印象に残ったお話

C++はまだまだオープンソースになっていない部分もあるが、オープン化自体は進んでいる。
そして、オープン化することで議論も活発になり、言語の進化が大幅に加速している。

高速化することで大きなメリットはあるけれど、教育が追いつかなくなっている。
変わりやすい最新のライブラリの設計をどう共有していくのかというのも課題。
オープンソースだと情報共有なども含めてボランティアに頼っているので、インセンティブをどう持たせるか・それに合わせて責任をどう持ってもらうかを考えていくことが、長く開発を続けていただくために必要
GitHubスポンサーという仕組みがうまくいき始めているところもあるようで、それがもっと発展していけば良いかも。
GitHub スポンサーについて - GitHub Docs

C++の仕事が無くなったと良く聞くようになった。それは、C++が活躍する場が変化したことが原因。
C++はGUIやゲームなど、高速化のためのバックエンドとして利用するという需要が増えてきていて、領域に特化して言語が選ばれることは健全な流れ。
C#のバックエンドやPythonのバックエンドにもC++が利用されている。

特定の言語に固執せず、複数の言語を学んで適材適所でプログラミング言語を選んでいくのが良い

講演『Pythonの現在とこれからと』鈴木 たかのり氏 / 一般社団法人PyCon JP Association 副代表理事

Pythonの概要から、どんな歴史で開発されてきたのか、どう運営されているかなどのお話がありました。
後半では言語のアップデートやこれからのPythonの未来のお話など、勉強になりました!

資料はこちら
slides.takanory.net

特に印象に残ったお話

Pythonで便利なライブラリを見つけるときはこのサイトがオススメ:Awesome Python
Pythonの妥協のないコードフォーマッター:Black
他にも旬なプロジェクトがいくつか紹介されていました!

Pythonのコミュニティも豊富

Python3.10のアップデートでは「Better error messages」という更新も入り、初心者に優しくなった

これからの未来:Pythonの高速化が進んでいきそう
The “Shannon Plan” :4年で5倍の高速化(1年で1.5倍)
GitHub - markshannon/faster-cpython: How to make CPython faster.

講演『26 Java Years - これが今のJavaだ!』谷本 心氏 / 日本Javaユーザーグループ代表

Javaは古い?堅い?ダサい?→No!! という走りだしから始まって楽しいプレゼンでした。

特に印象に残ったお話

JavaはOSSと共に歩んできた言語。エンタープライズ系で使われることが多い言語でありながら、開発環境・ライブラリ・フレームワークなどにOSSプロダクトが盛んに使われていた
言語も現在はOSS化され、企業でも提供を開始している

IDEはIntelliJ IDEAが主流。
追加で調べてみたら、2020年でシェア72%らしいです。良い。→数字で見る 2020年における Java の現状 | The IntelliJ IDEA Blog

主流になったOSSのプロダクトがJavaの標準機能として取り込まれている。
そうやって企業・団体・エンジニアの貢献によって、JavaのOSSエコシステムは成熟していった。

しかし、その一方でJava界隈のOSSで起きた問題もいろいろあった。
Javaは Write Once, Run Anywhereというポリシーを守るため、JavaではないものをJavaと認めないという意思があった。(不要なJavaの分断を防ぐという意味では良い判断。)
JavaであるかどうかについてはTechnology Compatibility Kit (TCK) で互換性のチェックを通っているかで判断している。
以下については、そういった考えがある中で、Javaと認められないことよって起こった事件。

  • Apache harmony事件 → OpenJDKに合流
  • Android事件 / Google訴訟事件 → OpenJDKになってAndroidの開発に適応されたが、既にJavaではなくKotlinが主流に。

※現在はOpenJDKが唯一のOSS版Javaになっている。

今の主流は各社が提供するOpenJDKを利用することが主流。
各社によって少しずつ提供するツールは異なるが、コア機能については100%同じ。他の部分も99%は同じ。

Javaのように長い歴史と巨大なエコシステムを伴うものをOSS化していく上で相当な努力があった。

講演『エコシステムと WebAssembly』chikoski氏 / WebAssembly Night、Rust.Tokyo 主催

WebAssembly、聞いたことはあるけれど触ったことがなかったし概念もよく分かってなかったので、そもそもWebAssemblyってなに?ってところからお話いただいたのとてもありがたかったです。

特に印象に残ったお話

Rust.Tokyo 2021: 9/18 開催

WebAssemblyは C / Rust / Assembly Script などをコンパイルしてブラウザで高速に動かせるようにしたもの
ブラウザの上でJavaScriptではないプログラム(C++など)を動かしたいというニーズはずっとあった。
VimをWebAssemblyで動かしてブラウザ上で動かしているというツールも既にある。
他にも、Webアプリでは Acrobat / Squoosh / Zoom / Autocad、サーバレス環境では Envoy / Istio など、利用例は広がっている。

WebAssemplyが利用されるにつれてニーズが分類できるようになってきた。それがエコシステムとパフォーマンス
パフォーマンスについて、WebAssemblyはネイティブよりも1.2倍遅いと言われてはいるが、ブラウザで処理することでAPIでアクセスすることもなくなり、そのレイテンシがいらなくなるなど、純粋に比較することは難しい。
パフォーマンスはJavaScriptよりも安定していると言われている。常に同じようなパフォーマンスで動いてほしいというニーズに合っている。

現在はパフォーマンスよりもエコシステムについての期待が高い
既にある資産をJavaScriptに書き直すのではなく、WebAssemblyを使うと少ないコストでブラウザ上で動かせるというメリットが大きい。
手に馴染んだ言語が使え、開発者体験をの向上が期待できる。(学習コストや既存資産の活用など)

WebAssemblyの利用事例:Shopify
Getting started

言語を選定する上で、Performance x Flexibility x Security を考える必要がある。WebAssemblyは以下の通りニーズを満たせる。

  • Performance
    • サーバー内の実行
    • ネイティブコードの事前生成
    • 精製したコードのキャッシュ
  • Flexibility
    • プログラムなのでユースケースが広い
    • いろんな言語で実装可能
  • セキュリティ
    • メモリ保護
    • 安全な実行コードの生成
    • アイソレーション

WebAssemblyはコンパイル・デコンパイルができるので、コンパイル後のもののコードが読めるというメリットもある。
Wasmファイルはコンパイルによって作られる関数定義のまとまり

WebAssemblyの辛いところ

  • Wasmにはバージョンがなく(1で固定されている)、仕様もさまざま。
  • データ表現に関する規定がない。
    • 言語ごとにライブラリを提供し、それを使ってデータ表現を統一しながらコンパイルをしていく必要がある。

全体を通して

全体を通して、OSS化によって言語の発展が活発になっているというポジティブさを感じました。
その一方で、ボランティアで成り立っている以上、開発者の生活をどう支えていくかについて課題を感じているという意見も複数あり、OSSの難しさもあるなぁと思いました。
セッション途中で紹介されたGitHubスポンサーがとても良い仕組みですね。

楽しかった〜!

他のクラスへの「呼び出し回数」と「引数として渡した値」をテストする

久しぶりにテストコードを書いたのでMEMO〜。

アプリから他のサービスを使っているけど、自動テストの時はそのサービスを使いたくない。
もしくは、テスト対象のクラスから他のクラスのメソッドを呼び出しているが、他のクラスの仕様はそのクラスのテストに委譲しており、今回のテストには含めたくない。
ただ、作成したクラスからサービスや他のクラスに対して、どんな値が渡されたのかはチェックしたい。

f:id:syobochim:20190630163339p:plain:w500

例えば、Controllerクラスのテストをする場合、 Controller内で Fukuzatsu クラスの hikisuIppai()メソッドを呼び出しているとする。
でも、hikisuIppai()メソッドの挙動は Fukuzatsu クラス側でテストするから、hikisuIppai() メソッドの「呼び出し回数」「引数として渡された値」が想定通りに設定されていることだけをテストできればOKとする。
そうした時のテストクラスはこんな感じになる。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.web.servlet.MockMvc;

import java.math.BigDecimal;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

@AutoConfigureMockMvc
@SpringBootTest
class ControllerTest {
  @Autowired
  private MockMvc mockMvc;
  @SpyBean
  private Fukuzatsu fukuzatsu;
  @Captor
  private ArgumentCaptor<Hotel> hotel;
  @Captor
  private ArgumentCaptor<Reservation> reservation;

  @Test
  void detailTest(@Autowired ObjectMapper mapper) throws Exception {
    doReturn(null).when(this.fukuzatsu).hikisuIppai(any(), any(), any(), any());

    CreateCommand cmd = new CreateCommand(hoge, fuga, piyo);
    String json = mapper.writeValueAsString(cmd);
    mockMvc.perform(post("/detail").content(json));

    verify(this.fukuzatsu, times(1)).hikisuIppai(any(), hotel.capture(), reservation.capture(), any());
    assertThat(reservation.getValue().getRating(), allOf(greaterThanOrEqualTo(new BigDecimal(0)), lessThanOrEqualTo(new BigDecimal(5))));
    assertThat(reservation.getValue().getNumberOfPeople(), is(greaterThanOrEqualTo(0)));
  }
}

内部の処理をスキップさせるために@SpyBean を利用して Fukuzatsu クラスの hikisuIppai メソッドの処理をモック化している。
今回は、引数に何が来ても null を返すように。

  @SpyBean
  private Fukuzatsu fukuzatsu;

...

    doReturn(null).when(this.fukuzatsu).hikisuIppai(any(), any(), any(), any());

アサーションでは、 hikisuIppai メソッドの呼び出し回数と、引数として渡した値を検査している。
キャプチャできれば普通に is メソッドなどを使って比較ができる。 今回は、

  • hikisuIppaiメソッドの呼び出し回数が1回であること
  • hikisuIppai メソッドの2番目、3番目に渡した値が想定通りであること
    • 2番目の値は hotel プロパティにキャプチャして、 hotel.getValue() で値を取得している。
    • 3番目の値は reservation プロパティにキャプチャして、 reservation.getValue() で値を取得している。

を検査している。

  @Captor
  private ArgumentCaptor<Hotel> hotel;
  @Captor
  private ArgumentCaptor<Reservation> reservation;

...

    verify(this.fukuzatsu, times(1)).hikisuIppai(any(), hotel.capture(), reservation.capture(), any());
    assertThat(hotel.getValue().getRating(), allOf(greaterThanOrEqualTo(new BigDecimal(0)), lessThanOrEqualTo(new BigDecimal(5))));
    assertThat(reservation.getValue().getNumberOfPeople(), is(greaterThanOrEqualTo(0)));

Spring BootのアプリとOracle CloudのAutonomous Databaseを接続する - アプリケーション編

Oracle Code Tokyoでハンズオンのお手伝いをしてきました!
ハンズオンは、Rails / laravel / Django / Spring Bootの4つのフレームワークを利用して、Oracle CloudのAutonomous Transaction Processingサービス(Oracle 18c)へ接続するサンプルアプリと、その手順を作っています。
私はSpring Boot(JPAを利用)のサンプルアプリとハンズオン手順、また、それに合わせてアプリの検証環境構築用のTerraformも作りました。

ハンズオンの手順やアプリはこちらのGitHubリポジトリに置いています。
ハンズオン手順と内容がかぶるところも多いのですが、この機会に、環境の作り方やデータベース接続方法などを整理したいと思います。

github.com

今回は、いよいよ完結編。アプリケーション作成のポイントを書いていこうと思います。
構成や環境構築編の内容についてはこちら
Spring BootのアプリとOracle CloudのAutonomous Databaseを接続する - 環境構築編 - そこに仁義はあるのか(仮)
アプリケーションの設定についてはこちら
Spring BootのアプリとOracle CloudのAutonomous Databaseを接続する - アプリケーション環境編 - そこに仁義はあるのか(仮)


f:id:syobochim:20190520002319p:plain

  • 👌 アプリで使っているもの
  • 👌 pom.xml
  • 👌 データベース接続設定を追加
  • 👌 シーケンスの設定
続きを読む

Java Day Tokyo 2018 の参加レポと、Night Sessionで司会をしました! #JavaDayTokyo

遅くなってしまいましたが、個人的な観点からのJava Day Tokyoの参加レポートです。

www.oracle.co.jp

💬 全体を通しての感想

基調講演は参加出来ず、午後からの参加でした…!

Night SessionでAsk the speakersという企画の司会をやることになっていたので、なるべく登壇者のセッションを聞きにいくようにしていた結果、海外からの登壇者ばかりのセッションばかり参加していました…!
でも、翻訳イヤホンがもらえるので問題なし!

私が受けたセッションがそうだったのかもしれませんが、ジャバジャバ(Java Java)した話というよりは、
コンテナやサーバレスなど、これからのプラットフォームに対してJavaで作るシステムを適用していくための話、というのが多かった印象でした。

あとは、私は聞いていないセッションでしたが、JDKのリリースモデルの変更に関するセッションは会場から人が溢れるほど聴講者が居て、やはり関心が高いんだなぁ、と感じました。

📖 全ての資料はこちらで公開されています

Java Day Tokyo 2018


以下、セッションのメモや感想です。
慣れない英語セッションの参加だったので、解釈間違ってるところもあるかもですが・・・。

続きを読む

GETのクエリパラメータの値をオブジェクト変換してvalidationをかけるときのやりかた(spring-boot)

メモだよ

✏️ パラメータ受け取り

RequestParamでクエリパラメータを取れる。他の取り方もある!
Spring Boot 使い方メモ - Qiita

@GetMapping(value = "/")
@ResponseBody
String getType(@RequestParam Map<String, String> queryParameters) {
    ....
}

✏️ Objectに変換する

ObjectMapperをつかってmapからObjectにする
クエリパラメータがsnake caseでくる場合は、ObjectMapperに設定を追加する

XXForm form = new ObjectMapper().convertValue(queryParameters, XXXForm.class);

XXForm form = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE).convertValue(queryParameters, XXXForm.class);

✏️ validationを実行する

Formにバリデーションを定義して、Validation実行。
精査に問題があったときは、violationsにエラー情報が設定される。

public class XXXForm {
    @NotNull
    public String type;
}
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
Set<ConstraintViolation<Object>> violations = validator.validate(form);
if (!violations.isEmpty()) {
    // バリデーションエラーのときの処理
}

✏️ 全体はこんな感じ

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.*;
import java.util.Map;
import java.util.Set;

@Controller
public class AuthenticationController {

    @GetMapping(value = "/")
    @ResponseBody
    String getType(@RequestParam Map<String, String> queryParameters) {
        XXForm form = getObjectMapper().convertValue(queryParameters, XXXForm.class);
        validate(authorize);
        // 正常処理
        return ...
    }

    private ObjectMapper getObjectMapper() {
        return new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    }

    private void validate(Object form) {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        Set<ConstraintViolation<Object>> violations = validator.validate(form);
        if (!violations.isEmpty()) {
            // バリデーションエラーのときの処理
        }
    }

}
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;

public class XXXForm {
    @NotNull
    public String type;

    public String state;

    @AssertTrue
    public boolean isType() {
        return responseType.equals("hogehoge");
    }
}

💭 うーーーーん

validationのときに、この値はこういうものだよ!って細かく定義したいけど、それって@AssertTrue使うのかな…?
相関ってわけじゃないので、モヤモヤする〜〜〜。
やりたいこととしては、そもそものプロパティのドメインって感じなんだけどな〜〜〜。

BeanValidationの相関バリデーションとそもそもの話 — 裏紙

上の記事がまさにソレ~!で、ドメインとして定義したい…

「SMTPサーバをたてといたから、メール送るプログラム作って」って言われたときのやりかた

メモだよ

やったこと

1. ✏️ SMTPサーバの情報を調べる
2. ✏️ spring-bootでメールを送る
おまけ. ✏️ 相手に送信できたかどうか調べるには
おまけのおまけ. ✏️ AWS SESとバウンス率

続きを読む

maven release pluginを使ってリリース作業を効率化する

maven release plugin を使うとリリース作業が超簡単になる〜

maven release plugin でやったこと

prepareperform を使いました〜!

mvn release:prepareでやってくれること

  • コミットされていないコードがないかチェックする
  • 依存関係(dependencies)に定義しているライブラリにSNAPSHOTバージョンのものがないかチェックする
  • pomのSNAPSHOTバージョンをリリースバージョンに書き換える(1.0.1-SNAPSHOT -> 1.0.1)
  • テストを実行して、正常に動作するか確認する
  • pomの変更をコミットする
  • Gitにタグをつける(デフォルトはSubversionになっているのでここは設定で変更した)(v1.0.1)
  • pomを新しいSNAPSHOTバージョンに書き換える(1.0.1 -> 1.0.2-SNAPSHOT)
  • pomの変更をコミットする

mvn release:performでやってくれること

  • Gitのタグにソースコードを切り替える
  • pomに書いたゴールを実行する
続きを読む