Reputation: 43970
Project Lombok is tempting to reduces boilerplate code in our Java 8 code base. The downside is that it limits tool support (refactoring, static analysis).
For example, in my experiments with IntelliJ, refactoring of fields of a class annotated with @Builder
, no longer works. I know of no workaround (you have to manually fix locations, where the old method name of the Builder is used).
Another example is that in Eclipse "find references" on a field does not find the references, but a good workaround is to open the outline and apply "find references" on the generated getter/setter.
My questions:
Upvotes: 8
Views: 4281
Reputation: 1188
For more complicated refactorings, I have settled on "delombok-refactor-relombok". This is a heavy weight approach, but has the benefits handling complex refactorings without intermediate broken builds.
In my case, I use maven for builds. I added the maven build plugin for lombok:delombok configured as follows:
<build>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.6.0</version>
<configuration>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<addOutputDirectory>>false</addOutputDirectory>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This makes delombok copies easily available under the target directory.
To refactor a specific lombok class:
I would expect skepticism for those looking at this for their first attempt to refactor a lombok class. I arrived here only after frustrations and limitations with other techniques and more complex lombok features (i.e. @Builder, @SuperBuilder).
For example, manually adding the setter for a @Builder requires declaring the matching lombok generated inner builder class correctly. This become more difficult to do with features like lombok @SuperBuilder builder inheritance. When I attempted to do this manually, I decided to look at the delombok class as a guide. That is when I realized it was simpler to substitute the delombok source, refactor at will, and then remove it.
Upvotes: 2
Reputation: 141
Here's a small workaround to refactor the getter/setter of a variable in a @Data class. This works in eclipse and probably elsewhere as well:
Sample class, where we want to refactor "value" to "value2":
import lombok.Data;
@Data
public class Thing {
int value;
}
(1) Rename (don't refactor) the variable to something temporary to remove lombak's generated getter/setter for the original name. You'll get compile errors wherever the old getter/setter were referenced, but that is temporary:
@Data
public class Thing {
int valueXXX; // reference to getValue() are broken for the moment
}
(2) Manually create a dummy getter/setter for the old name. Your compile errors will go away now:
@Data
public class Thing {
int valueXXX;
public int getValue() { return 0; }
public void setValue(int value) {}
}
(3) Use eclipse to refactor your dummy getter/setter. All references in your codebase now use getValue2() and setValue2():
@Data
public class Thing {
int valueXXX; //
public int getValue2() { return 0; }
public void setValue2(int value) {}
}
(4) Delete the renamed dummy getter/setter and change the variable name from your temporary name to the new one. Now it's all lombakized again:
@Data
public class Thing {
int value2;
}
Admittedly this is a bit annoying, but it doesn't actually take that long and it sure beats changing hundreds of references by hand.
Upvotes: 14
Reputation: 5575
One I recently came across:
In IntelliJ (don't know about Eclipse), you can't extract an interface that includes any methods generated by lombok. They don't show up on the relevant dialog.
There is an easy workaround: Let IntelliJ create the methods, extract the interface, revert your class and have it implement the interface again.
Upvotes: 2