Skip to content

@JsonAttribute(ignore = true) is ignored for fields in kotlin classes  #158

Open

Description

@runaloop

Faced with such a problem, I have 2 classes, one written in java, and one in a kotlin:

@CompiledJson
class KotlinClassWithIgnore(val name: String = "Kotlin", @JsonAttribute(ignore = true) val ignored: String = "IGNORED")

@CompiledJson
static class JavaClassWithIgnore {
    public String name = "JAVA";
    @JsonAttribute(ignore = true)
    public String ignored = "IGNORED";
}

If I serialize kotlin class, to a string, I always see "ignored" field in it.
To serialize I use this code:

DSL.JSON().serialize(KotlinClassWithIgnore(), PrettifyOutputStream(os))
println(os)
os.reset()
DSL.JSON().serialize(JavaClassWithIgnore(), PrettifyOutputStream(os))
println(os)

And I got this result:

I/System.out: {
I/System.out:   "name": "Kotlin",
I/System.out:   "ignored": "IGNORED"
I/System.out: }
I/System.out: {
I/System.out:   "name": "JAVA"
I/System.out: }

The question is how to make @JsonAttribute(ignore = true) field in kotlin class to be ignored by DSL-JSON?

Activity

  1. zapov commented on Jan 18, 2020

    @zapov
    Member

    It would be great if there was a Kotlin test project where such examples could be tested and verified but I have not yet found to setup such a project via Maven.
    I guess I could set it up via gradle, but I'd much prefer to have it in Maven so all tests can run at once.

    Anyway, can you write relevant Java class like this:

    and make a PR which shows the issue (there is some generated code which shows the exact Java output for the Kotlin model, thats how I extracted those examples).
    I can take a look then on how to resolve it [although it's possible you'll figure out how to resolve it when you write such a test :) ]

  2. runaloop commented on Jan 20, 2020

    @runaloop
    Author

    Thank you for your answer. I tried to import maven project - tests-java8, and created a kotlin test in it, to run it, I have to add these lines to pom.xml:

    --- dependencies: 
    <dependency>
    			<groupId>org.jetbrains.kotlin</groupId>
    			<artifactId>kotlin-stdlib</artifactId>
    			<version>${kotlin.version}</version>
    		</dependency>
    ---plugins:
    			<plugin>
    				<groupId>org.jetbrains.kotlin</groupId>
    				<artifactId>kotlin-maven-plugin</artifactId>
    				<version>${kotlin.version}</version>
    
    				<executions>
    					<execution>
    						<id>test-kapt</id>
    						<goals>
    							<goal>test-kapt</goal>
    						</goals>
    						<configuration>
    							<sourceDirs>
    								<sourceDir>src/test/kotlin</sourceDir>
    								<sourceDir>src/test/java</sourceDir>
    							</sourceDirs>
    							<annotationProcessorPaths>
    								<annotationProcessorPath>
    									<groupId>com.dslplatform</groupId>
    									<artifactId>dsl-json-java8</artifactId>
    									<version>1.9.5</version>
    								</annotationProcessorPath>
    							</annotationProcessorPaths>
    						</configuration>
    					</execution>
    
    
    					<execution>
    						<id>compile</id>
    						<goals> <goal>compile</goal> </goals>
    						<configuration>
    							<sourceDirs>
    								<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
    								<sourceDir>${project.basedir}/src/main/java</sourceDir>
    							</sourceDirs>
    						</configuration>
    					</execution>
    					<execution>
    						<id>test-compile</id>
    						<goals> <goal>test-compile</goal> </goals>
    						<configuration>
    							<sourceDirs>
    								<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
    								<sourceDir>${project.basedir}/src/test/java</sourceDir>
    							</sourceDirs>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    

    Kotlin class looks like:

    package com.dslplatform.json
    
    @CompiledJson
    data class AKotlinModel(val someString: String, @JsonAttribute(ignore = true)val paramWithIgnoreFlag: Boolean) {
    
        @JsonAttribute(ignore = true)
        lateinit var stringFieldWithIgnoreFlag: String
        @JsonAttribute(mandatory = true)
        lateinit var stringWhichShouldBeInPlace: String
    }

    And Kotlin test looks like:

    package com.dslplatform.json
    
    import com.dslplatform.json.runtime.Settings
    import org.junit.Assert
    import org.junit.Test
    import java.io.ByteArrayOutputStream
    
    
    
    
    class KotlinClassesTest{
        val dslJson = DslJson(Settings.withRuntime<Any>().includeServiceLoader().allowArrayFormat(true))
        @Test
        fun `Field with JsonAttribute(ignore = true) flag, must not be included to result string`() {
            val model = AKotlinModel("someStr", true)
            model.stringFieldWithIgnoreFlag = "this string is ignored"
            model.stringWhichShouldBeInPlace = "this string should be in json"
            val os = ByteArrayOutputStream()
            dslJson.serialize(model, os)
            Assert.assertEquals("{\"someString\" : \"someStr\", \"stringWhichShouldBeInPlace\" : \"this string should be in json\"}", os.toString())
        }
    }

    This test is red for now with this output:

    org.junit.ComparisonFailure: 
    Expected :{"someString" : "someStr", "stringWhichShouldBeInPlace" : "this string should be in json"}
    Actual   :{"stringFieldWithIgnoreFlag":"this string is ignored","paramWithIgnoreFlag":true}
    

    And I have no idea, why my output JSON string has some of the fields and doesn't have others. Any thoughts on how to deal with it?

  3. zapov commented on Feb 17, 2020

    @zapov
    Member

    I tried setting up java8 test project like that but it didn't do annotation processing on Kotlin at all.

    So I setup a separate project which is somewhat better but still fails to compile for some probably trivial reasons (it creates output in generated-sources instead of generated-test-sources)

    If you can help out with fixing that project so it starts compiling that would be great:
    2db2de5

    As for the ignore thing, DSL-JSON still does not support defaults on arguments, although you can simulate that with empty ctors in which case defaults are preserved. The model you provided for tests is missing those defaults so it doesn't compile, but I'll look whats going on when test project starts running.

  4. zapov commented on Oct 8, 2020

    @zapov
    Member

    FWIW this test is now in, although commented out: https://github.com/ngs-doo/dsl-json/blob/master/tests-kotlin/src/main/kotlin/com/dslplatform/json/ModelWithIgnore.kt#L17

    I have some questions though:

    • to be able to pass the default in, need to figure out where Kotlin defines this default
    • not sure what is expected to do when there is no default... the other use case looks like a bad requirement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions