Please explain the following about "Cannot find symbol" and "Cannot resolve symbol" errors:
- What does 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.
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 supportLocation:
http://download.eclipse.org/eclipse/updates/4.9-P-buildsthen update Java version in Maven properties of pom.xml file as below
Finally do right click on project Debug as -> Maven clean, Maven build steps
0. Is there any difference between the two errors?
Not really. "Cannot find symbol" and "Cannot resolve symbol" mean the same thing. Some Java compilers use one phrase, and some the other one.
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:
true
,false
,class
,while
, and so on.42
and'X'
and"Hi mum!"
.+
,=
,{
, and so on.Reader
,i
,toString
,processEquibalancedElephants
, and so on.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:
StringBiulder
instead ofStringBuilder
. Java cannot and will not attempt to compensate for bad spelling or typing errors.stringBuilder
instead ofStringBuilder
. All Java identifiers are case sensitive.mystring
andmy_string
are different. (If you stick to the Java style rules, you will be largely protected from this mistake ...)For identifiers that should be method or field names:
"someString".push()
2."someString".length
orsomeArray.length()
.Perhaps you are mistakenly operating on an array rather than array element; e.g.
For identifiers that should be class names:
Perhaps you forgot a
new
as in:For cases where type or instance doesn't appear to have the member you were expecting it to have:
The problem is often a combination of the above. For example, maybe you "star" imported
java.io.*
and then tried to use theFiles
class ... which is injava.nio
notjava.io
. Or maybe you meant to writeFile
... which is a class injava.io
.Here is an example of how incorrect variable scoping can lead to a "Cannot find symbol" error:
This will give a "Cannot find symbol" error for
i
in theif
statement. Though we previously declaredi
, that declaration is only in scope for thefor
statement and its body. The reference toi
in theif
statement cannot see that declaration ofi
. It is out of scope.(An appropriate correction here might be to move the
if
statement inside the loop, or to declarei
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:
This will give you a compilation error in the
println
call saying thati
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 thefor
loop. So that code actually means this:The
{ ... }
block is NOT the body of thefor
loop, and therefore the previous declaration ofi
in thefor
statement is out of scope in the block.Here is another example of "Cannot find symbol" error that is caused by a typo.
Despite the previous declaration, the
tmp
in thetmp(...)
expression is erroneous. The compiler will look for a method calledtmp
, and won't find one. The previously declaredtmp
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:
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
andBar
whereFoo
usesBar
. If you have never compiledBar
and you runjavac Foo.java
, you are liable to find that the compiler can't find the symbolBar
. The simple answer is to compileFoo
andBar
together; e.g.javac Foo.java Bar.java
orjavac *.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.
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:
Suppose that the compiler says "Cannot find symbol" for
j
. There are many ways I could "fix" that:for
tofor (int j = 1; j < 10; j++)
- probably correct.j
before the innerfor
loop, or the outerfor
loop - possibly correct.j
toi
in the innerfor
loop - probably wrong!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.
You are not 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 ...
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 describes a scenario where Eclipse does not handle a Maven "test" tree correctly: see this answer.
Android issues: When you are programming for Android, and you have "Cannot find symbol" errors related to
R
, be aware that theR
symbols are defined by thecontext.xml
file. Check that yourcontext.xml
file is correct and in the correct place, and that the correspondingR
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.
Redefining system classes: I've seen cases where the compiler complains that
substring
is an unknown symbol in something like the followingIt turned out that the programmer had created their own version of
String
and that his version of the class didn't define asubstring
methods.Lesson: Don't define your own classes with the same names as common library classes!
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 string.
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:
context.xml
file fromsrc/java/package
to theresource
directory (IntelliJ IDE)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%
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.