Ambiguous method call using Project Lombok - java

I have the following code:
import lombok.Builder;
import lombok.Getter;
#Getter
#Builder
public class NameParserResponse {
private boolean match;
}
public class Main {
public static void main(String[] args) {
NameParserResponse nameParserResponse = NameParserResponse.builder().build();
nameParserResponse.isMatch();
}
}
When trying to reference isMatch(), I get:
Ambiguous method call. Both
isMatch () in Response and
isMatch () in Response match
I have also tried removing the #Builder annotation, but this doesn't help.

It looks like I had the Hrisey Intellij plugin installed in addition to the Project Lombok plugin. I must have accidentally installed this when I was looking for the Project Lombok plugin.
After disabling this plugin, the issue was no longer present.

IntelliJ has a refactoring to "de-Lombok" the code, which will expand the Lombok magic out into the more lengthy code it auto-generates behind the scenes. When I've encountered oddities like this before, looking at the actual produced code, instead of just guessing about it, has helped make the problem clearer. YMMV.
Good luck.

Related

Is onConstructor property of the Lombok's #[No|All|Required]ArgsConstructor annotation work Java 7 style only?

According to the documentation, Lombok has 3 annotations for constructor generation:
#NoArgsConstructor - generates an empty constructor;
#AllArgsConstructor - generates a constructor that initializes all
fields;
#RequiredArgsConstructor - generates a constructor that
initializes only final fields.
They all have an onConstructor property that allows you to specify the annotations with which the generated constructor should be marked.
According to the Javadoc, the syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
Up to JDK7:
#NoArgsConstructor(onConstructor=#__({#AnnotationsGoHere}))
From JDK8:
#NoArgsConstructor(onConstructor_={#AnnotationsGohere}) // note the underscore after onConstructor
I am working on JDK8. However, only the JDK7 variant works for me, while the JDK8 variant does not work (a constructor without annotations is generated).
I checked on JDK11 - same result.
I check with Refactor -> Delombok -> #Constructors.
For example, like this:
#AllArgsConstructor(onConstructor = #__(#Deprecated))
public class SomeClass {
}
the following code is generated:
public class SomeClass {
#Deprecated
public SomeClass() {
}
}
But like so:
#AllArgsConstructor(onConstructor_ = #Deprecated)
public class SomeClass {
}
code like this is generated:
public class SomeClass {
public SomeClass() {
}
}
I noticed that the documentation on the Lombok site only contains a JDK7 style example.
The Javadoc is incorrect or am I doing something wrong?
I found, that it's not the Lombok's bug, it's Lombok IntelliJ plugin bug.
Constructor annotations add in compiled code.
Delombok tool of Lombok IntelliJ plugin incorrect convert Lombok's annotations to vanilla Java code.

AspectJ #DeclareParents defaultImpl code is not used when using it as dependency

I am working with AspectJ at the moment.
I seperated AspectJ code in a dependency.
Within that dependency everything works as intended.
But as soon as I import it in another project only some functionality does not work anymore.
When using the defaultImpl of #DeclareParents, the interface is shown within the compiled code but not the default Implementation.
Here is my code to show what I mean (every code snippet is its own File):
AspectJ code:
public interface IAspect
{
String hello();
}
public class IAspectDefaultImpl implements IAspect
{
#Override
public String hello()
{
return "hello";
}
}
#Aspect
public class AspectJ
{
#DeclareParents(value = "#SomeAnnotation*", defaultImpl = IAspectDefaultImpl.class)
private IAspect implementedInterface;
}
Target Class in a different project:
#SomeAnnotation
public class MyClass
{
private final int myValue;
public MyClass(final int wert)
{
this.myValue = wert;
}
public int getMyValue()
{
return myValue;
}
}
Maven throws me:
The type MyClass must implement the inherited abstract method IAspect.hello()
Which implies that it works partially.
When looking at the decompiled .class files the targeted Class does in fact implement IAspect.
The method defined in IAspectDefaultImpl is still missing tho.
My pom is set up like in this example.
I am not sure where I should start to look for errors.
Any help is apreciated.
Thanks for the MCVE. But hey, you don't use Git in order to commit 7z or ZIP archives, you ought to commit source code. I forked your project and fixed that, restructured and simplified your POMs and also fixed the main problem.
See my pull request and the commits in it for further details.
Concerning your problem, I can confirm that it occurs if you use #DeclareParents the way you do in an aspect library.
Actually, according to AspectJ maintainer Andy Clement there are certain problems with #DeclareParents when using it to provide parent interfaces + implementations in annotation style. The native AspectJ syntax via declare parents is not affected by that, but for annotation-style syntax Andy provided an alternative called #DeclareMixin, see the AspectJ manual. There he mentions that he is even considering to deprecate the defaultImpl argument of #DeclareParents in favour of #DeclareMixin.
So my bugfix (or workaround) for your problems is to actually replace
#DeclareParents(value = "#de.example.aspect.SomeAnnotation *", defaultImpl = IAspectDefaultImpl.class)
private IAspect implementedInterface;
by
#DeclareMixin("#de.example.aspect.SomeAnnotation *")
public static IAspect createIAspectImplementation() {
return new IAspectDefaultImpl();
}
This works with aspect libraries.
I will discuss with Andy about whether it makes sense to file a bug ticket for your problem or if he won't fix it anyway because there is a viable and recommended alternative.

Generating getters and setters using project Lombok

I wanted to use Lombok dependency in my project. So, I downloaded lombok-1.16.18.jar and added to the build path of on of my classes. The configuration is shown below.
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#ToString(includeFieldNames=true)
public #Data class Student {
#Getter
#Setter
private Integer id;
#Getter
#Setter
private String name;
//private Date dob;
#Getter
#Setter
private String uid;
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s = new Student();
System.out.println(s);
}
}
But, I am not getting proper output in console. I am getting Object classes toString() output like com.selflearn.sandesha.Student#7852e922
. I am also not able to use getters and setters. How to make Lombok work or what wrong I am doing?
Your configuration is incomplete. Review https://projectlombok.org/setup/eclipse and check if It compiles.
When it does, try again!
If you use netbeans go to properties->Build->compiling for checked the option Enable Annotation processing
or search this option in your editor
thanks for your help. In eclipse IDE, I was not exporting the lombok jar. Even though, I added jar to the build path, it seems I should export it to the project in order and export section of eclipse.
So, In eclipse editor,
right click on your project --> Build Path--> Configure Build Path...-->select order and export tab and check the jar you want to export to your project.
Or
you can also simply run the downloaded jar. This will detect the possible IDE's in the system and configure it to support all lombok features.
This solved my issue. Again thank you for your support.
Simply download the lombok-1.18.24.jar(any version) and once download, double click on that file, so it checks your system and detects the IDE's that are available on your system. Then verify the IDE's and click on install/update button. Once the above process is completed, restart your IDE maybe, sts or eclipse.
#Data on class level would be sufficient. Maybe it is a problem that you have put the #Data annotation between public and class.
Other question is whether your lombok.jar is on the classpath.
If I would rewrite your class, I would come up with the following:
#Data
public class Student {
private Integer id;
private String name;
private String uid;
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s = new Student();
System.out.println(s);
}
}

javax:javaee-api-6.0 contains non-abstract classes with no method body

I am fairly new to Java EE and when I look into the compiled code (I could not find the source code for javax:javaee-api-6.0), I notice this class.
package javax.servlet;
import java.util.EventObject;
public class ServletContextEvent extends EventObject
{
public ServletContextEvent(ServletContext paramServletContext);
public ServletContext getServletContext();
}
However, the same class in javax:javaee-api-7.0 is this.
package javax.servlet;
import java.util.EventObject;
public class ServletContextEvent extends EventObject
{
private static final long serialVersionUID = -7501701636134222423L;
public ServletContextEvent(ServletContext source)
{
super(source);
}
public ServletContext getServletContext()
{
return (ServletContext)super.getSource();
}
}
The also happens to ServletException in the same package (there might be more, as I didn't go through each of them).
Assuming Java Decompiler gave me what the source code looks like, from a pure java grammar point of view, I can't understand why the 6.0 classes are not abstract (or, not interfaces).
Question 1. Why are the classes in 6.0 not abstract or interfaces?
Question 2. Why is the implementation changed in 7.0? Did people realize the 6.0 version would cause trouble when you compile code with javaee-api?
The reason I ask is because I actually got compile errors when using javaee-web-api (which has similar classes as javaee-api, see this) in Intellij IDEA (12.1.4). The error looks like this:
Internal error: (java.lang.ClassFormatError) Absent Code attribute in method that is not native or abstract in class file javax/servlet/ServletContextEvent
So Question 3. Is there a way to avoid this in Intellij IDEA?
Did people realize the 6.0 version would cause trouble when you
compile code with javaee-api?
Yes, one of the problmes is that you cannot use those classes when running tests. See this Arquillian FAQ and Adam Bien's blog post.
Is there a way to avoid this in Intellij IDEA?
See the links above. The solution is not specific to Intellij IDEA.

Can not find test class 'junit.test.DepartmentTest' in project 'jyxxw'

when I run configurations, but my Eclipse shows that
Can not find test class 'junit.test.DepartmentTest' in project 'jyxxw'
This is a message that Eclipse gives when it doesn't recognize the class as being a test class. Do you have any #Test annotations in your class? (I realize that sounds like a silly question, but they could be in the superclass. In which case Eclipse doesn't see them.)
Can you try replacing your test code temporarily with a really simple test and see if the error goes away?
package junit.test;
import org.junit.*;
public class DepartmentTest {
#Test public void myTest() {}
}
If this works, you can see what's missing in your class. If it doesn't work, it is likely a classpath issue.

Categories