Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moshi Retrofit2 Kotlin Class Not Found Exception

I'm trying to learn how to implement Retrofit2 and Moshi inside the Kotlin programming language. However, I seem to be having trouble trying to compile my code.

I define the following data classes/models which map to the json response I receive from the api I am hitting:

@JsonClass(generateAdapter = true)
data class Catalogs(
        val languages: List<LanguageCatalog>
)

@JsonClass(generateAdapter = true)
data class LanguageCatalog(
    val direction: String,
    val identifier: String,
    val title: String,
    val resources: List<ResourceCatalog>
)

@JsonClass(generateAdapter = true)
data class Project(
        val identifier: String,
        val sort: Int,
        val title: String,
        val versification: String?
)

@JsonClass(generateAdapter = true)
data class ResourceCatalog(
        val identifier: String,
        val modified: String,
        val projects: List<Project>,
        val title: String,
        val version: String
)

Then I have an interface which defines the behavior for the API:

interface Door43Service
{
    @GET("v3/catalog.json")
    fun getFormat() : Observable<Catalogs>

    companion object
    {
        fun create(): Door43Service
        {
            val retrofit = Retrofit.Builder()
                    .addCallAdapterFactory(
                            RxJava2CallAdapterFactory.create()
                    )
                    .addConverterFactory(
                            MoshiConverterFactory.create()
                    )
                    .baseUrl("https://api.door32.org/")
                    .build()
            return retrofit.create(Door43Service::class.java)
        }
    }
}

Lastly, I implemented everything inside a main function to get the json data from the api:

val door43Service by lazy {
    Door43Service.create()
}

var disposable: Disposable? = null

fun main(args: Array<String>)
{
    door43Service.getFormat()
           .subscribe(
                   { result -> println(result.languages)},
                   { error -> println(error.message)}
           )
}

The data that gets returned from the api is pretty long, but an example of it can be found at http://api-info.readthedocs.io/en/latest/door43.html

My issue is I am getting the following error in my stack:

Exception in thread "main" java.lang.IllegalArgumentException: Unable to create converter for class model.Catalogs
    for method Door43Service.getFormat
    at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:755)
    at retrofit2.ServiceMethod$Builder.createResponseConverter(ServiceMethod.java:741)
    at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:172)
    at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
    at retrofit2.Retrofit$1.invoke(Retrofit.java:147)
    at com.sun.proxy.$Proxy0.getFormat(Unknown Source)
    at MainKt.main(main.kt:11)
Caused by: java.lang.RuntimeException: Failed to find the generated JsonAdapter class for class model.Catalogs
    at com.squareup.moshi.StandardJsonAdapters.generatedAdapter(StandardJsonAdapters.java:249)
    at com.squareup.moshi.StandardJsonAdapters$1.create(StandardJsonAdapters.java:62)
    at com.squareup.moshi.Moshi.adapter(Moshi.java:130)
    at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:91)
    at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:330)
    at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:313)
    at retrofit2.ServiceMethod$Builder.createResponseConverter(ServiceMethod.java:739)
    ... 5 more
Caused by: java.lang.ClassNotFoundException: model.CatalogsJsonAdapter
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.squareup.moshi.StandardJsonAdapters.generatedAdapter(StandardJsonAdapters.java:236)

At first glance, my understanding is that the compiler thinks I haven't defined an adapter for my Catalogs class, but I think that's supposed to be covered using the @JsonClass(generateradapter = true) annotation. Is there anything I'm missing? Why can't my program generate the adapter for my Catalogs class?

like image 336
Nicholas DiPinto Avatar asked Jun 18 '18 20:06

Nicholas DiPinto


1 Answers

So I got things working. All I had to do was rebuild the project by running gradle build in the terminal (I was originally running it in IntelliJ, but that didn't seem to actually run the build). The key issue was since the build wasn't running, the line in my gradle build script that says,

kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"

wasn't running. This line basically gives the compiler to understand annotations in the code like @JsonClass. Without this line, the compiler won't understand the annotation. This was the root cause of my issue. I am keeping this post up in case anyone runs into the same issue.

like image 90
Nicholas DiPinto Avatar answered Dec 17 '22 00:12

Nicholas DiPinto