カテゴリー: テクノロジー

PHP Laravel bladeとvuejsと。

いよいよ花粉症の季節がやってきますね。
> 花粉さん、今年は注射治療しますがお手柔らかにお願いしますね。
マエダです。

さてこのタイトルなんなのかとご説明させていただきますと、みんな大好きLaravelのBladeテンプレートにControllerから渡された変数を利用して、vuejsの変数名を生成して、vuejsの変数を表示したい!

僕の日本語がヘンくてわかりませんね。(変)

Bladeテンプレートの変数の表示

こちら利用したことある方はおなじみの記述方法ですね。

<span>
{{ $name }}
</span>

Vue.jsの変数の表示(Blade内)

Laravel利用者はおなじみだと思いますが、BladeとVue.jsの波括弧とで構文エラーとなるのを先頭に「@」を付けることで回避する記述方法を利用します。

<span>
@{{ name }}
</span>

Vue.jsの変数をPHP変数で変更して表示

上記を踏まえまして、これってどうかなーってBladeテンプレートに書くと・・・

<span>
@{{ users.{{ $user_id }}.name }}
</span>

「[Vue warn]: Error compiling template」

波括弧の閉じるがどっちやねん!って怒られてしまいますね。。。

そこでの回避方法として、

<span>
@php echo("{{ users.{$user_id}.name }}") @endphp
</span>

急に波括弧を使わない!という選択。( ー`дー´)キリッ

そもそもそんなPHPとJavaScriptどっちつかずの設計にするなよとかのツッコミは受け付けません。
こうやったらどうですか?という優しいツッコミだけお願いします。

以上、vuejsに触れてみようのコーナーでした。

\\優しくツッコミをいれてくれる仲間を募集中です!!//
vuejsビギナーの僕がよくわからない利用方法を実験しているときに優しくツッコミいれてくれるそこのあなた。
以下ページよりご応募お待ちしております。
https://splout.co.jp/recruit/

SolrCloudのエイリアス機能(その2)

はじめに

SolrCloudのエイリアス機能には大きく分けて Standard Aliases と Routed Aliases があります。基本的な機能はどちらも共通で、Routed Aliases には特定のフィールドの値に応じて特定のコレクションを対象として指定できるという特徴があります。

この記事では、Routed Aliases の中の Time Routed Aliases を採り上げます。

Time Routed Aliases の作成

Time Routed Aliases を作るときの基本的なリクエストは以下のようなものです。

$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=timedata&router.start=NOW/DAY&router.field=date&router.name=time&router.interval=%2B1DAY&router.maxFutureMs=3600000&router.autoDeleteAge=/DAY-90DAYS&create-collection.collection.configName=aliasConfigSet&create-collection.numShards=1'

指定されているパラメータの説明

  • action=CREATEALIAS
  • router.name=time
    • Time Routed Aliases の場合は “time” を指定
  • name=timedata
    • エイリアス名
    • コレクション名は、この文字列をプレフィックスとして”timedata_2019-12-25″のようになる
  • router.field=date
    • 振り分けの基準にするフィールド名
  • router.start=NOW/DAY
    • 起点の時刻
    • この時刻を含むコレクションが最初のコレクションとして生成される。それより古いデータはエラーになる。
  • router.interval=+1DAY
    • 1つのコレクションが受け持つ時間の範囲
  • router.maxFutureMs=3600000
    • 現在時刻よりもどのくらい先の時刻までのデータを受け入れるか(ミリ秒)
    • 3600000が指定された場合、1時間先のデータまでは受け入れる
  • router.autoDeleteAge=/DAY-90DAYS
    • ここで指定された期間を過ぎたコレクションは自動的に削除される
  • create-collection.collection.configName=aliasConfigSet
    • Time Routed Aliases に属するコレクションが共通して持つコンフィグセットの指定
  • create-collection.numShards=1
    • Routed Aliases では CREATEALIAS の際にコレクションを作成するので、CREATE アクションでコレクションを作成する際に指定できるパラメータをcreate-collection.* という形で指定できる。

たとえば2019年12月25日に上に示したリクエストを実行したとすると、以下のような運用になります。

  • エイリアス名 timedata
  • コレクション名 timedata_2019-12-25
  • 現在時刻から1時間先のデータまで受け付る
  • 2019年12月26日のデータを受け付けると timedata_2019-12-26 が作られる
  • 90日よりも古くなったコレクションは削除

コレクションの自動追加

上述の通り、最新のコレクションが timedata_2019-12-25 であるときに12月26日のデータを追加しようとすると、新しく timedata_2019-12-26 が作られます。 新しいコレクションの作成には数秒を要し、その間 timedata_2019-12-26 への更新処理はブロックされます。

秒あたりのデータ数が多く、このブロック発生が許容できない場合には、CREATEALIAS アクションのオプションとして router.preemptiveCreateMath を指定できます。ここで例えば60分を指定しておくと、12月25日の23:00のデータを処理した時点で先に timedata_2019-12-26 を非同期に作成しておくことができます。

おわりに

Time Routed Aliases は以下の特徴を持つ Routed Aliases です。

  • エイリアス配下のコレクションそれぞれが一定の時間範囲のデータを担当する
    • (例)12月10日用のコレクション、11日用のコレクション、12日用のコレクション…
  • 時刻のフィールドによる振り分け
  • 更新を許容する時間範囲の設定
  • 現在時刻に応じて自動的に新しいコレクションを追加
  • 現在時刻に応じて古いコレクションを自動的に削除

時間的に連続するログデータやセンサの計測データなどを扱うのに向いています。

SolrCloudのエイリアス機能(その1)

はじめに

SolrCloudにはコレクションにエイリアスを設定する機能があります。
このエイリアスが役に立つ場面として、リファレンスでは以下の3つが挙げられています。
・新しく作った、再生成したインデックスをダウンタイム無しで既存のものと差し替える
・コレクション名の変更がクライアントプラグラムに影響を与えないようにする
・同じスキーマの複数のコレクションに1回だけクエリを発行する

1つめと2つめについては経験がありますが、3つめの複数のコレクションを対象にエイリアスを設定するパターンは使ったことは無かったので、その挙動等を調べてみました。

複数コレクションにエイリアスを設定する

まずalias_test1とalias_test2の2つのコレクションを作成してエイリアスalias_testを設定。

$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATE&name=alias_test1&numShards=1&replicationFactor=1&wt=json'
$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATE&name=alias_test2&numShards=1&replicationFactor=1&wt=json'
$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=alias_test&collections=alias_test1,alias_test2'

エイリアスを確認。

curl -s 'http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS' | jq .cluster.aliases
{
  "alias_test1": "alias_test1",
  "alias_test2": "alias_test2",
  "alias_test": "alias_test1,alias_test2"
}

エイリアスに対するスキーマ変更

コレクションではなくエイリアスを指定してフィールドを追加してみます。

$ cat add_field.json
{
  "add-field":{
     "name":"date",
     "type":"pdate",
      "stored":true },
  "add-field":{
     "name":"body",
     "type":"string",
      "stored":true }
}
$ curl -s -X POST -H 'Content-type:application/json' -d @add_field.json 'http://localhost:8983/solr/alias_test/schema'

各コレクションのスキーマを確認。

$ curl -s 'http://localhost:8983/solr/alias_test1/schema/fields?omitHeader=true'
{
  "fields":[
    {
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"body",
      "type":"string",
      "stored":true},
    {
      "name":"date",
      "type":"pdate",
      "stored":true},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true}]
$ curl -s 'http://localhost:8983/solr/alias_test2/schema/fields?omitHeader=true'
{
  "fields":[{
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true}]

dataフィールドとbodyフィールドが追加されたのはalias_test1の方だけでした。alias_test2にはコレクション名を指定してフィールドを追加しておきます。

$ curl -s -X POST -H 'Content-type:application/json' -d @add_field.json 'http://localhost:8983/solr/alias_test2/schema'
$ curl -s 'http://localhost:8983/solr/alias_test2/schema/fields?omitHeader=true'
{
  "fields":[{
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true},
    {
      "name":"body",
      "type":"string",
      "stored":true},
    {
      "name":"date",
      "type":"pdate",
      "stored":true}]

エイリアスに対する更新

エイリアス alias_test を指定してデータを投入してみます。

$ cat data.json
[
    {"id":"1",
     "date":"2019-01-01T00:00:00Z",
     "body":"body1"
    }
]
$ curl -s -X POST -H 'Content-type:application/json' -d @data.json 'http://localhost:8983/solr/alias_test/update/json/docs?commit=true'

それぞれのコレクションの内容を確認。

$ curl -s 'http://localhost:8983/solr/alias_test1/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"1",
        "date":"2019-01-01T00:00:00Z",
        "body":"body1",
        "_version_":1653627228838166528}]
  }}
$ curl -s 'http://localhost:8983/solr/alias_test2/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":0,"start":0,"docs":[]
  }}

やはりalias_test1の方だけ更新されている。

エイリアスに対する検索

コレクションalias_test2を指定して別のデータを投入しておきます。

$ cat data2.json
[
    {"id":"2",
     "date":"2019-01-02T00:00:00Z",
     "body":"body2"
    }
]
$ curl -s -X POST -H 'Content-type:application/json' -d @data2.json 'http://localhost:8983/solr/alias_test2/update/json/docs?commit=true'
$ curl -s 'http://localhost:8983/solr/alias_test2/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"2",
        "date":"2019-01-02T00:00:00Z",
        "body":"body2",
        "_version_":1653898674683510784}]
  }}

エイリアスを指定して検索。

$ curl -s 'http://localhost:8983/solr/alias_test/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":2,"start":0,"maxScore":1.0,"docs":[
      {
        "id":"1",
        "date":"2019-01-01T00:00:00Z",
        "body":"body1",
        "_version_":1653627228838166528},
      {
        "id":"2",
        "date":"2019-01-02T00:00:00Z",
        "body":"body2",
        "_version_":1653898674683510784}]
  }}

コレクション alias_test1 と alias_test2 の結果が統合されていることが分かります。

おわりに

複数のコレクションを対象にしたエイリアスの挙動を探ってみました。
検索では1回のリクエストで統一的に結果を得ることができます。
更新の場合は最初に指定されたコレクションがUPDATEリクエストを処理するようになっており、更新先を指定したい場合にはコレクション名を使う必要があります。

同じスキーマのコレクションを複数に分けたい使い方というのは、ログ等の時系列のデータが典型例です。実はSolrではこのような使い方に便利なRouted Aliasという機能が用意されています。Routed Aliasの詳細については別の機会に採り上げたいと思います。

オレオレ証明書の入ったサーバーで Service Worker のテストをしたいとき

This work is licensed under a Creative Commons Attribution 4.0 International License. Web Fundamentals | Google Developers

こんな状況。

  • テストはイントラネット内にあるサーバーを使用。
  • 自己署名証明書 (通称: オレオレ証明書) が入っている。
  • ブラウザは Chrome。

普通に Chrome で開こうとするとエラーが出て動作しません。

どうすればいいか。

Chrome の起動オプションで以下を指定します。

--user-data-dir="D:\ユーザーデータディレクトリ" --unsafely-treat-insecure-origin-as-secure="https://テストサーバー.site"

これは何をしているの?

Service Worker は、その強大な力を抑えるために localhost であるか、https でないと動作しないという制限が課せられています。

しかし、https であっても、オレオレ証明書の場合には以下のようなエラーにより Service Worker は動作しません。

An SSL certificate error occurred when fetching the script.

–unsafely-treat-insecure-origin-as-secure を起動オプションに指定することで、エラーを出さずに Service Worker が動作させることができるようになります。

あまり重要そうに見えませんが –user-data-dir は必須です。

証明書の警告なんとかならないの?

確認の度に証明書の警告が表示されるのは非常に煩わしいものです。

これも起動オプションで非表示にします。

--ignore-certificate-errors 

これで Service Worker も動いて存分にテストできますね。

めでたしめでたし。

・・・

余談ですが、これらは Chrome の GUI からも設定できます。

ただ、GUI から設定すると状態が残ってしまうため、外部のインターネットに接続する際に戻し忘れが発生し危険です。

テスト用に専用のプロファイルを作るか、ショートカットやエイリアスを用意することをお勧めします。

Portions of this page are reproduced from work created and shared by Google and used according to terms described in the Creative Commons 4.0 Attribution License.

JVM系のソフトウェアをSDKMANで管理する

はじめに

不勉強なもので、JVM系の言語やツールを管理しやすくするSDKMANというツールの存在をつい最近知りました。 インストールやアップデート、複数のバージョンの切り替えなどをsdkというコマンドで扱えるようです。 この辺は悩みの種になりやすいところなので使ってみることにしました。

SDKMANインストール

$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh" 
$ sdk version
SDKMAN 5.7.4+362

使い方

扱えるソフトウェア一覧

$ sdk list
================================================================================
Available Candidates
================================================================================
q-quit                                  /-search down
j-down                                  ?-search up
k-up                                    h-help

--------------------------------------------------------------------------------
Ant (1.10.1)                                             https://ant.apache.org/

Apache Ant is a Java library and command-line tool whose mission is to drive
processes described in build files as targets and extension points dependent
upon each other. The main known usage of Ant is the build of Java applications.
Ant supplies a number of built-in tasks allowing to compile, assemble, test and
run Java applications. Ant can also be used effectively to build non Java
applications, for instance C or C++ applications. More generally, Ant can be
used to pilot any type of process which can be described in terms of targets and
tasks.

                                                               $ sdk install ant
--------------------------------------------------------------------------------
AsciidoctorJ (2.1.0)                                     http://asciidoctor.org/

AsciidoctorJ is the official library for running Asciidoctor on the JVM. Using
AsciidoctorJ, you can convert AsciiDoc content or analyze the structure of a
parsed AsciiDoc document from Java and other JVM languages.

                                                      $ sdk install asciidoctorj
--------------------------------------------------------------------------------
(略)

特定のソフトウェアのインストール候補

$ sdk list java
================================================================================
Available Java Versions
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK  |     | 13.0.1.j9    | adpt    |            | 13.0.1.j9-adpt      
               |     | 13.0.1.hs    | adpt    |            | 13.0.1.hs-adpt      
               |     | 12.0.2.j9    | adpt    |            | 12.0.2.j9-adpt      
               |     | 12.0.2.hs    | adpt    |            | 12.0.2.hs-adpt      
               |     | 11.0.5.j9    | adpt    |            | 11.0.5.j9-adpt      
               |     | 11.0.5.hs    | adpt    |            | 11.0.5.hs-adpt      
               |     | 8.0.232.j9   | adpt    |            | 8.0.232.j9-adpt     
               |     | 8.0.232.hs   | adpt    |            | 8.0.232.hs-adpt     
 Amazon        |     | 11.0.5       | amzn    |            | 11.0.5-amzn         
               |     | 8.0.232      | amzn    |            | 8.0.232-amzn        
 Azul Zulu     |     | 13.0.1       | zulu    |            | 13.0.1-zulu         
               |     | 12.0.2       | zulu    |            | 12.0.2-zulu         
               |     | 11.0.5       | zulu    |            | 11.0.5-zulu         
               |     | 10.0.2       | zulu    |            | 10.0.2-zulu         
               |     | 9.0.7        | zulu    |            | 9.0.7-zulu          
               |     | 8.0.232      | zulu    |            | 8.0.232-zulu        
               |     | 7.0.242      | zulu    |            | 7.0.242-zulu        
               |     | 6.0.119      | zulu    |            | 6.0.119-zulu        
 Azul ZuluFX   |     | 11.0.2       | zulufx  |            | 11.0.2-zulufx       
               |     | 8.0.202      | zulufx  |            | 8.0.202-zulufx      
 BellSoft      |     | 13.0.1       | librca  |            | 13.0.1-librca       
               |     | 12.0.2       | librca  |            | 12.0.2-librca       
               |     | 11.0.5       | librca  |            | 11.0.5-librca       
               |     | 8.0.232      | librca  |            | 8.0.232-librca      
 GraalVM       |     | 19.3.0.r11   | grl     |            | 19.3.0.r11-grl      
               |     | 19.3.0.r8    | grl     |            | 19.3.0.r8-grl       
               |     | 19.2.1       | grl     |            | 19.2.1-grl          
               |     | 19.1.1       | grl     |            | 19.1.1-grl          
               |     | 19.0.2       | grl     |            | 19.0.2-grl          
               |     | 1.0.0        | grl     |            | 1.0.0-rc-16-grl     
 Java.net      |     | 14.ea.26     | open    |            | 14.ea.26-open       
               | >>> | 13.0.1       | open    | installed  | 13.0.1-open         
               |     | 12.0.2       | open    |            | 12.0.2-open         
               |     | 11.0.5       | open    |            | 11.0.5-open         
               |     | 10.0.2       | open    |            | 10.0.2-open         
               |     | 9.0.4        | open    |            | 9.0.4-open          
               |     | 8.0.232      | open    |            | 8.0.232-open        
 SAP           |     | 12.0.2       | sapmchn |            | 12.0.2-sapmchn      
               |     | 11.0.4       | sapmchn |            | 11.0.4-sapmchn      
================================================================================
Use the Identifier for installation:

    $ sdk install java 11.0.3.hs-adpt
================================================================================

インストール

まずはJava。

$ sdk install java 13.0.1-open

Downloading: java 13.0.1-open

In progress...

######################################################################################################################################################### 100.0%

Repackaging Java 13.0.1-open...

Done repackaging...

Installing: java 13.0.1-open
Done installing!

Setting java 13.0.1-open as default.

$ java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)

ScalaとKotlinも。

$ sdk install kotlin 1.3.61
$ sdk install scala 2.13.1
$ sdk current

Using:

java: 13.0.1-open
kotlin: 1.3.61
scala: 2.13.1

複数のバージョンの使い分け

JDKをもう1種類インストールしてみる。

$ sdk install java 12.0.2-open

Downloading: java 12.0.2-open

In progress...

######################################################################################################################################################### 100.0%

Repackaging Java 12.0.2-open...

Done repackaging...

Installing: java 12.0.2-open
Done installing!

Do you want java 12.0.2-open to be set as default? (Y/n): Y

Setting java 12.0.2-open as default.

こっちをデフォルトにしますか?という質問にYと答えたので12.0.2-openがデフォルトになりました。

$ sdk list java
================================================================================
Available Java Versions
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK  |     | 13.0.1.j9    | adpt    |            | 13.0.1.j9-adpt      
               |     | 13.0.1.hs    | adpt    |            | 13.0.1.hs-adpt      
               |     | 12.0.2.j9    | adpt    |            | 12.0.2.j9-adpt      
               |     | 12.0.2.hs    | adpt    |            | 12.0.2.hs-adpt      
               |     | 11.0.5.j9    | adpt    |            | 11.0.5.j9-adpt      
               |     | 11.0.5.hs    | adpt    |            | 11.0.5.hs-adpt      
               |     | 8.0.232.j9   | adpt    |            | 8.0.232.j9-adpt     
               |     | 8.0.232.hs   | adpt    |            | 8.0.232.hs-adpt     
 Amazon        |     | 11.0.5       | amzn    |            | 11.0.5-amzn         
               |     | 8.0.232      | amzn    |            | 8.0.232-amzn        
 Azul Zulu     |     | 13.0.1       | zulu    |            | 13.0.1-zulu         
               |     | 12.0.2       | zulu    |            | 12.0.2-zulu         
               |     | 11.0.5       | zulu    |            | 11.0.5-zulu         
               |     | 10.0.2       | zulu    |            | 10.0.2-zulu         
               |     | 9.0.7        | zulu    |            | 9.0.7-zulu          
               |     | 8.0.232      | zulu    |            | 8.0.232-zulu        
               |     | 7.0.242      | zulu    |            | 7.0.242-zulu        
               |     | 6.0.119      | zulu    |            | 6.0.119-zulu        
 Azul ZuluFX   |     | 11.0.2       | zulufx  |            | 11.0.2-zulufx       
               |     | 8.0.202      | zulufx  |            | 8.0.202-zulufx      
 BellSoft      |     | 13.0.1       | librca  |            | 13.0.1-librca       
               |     | 12.0.2       | librca  |            | 12.0.2-librca       
               |     | 11.0.5       | librca  |            | 11.0.5-librca       
               |     | 8.0.232      | librca  |            | 8.0.232-librca      
 GraalVM       |     | 19.3.0.r11   | grl     |            | 19.3.0.r11-grl      
               |     | 19.3.0.r8    | grl     |            | 19.3.0.r8-grl       
               |     | 19.2.1       | grl     |            | 19.2.1-grl          
               |     | 19.1.1       | grl     |            | 19.1.1-grl          
               |     | 19.0.2       | grl     |            | 19.0.2-grl          
               |     | 1.0.0        | grl     |            | 1.0.0-rc-16-grl     
 Java.net      |     | 14.ea.26     | open    |            | 14.ea.26-open       
               |     | 13.0.1       | open    | installed  | 13.0.1-open         
               | >>> | 12.0.2       | open    | installed  | 12.0.2-open         
               |     | 11.0.5       | open    |            | 11.0.5-open         
               |     | 10.0.2       | open    |            | 10.0.2-open         
               |     | 9.0.4        | open    |            | 9.0.4-open          
               |     | 8.0.232      | open    |            | 8.0.232-open        
 SAP           |     | 12.0.2       | sapmchn |            | 12.0.2-sapmchn      
               |     | 11.0.4       | sapmchn |            | 11.0.4-sapmchn      
================================================================================
Use the Identifier for installation:

    $ sdk install java 11.0.3.hs-adpt
================================================================================

13.0.1-openと12.0.2-openがインストールされていて、デフォルトが12.0.2-openになっていることが分かります。

$ java -version
openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode, sharing)

確かに12.0.2が使われます。これを13.0.1-openに切り替えてみます。

$ sdk default java 13.0.1-open

Default java version set to 13.0.1-open

$ java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)

どのように管理されているのか?

このまま使うのは気持ち悪いので、各ソフトウェアがどういう風にインストールされているのかを確認してみます。

$ which java
/home/myuser/.sdkman/candidates/java/current/bin/java

どうやらホームディレクトリの.sdkman以下にインストールされているようです。
ディレクトリとファイルの構成は以下の通り。

$ cd ~/.sdkman
$ ls
archives  bin  candidates  etc  ext  src  tmp  var
$ ls archives/
java-12.0.2-open.zip  java-13.0.1-open.zip  kotlin-1.3.61.zip  scala-2.13.1.zip
$ ls bin
sdkman-init.sh
$ find etc
etc
etc/config
$ cat etc/config 
sdkman_auto_answer=false
sdkman_auto_selfupdate=false
sdkman_insecure_ssl=false
sdkman_curl_connect_timeout=7
sdkman_curl_max_time=10
sdkman_beta_channel=false
sdkman_debug_mode=false
sdkman_colour_enable=true
$ ls src
sdkman-availability.sh  sdkman-current.sh      sdkman-flush.sh    sdkman-list.sh     sdkman-path-helpers.sh  sdkman-update.sh   sdkman-utils.sh
sdkman-broadcast.sh     sdkman-default.sh      sdkman-help.sh     sdkman-main.sh     sdkman-selfupdate.sh    sdkman-upgrade.sh  sdkman-version.sh
sdkman-cache.sh         sdkman-env-helpers.sh  sdkman-install.sh  sdkman-offline.sh  sdkman-uninstall.sh     sdkman-use.sh
$ find var
var
var/delay_upgrade
var/broadcast_id
var/version
var/broadcast
var/candidates
$ cat var/version 
5.7.4+362
$ cat var/candidates 
ant,asciidoctorj,bpipe,ceylon,crash,cuba,cxf,gaiden,glide,gradle,grails,groovy,groovyserv,infrastructor,java,jbake,kotlin,kscript,lazybones,leiningen,maven,micronaut,sbt,scala,spark,springboot,sshoogr,vertx,visualvm

管理対象のソフトウェアは.sdkman/candidatesの下にありました。

$ ls candidates/
java  kotlin  scala
$ ls -l candidates/java
合計 8
drwxr-xr-x 8 myuser myuser 4096 12月 13 15:25 12.0.2-open
drwxr-xr-x 8 myuser myuser 4096 12月 13 15:12 13.0.1-open
lrwxrwxrwx 1 myuser myuser   48 12月 13 15:29 current -> /home/myuser/.sdkman/candidates/java/13.0.1-open
$ ls -l candidates/kotlin
合計 4
drwxr-xr-x 5 myuser myuser 4096 11月 26 09:15 1.3.61
lrwxrwxrwx 1 myuser myuser   45 12月 13 15:22 current -> /home/myuser/.sdkman/candidates/kotlin/1.3.61
$ ls -l candidates/scala
合計 4
drwxrwxr-x 6 myuser myuser 4096  9月 18 18:23 2.13.1
lrwxrwxrwx 1 myuser myuser   44 12月 13 15:23 current -> /home/myuser/.sdkman/candidates/scala/2.13.1

ソフトウェアの種類ごとにディレクトリを分けてその下に複数のバージョンを展開し、シンボリックリンクでcurrentを示す、という割とシンプルな構成でした。

おわりに

言語処理系以外でも、ant、Maven、sbt等の周辺ツールもSDKMANで管理できます。仕組みもシンプルで使い勝手良さそうです。開発環境で活用していきたいと思います。