Parsing of YAML file with Jackson fails if value starts with special character - kotlin

I am trying to parse the following YAML-content:
template:
amplitude: 5
noise: +-0.01
This fails with this exception:
com.fasterxml.jackson.databind.JsonMappingException: empty String (through reference chain: ... ->my.package.Template["noise"])
The class Template contains a property noise of type FlexValue. I made a custom JsonDeserializer that is responsible to parse the values for properties of this type. The notation allows somewhat fancy expressions, hence the name FlexValue for the type. The value in this example, "+-0.01", is a valid input for the deserializer. However, it seems like the deserializer isn't even called. The exception seems to be thrown before that.
Here is the relevant class definition of my custom deserializer:
class FlexValueParser : JsonDeserializer<FlexValue>() {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): FlexValue {
//...
}
}
The custom deserializer is registered as follows:
#JsonDeserialize(using = FlexValueParser::class)
class FlexValue {
// ...
}
This setup seems to work fine. It does on other types as well, which are parsed differently.
If I prepend a "0" before "+-", which is also a valid input, it works:
template:
amplitude: 5
noise: 0+-0.01
Is "+-" a special cahracter in YAML that causes Jackson to fail parsing it, because it tries to do something else than I expect? I expect it to treat the input "+-0.01" as a String because it doesn't represent a valid number input.
The same problem occurs, when I use noise: ~0.01, which is also a valid input for my deserializer. The same exception is thrown on this and can be avoided by prepending a "0" before the curly "~".
Can someone give me a hint on this?

Found the source of the problem, which had nothing to do with Jackson or YAML. Closing this question therefore.

Related

Quarkus/Kotlin: An annotation argument must be a compile-time constant with a java class

In a quarkus/kotlin app, I have a rest client that is very basic:
#Path("/my/api/v1")
#RestClient
interface MyApiClient { }
Problem is, when a request fails, it returns a response that fails to be mapped. So I want to add an exception mapper, in order to log the real error:
class MyExceptionMapper : ResponseExceptionMapper<java.lang.RuntimeException?> {
override fun toThrowable(r: Response): java.lang.RuntimeException {
Logger.getLogger(MyApiClient::class.java).error(r.status)
return RuntimeException("failed")
}
}
To do so, I should annoate my client with:
#RegisterProvider(MyExceptionMapper::class.java)
Doing so, I have a kotlin error:
An annotation argument must be a compile-time constant
I googled but could find solutions only for strings. In this case, kotlin expects the java class to be a compile time constant. How to get it?
Should work with simple:
#RegisterProvider(MyExceptionMapper::class)

How to handle conflicting function names when implementing multiple interfaces?

I have an interface defined in C# that implements IEnumerable. The implementation of the interface will be done in C++/WinRT as it needs direct access to native code. When I attempt to implement this interface using C++/WinRT, the generated header/implementation contains two 'First()' functions (one from IIterable, and one from IBindableIterable) with different return types. Obviously this isn't going to compile.
Is there some way to "rename" one (or both) of the conflicting functions in the IDL file? C++/CX had a work around that allowed you to use a different function name and then 'bind' it back to the interface name.
Simplified example code below:
Interface:
public interface IUInt32Array : IEnumerable<uint> {}
IDL:
[default_interface]
runtimeclass UInt32Array : IUInt32Array
{
UInt32Array(UInt32 size);
}
IDL Generated Header:
struct UInt32Array : UInt32ArrayT<UInt32Array>
{
UInt32Array(uint32_t size);
Windows::Foundation::Collections::IIterator<uint32_t> First(); // <-- Problem
Windows::UI::Xaml::Interop::IBindableIterator First(); // <-- Problem
}
A solution for this specific problem is to use a combination of 'auto' as the declared return type for the First() function implementation, and to return a type with conversion operators for the two different return types.
Here is an example showing how this was solved in the CppWinRT source code. The linked source code is for the base_collections_vector.h header, specifically see the convertible_observable_vector::First() function (replicated below).
auto First() {
struct result {
container_type* container;
operator wfc::IIterator<T>() {
return static_cast<base_type*>(container)->First();
}
operator wfc::IIterator<Windows::Foundation::IInspectable>() {
return make<iterator>(container);
}
};
return result{ this };
}
Notice here that the function itself is defined as returning auto, which allows us to return an intermediate type. This intermediate type then implements conversion operators for converting to the type expected by the caller. This works for this particular problem as the generated CppWinRT source code immediately assigns the result of the call to a value of the expected type, thus immediately causing the invocation of the conversion operators which in turn return the final correct iterator type.
Thanks to Kenny Kerr who pointed me at both the example and a write-up explaining the above.

Why Property must be initialized when there is auto back-end field generated

I'm new to properties and moved from the java to kotlin. I'm struggling with the properties, I learned much about it but initializing the properties are confusing me, when it should be initialized or when it can work without initialization.
Let me explain it by the help of code. Below is the code which is requiring to initialize the property when the back-end field generated, before posting the code let me post the paragraph from the kotlin official website.
A backing field will be generated for a property if it uses the
default implementation of at least one of the accessors, or if a
custom accessor references it through the field identifier.
Now here is the code below.
class Employee{
var data: String // because there are default implementation of get set
// so there will be a back-end field.
}
So I have to initialize it else compilation error.
Ok I can understand it as that some one can access it so there will be no value which can produce the wrong result.
Then I move next to understand it more, so I add custom getter.
class Employee{
var data: String
get() = "default value"
}
This also generate the back-end field so compilation error to initialize it. I can understand it as that there is no initialized value so compiler complain about it.
May be compiler is not smart enough yet to check that there is value which is giving result for this property by custom getter so don't complain about initializing just return that value when required.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Then I move one step more to implement custom setter too.
class Employee{
var data: String
get() = "default value"
set(value){
field = value
}
}
Still there is the back-end field because we have accessed the field so compiler generate the back-end field.
Same error, should be initialized.
Then the final stage where it works fine as below.
class Employee{
var data: String
get() = "default value"
set(value){
}
}
Now I'm not accessing field in custom getter setter so there is not a back-end field. And it works fine.
So the final question when the property should be intialized? When there is a back-end field generated?
Yes this does not compile:
class Employee{
var data: String
get() = "default value"
}
but this does:
class Employee{
val data: String
get() = "default value"
}
so maybe the compiler by stating Property must be initialized for the wrong declaration, wants from you to admit that data is something that you can not change. I say maybe.
Now the part that does compile:
class Employee{
var data: String
get() = "default value"
set(value){
}
}
This is where you explicitly admit that whatever happens I will never set a value to data, and that's why the compiler feels fine.
Just to save you from more confusion, there's a lot of explaining about Kotlin in the Internet and you may find it very difficult to get familiarized with this relatively new language, but keep in mind that everything needs to be tested by you.
I found the below code in a web page:
class User{
var firstName : String
get() = field
set(value) {field = value}
var lastName : String
get() = field
set(value) {field = value}
}
and it is presented as compilable when it's not.
You kind of answered your own question. There's no backing field when you override both getter and setter, and don't access field.
About your "compiler not being smart enough": get() function is actually RAN at runtime, so writing a lot of compiler code just to evaluate if return value is static and should be injected as default is too niche of a use case.
If your getter depends on another field which is only initialized later, this would cause a lot of confusion as to what default value should be.
Consider this code, assuming value of provider is not defined:
var data: String
get() = provider.data
What would be a default value? Do you want a null? Empty string? Maybe entire object initialization should crash? Explicit default value declaration is needed for that purpose.
That's where idea of lateinit var came to be: if You're certain you will set value before performing any get, You can use this keyword to prevent compiler errors and setting default value.
class Employee{
var data: String
get() = "default value"
}
var means there are both a getter and a setter. Because you didn't write a setter, you get the default one, which accesses the backing field. So there is a backing field, and it needs to be initialized.
But there should be not a problem if any one access it then a default value is already there, then why compiler still complain?
Because that makes the rules simpler: all properties with backing fields must be initialized. This in turn may be because in Java fields don't have to be initialized and this is a known source of bugs. I would like to say it also avoids a possible bug, because presumably you don't actually want the setter's result never to be accessible, but initializing doesn't fix that problem.
I don't see any obvious problem with changing the rules so that a field only needs to be initialized when accessed in the getter, and maybe adding a warning when only one accessor uses field. But I may be missing something, and don't see much benefit to doing so either.

Setter is invoked before constructor

I am trying to create instances of class HelloWorld, however it does not work. I found that problem is that setter methods called instead of constructor which should initialize variable name, while variable welcome is optional.
I specified getters and setters for both variables. Browser's console is throwing an error about maximum call stack size. If I comment my getters&setters it stops throwing errors.
Could anyone explain me that strange behaviour?
Also there is another problem with mapping. I'm trying to "return" an array if li elements like in React by using .map(). It gives me the result with commas. How can I get rid of them while printing?
This is a link to my code https://codepen.io/CrUsH20/pen/yzMjzL?editors=1010
Updated #1
I fixed the problem with getters&setters by giving a _ sign for private values.
Now I have a problem with
function print() {
if (invitations) {
document.getElementById('result').innerHTML = invitations.map((e)=> {
return `<li>${e.welcome + e.name}</li>`;
});
}
}
Compiler complains that Type 'string[]' is not assignable to type 'string'. in document.getElementById('result').innerHTML while type was not assigned since it is a html element
Update #2
There are solutions:
1# About conflict with constructor and set&get - I changed object's values by adding to their names _. It solved the conflicts.
2# About commas - I added after map .join('') which solved my problem.
The following code (subset of yours) is a compile error:
class HelloWorld {
constructor(public name: string) {
}
set name(e: string) {
this.name = e;
}
get name(): string {
return this.name;
}
}
Garbage in => Garbage out
Fix
Dont use getter / setters and properties with the same name.

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