It seems that #RequiredArgsConstructor not working in the code below. Why is it?
import java.io.Serializable;
import lombok.Data;
import lombok.RequiredArgsConstructor;
#Data
#RequiredArgsConstructor
public class User implements Serializable {
private String username;
/*public User(String username) {
this.username = username;
}*/
private static final long serialVersionUID = 8043545738660721361L;
}
I get the error:
javax.faces.el.EvaluationException: java.lang.Error: Unresolved compilation problem:
The constructor User(String) is undefined
For some reason seems it does work for other domain class in which no constructor defined but instead used the #RequiredArgsConstructor annotation.
According to Documentation,
Required arguments are final fields and fields with constraints such as #NonNull.
You need to make username as #NonNull
#NonNull private String username;
And you need to make them final too.
It's also worth noting for future readers that #Data also provides #RequiredArgsConstructor, so using both annotations isn't necessary :)
Did you installed Lombok plugin in IntelliJ?
If not then
File -> Settings -> Plugins: Search for Lombok (CodeStream) version.
Restart the IDE and it should be fixed.
Double Check:
You have Lombok library installed using Maven or Gradle.
Enabled Annotation Processors from IntelliJ IDE from File -> Settings: Search for Annotation Processors
#RequiredArgsConstructor
> Generates a constructor with required arguments. Required arguments
are final fields and fields with constraints such as #NonNull.
> Complete documentation is found at the project lombok features page
for #Constructor.
> Even though it is not listed, this annotation also has the
*`onConstructor`* parameter. See the full documentation for more details.
Lombok library
To use the #RequiredArgsConstructor, the variable has to be final and it will create the values in constructor automatically
private final String username;
Try changing project/module JDK to 1.8.
Project Structure -> Project Settings->Project SDK and Project Language Level
The argument fields for #RequiredArgsConstructor annotation has to be final. So this fix will work:
private final String username;
The IDE IntelliJ makes the variable grey (inactive status) when final keyword missed, which is very helpful to detect this kind of mistake.
Related
Let's have a simple MongoDB Document class with Lombok annotations
import lombok.Data;
import com.mongodb.lang.NonNull;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
#Data
public class Car {
#NonNull
private String plate;
}
and simple test
#Test
public void test() {
Car c = new Car();
c.setPlate(null);
}
With Lombok v1.18.22 this worked well and test succeeded. However since v1.18.24, the test starts to fail since apparently Lombok now understands more annotations that indicate that field/param shouldn't be null
https://projectlombok.org/changelog
I'm not sure if MongoDB uses these #NonNull annotations for anything (I think not?) but at least for a documentation purposes it's nice to have them. Also the field can be null in some cases for MongoDB documents f.e. when using Spring Data's filtering using Example
repository.findByExample(Example.of(car))
where I might filter by only some specific field, leaving also mandatory fields to null.
If it'd be about #lombok.NonNull then I'd simply remove it but I don't want to remove Mongo annotations just because of Lombok. Thus my question:
Question 1: Can I avoid these checks? Or can I turn this feature off? So either that Lombok will consider only lombok.* annotations or just suppress generation of null checks in general.
Second issue is that Intellij Idea Lombok plugin apparently doesn't know about this feature yet so it considers that code to be valid. The build then fails as Lombok v1.18.24 generates constructor with all the #NonNull fields so it can't call new Car(). With #lombok.NonNull it works well in Intellij but with Mongo's NonNull it doesn't. I'm using IntelliJ IDEA 2022.1.3 (Community Edition)
Question 2: Is this a bug in Intellij Idea or its Lombok plugin? If yes is it known? I haven't found any info about it which leads me to the idea that the error is on my side
So looking at my class files the getters/setters are being generated just fine, but I'm trying to write a copy method that looks like this in the same jar.
#Data
public class SoftwareVersions {
private String applicationVersion;
void copyTo( MonitorFoleyConnection mfc ) {
mfc.setApplicationVersion( applicationVersion );
}
}
in gradle
annotationProcessor("org.projectlombok:lombok:1.+")
compileOnly("org.projectlombok:lombok:1.+")
is it possible to get intellij to recognize the existance of this method?
Yes, you have. You just need to do two things:
Install the Lombok Plugin for Intellij:
Enable the annotation processing:
I've a class Product:
#Data
#SuperBuilder
public class Product {
private String name;
private String manufacturer;
}
and an extended class
#Data
#SuperBuilder
public class Frame extends Product{
private String model;
}
I'm trying to create a Frame object using the builder:
return Frame.builder()
.name("Frame ABC")
.manufacturer("Manufacturer")
.model("Model 1")
.build();
I'm using IntelliJ 2019.1.1 with Lombok plugin but unfortunately the compiler marks as error the .name() and .manufacturer() methods.
I saw this issue opened and I'm wondering if there is a workaround to make my code to work.
No, not until the issue is resolved.
Its a chicken and egg issue. Until the classes with the #SuperBuilder annotations are compiled, the actual generated builder methods do not exist. The plugin (once updated/fixed) works with the IDE for these methods so that even though they don't exist yet, the plugin tells the IDE what they will be when compilation takes place.
There are ways to 'cheat' but they are all hacks - for example, you could compile your (super)builder classes in their own jar and then import that jar into your project. As you compiled the SuperBuilder classes they now contain all the generated methods, thus the IDE will see the actual methods and will therefore propose them if you try use them. Functional but not very useful... if you need to update the SuperBuilder annotated classes, you now have to compile them each time before the changes become visible. Obviously you could create build tasks to do this for you, but you are always working around the actual issue which is plugin support.
This workaround works for me:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Product {
private String name;
private String manufacturer;
}
#Data
#NoArgsConstructor
public class Frame extends Product{
private String model;
#Builder
public Frame(String name, String manufacturer, String model){
super(name, manufacturer);
this.model = model;
}
}
The only problem I see is when you have a lot of fields in the class it is becoming annoying to write such constructors, but still I think it worth it cause at the end you can access parent and child fields.
return Frame.builder()
.name("Frame ABC")
.manufacturer("Manufacturer")
.model("Model 1")
.build();
Build with child member fields first, then parent member fields, with a type casting seems to work for me:
return (Frame) Frame.builder()
.model("Model 1")
.name("Frame ABC")
.manufacturer("Manufacturer")
.build();
I have a simple object:
#Value
#Builder
public class User implements Serializable {
private final String userId;
private final String email;
private final String name;
}
No magic here except the fact that im using Lombok 1.18.2 here for the #Value and #Builder Annotations. All was working fine with Java 10 and Gradle 4.10. Now I upgraded to Java 11 and Gradle 5.2 and suddenly I get:
> Task :application:compileJava
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:12: error: variable userId not initialized in the default constructor
private final String userId;
^
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:13: error: variable email not initialized in the default constructor
private final String email;
^
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:14: error: variable name not initialized in the default constructor
private final String name;
^
I dont really know what to do here. First I thought it is a problem with lombok but I upgraded to 1.18.6 which supports java 11. Now I have no new idea whats wrong.
Gradle 5 release has new annotationProcessor() configuration for dependencies (lombok issue)
Change your build.gradle as follows:
annotationProcessor("org.projectlombok:lombok:1.18.6")
compileOnly("org.projectlombok:lombok:1.18.6")
Or use recommended plugin - https://plugins.gradle.org/plugin/io.freefair.lombok
plugins {
id "io.freefair.lombok" version "3.1.0"
}
In gradle 5, you need to list annotation processors separately. Maybe that's the problem?
An example gradle build can be found here:
https://projectlombok.org/setup/gradle
IntelliJ is suggesting to import com.sun.istack.internal.NotNull the #NotNull annotation (which is wrong) in the following program:
public class Test implements Comparable<Test> {
#Override
public int compareTo(#NotNull Test o) {
return 0;
}
}
When trying the correct import com.intellij.annotations.NotNull (I think) it looks like it can't find the class:
You can Alt+Enter on the warning before you add the annotation, press Right, choose Edit Inspection Settings, then Configure Annotations and specify the annotation you want to be inserted there.
Remove the import from the code. IntelliJ will ask you to import it again. It should suggest that there are multiple choices available. The annotation you want should be in the list.
I found I had to add the following dependency declaration to my Java project's build.gradle file before I was able to import the org.jetbrains.annotations.NotNull and org.jetbrains.annotations.Nullable annotations rather than the com.sun.istack.internal.NotNull and com.sun.istack.internal.Nullable annotations:
repositories {
mavenCentral()
}
dependencies {
compile 'org.jetbrains:annotations:15.0'
}
For later versions of Intellij, use Cmd+Shift+A (on MacOS) to bring up the Find Actions menu, then type Configure annotations, select the suggestion to bring up the Compiler preference window.
Then click on the Configure annotations button next to the option Add runtime assertions for notnull-annotated methods and parameters. It will then bring up the list of NonNull and Nullable configuration defaults. Select the one you want as default then set it as default with the check button.