Lombok + Intellij: cannot resolve method of super class - intellij-idea

I have a superclass
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class ErrorResponse {
#JsonProperty
private String message;
}
And I have a child one
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder(builderMethodName = "_builder") // add custom builder name to avoid compilation issue 'return type is not compatible...'
#EqualsAndHashCode(callSuper=true)
public class AskQuestionErrorResponse extends ErrorResponse {
#JsonProperty
private String status;
#Builder(builderMethodName = "_builder") // add custom builder name to avoid compilation issue 'return type is not compatible...'
private AskQuestionErrorResponse(String status, String message){
super(message);
this.status = status;
}
}
When I use a builder to create an object like this
AskQuestionErrorResponse._builder()
.status(1)
.message("my message here").build()
Intellij shows me message in red and there is an issue cannot resolve method 'message(java.lang.String)' Anyway project compiles and runs even with this error.
I've already enabled annotations precessing.
If I comment field from superclass like this
AskQuestionErrorResponse._builder()
.status(ex.getStatus().getValue()
//.message(ex.getMessage()
).build()
It works. It seems that it does not see superclass members. I've also tried maven clean and install, rebuild project.
UPDATE
Lombok plugin is installed
Annotation Processors are enabled in Preferences and in Default preferences

I found it. If you take a look to my class you'll see two #Builder annotations. I removed first one and magic happens. Now my class looks like this and there is no warning
#Data
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(callSuper=true)
public class AskQuestionErrorResponse extends ErrorResponse {
#JsonProperty
private String status;
#Builder(builderMethodName = "_builder") // add custom builder name to avoid compilation issue 'return type is not compatible...'
public AskQuestionErrorResponse(String status, String message){
super(message);
this.status = status;
}
}
Hope it helps :)

You need to install the Intellij Lombok plugin so that it can understand the annotations before the compilation to byte code.
https://projectlombok.org/setup/intellij

Related

org.jetbrains.annotations.NotNull instead of javax.annotation.Nonnull when implement method in Intellij IDEA

After recent JetBrains Intellij IDEA updates I found out that when I'm trying to implement method annotated with javax.annotation.Nonnull - IDE implements it with org.jetbrains.annotations.NotNull instead.
Example:
If you have an interface:
import javax.annotation.Nonnull;
interface User {
#Nonnull
String getName();
}
it will be implemented as:
import org.jetbrains.annotations.NotNull;
class Customer implements User {
#NotNull
#Override
public String getName() {
return null;
}
}
The question is how to configure IDE to implement methods with strict validation annotation?
Looks like a defect (https://youtrack.jetbrains.com/issue/IDEA-253324) although there is a workaround exist:
Inspections > Java > Probable bugs > Nullability problems > #NotNull/#Nullable problems > Configure Annotations. Set javax.annotation.Nullable/javax.annotation.Nonnull as defaults and restart the IDE.
To add the library with annotations to a Gradle project, add the implementation org.jetbrains:annotations:23.0.0 dependency to the build.gradle file.

Generating all fields Builder from lombok #Builder annotated class

I am wondering if there is a shortcut to create full builder without manually adding fields one by one from class annotated with Builder?
Let's say we have a class:
#Builder
public class Classroom {
private Long id;
private String name;
private String location;
private String fullName;
}
It creates Classroom.builder().build(), but instead of that I want to instantly unfold a code with every field added like:
Classroom.builder()
.id()
.name()
.location()
.fullName()
.build()
Any Intellij shortcut to make that happend?

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.

redefine static methods with ByteBuddy

Can homebody help me please to give me a hint how to redefine static methods using byte-buddy 1.6.9 ?
I have tried this :
public class Source {
public static String hello(String name) {return null;}
}
public class Target {
public static String hello(String name) {
return "Hello" + name+ "!";
}
}
String helloWorld = new ByteBuddy()
.redefine(Source.class)
.method(named("hello"))
.intercept(MethodDelegation.to(Target.class))
.make()
.load(getClass().getClassLoader())
.getLoaded()
.newInstance()
.hello("World");
I got following Exception :
Exception in thread "main" java.lang.IllegalStateException: Cannot inject already loaded type: class delegation.Source
Thanks
Classes can only be loaded once by each class loader. In order to replace a method, you would need to use a Java agent to hook into the JVM's HotSwap feature.
Byte Buddy provides a class loading strategy that uses such an agent, use:
.load(Source.class.getClassLoader(),
ClassReloadingStrategy.fromInstalledAgent());
This does however require you to install a Java agent. On a JDK, you can do so programmatically, by ByteBuddyAgent.install() (included in the byte-buddy-agent artifact). On a JVM, you have to specify the agent on the command line.

JsonIgnoreProperties not working

I have the following simple class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
#JsonIgnoreProperties({ "thirdField" })
public class Message {
private TypeA type;
private String producer;
//Getters and Setters
}
in my test class
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public void testMethd() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, true);
Class<T> instanceType = Message.class;
String msgBody = "{\"producer\": \"clientApp\", \"type\": \"aType\", \"thirdField\": []}";
objectMapper.readValue(msgBody, instanceType);
}
}
All I am trying to do is to convert the above json string into Message class and ignore the 'thirdField'. But I keep getting
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "thirdField" (class Message), not marked as ignorable (2 known properties: , "type", "producer"])
You've mixed different versions of Jackson.
Notice that you import JsonIgnoreProperties from org.codehaus.jackson.annotate (version 1.x)
while you're using ObjectMapper from com.fasterxml.jackson.databind (version 2.x).
Try using the last Jackson version (2.4):
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
#JsonIgnoreProperties({"id"})
Here you can find an example where it's implement using version 2.4:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html
I found a Solution to this.
Try to add
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
About your class
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
class ResponseModel {
//your properties here
#JsonIgnoreProperties("messageList","contactList","sender")
var contactList= ArrayList<ContactModel>()
}
That will solve your issue buddy.
It didn't work for me any of the above answers, i found a workaround that I have reinitialized the object and values (copied the object).