Spray Marshalling Custom Objects - marshalling

I'm trying to marshal some custom objects to JSON in one of my responses and can't seem to get the logic right. I suspect this is a straight forward issue, but I just can't seem to find the solution anywhere.
I have the following which is fine...
case class MyKeyResponse(success:Boolean, key:String,
key_id:Int, key_description:String)
object MyKeyJsonResponseProtocols extends DefaultJsonProtocol {
implicit val responseFormat = jsonFormat4(AppKeyResponse)
}
I then declare the following which is meant to wrap a collection of the above MyKey objects which are returned from a DB query...
case class MyKeysResponse(success:Boolean, appKeys:Seq[MyKey])
object MyKeysJsonResponseProtocols extends DefaultJsonProtocol {
implicit val responseFormat = jsonFormat2(AppKeysResponse)
}
However I get the following errors...
not enough arguments for method jsonFormat2:
(implicit evidence$4: … MyKeysJsonResponseProtocols.JF[Boolean],
implicit evidence$5: …MyKeysJsonResponseProtocols.JF[Seq[…
MyKeys.AppKey]], implicit evidence$6: ClassManifest[…
MyKeysResponse])spray.json.RootJsonFormat[…MyKeysResponse]. Unspecified
value parameters evidence$5, evidence$6. MyKeysResponse.scala
and marshalling errors.
Any help would be appreciated!
Thanks

My issue was actually fairly straight forward and a lesson learned!
Each of my marshallers were using the same same implicit variable name...
object MyJsonResponseProtocol1 extends DefaultJsonProtocol {
implicit val responseFormat = jsonFormat2(...)
}
object MyJsonResponseProtocol2 extends DefaultJsonProtocol {
implicit val responseFormat = jsonFormat2(...)
}
and so on... They were obviously conflicting when I imported them. So I just renamed them.

Related

How can I circumvent Kotlin's generics type variance constraints

I am relatively new Kotlin and Generics kind of give me a headache. I have the following architecture made out of:
A few data classes
A generic interface to process data
Implementations of that processing interface for each data type
A generic processing job class containing the data to be processed and it's appropriate processor
A global (singleton) processor which implements the processing interface, takes processing jobs and just delegates the processing to the job processor. It doesn't care about the data itself at all.
The simplified code looks like this
class DataOne
class DataTwo
interface DataProcessor<in T> {
fun process(o: T)
}
class DataOneProcessor: DataProcessor<DataOne> {
override fun process(o: DataOne) = println("Processing DataOne")
}
class DataTwoProcessor: DataProcessor<DataTwo> {
override fun process(o: DataTwo) = println("Processing DataTwo")
}
class ProcessingJob<T>(val data: T, val processor: DataProcessor<T>)
object GlobalProcessor: DataProcessor<ProcessingJob<Any>> {
override fun process(job: ProcessingJob<Any>) = job.processor.process(job.data)
}
fun main() {
GlobalProcessor.process(ProcessingJob(DataOne(), DataOneProcessor()))
}
In the main function I get a compiler error
Type mismatch.
Required: ProcessingJob<Any>
Found: ProcessingJob<DataOne>
I understand why this happens: A DataProcessor of DataOne, viewed as a DataProcessor of Any could be asked to process DataTwos and for type safety this is not allowed.
Can you give me any suggestions on how/what to change to make it compile and achieve the required result? Thanks for your time!
There are two problems here.
First, Any isn't actually the top-level type. Any implies not null, but T is unconstrained, which means it can be a nullable type. In this case you can use *, or you could also specify the type as Any?.
Change the signature of the GlobalProcessor to this:
object GlobalProcessor: DataProcessor<ProcessingJob<*>> {
override fun process(job: ProcessingJob<*>): ...
The second problem is that the implementation of process can't take advantage of the generic information from the job in order to know that the job.processor and the job.data are compatible. It just sees two objects of unknown type. To let it know they share a compatible type, you need to capture that type as a type variable. We can't add a generic type parameter to the existing method, because it has to match the signature of the interface method, but we can add a new private method that introduces the generic parameter.
Here's the GlobalProcessor with both the required changes.
object GlobalProcessor: DataProcessor<ProcessingJob<*>> {
override fun process(job: ProcessingJob<*>) = processGeneric(job)
private fun <T> processGeneric(job: ProcessingJob<T>) = job.processor.process(job.data)
}

Subtypes not being recognized in Subclasses

I have the following code setup;
abstract class GenericQuestionEditor() {
protected abstract var data: GenericQuestionData
}
but then when I create EditorSimple() it throws an error when I try to set data to DataSimple(), why?
class EditorSimple(): GenericQuestionEditor() {
override var data = DataSimple()
}
my GenericQeustionData and DataSimple() are setup like this;
abstract class GenericQuestionData {}
class DataSimple: GenericQuestionData() {}
it doesn't complain if I create this function in GenericQuestionEditor()
fun test() {
data = DataSimple()
}
Why do I get an error on data in EditorSimple()? It should recognize it as a subtype and it should be allowed as I understand.
I feel like the answer is found in the kotlin documentation but i'm not sure how to configure it in this case since they are not passed values or part of a collection.
You need to specify the type explicitly:
class EditorSimple(): GenericQuestionEditor() {
override var data: GenericQuestionData = DataSimple()
}
Without the type annotation, the type of data would be inferred to be DataSimple, which doesn't match the type of its super class' data. Even though the types are related, you can't override writable a property with a subtype. Imagine if I did:
class SomeOtherData: GenericQuestionData()
val editor: GenericQuestionEditor = EditorSimple()
editor.data = SomeOtherData() // data is of type GenericQuestionData, so I should be able to do this
But, editor actually has a EditorSimple, which can only store DataSimple objects in data!

Serialize `Nothing?` property via Jackson

I want to serialize FAIL object via Jackson:
interface OptionalResult<out ResultType : Any> {
val data: ResultType?
object FAIL : OptionalResult<Nothing> {
override val data: Nothing? = null
}
}
What I get is {} but I expect to receive {"data": null}.
How can I fix my object?
By the way, the following object is serialized properly:
object FAIL : OptionalResult<Int> {
override val data: Int? = null
}
Technical problem is that Jackson determines that indicator that would normally indicate existence of a property (public or annotated setter) will be filtered out, as getter is seen as public void getData() that returns nothing.
Filtering is done at low level processing, along with removal of static methods, methods that are neither annotated nor follow naming convention and so on.
It might be possible to improve upon this detection since there is actual difference between void and Void (similar to primitive/Wrapper difference).
But this is the first time such usage has been reported.
One thing that you could try which may (or might not) help: add #JsonProperty for val data. It could help if filtering is only done for non-annotated accessors.

What is the benefit of having a private constructor and a use a method inside companion object to instantiate a class?

I've bumped into this code and I'm not sure why would anyone do this. Basically the author decided for making the class constructor private so that it cannot be instantiated outside the file, and added a public method to a companion object in the class that creates a new instance of this class. What is the benefit of this approach?
This is what I found:
class Foo private constructor(private val arg1: Any) {
//more code here..
companion object {
fun newFoo(arg1: Any) = Foo(arg1 = arg1)
}
}
Why is it better than this?
class Foo(private val arg1: Any) {
//more code here..
}
There are several benefits to providing a factory method instead of a public constructor, including:
It can do lots of processing before calling the construstor. (This can be important if the superclass constructor takes parameters that need to be calculated.)
It can return cached values instead of new instances where appropriate.
It can return a subclass. (This allows you to make the top class an interface, as noted in another answer.) The exact class can differ between calls, and can even be an anonymous type.
It can have a name (as noted in another answer). This is especially important if you need multiple methods taking the same parameters. (E.g. a Point object which could be constructed from rectangular or polar co-ordinates.) However, a factory method doesn't need a specific name; if you implement the invoke() method in the companion object, you can call it in exactly the same way as a constructor.
It makes it easier to change the implementation of the class without affecting its public interface.
It also has an important drawback:
It can't be used by subclass constructors.
Factory methods seem to be less used in Kotlin than Java, perhaps due to Kotlin's simpler syntax for primary constructors and properties. But they're still worth considering — especially as Kotlin companion objects can inherit.
For much deeper info, see this article, which looks at the recommendation in Effective Java and how it applies to Kotlin.
If you want to change Foo into an interface in the future the code based on the method will keep working, since you can return a concrete class which still implements Foo, unlike the constructor which no longer exists.
An example specific to android is, that Fragments should be constructed with an empty constructed, and any data you'd like to pass through to them should be put in a bundle.
We can create a static/companion function, which takes in the arguments we need for that fragment, and this method would construct the fragment using the empty constructor and pass in the data using a bundle.
There are many useful cases, for example what Kiskae described. Another good one would be to be able to "give your constructors names":
class Foo<S: Any, T: Any> private constructor(private val a: S, private val b: T) {
//more code here...
companion object {
fun <S: Any> createForPurposeX(a: S) = Foo(a = a, b = "Default value")
fun createForPurposeY() = Foo(a = 1, b = 2)
}
}
Call site:
Foo.createForPurposeX("Hey")
Foo.createForPurposeY()
Note: You should use generic types instead of Any.

Validation Data Class Parameters Kotlin

If I am modeling my value objects using Kotlin data classes what is the best way to handle validation. Seems like the init block is the only logical place since it executes after the primary constructor.
data class EmailAddress(val address: String) {
init {
if (address.isEmpty() || !address.matches(Regex("^[a-zA-Z0-9]+#[a-zA-Z0-9]+(.[a-zA-Z]{2,})$"))) {
throw IllegalArgumentException("${address} is not a valid email address")
}
}
}
Using JSR-303 Example
The downside to this is it requires load time weaving
#Configurable
data class EmailAddress(#Email val address: String) {
#Autowired
lateinit var validator: Validator
init {
validator.validate(this)
}
}
It seems unreasonable to me to have object creation validation anywhere else but in the class constructor. This is the place responsible for the creation, so that is the place where the rules which define what is and isn't a valid instance should be. From a maintenance perspective it also makes sense to me as it would be the place where I would look for such rules if I had to guess.
I did make a comment, but I thought I would share my approach to validation instead.
First, I think it is a mistake to perform validation on instantiation. This will make the boundary between deserialization and handing over to your controllers messy. Also, to me, if you are sticking to a clean architecture, validation is part of your core logic, and you should ensure with tests on your core logic that it is happening.
So, to let me tackle this how I wish, I first define my own core validation api. Pure kotlin. No frameworks or libraries. Keep it clean.
interface Validatable {
/**
* #throws [ValidationErrorException]
*/
fun validate()
}
class ValidationErrorException(
val errors: List<ValidationError>
) : Exception() {
/***
* Convenience method for getting a data object from the Exception.
*/
fun toValidationErrors() = ValidationErrors(errors)
}
/**
* Data object to represent the data of an Exception. Convenient for serialization.
*/
data class ValidationErrors(
val errors : List<ValidationError>
)
data class ValidationError(
val path: String,
val message: String
)
Then I have a framework specific implementations. For example a javax.validation.Validation implementation:
open class ValidatableJavax : Validatable {
companion object {
val validator = Validation.buildDefaultValidatorFactory().validator!!
}
override fun validate() {
val violations = validator.validate(this)
val errors = violations.map {
ValidationError(it.propertyPath.toString(), it.message)
}.toMutableList()
if (errors.isNotEmpty()) {
throw ValidationErrorException(errors = errors)
}
}
}
The only problem with this, is that the javax annotations don't play so well with kotlin data objects - but here is an example of a class with validation:
import javax.validation.constraints.Positive
class MyObject(
myNumber: BigDecimal
) : ValidatableJavax() {
#get:Positive(message = "Must be positive")
val myNumber: BigDecimal = myNumber
}
Actually, it looks like that validation is not a responsibility of data classes. data tells for itself — it's used for data storage.
So if you would like to validate data class, it will make perfect sense to set #get: validation on arguments of the constructor and validate outside of data class in class, responsible for construction.
Your second option is not to use data class, just use simple class and implement whole logic in the constructor passing validator there
Also, if you use Spring Framework — you can make this class Bean with prototype scope, but chances are it will be absolutely uncomfortable to work with such kind of spaghetti-code :)
I disagree with your following statement :
Seems like the init block is the only logical place since it executes after the primary constructor.
Validation should not be done at construction time, because sometimes, you need to have intermediate steps before getting a valid object, and it does not work well with Spring MVC for example.
Maybe use a specific interface (like suggested in previous answer) with a method dedicated to executing validation.
For the validation framework, I personnaly use valiktor, as I found it a lot less cumbersome that JSR-303