Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
runaloop opened this issue Jan 18, 2020 · 4 comments
Open

Comments

@runaloop
Copy link

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?

@zapov
Copy link
Member

zapov commented Jan 18, 2020

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 :) ]

@runaloop
Copy link
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?

@zapov
Copy link
Member

zapov commented Feb 17, 2020

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.

@zapov
Copy link
Member

zapov commented Oct 8, 2020

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
Projects
None yet
Development

No branches or pull requests

2 participants