Closed28

サーバーサイド Kotlin から Box API Java SDK を使う

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

このスクラップについて

このスクラップではサーバーサイド Kotlin から Box API Java SDK を使う方法について調べる。

Kotlin は Java 互換なので Java 製 SDK なら何でも使えると考えているが実際にやってみるのは初めてなので自分の手を動かして確信を得たい。

一応ちょっと前にサーバーサイド Kotlin で Spring Boot を動かしたので Kotlin で Java 的なものを動かした経験はあるが SDK 的なものは初めてだ。

IDE には無難に IntelliJ IDEA を使おう。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

プロジェクト作成

IntelliJ IDEA を起動する。

New Project ボタンを押す。

Language として Kotlin を選択してから Create ボタンを押す。

Java と違って Kotlin でプロジェクトを作成すると色々なダウンロードに時間がかかるようだ。

2 回目以降はキャッシュとかで短時間で終わるようになるのかな?

ビルドが終わると main() 関数の隣に ▶︎ ボタンが出現して実行できるようになる。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

共有インデックス

スクリーンショットを撮るのを忘れたが共有インデックス設定に関する提案を IntelliJ から通知された。

https://qiita.com/tasshi/items/1389be4731640b59ff9d

初回のセットアップ時間が短くなるらしい。

とりあえず Always Download ボタンを押して有効化しておいた。

Command + , を押してから Preferences → Tools → Shared Indexes でも設定できる。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

実行できない

とりあえず main() 関数を実行したら下記のエラーメッセージが表示された。

エラーメッセージ
Unknown host 'repo.maven.apache.org: unknown error'. You may need to adjust the proxy settings in Gradle.
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Java バージョンを変えてみたけどダメだった

Java SDK を 17 に変更してみたけど結果は変わらなかった。

Java バージョンは Command + ; またはメニュー > File > Project Structure で設定できる。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

プロジェクトを作り直したけどダメだった

Java 17 を指定してプロジェクトを作り直したけど結果は変わらなかった。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

そもそも Java は動く?

問題なく動いた。

build.gradle はこんな感じ。

build.gradle
plugins {
    id 'java'
}

group = 'org.example'
version = '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation platform('org.junit:junit-bom:5.9.1')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

test {
    useJUnitPlatform()
}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Spring Boot の build.gradle.kts

Kotlin で Spring Boot を使った時は問題なく動いた。

その時の build.gradle.kts を見直してみる。

build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
	id("org.springframework.boot") version "3.0.5"
	id("io.spring.dependency-management") version "1.1.0"
	kotlin("jvm") version "1.7.22"
	kotlin("plugin.spring") version "1.7.22"
	kotlin("plugin.jpa") version "1.7.22"
	kotlin("plugin.allopen") version "1.7.22"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
	mavenCentral()
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-data-jpa")
	implementation("org.springframework.boot:spring-boot-starter-mustache")
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	developmentOnly("org.springframework.boot:spring-boot-devtools")
	runtimeOnly("com.h2database:h2")
//	testImplementation("org.springframework.boot:spring-boot-starter-test")

	testImplementation("org.springframework.boot:spring-boot-starter-test") {
		exclude(module = "mockito-core")
	}
	testImplementation("org.junit.jupiter:junit-jupiter-api")
	testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
	testImplementation("com.ninja-squad:springmockk:4.0.2")
}

tasks.withType<KotlinCompile> {
	kotlinOptions {
		freeCompilerArgs = listOf("-Xjsr305=strict")
		jvmTarget = "17"
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

allOpen {
	annotation("jakarta.persistence.Entity")
	annotation("jakarta.persistence.Embeddable")
	annotation("jakarta.persistence.MappedSuperclass")
}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Kotlin プロジェクトの build.gradle

build.gradle
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.8.0'
    id 'application'
}

group = 'org.example'
version = '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.jetbrains.kotlin:kotlin-test'
}

test {
    useJUnitPlatform()
}

kotlin {
    jvmToolchain(11)
}

application {
    mainClassName = 'MainKt'
}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

IntelliJ IDEA での Kotlin の使い方を調べよう

まさか最初からつまづくとは。

初心に帰ってまずは Intelli J IDEA で Kotlin プロジェクトを正しく作成する方法を調べよう。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Kotlin 公式ドキュメントのbuild.gradle.kts

build.gradle.kts
// For `KotlinCompile` task below
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.8.20" // Kotlin version to use
    application // Application plugin. Also see 1️⃣ below the code
}

group = "org.example" // A company name, for example, `org.jetbrains`
version = "1.0-SNAPSHOT" // Version to assign to the built artifact

repositories { // Sources of dependencies. See 2️⃣
    mavenCentral() // Maven Central Repository. See 3️⃣
}

dependencies { // All the libraries you want to use. See 4️⃣
    // Copy dependencies' names after you find them in a repository
    testImplementation(kotlin("test")) // The Kotlin test library
}

tasks.test { // See 5️⃣
    useJUnitPlatform() // JUnitPlatform for tests. See 6️⃣
}

kotlin { // Extension for easy setup
    jvmToolchain(8) // Target version of generated JVM bytecode. See 7️⃣
}

application {
    mainClass.set("MainKt") // The main class of the application
}

IntelliJ IDEA が生成する build.gradle.kts とほぼ同じだが下記が異なる。

build.gradle.kts(抜粋)
kotlin {
    jvmToolchain(11)
}

もしかして 11 → 8 に変更したら実行できるようになる?

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

実行できた

jvmTollchain を 11 → 8 に変更したら実行できた。

build.gradle.kts
plugins {
    kotlin("jvm") version "1.8.0"
    application
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}

kotlin {
    jvmToolchain(8)
}

application {
    mainClass.set("MainKt")
}
実行結果
Hello World!
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

気になる警告が出ている

コンソール出力に何やら警告が表示されている。

objc[25614]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/bin/java (0x107f8d4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1081554e0). One of the two will be used. Which one is undefined.

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

依存関係の追加

build.gradle.kts
dependencies {
    implementation("com.box:box-java-sdk:4.0.1")
}

追加したら Gradle ツールウィンドウを開いて左上の更新 🔃 ボタンを押す。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

コーディング

src/main/kotlin/Main.kt
import com.box.sdk.BoxAPIConnection
import com.box.sdk.BoxFolder

fun main(args: Array<String>) {
    val accessToken = System.getenv("BOX_ACCESS_TOKEN")
    val api = BoxAPIConnection(accessToken)
    val rootFolder = BoxFolder.getRootFolder(api);

    for (itemInfo in rootFolder) {
        println("[%s] %s\n".format(itemInfo.id, itemInfo.name))
    }
}

等価な Java コードは下記の通り。

src/main/java/org/example/Main.java
package org.example;

import com.box.sdk.BoxAPIConnection;
import com.box.sdk.BoxFolder;
import com.box.sdk.BoxItem;

public class Main {

    public static void main(String[] args) {
        String accessToken = System.getenv("BOX_ACCESS_TOKEN");
        BoxAPIConnection api = new BoxAPIConnection(accessToken);
        BoxFolder rootFolder = BoxFolder.getRootFolder(api);

        for (BoxItem.Info itemInfo : rootFolder) {
            System.out.format("[%s] %s\n", itemInfo.getID(), itemInfo.getName());
        }
    }
}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

動作確認

Ctrl + R か ▶︎ ボタンを押して main() 関数を実行する。

実行結果(例)
[11111111] New folder created by Java SDK
[22222222] hello-box.txt
[33333333] New file created by Java SDK

しっかり取得できている様子だ。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

これで終わり?

Kotlin で Box API Java SDK を使うこと自体は一瞬で終わってしまった。

むしろ IntelliJ IDEA で Kotlin プロジェクトを作成する方が大変だった。

何か試してみたいことを探してみて無ければクローズしよう。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Kotlin はいいぞ

当り前かもしれないが Java よりも Kotlin の方がはるかに書きやすい。

val キーワードを使えるので Java のように変数の型をいちいち書く必要がない、これだけでも全然違う。

これ以外にも Kotlin には色々と便利な言語機能が備わっていると思うので、Kotlin を学べば学ぶほど楽にプログラミングができそう。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

まとめ

  • IntelliJ IDEA 2023.1 (Community Edition) で Kotlin プロジェクトを作成するとそのままの状態では main() 関数を実行できない。
  • 実行できるようにするためには build.gradle.kts の jvmToolchain を 11 → 8 に変更する必要がある。
  • Class JavaLaunchHelper is implemented in both の警告は無視しても大丈夫そう。
  • Kotlin から Box API Java SDK を使うために特別なことをする必要はない。
このスクラップは2023/04/28にクローズされました