I'm using lombok in intellij, and have the plugin installed.
My problem is that when I use the #Date notation in my class, only that class can see the methods created by lombok. So if my class declaration looks like this:
#Document
#Data
public class dbDocument {
#Id
private String uniqueId;
And the method
public String testGetter (dbDocument doc) {
return doc.getUniqueId;
}
Will work inside the dbDocument class, but not in any other class. (where I get a Java: cannot find symbol error)
How can I fix/debug this?
Oops.
Looks like I was spelling the method wrong while invoking it. Nothing to see here.
Related
I imported everything according to the Projectlombok site into my project.
I wonder if it is possible to call the getters and other things generated by Lombok right in the source code? I've tested that the JSON serializer can access these after compiling, but I can't use them in the project.
For example:
#Getter
class Person {
String name;
}
class MyClass {
void f(Person p) {
p.getName(); // doesn't compile for me
}
}
Tell me if I am wrong that Lombok can be used for this purpose.
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();
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.
when running the code below
i'm getting compilation error:
java: ..\JavaClass.java:8: cannot find symbol
symbol : method add(java.math.BigDecimal)
location: class BigDecimalDelegated
it seems like the stub of the groovy class created for the java compiler does not contain the delegated methods.
any idea?
consider this classes:
class BigDecimalDelegated //groovy class
{
#Delegate BigDecimal delegated;
String data;
}
import org.junit.Test;
import java.math.BigDecimal;
public class JavaClass //java class
{
#Test
public void temp()throws Exception
{
new BigDecimalDelegated().add(BigDecimal.TEN);
}
}
Groovy compiler used in IDEA's external build doesn't support this, see https://issues.apache.org/jira/browse/GROOVY-4647
You can either use #Delegate classes from Groovy code only, or switch off external build in Settings | Compiler to use the old build mechanism.
How are you running/compiling the code?
Also, I believe you'll need to set delegated in the constructor for BigDecimalDelegated
class BigDecimalDelegated //groovy class
{
#Delegate BigDecimal delegated
String data
BigDecimalDelegated() {
delegated = 0.0G
}
}