Serialization issue with CommonsMultipartFile - jackson

my bean has folliwng snippet
#JsonIgnore
private List<MultipartFile> fileData;
#XmlTransient
public List<MultipartFile> getFileData() {
return fileData;
}
I et this error upon a file upload
org.codehaus.jackson.map.JsonMappingException: No serializer found for class java.io.FileDescriptor and
no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )
(through reference chain: com.commands.MyCommand["fileData"]->
java.util.ArrayList[0]->org.springframework.web.multipart.commons.CommonsMultipartFile["fileItem"]->
org.apache.commons.fileupload.disk.DiskFileItem["inputStream"]->java.io.FileInputStream["fd"])
I read that if i used #JsonIgnore then I may be able to avoid this error, but this does not seem to be the case for me.

even though my getter was marked with #XMlTransient, seemed the jackson was still looking for #JsonIgnore and upon adding it, things worked as expected.

Related

Why jackson is not serializing this?

#Data
public class IdentificacaoBiometricaDto {
private Integer cdIdentifBiom;
private String nrMatricula;
private String deImpressaoDigital;
private Integer cdFilialAtualizacao;
}
I am using retrofit 2.6.1, jackson 2.9.9 and lombok 1.8.10.
The exception is:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class br.com.clamed.modelo.loja.dto.central.IdentificacaoBiometricaDto and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:313)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsBytes(ObjectWriter.java:1017)
at retrofit2.converter.jackson.JacksonRequestBodyConverter.convert(JacksonRequestBodyConverter.java:34)
at retrofit2.converter.jackson.JacksonRequestBodyConverter.convert(JacksonRequestBodyConverter.java:24)
at retrofit2.ParameterHandler$Body.apply(ParameterHandler.java:355)
... 14 more
The object mapper:
return new ObjectMapper().registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
I am setting all fields, when passing it to a request body, retrofit fails because jackson could not serialize the object.
Retrofit call:
#POST("/usuario/v1.0/cadastraBiometria")
Call<IdentificacaoBiometricaDto> cadastraBiometria(#Body IdentificacaoBiometricaDto identificacaoBiometricaDto);
Rest service:
#RestController
#RequestMapping("/usuario")
public class UsuarioController {
#PostMapping(value = "/v1.0/cadastraBiometria")
public ResponseEntity<IdentificacaoBiometricaDto> cadastraBiometria(#RequestBody IdentificacaoBiometricaDto identificacaoBiometricaDto) {
}
}
Update:
If I change the retrofit converter to Gson it works;
If I serialize it using Jackson directly, it works;
Removing lombok makes no difference;
Found the problem. The biometric reader library was causing this. For some reason it's incompatible with openjdk-11 and is causing all sort of unrelated problems.
Yes, very weird. But the lib is very poorly done.

How to bind Ninject to [Obsolete] constructor?

In my submodule, I have:
public class CustomerRepository : ICustomerRepository
{
private readonly IDBEngine _dbEngine;
[CanBeNull] private readonly string _overriddenDebugEmail;
[Obsolete("Use the other constructor")]
public CustomerRepository(IDBEngine dbEngine)
{
_dbEngine = dbEngine;
_overriddenDebugEmail = null;
}
// ReSharper disable once UnusedMember.Global
public CustomerRepository(IDBEngine dbEngine, IDebugConstants debugConstants)
{
_dbEngine = dbEngine;
_overriddenDebugEmail = debugConstants.OverridingDebugEmail;
}
...
The problem is, when I simply update the submodule without implementing IDebugConstants, I get the following runtime error:
Error activating IDebugConstants
No matching bindings are available, and the type is not self-bindable.
I want Ninject to bind to the Obsolete constructor if IDebugConstants is not implemented. But it refuses to because of the obsolete attribute.
In theory I could remove the Obsolete attribute, but I want it to show that that code should no longer exist once all old programs using the submodule have been updated.
Is there some way to make Ninject ignore the Obsolete attribute?
Or am I going about this entirely wrong somehow?
You can do this by adding the [Inject] attribute to your [Obsolete] constructor.
The reason for this is how the constructor scoring is implemented. Specifically this section of the Score method:
if (directive.Constructor.HasAttribute(this.settings.InjectAttribute))
{
return int.MaxValue;
}
if (directive.Constructor.HasAttribute(typeof(ObsoleteAttribute)))
{
return int.MinValue;
}
You will see that if the constructor has the [Obsolete] attribute then it is given the minimum possible score. But prior to that, if the constructor has the [Inject] attribute then it will be given the highest possible score.
This doesn't help in the specific case you mentioned where you want a conditional binding when IDebugConstants is not implemented, but it does answer "Is there some way to make Ninject ignore the Obsolete attribute?"

jdto superclass boolean field binding incorrect value

public class Model {
}
public class SuperclassDTO {
private boolean funny = true;
public boolean isFunny() {
return funny;
}
public boolean setFunny(boolean f) {
this.funny = f;
}
}
public class SubclassDTO extends SuperclassDTO {
}
new SubclassDTO().isFunny() //returns true
SubclassDTO dto = binder.bindFromBusinessObject(SubclassDTO.class, new Model());
dto.isFunny(); //returns false!!!!
Isn't this weird? Model class does not have a "funny" field but somehow dto is bind with a wrong value. First I thought jDTO required "getFunny" convention, so it couldn't read the value and just set it "false" but changing the getter name to "getFunny" does not resolve the issue, plus I'm not allowed to modify SuperclassDTO. How can I bind the correct value?
Jdto version 1.4 by the way...
The behavior you're experiencing is a "side effect" of the convention over configuration approach. All the fields on the DTO are configured unless you mark them as transient, either by using the #DTOTransient annotation or the transient configuration on the XML file. If a configured field does not have a corresponding field on the source bean, it will be set with default values and that is the reason why you're experiencing this behavior.
You have some options to overcome this issue:
Add the #DTOTransient annotation to the DTO.
Since you're not able to modify the DTO, you could configure it through XML.
Use Binding lifecycle to Restore the value. By adding code on the subclass.
You might as well submit a bug report on the jDTO issue tracker on github.

Proxying NHibernate Objects with Castle DynamicProxy swallows NH-Functionality

I'm doing things considered horrible by some lately, but I personally enjoy this kind of experiment. Here's a telegraph style description:
Use NH to fetch data objects
Each DataObject is wrapped by a CastleDynamicProxy
When Properties decorated with Custom Attributes are queried, redirect to own code instead of NHibernate to get Returnvalue.
Object creation / data fetch code
Objects=GetAll().Select(x=>ProxyFactory.CreateProxy<T>(x)).ToList();
public IList<Person> GetAll()
{
ISession session = SessionService.GetSession();
IList<Person> personen = session.CreateCriteria(typeof(Person))
.List<Person>();
return personen;
}
The Proxy generation Code:
public T CreateProxy<T>(T inputObject)
{
T proxy = (T)_proxyGenerator.CreateClassProxy(typeof(T), new ObjectRelationInterceptor<T>(inputObject));
return proxy;
}
The Interceptor used is defined like so:
public class MyInterceptor<T> : IInterceptor
{
private readonly T _wrappedObject;
public MyInterceptor(T wrappedObject)
{
_wrappedObject = wrappedObject;
}
public void Intercept(IInvocation invocation)
{
if (ShouldIntercept(invocation)) { /* Fetch Data from other source*/ }
else
{
invocation.ReturnValue = invocation.Method.Invoke(_wrappedObject, invocation.Arguments);
}
}
public bool ShouldIntercept(IInvocation invocation)
{
// true if Getter / Setter and Property
// has a certain custom attribute
}
}
This works fine in an environment without NHibernate (creating objects in code, where the Object holds its own data).
Unfortunately, the else part in the Intercept method seems to leave NHibernate unfunctional, it seems the _wrappedObject is reduced to it's base type functionality (instead of being proxied by NHibernate), so all mapped Child collections remain empty.
I tried switching from lazy to eager loading (and confirmed that all SQL gets executed), but that doesn't change anything at all.
Does anybody have an idea what I could do to get this back to work?
Thanks a lot in advance!
I found out that what I do is partially wrong and partially incomplete. Instead of deleting this question, I chose to answer it myself, so that others can benefit from it as well.
First of all, I have misunderstood the class proxy to be an instance proxy, which is why i stored the _wrappedObject. I needed the Object to perform invocation.Method.Invoke(_wrappedObject, invocation.Arguments), which is the next mistake. Instead of doing so, I should have passed the call on to the next interceptor by making use of invocation.Proceed().
Now, where was that Incomplete? NH seems to need to know Metadata about it's instances, so I missed one important line to make NH aware that the proxy is one of its kin:
SessionFactory.GetClassMetadata(entityName).SetIdentifier(instance, id, entityMode);
This only works in an NHibernate Interceptor, so the final product differs a bit from my initial one...Enough gibberish, you can see a very very comprehensible example on this on Ayende's website. Big props for his great tutorial!

Stub generation failes with obsolete attribute, Pex v0.94.51023.0

I have an interface with a method marked with the obsolete attribute. The attributes error parameter is set to true to throw an exception when used. The problem is this causes the stub to not generate for the whole class. When I alter the value to false the stub generates as expected.
I’m looking for a way to generate the stub while retaining the error parameter as true.
public interface ICar
{
void Start();
[Obsolete("this is obsolete Stop, stop using it", true)]
void Stop();
}
I’ve tried different permutations of.
<Moles xmlns="http://schemas.microsoft.com/moles/2010/">
<Assembly Name="My.Car.Services"/>
<StubGeneration>
<TypeFilter TypeName="ICar" SkipObsolete="true" />
</StubGeneration>
</Moles>
This is by design. When a method is marked at Obsolete(..., true), C# will not allow to instantiate an class implementing that interface.