I'm using Intellij and trying to apply lombok to the project.
But it keeps saying "cannot find symbol".
Here's a quick sample of my code.
Class
import lombok.*;
#Data
public class Product {
private String name;
private Integer price;
public Product(String name, Integer price){
this.name = name;
this.price = price;
}
}
Main
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionMain {
public static void main(String[] args) {
Collection<Product> products = new ArrayList<>();
Product door = new Product("DOOR",90);
Product bed = new Product("BED",60);
Product ipad = new Product("iPad",15);
products.add(door);
products.add(bed);
products.add(ipad);
final Iterator<Product> productIterator = products.iterator();
while(productIterator.hasNext()){
Product product = productIterator.next();
System.out.println(product.getPrice());
}
}
}
and the error says
CollectionMain.java:23: error: cannot find symbol
System.out.println(product.getPrice());
^
symbol: method getPrice()
location: variable product of type Product
I have enabled the annotation processor
plugin
I didn't put
annotationProcessor 'org.projectlombok:lombok:1.18.12'
in my build.gradle
problem solved.
For some reason the Maven repository only provides you with the 'compileOnly' dependency for the Gradle builder.
However, if you look in the Lombok documentation you will find that you also need to use the 'annotationProcessor'.
https://projectlombok.org/setup/gradle
I had the same issue. But my solution was bit different.
My project is on java 8 but IDEA SDK was set to java 17. Once I changed it to java 8 issue was solved.
Go to File > Project Structure > Project
Change SDK
Apply > OK
File > Invalidate and Restart
I faced the same error when tried to build my project (gradle). I used jdk-15 on my project, but then installed jdk-17 on my computer (even without changing sdk in the project) and the problem happened.
To fix the issue I uninstalled jdk-17 from the computer (deleting sdk on project is not enough)
Related
UPDATE: Solution & Lessons
Corrected naming convention to be detected by Maven/JUnit: IngredientTest, not Ingredient_Test.
Deleted runner class (not required for tests). Struggled with how exactly to run tests to see results (without any main method).
Solution: in netbeans, ran the test file from original class (Ingredient), NOT the test class (IngredientTest). Right-click in body of original class (Ingredient), click 'Test file'. Upon completion, an output and and test result window should open.
netbeansSnapSolution
Thanks Chrylis, it appears I was mixing JUnit 4 & 5.
https://learn.vogella.com/courses/details/java-software-testing
https://junit.org/junit5/docs/current/user-guide/
What I'm trying to do: write and run JUnit on existing classes in netbeans.
What's wrong
#Before in Ingredient_Test: "Cannot find symbol"
imports in Ingredient_TestRunner: "Package <> does not exist."
Environment
Product Version: Apache NetBeans IDE 12.4
Java: 16; Java HotSpot(TM) 64-Bit Server VM 16+36-2231
Runtime: Java(TM) SE Runtime Environment 16+36-2231
Project built with Maven as default, though I haven't modified the Maven XML file in any manner, saving that as the next tutorial item after unit testing.
Background: I wrote my own quick ad hoc test classes (mixed in with src files), meaning to do proper Junit testing "later". I'm several classes in, and I should have started with proper testing! Now I'm in the process of rewriting ad hoc test classes properly.
NetbeansSnap
Thanks in advance.
package com.riverrat.recipebook;
public class Ingredient{
String name;
String amount;
String unit;
String form;
// do stuff
}
package com.riverrat.recipebook;
import com.riverrat.recipebook.Ingredient;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
public class Ingredient_Test {
#Before
public void buildIngredients(){
Ingredient beans = new Ingredient("beans");
Ingredient onions = new Ingredient("onions", "2", "cups", "chopped coarsley");
Ingredient water = new Ingredient("water", "3", "oz");
Ingredient bacon = new Ingredient("bacon", "", "slab");
}
#Test
public void testNames(){
assertEquals("beans", beans.name);
}
}
package com.riverrat.recipebook;
import org.JUnit.runner.JUnitCore;
import org.JUnit.runner.Result;
import org.JUnit.runner.notification.Failure;
public class Ingredient_TestRunner {
public static void main(String[] args){
Result result = JUnitCore.runclasses(IngredientTest);
for (Failure failure : result.getFailure()){
System.out.println(failure.toString());
}
System.out.println("Result " + result.wasSuccessful());
}
}
I have a simple object:
#Value
#Builder
public class User implements Serializable {
private final String userId;
private final String email;
private final String name;
}
No magic here except the fact that im using Lombok 1.18.2 here for the #Value and #Builder Annotations. All was working fine with Java 10 and Gradle 4.10. Now I upgraded to Java 11 and Gradle 5.2 and suddenly I get:
> Task :application:compileJava
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:12: error: variable userId not initialized in the default constructor
private final String userId;
^
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:13: error: variable email not initialized in the default constructor
private final String email;
^
/src/application/src/main/java/com/rbb/tutor/user/model/User.java:14: error: variable name not initialized in the default constructor
private final String name;
^
I dont really know what to do here. First I thought it is a problem with lombok but I upgraded to 1.18.6 which supports java 11. Now I have no new idea whats wrong.
Gradle 5 release has new annotationProcessor() configuration for dependencies (lombok issue)
Change your build.gradle as follows:
annotationProcessor("org.projectlombok:lombok:1.18.6")
compileOnly("org.projectlombok:lombok:1.18.6")
Or use recommended plugin - https://plugins.gradle.org/plugin/io.freefair.lombok
plugins {
id "io.freefair.lombok" version "3.1.0"
}
In gradle 5, you need to list annotation processors separately. Maybe that's the problem?
An example gradle build can be found here:
https://projectlombok.org/setup/gradle
After updating my GWT 2.7 application to GWT 2.8.1 I receive the following exception:
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: The response could not be deserialized
Caused by: com.google.gwt.user.client.rpc.SerializationException: /my/path/to/a/file.pdf. This path is stored in the path variable of MyClass:
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.user.client.rpc.IsSerializable;
public class MyClass implements IsSerializable {
private Integer id;
private String name;
private String path;
private List<String> assetClasses = new ArrayList<>();
private List<String> keywords = new ArrayList<>();
private List<Integer> regions = new ArrayList<>();
public ReportLink() {
// Empty default constructor for GWT serialization.
}
...getters + setters following
}
As you can see I'm implementing IsSerializable. Moreover I have an empty constructor (which is probably the most popular reason for this exception ;-)) and the class is located in the shared folder (referenced in the *.gwt.xml).
I set the data like this from a database query:
myClass.setName(resultSet.getString("name"));
myClass.setPath(resultSet.getString("path"));
String keywords = resultSet.getString("keywords");
myClass.setKeywords(Arrays.asList(keywords.split("\\s*,\\s*")))
...
and add different MyClass to a List<MyClass>. Afterwards two of these lists are added to a map and returned:
Map<String, List<MyClass>> map = new HashMap<>();
map.put("A", a);
map.put("B", b);
return map;
This is only happening on the server after compilation. In SuperDevMode everything works fine. Any idea?
I already deleted the classes and deploy folders, did a project + gwt-unit-cache clean and recompiled the project multiple times but the exception still occurs.
I'm also wondering why the exception explicitly logs the String path which should be serializable without problems?!
The reason was an old version of gwt-servlet.jar with another name in the WEB-INF/lib folder beside the new gwt-servlet.jar of version 2.8.1. Due to that it was not obvious on the first sight. Embarrassing, but perhaps it reminds others to double-check...
I had the same problem, just add Serializable to the enum (implement the interface) and add a constructor without parameters, that's it...
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.
I'm evaluating Scala on Android by starting with the NotesList demo. I was able to replace the NotesLiveFolder.java file with its Scala equivalent without problem.
Next, I introduced Roboguice, creating a simple NotesListApplication.java that sets up the Guice modules, and successfully injected a resource into the NoteEditor.java activity.
Finally, I when I tried to replace NotesListApplication.java with its Scala equivalent, I get the following runtime error before the application finishes booting:
java.lang.ClassNotFoundException: com.example.android.notepad.NotesListApplication in loader dalvik.system.PathClassLoader[/data/app/com.example.android.notepad-1.apk]
I created a Google Code project containing the complete Eclipse project and source. The original functioning NotesListApplication.java is:
package com.example.android.notepad;
import java.util.List;
import roboguice.application.RoboApplication;
import com.google.inject.Module;
public class NotesListApplication extends RoboApplication {
private Module module = new BindEverything();
public void setModule(Module module) {
this.module = module;
}
#Override
protected void addApplicationModules(List<Module> modules) {
modules.add(module);
}
}
and the Scala equivalent that causes the error is:
package com.example.android.notepad
import roboguice.application.RoboApplication
class NotesListApplication extends RoboApplication {
val module : Module = new BindEverything()
override protected def addApplicationModules(modules:java.util.List[Module] ) {
modules.add(module)
}
}
I'm building in Eclipse with the ScalaIDE plugin. I'm not running any treeshaker/proguard/etc.
The disassembly shows the Scala classes as expected:
Class descriptor : 'Lcom/example/android/notepad/NotesLiveFolder;'
...
Class descriptor : 'Lcom/example/android/notepad/NotesListApplication;'
Any ideas what could cause this?
Upgrade to 2.0-SNAPSHOT of RoboGuice and then you dont have to use RoboApplication and it all binds automatically. For more how to bind check out the slides from Mike Burtons presentations about RoboGuice at AnDevCon 2 and check out the 2.0 section on the wiki.
Like I posted on the mailing list maybe check out the apk with dedexer and see if the class was actually removed e.g. by Proguard or renamed so it cant be found as a next step.