Are unnecessary semicolons syntax errors? - java

This morning, after doing a git refresh, IntelliJ complained that my project wasn't compiling clean any more. The culprit:
import javax.naming.Context;;
IntelliJ complains:
Error:(33, 29) java: Syntax error on token ";", delete this token
That code was pushed by a person who is not using IntelliJ, and it passed our backend build.
Question: is javac at fault, or IntelliJ? And what would be the document/spec that clarifies whether the above code should be an error or a warning?
This is IntelliJ 2019.2 CE EAP, running on MacOs.
And just to be precise: there seems to be a mismatch between the IntelliJ "editor compile", and the result of hitting the "build" action. Fun fact: we have "use eclipse compiler" in our project setup. Changing it that to use javac fixes the problem, the double ;; is just a warning then.

Unnecessary semicolons are not an error. They are considered as empty statements. And an empty statement, which does nothing, is not an error.
Cross check your code. It might also be IntelliJ at fault too. Its linting service might not be considering it as a legal statement.
The question is similar to this
Edit 1: The IntelliJ has an option in it's settings to which posts redundant semicolons as error.

According to the Java Language Specification §7.6 ; is a valid Type Declaration:
A top level type declaration declares a top level class type (§8 (Classes)) or a top level interface type (§9 (Interfaces)).
TypeDeclaration:
ClassDeclaration
InterfaceDeclaration
;
Extra ";" tokens appearing at the level of type declarations in a compilation unit have no effect on the meaning of the compilation unit. Stray semicolons are permitted in the Java programming language solely as a concession to C++ programmers who are used to placing ";" after a class declaration. They should not be used in new Java code.
If there is no setting in InteliJ that would change this behavior, then the extra semicolon should not produce an error.

Disclaimer
This does not resolve the issue, as it turns out the error occurs in relation to usage of the Eclipse compiler (as opposed to the default javac compiler).
This might still be useful to troubleshoot / highlight the inspection customization feature of IntelliJ.
You can set the level of severity for unnecessary semicolons (among many other things) in IntelliJ, in the Inspections profile.
The default setting for redundant semi-colons is "warning".
Probably yours has been set to "Error".
This should not impact on the Java compiler, as redundant semi-colons are not a syntactic error.

Related

I am getting error in PreparedStatement. What should I do? [duplicate]

Please explain the following about "Cannot find symbol", "Cannot resolve symbol" or "Symbol not found" errors (in Java):
What do they mean?
What things can cause them?
How does the programmer go about fixing them?
This question is designed to seed a comprehensive Q&A about these common compilation errors in Java.
0. Is there any difference between these errors?
Not really. "Cannot find symbol", "Cannot resolve symbol" and "Symbol not found" all mean the same thing. (Different Java compilers are written by different people, and different people use different phraseology to say the same thing.)
1. What does a "Cannot find symbol" error mean?
Firstly, it is a compilation error1. It means that either there is a problem in your Java source code, or there is a problem in the way that you are compiling it.
Your Java source code consists of the following things:
Keywords: like class, while, and so on.
Literals: like true, false, 42, 'X' and "Hi mum!".
Operators and other non-alphanumeric tokens: like +, =, {, and so on.
Identifiers: like Reader, i, toString, processEquibalancedElephants, and so on.
Comments and whitespace.
A "Cannot find symbol" error is about the identifiers. When your code is compiled, the compiler needs to work out what each and every identifier in your code means.
A "Cannot find symbol" error means that the compiler cannot do this. Your code appears to be referring to something that the compiler doesn't understand.
2. What can cause a "Cannot find symbol" error?
As a first order, there is only one cause. The compiler looked in all of the places where the identifier should be defined, and it couldn't find the definition. This could be caused by a number of things. The common ones are as follows:
For identifiers in general:
Perhaps you spelled the name incorrectly; i.e. StringBiulder instead of StringBuilder. Java cannot and will not attempt to compensate for bad spelling or typing errors.
Perhaps you got the case wrong; i.e. stringBuilder instead of StringBuilder. All Java identifiers are case sensitive.
Perhaps you used underscores inappropriately; i.e. mystring and my_string are different. (If you stick to the Java style rules, you will be largely protected from this mistake ...)
Perhaps you are trying to use something that was declared "somewhere else"; i.e. in a different context to where you have implicitly told the compiler to look. (A different class? A different scope? A different package? A different code-base?)
For identifiers that should refer to variables:
Perhaps you forgot to declare the variable.
Perhaps the variable declaration is out of scope at the point you tried to use it. (See example below)
For identifiers that should be method or field names:
Perhaps you are trying to refer to an inherited method or field that wasn't declared in the parent / ancestor classes or interfaces.
Perhaps you are trying to refer to a method or field that does not exist (i.e. has not been declared) in the type you are using; e.g. "rope".push()2.
Perhaps you are trying to use a method as a field, or vice versa; e.g. "rope".length or someArray.length().
Perhaps you are mistakenly operating on an array rather than array element; e.g.
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
For identifiers that should be class names:
Perhaps you forgot to import the class.
Perhaps you used "star" imports, but the class isn't defined in any of the packages that you imported.
Perhaps you forgot a new as in:
String s = String(); // should be 'new String()'
Perhaps you are trying to import or otherwise use a class that has been declared in the default package; i.e. the one where classes with no package statements go.
Hint: learn about packages. You should only use the default package for simple applications that consist of one class ... or at a stretch, one Java source file.
For cases where type or instance doesn't appear to have the member (e.g. method or field) you were expecting it to have:
Perhaps you have declared a nested class or a generic parameter that shadows the type you were meaning to use.
Perhaps you are shadowing a static or instance variable.
Perhaps you imported the wrong type; e.g. due to IDE completion or auto-correction may have suggested java.awt.List rather than java.util.List.
Perhaps you are using (compiling against) the wrong version of an API.
Perhaps you forgot to cast your object to an appropriate subclass.
Perhaps you have declared the variable's type to be a supertype of the one with the member you are looking for.
The problem is often a combination of the above. For example, maybe you "star" imported java.io.* and then tried to use the Files class ... which is in java.nio not java.io. Or maybe you meant to write File ... which is a class in java.io.
Here is an example of how incorrect variable scoping can lead to a "Cannot find symbol" error:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
This will give a "Cannot find symbol" error for i in the if statement. Though we previously declared i, that declaration is only in scope for the for statement and its body. The reference to i in the if statement cannot see that declaration of i. It is out of scope.
(An appropriate correction here might be to move the if statement inside the loop, or to declare i before the start of the loop.)
Here is an example that causes puzzlement where a typo leads to a seemingly inexplicable "Cannot find symbol" error:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
This will give you a compilation error in the println call saying that i cannot be found. But (I hear you say) I did declare it!
The problem is the sneaky semicolon ( ; ) before the {. The Java language syntax defines a semicolon in that context to be an empty statement. The empty statement then becomes the body of the for loop. So that code actually means this:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
The { ... } block is NOT the body of the for loop, and therefore the previous declaration of i in the for statement is out of scope in the block.
Here is another example of "Cannot find symbol" error that is caused by a typo.
int tmp = ...
int res = tmp(a + b);
Despite the previous declaration, the tmp in the tmp(...) expression is erroneous. The compiler will look for a method called tmp, and won't find one. The previously declared tmp is in the namespace for variables, not the namespace for methods.
In the example I came across, the programmer had actually left out an operator. What he meant to write was this:
int res = tmp * (a + b);
There is another reason why the compiler might not find a symbol if you are compiling from the command line. You might simply have forgotten to compile or recompile some other class. For example, if you have classes Foo and Bar where Foo uses Bar. If you have never compiled Bar and you run javac Foo.java, you are liable to find that the compiler can't find the symbol Bar. The simple answer is to compile Foo and Bar together; e.g. javac Foo.java Bar.java or javac *.java. Or better still use a Java build tool; e.g. Ant, Maven, Gradle and so on.
There are some other more obscure causes too ... which I will deal with below.
3. How do I fix these errors ?
Generally speaking, you start out by figuring out what caused the compilation error.
Look at the line in the file indicated by the compilation error message.
Identify which symbol that the error message is talking about.
Figure out why the compiler is saying that it cannot find the symbol; see above!
Then you think about what your code is supposed to be saying. Then finally you work out what correction you need to make to your source code to do what you want.
Note that not every "correction" is correct. Consider this:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
Suppose that the compiler says "Cannot find symbol" for j. There are many ways I could "fix" that:
I could change the inner for to for (int j = 1; j < 10; j++) - probably correct.
I could add a declaration for j before the inner for loop, or the outer for loop - possibly correct.
I could change j to i in the inner for loop - probably wrong!
and so on.
The point is that you need to understand what your code is trying to do in order to find the right fix.
4. Obscure causes
Here are a couple of cases where the "Cannot find symbol" is seemingly inexplicable ... until you look closer.
Incorrect dependencies: If you are using an IDE or a build tool that manages the build path and project dependencies, you may have made a mistake with the dependencies; e.g. left out a dependency, or selected the wrong version. If you are using a build tool (Ant, Maven, Gradle, etc), check the project's build file. If you are using an IDE, check the project's build path configuration.
Cannot find symbol 'var': You are probably trying to compile source code that uses local variable type inference (i.e. a var declaration) with an older compiler or older --source level. The var was introduced in Java 10. Check your JDK version and your build files, and (if this occurs in an IDE), the IDE settings.
You are not compiling / recompiling: It sometimes happens that new Java programmers don't understand how the Java tool chain works, or haven't implemented a repeatable "build process"; e.g. using an IDE, Ant, Maven, Gradle and so on. In such a situation, the programmer can end up chasing his tail looking for an illusory error that is actually caused by not recompiling the code properly, and the like.
Another example of this is when you use (Java 9+) java SomeClass.java to compile and run a class. If the class depends on another class that you haven't compiled (or recompiled), you are liable to get "Cannot resolve symbol" errors referring to the 2nd class. The other source file(s) are not automatically compiled. The java command's new "compile and run" mode is not designed for running programs with multiple source code files.
An earlier build problem: It is possible that an earlier build failed in a way that gave a JAR file with missing classes. Such a failure would typically be noticed if you were using a build tool. However if you are getting JAR files from someone else, you are dependent on them building properly, and noticing errors. If you suspect this, use tar -tvf to list the contents of the suspect JAR file.
IDE issues: People have reported cases where their IDE gets confused and the compiler in the IDE cannot find a class that exists ... or the reverse situation.
This could happen if the IDE has been configured with the wrong JDK version.
This could happen if the IDE's caches get out of sync with the file system. There are IDE specific ways to fix that.
This could be an IDE bug. For instance #Joel Costigliola described a scenario where Eclipse did not handle a Maven "test" tree correctly: see this answer. (Apparently that particular bug was been fixed a long time ago.)
Android issues: When you are programming for Android, and you have "Cannot find symbol" errors related to R, be aware that the R symbols are defined by the context.xml file. Check that your context.xml file is correct and in the correct place, and that the corresponding R class file has been generated / compiled. Note that the Java symbols are case sensitive, so the corresponding XML ids are be case sensitive too.
Other symbol errors on Android are likely to be due to previously mention reasons; e.g. missing or incorrect dependencies, incorrect package names, method or fields that don't exist in a particular API version, spelling / typing errors, and so on.
Hiding system classes: I've seen cases where the compiler complains that substring is an unknown symbol in something like the following
String s = ...
String s1 = s.substring(1);
It turned out that the programmer had created their own version of String and that his version of the class didn't define a substring methods. I've seen people do this with System, Scanner and other classes.
Lesson: Don't define your own classes with the same names as common library classes!
The problem can also be solved by using the fully qualified names. For example, in the example above, the programmer could have written:
java.lang.String s = ...
java.lang.String s1 = s.substring(1);
Homoglyphs: If you use UTF-8 encoding for your source files, it is possible to have identifiers that look the same, but are in fact different because they contain homoglyphs. See this page for more information.
You can avoid this by restricting yourself to ASCII or Latin-1 as the source file encoding, and using Java \uxxxx escapes for other characters.
1 - If, perchance, you do see this in a runtime exception or error message, then either you have configured your IDE to run code with compilation errors, or your application is generating and compiling code .. at runtime.
2 - The three basic principles of Civil Engineering: water doesn't flow uphill, a plank is stronger on its side, and you can't push on a rope.
You'll also get this error if you forget a new:
String s = String();
versus
String s = new String();
because the call without the new keyword will try and look for a (local) method called String without arguments - and that method signature is likely not defined.
One more example of 'Variable is out of scope'
As I've seen that kind of questions a few times already, maybe one more example to what's illegal even if it might feel okay.
Consider this code:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(message);
That's invalid code. Because neither of the variables named message is visible outside of their respective scope - which would be the surrounding brackets {} in this case.
You might say: "But a variable named message is defined either way - so message is defined after the if".
But you'd be wrong.
Java has no free() or delete operators, so it has to rely on tracking variable scope to find out when variables are no longer used (together with references to these variables of cause).
It's especially bad if you thought you did something good. I've seen this kind of error after "optimizing" code like this:
if(somethingIsTrue()) {
String message = "Everything is fine";
System.out.println(message);
} else {
String message = "We have an error";
System.out.println(message);
}
"Oh, there's duplicated code, let's pull that common line out" -> and there it it.
The most common way to deal with this kind of scope-trouble would be to pre-assign the else-values to the variable names in the outside scope and then reassign in if:
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
SOLVED
Using IntelliJ
Select Build->Rebuild Project will solve it
One way to get this error in Eclipse :
Define a class A in src/test/java.
Define another class B in src/main/java that uses class A.
Result : Eclipse will compile the code, but maven will give "Cannot find symbol".
Underlying cause : Eclipse is using a combined build path for the main and test trees. Unfortunately, it does not support using different build paths for different parts of an Eclipse project, which is what Maven requires.
Solution :
Don't define your dependencies that way; i.e. don't make this mistake.
Regularly build your codebase using Maven so that you pick up this mistake early. One way to do that is to use a CI server.
"Can not find " means that , compiler who can't find appropriate variable, method ,class etc...if you got that error massage , first of all you want to find code line where get error massage..And then you will able to find which variable , method or class have not define before using it.After confirmation initialize that variable ,method or class can be used for later require...Consider the following example.
I'll create a demo class and print a name...
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
Now look at the result..
That error says, "variable name can not find"..Defining and initializing value for 'name' variable can be abolished that error..Actually like this,
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
Now look at the new output...
Ok Successfully solved that error..At the same time , if you could get "can not find method " or "can not find class" something , At first,define a class or method and after use that..
If you're getting this error in the build somewhere else, while your IDE says everything is perfectly fine, then check that you are using the same Java versions in both places.
For example, Java 7 and Java 8 have different APIs, so calling a non-existent API in an older Java version would cause this error.
There can be various scenarios as people have mentioned above. A couple of things which have helped me resolve this.
If you are using IntelliJ
File -> 'Invalidate Caches/Restart'
OR
The class being referenced was in another project and that dependency was not added to the Gradle build file of my project. So I added the dependency using
compile project(':anotherProject')
and it worked. HTH!
If eclipse Java build path is mapped to 7, 8 and in Project pom.xml Maven properties java.version is mentioned higher Java version(9,10,11, etc..,) than 7,8 you need to update in pom.xml file.
In Eclipse if Java is mapped to Java version 11 and in pom.xml it is mapped to Java version 8. Update Eclipse support to Java 11 by go through below steps in eclipse IDE
Help -> Install New Software ->
Paste following link http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With
or
Add (Popup window will open) ->
Name: Java 11 support
Location: http://download.eclipse.org/eclipse/updates/4.9-P-builds
then update Java version in Maven properties of pom.xml file as below
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
Finally do right click on project Debug as -> Maven clean, Maven build steps
I too was getting this error. (for which I googled and I was directed to this page)
Problem: I was calling a static method defined in the class of a project A from a class defined in another project B.
I was getting the following error:
error: cannot find symbol
Solution: I resolved this by first building the project where the method is defined then the project where the method was being called from.
you compiled your code using maven compile and then used maven test to run it worked fine. Now if you changed something in your code and then without compiling you are running it, you will get this error.
Solution: Again compile it and then run test. For me it worked this way.
In my case - I had to perform below operations:
Move context.xml file from src/java/package to the resource directory (IntelliJ
IDE)
Clean target directory.
For hints, look closer at the class name name that throws an error and the line number, example:
Compilation failure
[ERROR] \applications\xxxxx.java:[44,30] error: cannot find symbol
One other cause is unsupported method of for java version say jdk7 vs 8.
Check your %JAVA_HOME%
We got the error in a Java project that is set up as a Gradle multi-project build. It turned out that one of the sub-projects was missing the Gradle Java Library plugin.
This prevented the sub-project's class files from being visible to other projects in the build.
After adding the Java library plugin to the sub-project's build.gradle in the following way, the error went away:
plugins {
...
id 'java-library'
}
Re: 4.4: An earlier build problem in Stephen C's excellent answer:
I encountered this scenario when developing an osgi application.
I had a java project A that was a dependency of B.
When building B, there was the error:
Compilation failure: org.company.projectA.bar.xyz does not exist
But in eclipse, there was no compile problem at all.
Investigation
When i looked in A.jar, there were classes for org.company.projectA.foo.abc but none for org.company.projectA.bar.xyz.
The reason for the missing classes, was that in the A/pom.xml, was an entry to export the relevant packages.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
...
<configuration>
<instructions>
....
<Export-Package>org.company.projectA.foo.*</Export-Package>
</instructions>
</configuration>
</plugin>
Solution
Add the missing packages like so:
<Export-Package>org.company.projectA.foo.*,org.company.projectA.bar.*</Export-Package>
and rebuild everything.
Now the A.jar includes all the expected classes, and everything compiles.
I was getting below error
java: cannot find symbol
symbol: class __
To fix this
I tried enabling lambok, restarted intellij, etc but below worked for me.
Intellij Preferences ->Compiler -> Shared Build process VM Options and set it to
-Djps.track.ap.dependencies=false
than run
mvn clean install
Optional.isEmpty()
I was happily using !Optional.isEmpty() in my IDE, and it works fine, as i was compiling/running my project with >= JDK11. Now, when i use Gradle on the command line (running on JDK8), i got the nasty error in the compile task.
Why?
From the docs (Pay attention to the last line):
boolean java.util.Optional.isEmpty()
If a value is not present, returns true, otherwise false.
Returns:true if a value is not present, otherwise false
Since:11
I solved this error like this... The craziness of android. I had the package name as Adapter and the I refactor the name to adapter with an "a" instead of "A" and solved the error.

i'm getting an error while executing this java awt code...can anyone help me with those errors [duplicate]

Please explain the following about "Cannot find symbol", "Cannot resolve symbol" or "Symbol not found" errors (in Java):
What do they mean?
What things can cause them?
How does the programmer go about fixing them?
This question is designed to seed a comprehensive Q&A about these common compilation errors in Java.
0. Is there any difference between these errors?
Not really. "Cannot find symbol", "Cannot resolve symbol" and "Symbol not found" all mean the same thing. (Different Java compilers are written by different people, and different people use different phraseology to say the same thing.)
1. What does a "Cannot find symbol" error mean?
Firstly, it is a compilation error1. It means that either there is a problem in your Java source code, or there is a problem in the way that you are compiling it.
Your Java source code consists of the following things:
Keywords: like class, while, and so on.
Literals: like true, false, 42, 'X' and "Hi mum!".
Operators and other non-alphanumeric tokens: like +, =, {, and so on.
Identifiers: like Reader, i, toString, processEquibalancedElephants, and so on.
Comments and whitespace.
A "Cannot find symbol" error is about the identifiers. When your code is compiled, the compiler needs to work out what each and every identifier in your code means.
A "Cannot find symbol" error means that the compiler cannot do this. Your code appears to be referring to something that the compiler doesn't understand.
2. What can cause a "Cannot find symbol" error?
As a first order, there is only one cause. The compiler looked in all of the places where the identifier should be defined, and it couldn't find the definition. This could be caused by a number of things. The common ones are as follows:
For identifiers in general:
Perhaps you spelled the name incorrectly; i.e. StringBiulder instead of StringBuilder. Java cannot and will not attempt to compensate for bad spelling or typing errors.
Perhaps you got the case wrong; i.e. stringBuilder instead of StringBuilder. All Java identifiers are case sensitive.
Perhaps you used underscores inappropriately; i.e. mystring and my_string are different. (If you stick to the Java style rules, you will be largely protected from this mistake ...)
Perhaps you are trying to use something that was declared "somewhere else"; i.e. in a different context to where you have implicitly told the compiler to look. (A different class? A different scope? A different package? A different code-base?)
For identifiers that should refer to variables:
Perhaps you forgot to declare the variable.
Perhaps the variable declaration is out of scope at the point you tried to use it. (See example below)
For identifiers that should be method or field names:
Perhaps you are trying to refer to an inherited method or field that wasn't declared in the parent / ancestor classes or interfaces.
Perhaps you are trying to refer to a method or field that does not exist (i.e. has not been declared) in the type you are using; e.g. "rope".push()2.
Perhaps you are trying to use a method as a field, or vice versa; e.g. "rope".length or someArray.length().
Perhaps you are mistakenly operating on an array rather than array element; e.g.
String strings[] = ...
if (strings.charAt(3)) { ... }
// maybe that should be 'strings[0].charAt(3)'
For identifiers that should be class names:
Perhaps you forgot to import the class.
Perhaps you used "star" imports, but the class isn't defined in any of the packages that you imported.
Perhaps you forgot a new as in:
String s = String(); // should be 'new String()'
Perhaps you are trying to import or otherwise use a class that has been declared in the default package; i.e. the one where classes with no package statements go.
Hint: learn about packages. You should only use the default package for simple applications that consist of one class ... or at a stretch, one Java source file.
For cases where type or instance doesn't appear to have the member (e.g. method or field) you were expecting it to have:
Perhaps you have declared a nested class or a generic parameter that shadows the type you were meaning to use.
Perhaps you are shadowing a static or instance variable.
Perhaps you imported the wrong type; e.g. due to IDE completion or auto-correction may have suggested java.awt.List rather than java.util.List.
Perhaps you are using (compiling against) the wrong version of an API.
Perhaps you forgot to cast your object to an appropriate subclass.
Perhaps you have declared the variable's type to be a supertype of the one with the member you are looking for.
The problem is often a combination of the above. For example, maybe you "star" imported java.io.* and then tried to use the Files class ... which is in java.nio not java.io. Or maybe you meant to write File ... which is a class in java.io.
Here is an example of how incorrect variable scoping can lead to a "Cannot find symbol" error:
List<String> strings = ...
for (int i = 0; i < strings.size(); i++) {
if (strings.get(i).equalsIgnoreCase("fnord")) {
break;
}
}
if (i < strings.size()) {
...
}
This will give a "Cannot find symbol" error for i in the if statement. Though we previously declared i, that declaration is only in scope for the for statement and its body. The reference to i in the if statement cannot see that declaration of i. It is out of scope.
(An appropriate correction here might be to move the if statement inside the loop, or to declare i before the start of the loop.)
Here is an example that causes puzzlement where a typo leads to a seemingly inexplicable "Cannot find symbol" error:
for (int i = 0; i < 100; i++); {
System.out.println("i is " + i);
}
This will give you a compilation error in the println call saying that i cannot be found. But (I hear you say) I did declare it!
The problem is the sneaky semicolon ( ; ) before the {. The Java language syntax defines a semicolon in that context to be an empty statement. The empty statement then becomes the body of the for loop. So that code actually means this:
for (int i = 0; i < 100; i++);
// The previous and following are separate statements!!
{
System.out.println("i is " + i);
}
The { ... } block is NOT the body of the for loop, and therefore the previous declaration of i in the for statement is out of scope in the block.
Here is another example of "Cannot find symbol" error that is caused by a typo.
int tmp = ...
int res = tmp(a + b);
Despite the previous declaration, the tmp in the tmp(...) expression is erroneous. The compiler will look for a method called tmp, and won't find one. The previously declared tmp is in the namespace for variables, not the namespace for methods.
In the example I came across, the programmer had actually left out an operator. What he meant to write was this:
int res = tmp * (a + b);
There is another reason why the compiler might not find a symbol if you are compiling from the command line. You might simply have forgotten to compile or recompile some other class. For example, if you have classes Foo and Bar where Foo uses Bar. If you have never compiled Bar and you run javac Foo.java, you are liable to find that the compiler can't find the symbol Bar. The simple answer is to compile Foo and Bar together; e.g. javac Foo.java Bar.java or javac *.java. Or better still use a Java build tool; e.g. Ant, Maven, Gradle and so on.
There are some other more obscure causes too ... which I will deal with below.
3. How do I fix these errors ?
Generally speaking, you start out by figuring out what caused the compilation error.
Look at the line in the file indicated by the compilation error message.
Identify which symbol that the error message is talking about.
Figure out why the compiler is saying that it cannot find the symbol; see above!
Then you think about what your code is supposed to be saying. Then finally you work out what correction you need to make to your source code to do what you want.
Note that not every "correction" is correct. Consider this:
for (int i = 1; i < 10; i++) {
for (j = 1; j < 10; j++) {
...
}
}
Suppose that the compiler says "Cannot find symbol" for j. There are many ways I could "fix" that:
I could change the inner for to for (int j = 1; j < 10; j++) - probably correct.
I could add a declaration for j before the inner for loop, or the outer for loop - possibly correct.
I could change j to i in the inner for loop - probably wrong!
and so on.
The point is that you need to understand what your code is trying to do in order to find the right fix.
4. Obscure causes
Here are a couple of cases where the "Cannot find symbol" is seemingly inexplicable ... until you look closer.
Incorrect dependencies: If you are using an IDE or a build tool that manages the build path and project dependencies, you may have made a mistake with the dependencies; e.g. left out a dependency, or selected the wrong version. If you are using a build tool (Ant, Maven, Gradle, etc), check the project's build file. If you are using an IDE, check the project's build path configuration.
Cannot find symbol 'var': You are probably trying to compile source code that uses local variable type inference (i.e. a var declaration) with an older compiler or older --source level. The var was introduced in Java 10. Check your JDK version and your build files, and (if this occurs in an IDE), the IDE settings.
You are not compiling / recompiling: It sometimes happens that new Java programmers don't understand how the Java tool chain works, or haven't implemented a repeatable "build process"; e.g. using an IDE, Ant, Maven, Gradle and so on. In such a situation, the programmer can end up chasing his tail looking for an illusory error that is actually caused by not recompiling the code properly, and the like.
Another example of this is when you use (Java 9+) java SomeClass.java to compile and run a class. If the class depends on another class that you haven't compiled (or recompiled), you are liable to get "Cannot resolve symbol" errors referring to the 2nd class. The other source file(s) are not automatically compiled. The java command's new "compile and run" mode is not designed for running programs with multiple source code files.
An earlier build problem: It is possible that an earlier build failed in a way that gave a JAR file with missing classes. Such a failure would typically be noticed if you were using a build tool. However if you are getting JAR files from someone else, you are dependent on them building properly, and noticing errors. If you suspect this, use tar -tvf to list the contents of the suspect JAR file.
IDE issues: People have reported cases where their IDE gets confused and the compiler in the IDE cannot find a class that exists ... or the reverse situation.
This could happen if the IDE has been configured with the wrong JDK version.
This could happen if the IDE's caches get out of sync with the file system. There are IDE specific ways to fix that.
This could be an IDE bug. For instance #Joel Costigliola described a scenario where Eclipse did not handle a Maven "test" tree correctly: see this answer. (Apparently that particular bug was been fixed a long time ago.)
Android issues: When you are programming for Android, and you have "Cannot find symbol" errors related to R, be aware that the R symbols are defined by the context.xml file. Check that your context.xml file is correct and in the correct place, and that the corresponding R class file has been generated / compiled. Note that the Java symbols are case sensitive, so the corresponding XML ids are be case sensitive too.
Other symbol errors on Android are likely to be due to previously mention reasons; e.g. missing or incorrect dependencies, incorrect package names, method or fields that don't exist in a particular API version, spelling / typing errors, and so on.
Hiding system classes: I've seen cases where the compiler complains that substring is an unknown symbol in something like the following
String s = ...
String s1 = s.substring(1);
It turned out that the programmer had created their own version of String and that his version of the class didn't define a substring methods. I've seen people do this with System, Scanner and other classes.
Lesson: Don't define your own classes with the same names as common library classes!
The problem can also be solved by using the fully qualified names. For example, in the example above, the programmer could have written:
java.lang.String s = ...
java.lang.String s1 = s.substring(1);
Homoglyphs: If you use UTF-8 encoding for your source files, it is possible to have identifiers that look the same, but are in fact different because they contain homoglyphs. See this page for more information.
You can avoid this by restricting yourself to ASCII or Latin-1 as the source file encoding, and using Java \uxxxx escapes for other characters.
1 - If, perchance, you do see this in a runtime exception or error message, then either you have configured your IDE to run code with compilation errors, or your application is generating and compiling code .. at runtime.
2 - The three basic principles of Civil Engineering: water doesn't flow uphill, a plank is stronger on its side, and you can't push on a rope.
You'll also get this error if you forget a new:
String s = String();
versus
String s = new String();
because the call without the new keyword will try and look for a (local) method called String without arguments - and that method signature is likely not defined.
One more example of 'Variable is out of scope'
As I've seen that kind of questions a few times already, maybe one more example to what's illegal even if it might feel okay.
Consider this code:
if(somethingIsTrue()) {
String message = "Everything is fine";
} else {
String message = "We have an error";
}
System.out.println(message);
That's invalid code. Because neither of the variables named message is visible outside of their respective scope - which would be the surrounding brackets {} in this case.
You might say: "But a variable named message is defined either way - so message is defined after the if".
But you'd be wrong.
Java has no free() or delete operators, so it has to rely on tracking variable scope to find out when variables are no longer used (together with references to these variables of cause).
It's especially bad if you thought you did something good. I've seen this kind of error after "optimizing" code like this:
if(somethingIsTrue()) {
String message = "Everything is fine";
System.out.println(message);
} else {
String message = "We have an error";
System.out.println(message);
}
"Oh, there's duplicated code, let's pull that common line out" -> and there it it.
The most common way to deal with this kind of scope-trouble would be to pre-assign the else-values to the variable names in the outside scope and then reassign in if:
String message = "We have an error";
if(somethingIsTrue()) {
message = "Everything is fine";
}
System.out.println(message);
SOLVED
Using IntelliJ
Select Build->Rebuild Project will solve it
One way to get this error in Eclipse :
Define a class A in src/test/java.
Define another class B in src/main/java that uses class A.
Result : Eclipse will compile the code, but maven will give "Cannot find symbol".
Underlying cause : Eclipse is using a combined build path for the main and test trees. Unfortunately, it does not support using different build paths for different parts of an Eclipse project, which is what Maven requires.
Solution :
Don't define your dependencies that way; i.e. don't make this mistake.
Regularly build your codebase using Maven so that you pick up this mistake early. One way to do that is to use a CI server.
"Can not find " means that , compiler who can't find appropriate variable, method ,class etc...if you got that error massage , first of all you want to find code line where get error massage..And then you will able to find which variable , method or class have not define before using it.After confirmation initialize that variable ,method or class can be used for later require...Consider the following example.
I'll create a demo class and print a name...
class demo{
public static void main(String a[]){
System.out.print(name);
}
}
Now look at the result..
That error says, "variable name can not find"..Defining and initializing value for 'name' variable can be abolished that error..Actually like this,
class demo{
public static void main(String a[]){
String name="smith";
System.out.print(name);
}
}
Now look at the new output...
Ok Successfully solved that error..At the same time , if you could get "can not find method " or "can not find class" something , At first,define a class or method and after use that..
If you're getting this error in the build somewhere else, while your IDE says everything is perfectly fine, then check that you are using the same Java versions in both places.
For example, Java 7 and Java 8 have different APIs, so calling a non-existent API in an older Java version would cause this error.
There can be various scenarios as people have mentioned above. A couple of things which have helped me resolve this.
If you are using IntelliJ
File -> 'Invalidate Caches/Restart'
OR
The class being referenced was in another project and that dependency was not added to the Gradle build file of my project. So I added the dependency using
compile project(':anotherProject')
and it worked. HTH!
If eclipse Java build path is mapped to 7, 8 and in Project pom.xml Maven properties java.version is mentioned higher Java version(9,10,11, etc..,) than 7,8 you need to update in pom.xml file.
In Eclipse if Java is mapped to Java version 11 and in pom.xml it is mapped to Java version 8. Update Eclipse support to Java 11 by go through below steps in eclipse IDE
Help -> Install New Software ->
Paste following link http://download.eclipse.org/eclipse/updates/4.9-P-builds at Work With
or
Add (Popup window will open) ->
Name: Java 11 support
Location: http://download.eclipse.org/eclipse/updates/4.9-P-builds
then update Java version in Maven properties of pom.xml file as below
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
Finally do right click on project Debug as -> Maven clean, Maven build steps
I too was getting this error. (for which I googled and I was directed to this page)
Problem: I was calling a static method defined in the class of a project A from a class defined in another project B.
I was getting the following error:
error: cannot find symbol
Solution: I resolved this by first building the project where the method is defined then the project where the method was being called from.
you compiled your code using maven compile and then used maven test to run it worked fine. Now if you changed something in your code and then without compiling you are running it, you will get this error.
Solution: Again compile it and then run test. For me it worked this way.
In my case - I had to perform below operations:
Move context.xml file from src/java/package to the resource directory (IntelliJ
IDE)
Clean target directory.
For hints, look closer at the class name name that throws an error and the line number, example:
Compilation failure
[ERROR] \applications\xxxxx.java:[44,30] error: cannot find symbol
One other cause is unsupported method of for java version say jdk7 vs 8.
Check your %JAVA_HOME%
We got the error in a Java project that is set up as a Gradle multi-project build. It turned out that one of the sub-projects was missing the Gradle Java Library plugin.
This prevented the sub-project's class files from being visible to other projects in the build.
After adding the Java library plugin to the sub-project's build.gradle in the following way, the error went away:
plugins {
...
id 'java-library'
}
Re: 4.4: An earlier build problem in Stephen C's excellent answer:
I encountered this scenario when developing an osgi application.
I had a java project A that was a dependency of B.
When building B, there was the error:
Compilation failure: org.company.projectA.bar.xyz does not exist
But in eclipse, there was no compile problem at all.
Investigation
When i looked in A.jar, there were classes for org.company.projectA.foo.abc but none for org.company.projectA.bar.xyz.
The reason for the missing classes, was that in the A/pom.xml, was an entry to export the relevant packages.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
...
<configuration>
<instructions>
....
<Export-Package>org.company.projectA.foo.*</Export-Package>
</instructions>
</configuration>
</plugin>
Solution
Add the missing packages like so:
<Export-Package>org.company.projectA.foo.*,org.company.projectA.bar.*</Export-Package>
and rebuild everything.
Now the A.jar includes all the expected classes, and everything compiles.
I was getting below error
java: cannot find symbol
symbol: class __
To fix this
I tried enabling lambok, restarted intellij, etc but below worked for me.
Intellij Preferences ->Compiler -> Shared Build process VM Options and set it to
-Djps.track.ap.dependencies=false
than run
mvn clean install
Optional.isEmpty()
I was happily using !Optional.isEmpty() in my IDE, and it works fine, as i was compiling/running my project with >= JDK11. Now, when i use Gradle on the command line (running on JDK8), i got the nasty error in the compile task.
Why?
From the docs (Pay attention to the last line):
boolean java.util.Optional.isEmpty()
If a value is not present, returns true, otherwise false.
Returns:true if a value is not present, otherwise false
Since:11
I solved this error like this... The craziness of android. I had the package name as Adapter and the I refactor the name to adapter with an "a" instead of "A" and solved the error.

It is right thing to ignore warning in proguard android

I started learning Proguard for android. After a bit of reading, i start trying to use in my project. When i start generating release build, i see lots of warnings and notes in android studio terminal. I know it totally depends on my code base and third party libraries i used.
My Questions
I don't understand what these warning trying to say? But build will fail for sure and will not able to generate apk file.
Surprisingly adding -dontwarn packagename* will ignore these warnings but again not sure it is safe thing to do. Is it always feasible to simply ignore those warning just by adding -dontwarn ?
-dontwarn [class_filter]
Specifies not to warn about unresolved references and other important problems at all. The optional filter is
a regular expression; ProGuard doesn't print warnings about classes
with matching names. Ignoring warnings can be dangerous. For instance,
if the unresolved classes or class members are indeed required for
processing, the processed code will not function properly. Only use
this option if you know what you're doing!
Well definitely at this point, i don't really know what i am doing. I would be very much appreciate if you could help me understand ;-) .
Retrofit2 warnings from my current project
Warning: retrofit2.OkHttpCall: can't find referenced class javax.annotation.concurrent.GuardedBy
Warning: retrofit2.OkHttpCall:can't find referenced class javax.annotation.concurrent.GuardedBy
Warning: retrofit2.OkHttpCall: can't find referenced class javax.annotation.concurrent.GuardedBy
Simply turn off above warning by adding this line in proguard-rules.pro
-dontwarn retrofit2.**
So basically the Proguard maps your code or performs the code obfuscation, shrinking, optimization removes unused code...etc while performing the same, sometimes it finds many classes which are used either in import statement or some where else but those class are not actually present inside the package, so it generates the warnings as Proguard is not able to get the reference for some classes. Optimization operates with Java bytecode, though, and since Android runs on Dalvik bytecode which is converted from Java bytecode, some optimizations won't work so well. So you should be careful there.
So in dont warn we simply ignores those files to go through the proguard operations.
Hope this is enough information for you.

Eclipse complaining about Javadoc even after Disabling javadoc in compiler options, and inconsistent

I've got some open source code using the {#Code annotation that Eclipse is complaining about. Since I don't care I turned off Javadoc in the compiler options, but it's still complaining and will not compile compile.
Error is: "Javadoc: Missing closing brace for inline tag"
Actually the closing brace IS present. In some cases it's just a few lines down, but in others it's even on the same line!
Even stranger: The same code in a smaller project in a different workspace works OK. I've compared the 2 projects' settings a couple times and they appear to be the same. In many cases options are set to not allow project specific settings.
I also did other things like doing a project clean, and trying Java 1.5 vs. 1.7 compiler options, etc.
Other details:
Java 7 on Mac
Eclipse Kepler
Code is Guice 2.0 (I know that's old, and normally should use jar, long story)
one example is Key.java line 107, see below
Example from Guice code (though I normally wouldn't care since it's just comments)
/**
...
* <p>{#code new Key<Foo>() {}}.
#code tag has a few caveats (see: Multiple line code example in Javadoc comment)... One of which is that you need to avoid mixing tag braces and actual content braces in the same line.
With that in mind I would rewrite the Javadoc as:
<p><pre><code>new Key{#literal<Foo>}(){}</code><pre>.</p>
You could also use #code to prevent <Foo> from being interpreted as a HTML tag.
I'm using #literal since the contents are already wrapped with a <code> tag. The <pre> tag is used to retain spaces and line breaks.
About Javadoc configuration, if you want to sweep the dirt under the rug, go to:
Windows -> Preferences -> Java -> Compiler -> Javadoc
And set Malformed Javadoc comments to Ignore. Apply, rebuild and you should be ready to go
(also make sure that specific project settings under Project -> Properties-> Java Compiler -> Javadoc are not messing up the setup).

Eclipse / conditional breakpoint results in BreakpointException

I want to debug a static inner class, which is actually a Callable. Whenever I try to set a conditional breakpoint in Eclipse I get the breakpoint error:
The type com.sun.source.tree.Tree$Kind cannot be resolved. It is
indirectly referenced from required .class files.
What is causing this error? Is it a bug in the class/package that uses com.sun.source.tree.Tree$Kind but does not provide it? How do I find out which class it is? How do I resolve it?
An example expression which should be correct is: return mRtx.getNode().getNodeKey() == 74;
I have changed it to mRtx.getNode().getNodeKey() == 74 but still the same error. Recently I've found the bug and simply used:
if (mRtx.getNode().getNodeKey() == 74) {
System.out.println("bla");
}
and set a "normal" breakpoint on the "sysout" statement just in case someone has the same problem.
I am not sure on how I would reproduce it as your description is not exactly telling much.
The com.sun.source.tree package is included in tools.jar, which is part of JDK but not of JRE, so make sure you run your Eclipse in JDK (JAVA_HOME variable?), maybe try setting projects JRE to a JDK folder.
I also think that the Compiler API was introduced in Java 6, so check if you are not using a lower version.
Maybe you should try to edit the debugger's source lookup.
To do this, go to debug perspective, in the debug view (where the stack is normally shown) right click on the terminated run, and choose 'Edit Source Lookup...'.
Then you can add a lookup place. In this case you should maybe add the tools.jar that is in the jre folder.
The compiler can't find the type, that is the root issue, but in my thinking, this should only be a compile time error, but by implication from what I read, it's a run time error. Is that correct?
Here is are some tips:
http://java.syntaxerrors.info/index.php?title=Cannot_resolve_type
Indirectly referenced from required .class file
Maybe you could post more code or use "control + T" in Eclipse on the class to look at the type hierarchy, I would like to know what other classes are referenced.
HTH,
James

Categories

Resources