質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.07%

プレーンなKotlinで、Moshiでjsonを処理したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 776

picohead

score 7

前提・実現したいこと

プレーン(意図→SpringBootやIntellijを使わずにテキストエディタでktファイルを書いてkotlinc-jvm.batでコンパイルし、コマンドプロンプトで実行)なKotlinで、Moshiでjsonを処理したい。

発生している問題・エラーメッセージ

コマンドプロンプト上で下記を実行すると、 
kotlinc-jvm.bat -include-runtime -d json.jar json.kt
(コンパイルは通りました)

kotlinc-jvm.bat ".\json.kt" -cp "~\moshi-1.9.2.jar" -include-runtime -d ".\json.jar"
java -cp "~\moshi-1.9.2.jar;~\okio-1.14.0.jar;.\json.jar" JsonKt


以下のエラーが出ます。 
json.kt:1:12: error: unresolved reference: squareup
import com.squareup.moshi.Json;
           ^
json.kt:8:16: error: unresolved reference: Moshi
        val adapter = Moshi.Builder().build().adapter(User::class.java);
               ^

Exception in thread "main" java.lang.IllegalArgumentException: Cannot serialize Kotlin type User. Reflective serialization of Kotlin classes without using kotlin-reflect has undefined and unexpected behavior. Please use KotlinJsonAdapter from the moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact.
        at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:83)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:138)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:98)
        at com.squareup.moshi.Moshi.adapter(Moshi.java:72)
        at JsonKt.main(json.kt:11)

該当のソースコード

//json.kt
import com.squareup.moshi.*;

fun main(args:Array<String>) {

    val user = createUser();

    // クラス→JSON変換
    val m:Moshi = Moshi.Builder().build();
    val ja:JsonAdapter<User> = m.adapter(User::class.java);
    val decodeJson:String = ja.toJson(user);

    println("クラス→JSON:${decodeJson}");

}

data class User(val name:String,val detail:UserDetail)

data class UserDetail(val age:Int, val job:String)

fun  createUser():User{
    return User("山田太郎",UserDetail(25,"会社員"));
}

試したこと

「unresolved reference」でググると、import時の誤字やそもそもimportしてないという情報は見つかりましたが、import自体でエラーというケースは見つからず、行き詰まってしまいました。
-cpオプションでClassPathは通せたと思うのですが、型の渡し方が良くないのかエラーとなってしまいました。
"User::class.java"を"User.class","User()","User"などに変えるとコンパイルエラーでした。
そもそも"::"の意味がわからないのと、"class.java"なんてファイル作った覚えがないのが原因でしょうか。

補足情報(FW/ツールのバージョンなど)

・Windows10 pro 64bit
・kotlincは1.3.60(多分)
・moshi-1.9.2.jar

Gsonなどのライブラリではなく、Moshiを選択した理由は、nullで例外を返してくれると記載があったためです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • nakasho_dev

    2019/12/22 23:47

    moshi-1.9.2.jarにはClasspathが通っていますか?

    キャンセル

  • picohead

    2019/12/23 20:58 編集

    ご質問ありがとうございます。
    D:\Moshi\moshi-1.9.2.jarに配置し、
    set CLASSPATH=D:\Moshi\moshi-1.9.2.jar
    kotlinc-jvm.bat -include-runtime -d json.jar json.kt
    および
    set CLASSPATH=D:\Moshi
    kotlinc-jvm.bat -include-runtime -d json.jar json.kt
    をそれぞれ実行してみましたが、エラーの内容は変わりませんでした。

    キャンセル

回答 1

checkベストアンサー

0

Moshiの1.9.0以降では、Kotlinのクラスを処理するのに以下のいずれかの補助ライブラリが必須となっています。
https://github.com/square/moshi/blob/master/CHANGELOG.md#version-190

  • moshi-kotlin-codegen(kaptの設定も必要)
  • moshi-kotlin + kotlin-reflect

必要なjarを用意して、クラスパスを通してください。
kaptをCLIで設定する場合は以下の公式ドキュメントを参考にどうぞ。
https://kotlinlang.org/docs/reference/kapt.html


User::class.java という記法については、特にご質問のエラーとは関係ありません。User::classでKotlinのクラスオブジェクト(KClass)を取得し、さらに.javaプロパティでJavaのClassを取得する記法になります。
https://kotlinlang.org/docs/reference/reflection.html#class-references

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/12 15:23

    ご回答ありがとうございます。
    アドバイスを参考に変更し、エラーを直したり、jarファイルを新しいものに差し替えた結果、以下で解決しました。

    (1)
    jarファイルを新しいものに差し替え。

    (2)
    ktファイルのビルド文を下記に変更。
    val m:Moshi = Moshi.Builder().add(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory()).build();

    (3)
    コマンドプロンプトの実行文を下記に変更。
    kotlinc-jvm.bat ".\json.kt" -cp "D:\Moshi\moshi-1.9.2.jar;D:\Moshi\moshi-kotlin-1.9.2.jar;D:\Moshi\kotlin-reflect-1.3.50.jar" -include-runtime -d ".\json.jar"
    java -cp "D:\Moshi\moshi-1.9.2.jar;D:\Moshi\moshi-kotlin-1.9.2.jar;D:\Moshi\kotlin-reflect-1.3.50.jar;D:\Moshi\kotlin-stdlib-1.3.50.jar;D:\Moshi\okio-1.16.0.jar;.\json.jar" JsonKt

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る