ngs-doo / dsl-json

High performance JVM JSON library
https://dsl-platform.com
BSD 3-Clause "New" or "Revised" License
1k stars 105 forks source link

error: Failed saving compiled json serialization files #50

Closed dvhp closed 6 years ago

dvhp commented 6 years ago

I'm getting this error when trying to build an Android (Kotlin) project with dsl-json.

error: Failed saving compiled json serialization files

This is my build.gradle:

dependencies {
  ...
  kapt "com.dslplatform:dsl-json-processor:1.7.3"
  implementation "com.dslplatform:dsl-json-java8:1.7.3"
}

These are the entities I'm trying to deserialize:

@CompiledJson
data class CityJson(
        var id:         Long        = 0,
        var name:       String      = "",
        var country:    String      = "",
        var coord:      CoordJson   = CoordJson(0.0, 0.0)
)

@CompiledJson
data class CoordJson(
        var lat: Double = 0.0,
        var lon: Double = 0.0
)

and this is how I'm trying to do use dsl-json:

val input = ctx.resources.openRawResource(R.raw.city_list)
val dslJson = DslJson<Any>(Settings.withRuntime<Any>().includeServiceLoader())
val reader =  dslJson.newReader().process(input)
var city = reader.next(CityJson::class.java)

while (city != null) {
  ...
  city = reader.next(CityJson::class.java)
}

Link to debug log (with gradle --stacktrace option and dsl-json.loglevel=DEBUG): https://gist.github.com/dvhp/d1be8a8bebad9f0539b4a50b16374cd8

zapov commented 6 years ago

I'll try to replicate your setup. In the meantime I would try:

1) using clean before the build 2) using the java8 annotation processor instead

So try replacing

kapt "com.dslplatform:dsl-json-processor:1.7.3"

with

kapt "com.dslplatform:dsl-json-java8:1.7.3"
dvhp commented 6 years ago

I always do a Rebuild or (Clean -> Rebuild). I've tried using the java8 annotation processor, but doing so gets me on a whole different path of errors:

Annotation processors must be explicitly declared now.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:javaPreCompileDebug'.
> Annotation processors must be explicitly declared now.  The following dependencies on the compile classpath are found to contain annotation processor.  Please add them to the annotationProcessor configuration.
    - dsl-json-java8-1.7.3.jar (com.dslplatform:dsl-json-java8:1.7.3)
  Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior.  Note that this option is deprecated and will be removed in the future.
  See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.

so then I can either change kapt "com.dslplatform:dsl-json-java8:1.7.3" to annotationProcessor "com.dslplatform:dsl-json-java8:1.7.3", or do something like:

android {
    ...
    defaultConfig {
    ...
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false //(or true)
            }
        }
    }
}

but then I get this desugaring error: https://gist.github.com/dvhp/b9daf7000e1db075cde3d01678ab7d88

so I add the compileOptions:

android {
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

And finally i get this: Exception in thread "main" java.lang.NoClassDefFoundError: javax/json/bind/Jsonb https://gist.github.com/dvhp/468aecdb625a1078fbf18de01f0ff88f

If you want I can provide more detailed gradle logs and/or a sample project. I've also tried 2 different versions of kotlin and kotlin-gradle-plugin - 1.2.31 and 1.2.40

zapov commented 6 years ago

Try adding explicit jsonb dependency

javax.json.bind:javax.json.bind-api:1.0

Currently it's provided, but I guess I should make it compile time ;( https://github.com/ngs-doo/dsl-json/blob/master/java8/pom.xml#L22

zapov commented 6 years ago

As for that annotation procesor error in never versions gradle now expects

annotationProcessor 'com.dslplatform:dsl-json-java8:1.7.3'

instead of apt

dvhp commented 6 years ago

after adding the jsonb dependency, I'm getting:

:app:transformClassesWithStackFramesFixerForDebug
Exception in thread "main" java.lang.IllegalArgumentException: Type without superclass: module-info
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:191)

Full trace here: https://gist.github.com/dvhp/a2f985cfbfe1f57b6ba6eefbb2ee2a5f

build.gradle looks like this:

android {
    ...
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}
dependencies {
    ...
    implementation "javax.json.bind:javax.json.bind-api:1.0"
    annotationProcessor "com.dslplatform:dsl-json-java8:1.7.3"
    implementation "com.dslplatform:dsl-json-java8:1.7.3"
}

... On a side note: Any chance of seeing a "converter" (like gson or moshi) for retrofit using dsl-json? Is it even possible to do it? I would happily work on it with some indication in the right direction.

dvhp commented 6 years ago

I managed to get the build working. I removed the jsonb dependency implementation "javax.json.bind:javax.json.bind-api:1.0" and added android.enableD8.desugaring = true in gradle.properties. Everything else is the same as in the .gradle file from the previous post.

So I guess this issue can be closed.

However I do have another question if someone is willing to help me out: I'm basically trying to deserialize a big .json file (this one) and insert the data into an sqlite table. And I'm wondering what combination of annotated classes and dsl-json reader would give the best performance. Since this file is formatted like an array of objects [{}, {}], I cannot use the class structure mentioned in the first post and I don't think it would be ok to deserialize into something like a List<...>. I have not managed to find an example dealing with large json list streaming.

zapov commented 6 years ago

I'll look into creating Android example for Kotlin anyway, so let's leave this open until I do.

As for the second thing... I think it's fine to deserialize such input into some list... there is even specialized API for that: https://github.com/ngs-doo/dsl-json/blob/master/library/src/main/java/com/dslplatform/json/DslJson.java#L1692 If you wish to avoid having all instances in memory you can use the iterate over API: https://github.com/ngs-doo/dsl-json/blob/master/library/src/main/java/com/dslplatform/json/DslJson.java#L2042

zapov commented 6 years ago

I've added Android Kotlin example: https://github.com/ngs-doo/dsl-json/tree/master/examples/AndroidKotlin