Open mattsains opened 8 years ago
Is this still being looked into? Is this a technically viable feature request? The absence of any issue management is quite daunting in the Lombok team.
Is this still being looked into?
I guess, it's got just forgotten. There are so many new feature requests opened monthly, that implementing them could keep a big company busy all the time. What's worse: They don't fit together.
Is this a technically viable feature request?
Most probably, yes. But is completely ignoring the field the best possibility? What if a final
field without an initializer gets ignored?
getCompiledRegex
looks like a lazy getter. Then all you need is @EqualsAndHashCode(exclude={"compiledRegex"})
and a manual constructor annotated with @Builder
(the setter gets suppressed automatically).
So maybe @AllArgsConstructor(exclude = {"compiledRegex"})
and @Builder
automatically using this constructor would be better?
The absence of any issue management is quite daunting in the Lombok team.
Yes (I'm not a member).
+1 for to have possibility exclude particular field(s) from builder with a simple annotation, or e.g. by @Builder(exclude={"",""}). Because currently for to exclude a field from being generated Builder, I had to manually define Constructor (without lombok annotations) and put @Builder annotation above it. Such implementation looked awkward.
I just stumbled upon the @RequiredArgsConstructor
. It will build a constructor for only final
fields and fields annotated with @NonNull
. So it's inclusive rather than exclusive, but the same effect can be achieved.
Consider this Issue: #2267
Now see this fixing change I have made to my project related to that Issue:
private @Getter @Setter OkHttpClient httpClient;
public final CompletableFuture<Void> lazyLoading;
{ // Initialization
// Initialize httpClient first so that lazyLoading will always have the client ready.
httpClient = new OkHttpClient.Builder().build();
lazyLoading = CompletableFuture.allOf(requestLanguages(), requestCategories());
}
I am using the instance initializer to order the initialization of httpClient
and lazyLoading
, but this opened a new problem:
Since the lazyLoading
field now has no value attached directly to it, the Builder now tries to generate a setter function for that field; which will fail, since the lazyLoading
field is final
.
This could be circumvented by an ignoring-annotation, like here:
public @Builder.Ignore final CompletableFuture<Void> lazyLoading;
Now, lombok no longer would try to generate a Builder setter to that value and my problem would finally be solved.
EDIT: Before this suggestion gets made, because of code styling preferences I will NOT implement the whole AllArgsConstructor
myself for the sake of solving this problem. In that case, Lombok would permanently be removed from my "useful dependencies" toolkit, since the whole reason of using Lombok is to not be required to have code clutter (like an AllArgsConstructor
would be).
@burdoto I'm afraid, you're doing something wrong. IMHO the core problem is that you're assigning a running CompletableFuture
which needs a different field to field. I'm not sure how it should work in the builder, where the different field doesn't exist yet.
Anyway, I'd suggest to construct the CodeBottle
without started threads and add a method for starting them (this should be simple to do with CompletableFuture
). Then you can use your original code with @Builder.Default
and you may avoid other problems, too.
IIUIC @Builder.Ignore
is not the solution. IIRC @Builder
doesn't use setters, it uses a constructor. Builder must ignore assigned fields and no annotation should be needed.... I guess, your use of initializer confused it into believing that lazyLoading
is not initialized.
This should be equivalent code without the problem:
private @Getter @Setter OkHttpClient httpClient =
new OkHttpClient.Builder().build();
public final CompletableFuture<Void> lazyLoading =
CompletableFuture.allOf(requestLanguages(), requestCategories());
[@Maaartinus]
Sorry, but I don't understand the meaning of your first part.
When constructing the CodeBottle instance, I NEED lazy loading to start already due to future changes that will require it to run right on construction.
When doing it the way you suggested, I lose power over execution order, which was a problem mentioned earlier in this issue. Before, I had my solution just the way you provided, which didn't work.
When constructing the CodeBottle instance, I NEED lazy loading to start already due to future changes that will require it to run right on construction.
Can't you simply replace all occurrences of new CodeBottle(....)
by new CodeBottle(....).start()
or provide a static factory method returning already started instances (this is no problem, only the construction is tricky)?
Before, I had my solution just the way you provided, which didn't work.
AFAIK no. Before, you used @Builder.Default
, which broke it (by delaying the initialization of httpClient
). Without it, it should be fine.
In any case, this is not an issue to discuss my way of solving my project, this issue is about requesting a feature arguing with a project. Since there is a template for feature requests, I assume those are welcome.
@burdoto
Disclaimer: I'm not a Lombok team member. Just trying to help.
Lombok is not a library.... it's a tool which can do things others can't do and it's way more difficult to implement and maintain any feature in Lombok than in a library (I hacked on Lombok some time ago and I do some code generation, too; so I'm perfectly sure about the workload ratio being something like 1:100).
Any new feature has it's (huge) cost and may or may not help users. Therefore, I'm trying to show the alternatives, which may be better than the feature requested.
Feature requests are surely welcome, it's just that there are too many of them and too few contributors.
@burdoto @mattsains have you tried annotating your to be ignored fields with
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
?
Of course, a shortcut such as @Ignore
would be great.
Why does the builder still provide a setter for something with AccessLevel.NONE?
@silkentrance
Why does the builder still provide a setter for something with AccessLevel.NONE?
With @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
you said, there should be no getter and no setter in the class, but the field still exists and will be set in the constructor, so the builder has a field for it, too. And a field in the builder which can't be set makes no sense.
@Maaartinus see my Why does the builder... comment.
You can add $
as prefix to the field name, lombok ignores all these fields
@Rawi01 yeah, this works, although... nevermind, will go for that approach for now.
@Rawi01 I have found a solution to this, without having to prefix the field with $
@Data
@Builder
public class Data {
private final List<String> someStringList = new ArrayList<>();
}
for the above, no builder method will be generated unless you annotate the above field with @Builder.Default
.
Is this proposal still unanswered?
still answered...
It would be great if there was an annotation which allowed you to tell Lombok to ignore a field entirely. This would benefit people looking for things like
@AllArgsConstructor(except = {"field"})
Example:
For cases where you want to do anything out of the ordinary with a field, you're left fighting with Lombok over control of the field. For instance, the same behaviour in Lombok as it is now would be pretty hard to accomplish, as far as I'm aware.
For instance, you might want to:
compiledRegex
from appearing in builder (Not sure how)compiledRegex
from appearing in an@AllArgsConstructor
(Not sure how, except by manually writing the constructor)@EqualsAndHashCode(exclude={"compiledRegex"})
@Setter(AccessLevel.NONE)
oncompiledRegex