Infinito Nirone 7

白羽の矢を刺すスタイル

箱根を登ってインターハイしてきた

先週は金精峠に行ったので、今週は箱根です。

はじめての箱根、聞いていたとおりのキツさで、かつ距離を勘違いしていて終盤ヘタってしまいました……

 

国道1号最高地点の標識を見てだいぶ満足しましたが、芦ノ湖に降りてからは「このまま小田原に降りてしまっていいのか?」と頭の悪いことを考えてしまい、結果芦ノ湖から山中湖まで行く修行のような行程になりました。
f:id:KeithYokoma:20180512175630j:image

芦ノ湖からはまず大涌谷方面に走り出し乙女峠を目指します。そこを越えると一気に御殿場まで降り、御殿場の市街地を抜けるとすぐに籠坂峠(山中湖村)まで続く長い長い登りが始まります。斜度は7%を超えることはなく、ひたすら4%5%あたりの坂が無限に続きます。緩くなることが殆どないので、ペースを守らないと簡単に足が売り切れると思います……

 

山中湖からは、富士吉田から大月を目指すプランと道志みちを通って相模原を目指すプランというふたつのヤバいプランをまたしても考えましたが、もう足がないので富士山駅輪行することにしました。
f:id:KeithYokoma:20180512180112j:image

来月は富士ヒルでまた来ます。

GWのシメに日光から金精峠を登ってきた

ゴールデンなウイークの間にどこかへ輪行して山に行こうという計画は前々からしていて、本当は渋峠に行きたかったんですが、火山活動の関係で長野県側からしか登れなくなってしまいました。長野側から登るのもいいんですが、ゴールデンなウイークでみんな電車やら新幹線使うのでそういう中での輪行は大変だからもうちょっとイージーモードで行ける場所!と思って出した結論が日光でした。もともといろは坂やら金精峠は言ってみたかったのでちょうど良いタイミングだ!と思ってせっせときっぷを確保しました。

 

とりあえず我が家からなら新宿に行けば東武日光までの特急に乗れるので、あとは駅から金精峠までまっしぐら!

 

いろは坂までの道でもすでに上り坂なので油断ならないのですが、いろは坂自体は激坂というわけでもないので、淡々と登りました。
f:id:KeithYokoma:20180506174353j:image

はじめて自転車で来る中禅寺湖


f:id:KeithYokoma:20180506174515j:image

戦場ヶ原からさきは車でも来たことがないので、完全にテンションがあがっています。


f:id:KeithYokoma:20180506174626j:image

戦場ヶ原から金精峠までは割とキツめ。たまに10%を超える坂が出てきましたがなんとか登りきりました。たぶん途中でろんぐらいだぁすの原作者の方っぽい人を追い越した気がする。朝の電車でツイッターみてたら先に登り始めていたらしいので。。


f:id:KeithYokoma:20180506174845j:image

峠を超えて少し下ったところにある休憩所で山菜そばとゆば豚まんを食べました。


f:id:KeithYokoma:20180506174951j:image

山と言えばソフトクリーム。


f:id:KeithYokoma:20180506175045j:image

下りはゆるゆる、上りで通過してきたところに寄り道を。この寄り道の途中で、登ってきたときに見かけたユーコンというお店がろんぐらいだぁすの聖地だということに気がついて、ここでご飯食べたら良かったと少し後悔しました。


f:id:KeithYokoma:20180506175226j:image

帰りは、行きに食べ損なった駅弁。おいしゅうございました。

桜のAACR完走

今年はじめて桜の AACR(Alps Azumino Century Ride)に参加しました。

これまではヒルクライムが中心だ、長距離ライドのイベントはツールド東北以来ということになります。

車で行くか電車で行くか悩みましたが、150km走ったあとに運転するのはヤバそうだなと思ったので、特急でいくことに。

前日に受付を済ませて松本の観光と食事を。晩御飯は以前ツールド美ヶ原に来たときにたまたま立ち寄ったとんかつ屋さんが最高だったので、リピートしました。
f:id:KeithYokoma:20180422173848j:image

お通しに二種類のお漬物がでてきて、それからたんまりのとんかつや揚げ物、ご飯とお味噌汁がでてきます。

スタートは1組なので早めに就寝。4時に起きて準備して、5時半スタートに備えました。昼間はあんなに暑かったのに、夜や明け方は超寒かったです。まあでも、自転車に乗っていれば体はあたたまるので、日がいい感じに登るまでの辛抱でした。
f:id:KeithYokoma:20180422174748j:image

安曇野やその周辺はどこを走ってもキレイな眺めで、ちょうど今のこの時期が、雪をかぶった山と満開の桜が楽しめるようで、エイドステーション以外の場所でも写真撮影をしていました。普通に一眼レフなどを持ち歩いている観光客も多くいました。
f:id:KeithYokoma:20180422175013j:image

独特な味噌をつけていただくおにぎり最高!🍙
f:id:KeithYokoma:20180422175044j:image
f:id:KeithYokoma:20180422175124j:image
f:id:KeithYokoma:20180422175056j:image
f:id:KeithYokoma:20180422175218j:image
f:id:KeithYokoma:20180422175235j:image
f:id:KeithYokoma:20180422175338j:image

14時前にゴールするのは完全に予想外でしたが、無事完走できました。
f:id:KeithYokoma:20180422175416j:image
 手足はカバーをつけて日焼け対策をしましたが、顔や首周りの対策ができていなくて、ゴール後梓水苑のお風呂に入ったときにヒリヒリしてしまいました。次はきをつけよう。

ゴールしたときにゼッケン番号による抽選会をやっていて、こういうの当たらないんだよなと思っていたらハンドクリームが当たりました。肌荒れひどいマンなので助かる。

Robolectric を offline mode で動作させる

Robolectric でテストを実行すると、初めの方のテストでなにかを Maven Central からダウンロードしているログが出力されることがあります。これは Robolectric がテスト実行時に必要な依存をダウンロードしているもので、Android SDK のなかのクラスを JVM で実行可能にしている jar が入っています。

ローカルでテストを動かす分には初めてテストを実行するときにしかお目にかかることはありませんが、CI のような環境の場合、CI が走るたびに Robolectric の依存解決が動きます。 また、Robolectric はどの SDK version でテストを動かすかを動的に指定できるので、@Config(sdk = [21]) とか @Config(sdk = [25]) とかが付いているテストケースがあるたびに、必要な jar を適宜取りに行くようになっています。 そうすると、@Config アノテーションの数だけ jar のダウンロード時間が必要になるので、CI だと結構な時間が依存解決に費やされてしまいます。

そこで Robolectric には offline mode というのがあって、あらかじめ jar をローカルに保存しそのパスを教えてあげると、テスト実行時には Maven Central へアクセスせずともテストが実行できるようになっています。 これで時間の節約ができるというわけです。

事前にダウンロードする Gradle スクリプト

medium.com

実はすでにこれを実現するスクリプトが公開されています。

問題点

概ね offline mode の設定と jar の場所の設定はこのスクリプトで問題ありませんが、複数の jar が必要なときにうまく動きません。

上記の記事で書かれたスクリプトの dependencies を次のように書いたとします。

configurations {
    robolectricRuntime
}

dependencies {
    robolectricRuntime "org.robolectric:android-all:4.1.2_r1-robolectric-r1"
    robolectricRuntime "org.robolectric:android-all:4.3_r2-robolectric-r1"
    robolectricRuntime "org.robolectric:android-all:4.4_r1-robolectric-r2"
    robolectricRuntime "org.robolectric:android-all:5.0.2_r3-robolectric-r0"
    robolectricRuntime "org.robolectric:android-all:7.1.0_r7-robolectric-r1"
    robolectricRuntime "org.robolectric:android-all:8.1.0-robolectric-4611349"
}

テストでは ICS, JB, K, L, N, O のそれぞれの android-all について jar が必要な状態です。 複数必要なので dependencies の指定も複数並べることになりますが、robolectricRuntime のどの dependency も GroupId と Artifact が同じで Version のみが異なるため、Gradle はこの列挙された dependencies の中から最新のものしか解決しません。 結果、jar を放り込むディレクトリには O の android-all の jar ファイルしかいないことになります。

どう解決するか

Configuration ごとに dependency の解決が行われることを考えると、必要な android-all の jar ごとに Configuration を作れば良いことになります。

configurations {
    robolectricRuntimeICS
    robolectricRuntimeJB
    robolectricRuntimeK
    robolectricRuntimeL
    robolectricRuntimeN
    robolectricRuntimeO
}

dependencies {
    robolectricRuntimeICS "org.robolectric:android-all:4.1.2_r1-robolectric-r1"
    robolectricRuntimeJB "org.robolectric:android-all:4.3_r2-robolectric-r1"
    robolectricRuntimeK "org.robolectric:android-all:4.4_r1-robolectric-r2"
    robolectricRuntimeL "org.robolectric:android-all:5.0.2_r3-robolectric-r0"
    robolectricRuntimeN "org.robolectric:android-all:7.1.0_r7-robolectric-r1"
    robolectricRuntimeO "org.robolectric:android-all:8.1.0-robolectric-4611349"
}

そして jar を copy するタスクの中身を次のように書き換えます。

rootProject.task(type: Copy, overwrite: true, "downloadRobolectricDependencies") {
    configurations.all { configuration ->
        if (configuration.name.startsWith("robolectricRuntime")) {
            from configuration
        }
    }
    into robolectricDependenciesFolder
}

これで Configuration ごとに別の android-all の jar をダウンロードしてローカルにコピーするまでが実現できました。

あとは ./gradlew downloadRobolectricDependencies とするだけですべての jar がダウンロードできます。

Android Plugin for Gradle 3.1.0 で The SourceSet 'xxx' is not recognized by Android Gradle Plugin

Android Studio が 3.1.0 になったのに合わせて Android Plugin for Gradle も 3.1.0 が出ました。

Android Plugin for Gradle Release Notes | Android Studio

リリースノートには記述がありませんが、alpha のころから存在する問題として、3.1.0 にあげると"The SourceSet 'xxx' is not recognized by Android Gradle Plugin"というエラーでビルドが失敗する場合があるようです。 たまたま自分もこの問題にぶちあたったので、何がダメでどうするとよいかをメモしておきます。

次のような build.gradle がある前提です。 minSdktypeのふたつの flavorDimensions があり、variantFilter で api19FlavorA だけを無視する設定です。

android {
  flavorDimensions 'minSdk', 'type'

  productFlavors {
    api19 {
      dimension 'minSdk'
      minSdkVersion 19
    }
    api21 {
      dimension 'minSdk'
      minSdkVersion 21
    }
    flavorA {
      dimension 'type'
    }
    flavorB {
      dimension 'type'
    }
  }

  variantFilter { variant ->
    def names = variant.flavors*.name
    if (names.contains('api19') && names.contains('flavorA') {
      setIgnore(true)
    }
  }
}

このとき api19FlavorA の SourceSet を設定すると、タイトルにあるようなThe SourceSet 'xxx' is not recognized by Android Gradle Pluginというエラーが発生します。 Android Plugin for Gradle 3.0.x まではとくにエラーになるものではありませんでしたが、3.1.0 からはダメなようです。

上記のビルドスクリプトでは variantFilter で variant を setIgnore(true) する条件が ProductFlavor の名前だけなので、不注意でないかぎり無視した ProductFlavor の SourceSet を設定することはないと思いますが、無視する条件が環境によって変わる場合は、それにあわせて SourceSet の設定を変えてやる必要があります。

def disable_condition = // Condition to disable api19Flavor variant

android {
  // ...

  variantFilter { variant ->
    def names = variant.flavors*.name
    if (disable_condition && names.contains('api19') && names.contains('flavorA') {
      setIgnore(true)
    }
  }

  sourceSets {
    if (!disable_condition) {
      api19FlavorA {
        // api19FlavorA SourceSet configuration under a specific condition
      }
    }
    api19FlavorB {
      // always configure SourceSet for api19FlavorB
    }
    // ...
  }
}

割とよくあるパターンでリアディレイラーを壊す実績を解除した話

おそらくスポーツ自転車を買った人なら誰もが、納車のタイミングでお店の人に説明を受けるであろう「ディレイラーハンガーが曲がる」パターンでリアディレイラーが昇天してしまう体験を通勤チャリに乗って帰宅している最中に体験したのでメモしておきます。

ディレイラーハンガー is 何

スポーツ自転車の変速機は外にむき出しで、かつ一点で支えられている上に結構長さがあるので、ほんのちょっとでも力がかかると簡単に折れ曲がります。このとき変速機が車体に直接くっついていると、一緒に車体まで巻き添えにしてしまい車体ごと買い換えないといけなくなって辛いので、ディレイラーハンガーというのを車体に取り付け、そのディレイラーハンガーに変速機(リアディレイラー)を取り付けることで、たとえ折れ曲がってもディレイラーハンガーで負荷を吸収して車体までダメージが行かないようにしています。ただしやはりリアディレイラーのついているところが急所であることには変わりないので、ディレイラーハンガーがほんのちょっとでも曲がってしまうと変速がおかしくなったり、最悪後ろの車輪にリアディレイラーが巻き込まれて破損します。

どのタイミングで壊れたのか

ちょうど渋滞のなかでユルユル進んでいる最中に漕ぎ出して間もないタイミングで壊れました。自転車の後ろからけたたましい音がして車輪がロックしたのですぐに止めて、あーこれが例のアレだってことに気が付きました。 スピードがそんなに出てなかったこともあって転倒するなどの事故にはならなかったので本当にホッとしています。

結果

f:id:KeithYokoma:20180323210856j:plain

このとおりです。スピードがそこまで出てなかったとはいえ車輪に巻き込まれたので見事にヒョエエエエエエッッ!!!!となってます。

壊れたのに気がついて道の脇に寄せて、とりあえずディレイラーを取り外せる大きさの六角レンチがないのでハンガーまるごとワイヤーも解除して車体から取り外しました。その時は気づきませんでしたが家に帰ってよく見てみるとハンガーがえらい勢いで曲がってたので、そりゃあ車輪に巻き込まれるよねって感じでした。

今後

車体にあうディレイラーハンガーを探すのと、ディレイラーそのものも修理不能なので買い換える必要があります。といってもしばらくはチャリ通ができなそうなのでぼちぼちやっていきます。

ちなみにほんのちょっとしたディレイラーハンガーの曲がりならお店の人に見てもらうと直してもらえます。ですが極端に曲がってると直せないですし、直せるレベルでも交換できるなら交換したほうがいいですね。アルミ製とはいえ力のかかり方によっては簡単に曲がってしまうので。

現場からは以上です。