For class with #Builder Eclipse auto complete (Ctrl+Space) builder methods:
ResponseVO.builder().
It also suggests new which can't work
ResponseVO.builder().new;
Error:
Syntax error on token(s), misplaced construct(s)
Also as creating new instance
new ResponseVO.builder();
Error:
ResponseVO.builder cannot be resolved to a type
Why new is added in suggestion to Builder class?
Checked with Eclipse 4.9.0 version and lower
EDIT
It's happening without lombok's builder, if extracting generated code using inner class Eclipse suggest new when calling MyClass.BuilderExampleBuilder.builder().
public class MyClass {
public static BuilderExampleBuilder builder() {
return new BuilderExampleBuilder();
}
public static class BuilderExampleBuilder {
BuilderExampleBuilder() { }
}
}
Opened Bug 558621 - [content assist] Eclipse suggests 'new' for qualified allocation even if no inner class exists
Proposing new after . is fundamentally correct, helping the user to create a qualified instance creation a la outerInstance.new InnerClass() (see JLS §15.9)
It seems wrong, however, that Eclipse proposes this syntax even if no applicable inner class exists.
Related
I have written an annotation processor that generates a builder class for my classes annotated with #DataBuilder
#Target(AnnotationTarget.CLASS)
#Retention(AnnotationRetention.SOURCE)
annotation class DataBuilder
My classes annotated with this annotation are located in the com.my.package.model package and the generated builder class is also located in the same package com.my.package.model but in the generated directory of course build/generated/source/kapt/debug/com/my/package/model/MyModelBuilder.kt, I can use these generated classes fine inside of my model classes(written in Kotlin)
BUT I can NOT use the generated MyModelBuilder Kotlin class inside of a java class as a class member
package com.my.package.home;
import com.my.package.model.MyModelBuilder;
public class Home {
MyModelBuilder builder; // <=== AS recognizes the class, but I'm having an compilation issue
}
Android Studio recognizes the class, but I’m having this compilation issue
com/my/package/home/Home.java:4: error: cannot find symbol
MyModelBuilder builder;
^
symbol: class MyModelBuilder
location: class Home
it’s weird because I can use this generated builder class only inside of methods, this code compiles fine:
package com.my.package.home;
import com.my.package.model.MyModelBuilder;
public class Home {
public void hello() {
MyModelBuilder builder;
}
}
could somebody here help me to understand this behavior and how to fix this? In advance, thanks!
UPDATE
I just created this repo with the necessary code to replicate the issue
https://github.com/epool/HelloKapt
The project works fine after cloning and running, to replicate the issue please un-comment this line https://github.com/epool/HelloKapt/blob/master/app/src/main/java/com/nearsoft/hellokapt/app/MainActivity.java#L13
Note: If I convert my MainActivity.java class to Kotlin(MainActivity.kt) the issues is NOT reproducible and works fine, but I don’t want to do so due to some project limitations so far
Kotlin Issue: https://youtrack.jetbrains.net/issue/KT-24591
Looking at your Github project, I notice that you don't declare a dependency on kotlin-stdlib-jdk7 in the app module. When I build the module, compiler emits the following warnings:
warning: unknown enum constant AnnotationTarget.CLASS
reason: class file for kotlin.annotation.AnnotationTarget not found
warning: unknown enum constant AnnotationRetention.SOURCE
reason: class file for kotlin.annotation.AnnotationRetention not found
warning: unknown enum constant AnnotationTarget.CLASS
reason: class file for kotlin.annotation.AnnotationTarget not found
Since kotlin-stdlib-jdk7 is declared as implementation in the annotations module, the app module doesn't see it as a transitive dependency, that might be the reason why compilation fails. To fix it, you should probably declare the correct dependency in the app module, or at least use apiElements scope for kotlin-stdlib-jdk7 in annotations.
The fact that the IDE doesn't notify you that compilation failed might be a tools bug, but there's definitely no underlying Kotlin compiler issue.
I have a generic class with a constructor and builder method:
public class FilterBuilder<T> {
public FilterBuilder() {
}
public FilterBuilder<T> add(T x) {
...
return this;
}
}
I instantiate, yet add doesn't work from constructor call:
FilterBuilder<String> filter = new FilterBuilder().add("test");
This gives 'Cannot resolve method add' error in Intellij. I have to do this to make it work:
FilterBuilder<String> filter = new FilterBuilder();
filter.add("test");
but why?
With your actual code, I think that the problem occurs as you specify the diamond operator <> :
FilterBuilder<String> filter = new FilterBuilder<>().add("test");
Raw types should not generate compilation errors but warnings but if your IDE configuration is stricter on this matter.
It is a compilation error specific to IDE as they consider new FilterBuilder<>() as a raw type even if the type of the declared builder is <String>.
By compiling with javac, no compilation error while on Eclipse Oxygen, I have the issue.
I suspect that the diamond operator support was not implemented in IDEs to allow the chaining of the instantiation to an instance method invocation.
As workaround you could do things in two times :
FilterBuilder<String> filter = new FilterBuilder<>();
filter.add("test");
or specify the generic twice :
FilterBuilder<String> filter = new FilterBuilder<String>().add("test");
I am trying to make a Java app that can load plugins implementing an abstract class and am having an AbstractMethodError with the instances generated from ServiceLoader. The code is a bit heavy so I've made a simplification below.
First, I have an abstract class:
package stuff.TheAbstractClass;
public abstract class TheAbstractClass implements ClassInterface{
//Stuff happens
}
Which implements the below interface:
package stuff.ClassInterface;
public interface ClassInterface {
public String getClassName();
}
I have a service provider NotAbstractClass which extends TheAbstractClass and states so in a meta-inf/services folder:
package anotherstuff.NotAbstractClass;
public final class NotAbstractClass extends TheAbstractClass implements ClassInterface{
private String name = "Silent Bob";
#Override
public String getClassName() { return name; }
}
Then on the main application (which is actually a plugin inside another application), I want to find all classes which extend TheAbstractClass:
package stuff.TheApp;
import java.util.ServiceLoader;
public class TheApp {
private String name;
public final static TheApp INSTANCE = new TheApp();
private TheApp() {
ServiceLoader<TheAbstractClass> serviceLoader =
ServiceLoader.load(TheAbstractClass.class);
for (TheAbstractClass class: serviceLoader) {
name = class.getClassName;
}
}
My application does find NotAbstractClass. I know this since, in the for loop, I can do class.getName() and it'll give me anotherstuff.NotAbstractClass) but gives the error:
java.lang.AbstractMethodError: stuff.TheAbstractClass.getClassName()Ljava/lang/String;
I'm stumped. Any suggestion? Thank you, Pedro
According to the API for AbstractMethodError you get this:
Thrown when an application tries to call an abstract method. Normally,
this error is caught by the compiler; this error can only occur at run
time if the definition of some class has incompatibly changed since
the currently executing method was last compiled.
Just by looking at your code and your comment I see that this could only have happened at runtime.
If that is the case then:
some class has incompatibly changed since the currently executing
method was last compiled
I've tested your logic after some adjustments in a Java compatible form and I had no problems. The only thing that seems to be happening is a change in any of the subclasses of TheAbstractClass.
Another thing I did was to declare the dependencies using the dependency files in: resources/META-INF/services:
file: <full-package>.TheAbstractClass
content: <full-package>.NotAbstractClass
After this I had no problems.
It seems the issue wasn't in the code, but in the IDE (IntelliJ). I deleted all previously packaged jars and made new jars without changing anything and it magically worked... So it's an IDE bug, and not a language issue!
Thanks to #Joao and #hotzst for taking time to read however.
Best, Pedro
I'm working in Java and have come across an incredibly odd error. I have a very basic class as follows:
public class ClassA{
private static Logger log = Logger.getLogger(ClassA.class.getName());
private boolean trace;
public ClassA(){
trace = log.isTraceEnabled();
}
public void doSomething(){
//does stuff
}
}
I can use this class just fine within my current project. However, when I build, package, and install to my local repo (using Maven, no remote artifact repo set up), other projects cannot properly use this class because they cannot instantiate it. When I try anything like:
ClassA classA = new ClassA();
I get the following compilation error:
ClassA() has private access in [package].ClassA
I've decompiled the .jar in my local repo to ensure the constructor is present and is public - it is. I've also used the -U flag to force updates and the compilation continues to fail. What could be causing this error?
Maybe you have some other ClassA.class file somewhere in the classpath. Check all the jars used by the project that cannot call the constructor: one of them should contain an old version of your class.
My only thought is that you have a problem with your package. Make sure to define the package at the top of the source file for classA using the package keyword. When you call it ensure that the file is in include list with the include keyword. You could be running into the error because ClassA exists in some default package and that is what you are actually calling instead of calling your locally made ClassA class. The code you posted looks fine and you have already double checked to ensure the changes have taken effect in your repository.
//for those with Kotlin-Java mixed projects:
If the said file (With constructor) is in Kotlin and is being used in Java:
Instead of A a = new A(); //which causes the said error
Use A.INSTANCE. …
I have this error, where write "private", instead "public" for class constructor;
I have this warning on most of my classes and not sure why is that. This happens on both public normal classes and final classes which have private constructors, some no constructor at all. I tried changing my private class methods to protected, doesn't help. Any suggestions on how to turn this off?
Here's a class example
public final class PlanBenefitManagerAssembler {
private static final Logger LOGGER = Logger.getLogger(PlanBenefitManagerAssembler.class);
/**
* No Instance of the this class is allowed.
*/
private PlanBenefitManagerAssembler() {
}
public static List<BenefitDecisionDetailsBean> assembleBenefitDecisionDetailsBean(
List<BenefitDetails> benefitDecisionDetailsList, int relationalSequenceNumber) {
LOGGER.debug("Enter assembleBenefitDecisionDetailsBean");
List<BenefitDecisionDetailsBean> benefitDecisionDetailsBeanList = new ArrayList<BenefitDecisionDetailsBean>();
for (BenefitDetails benefitDecisionDetails : benefitDecisionDetailsList) {
BenefitDecisionDetailsBean benefitDecisionDetailsBean = new BenefitDecisionDetailsBean();
benefitDecisionDetailsBean.setBenefitTypeCode(benefitDecisionDetails.getBenefitTypeCode());
benefitDecisionDetailsBean.setRelationSequenceNumber(relationalSequenceNumber);
benefitDecisionDetailsBean.setBenefitStatusDescription(
benefitDecisionDetails.getBenefitStatusDescription());
benefitDecisionDetailsBean.setBenefitStatusCode(benefitDecisionDetails.getBenefitStatusCode());
benefitDecisionDetailsBean.setBenefitUnderwritingStatusCode(
benefitDecisionDetails.getBenefitUnderwritingStatusCode());
benefitDecisionDetailsBean.setBenefitUnderwritingStatusDescription(
benefitDecisionDetails.getBenefitUnderwritingStatusDescription());
benefitDecisionDetailsBean.setBenefitChangeReasonCode(
String.valueOf(benefitDecisionDetails.getBenefitChangeReasonCode()));
benefitDecisionDetailsBean.setBenefitChangeReasonDescription(
benefitDecisionDetails.getBenefitChangeReasonDescription());
benefitDecisionDetailsBean.setComponentNumber(benefitDecisionDetails.getBenefitNumber());
benefitDecisionDetailsBean.setBenefitVisible(benefitDecisionDetails.isExplicitBenefitDecisionRequired());
benefitDecisionDetailsBean.setModelChanged(false);
// * Set BenefitLoading and BenefitExclusion
List<ExclusionDetailsBean> exclusionDetailsBeanList =
PlanBenefitManagerAssembler.assembleExclusionDetailsList(benefitDecisionDetails
.getBenefitExclusionsDetailsList().getBenefitExclusionsDetailsList());
List<LoadingDetailsBean> loadingDetailsBeanList =
PlanBenefitManagerAssembler.assembleLoadingDetailsList(benefitDecisionDetails
.getBenefitLoadingsDetailsList().getBenefitLoadingsDetailsList());
benefitDecisionDetailsBean.setExclusionDetailsBeanList(exclusionDetailsBeanList);
benefitDecisionDetailsBean.setLoadingDetailsBeanList(loadingDetailsBeanList);
benefitDecisionDetailsBeanList.add(benefitDecisionDetailsBean);
}
LOGGER.debug("Exit assembleBenefitDecisionDetailsBean");
return benefitDecisionDetailsBeanList;
}
}
When Checkstyle produces a warning the warning text should include a short rule name which will allow you to look up the exact rule that is being triggered. "DesignForExtension", for example.
Given the rule name, you can look up more detail on what it means in the Checkstyle documentation: http://checkstyle.sourceforge.net/availablechecks.html
Post the full details of the rule being triggered and someone might be able to help.
You can always turn the warnings off, but they generally are here for a reason :)
Do you intend to make them abstract classes ? If so, declare them that way.
Will you need to instantiate them at some point ? If so, add a public constructor.
I'm pretty sure this will solve your problem.
On sourceforge it says that the AbstractClassName rule uses the following regex:
^Abstract.*$|^.*Factory$
This causes classes with a name starting with 'Abstract' or ending with 'Factory' to be flagged. I get the 'Abstract..' part of that, but why should all '..Factory' classes be abstract? Sometimes I create factories which use dependencies to do their work so I need an instance to inject into.
This however does not explain your case. I tried your example class and did not get any Checkstyle warning (I am using the Eclipse Checkstyle Plug-in version 5.3.0.201012121300).
Are you sure you are getting the AbstractClassName warning for this class? Which version of Checkstyle are you using?