I’m a C++ developer — not a java developer, but have to get this code working…
I have 2 public classes that will be used by another product. I used the package directive in each of the java files.
package com.company.thing;
class MyClass ...
When I try to compile a test app that uses that I add
import com.company.thing.*;
The javac compiler fails with errors about com.company does not exist. (even if I compile it in the same directory as the class files I just made a package of)
I am sure I am doing something bone-headed and silly.
I’ve read the http://java.sun.com/docs/books/tutorial/java/package/usepkgs.html pages and tried to set up a directory structure like /com/company/thing etc, but either I have totally screwed it all up or am missing something else.
EDIT
thanks for the suggestions — I had tried the classpath previously. It does not help.
I tried compiling
javac -classpath <parent> client.java
and the result is:
package com.company does not exist
I have the code I want to import (the two java files) in comcompanyproduct. I compile those fine. (they contain MyClass) I even made a jar file for them. I copied the jar file up to the parent directory.
I then did (in the parent directory with the client java file)
javac -cp <jarfile> *.java
the result is:
cannot access MyClass
bad class file: MyClass.class(:MyClass.class)
class file contains wrong class: com.company.product.MyClass
Please remove or make sure it appears in the correct subdirectory of the classpath.
EDIT
I got the client code to compile and run if I used the fully qualified name for MyClass and compiled it in the parent directory. I am totally confused now.
compiled with no classpath set — just
javac *.java
in the parent directory — and it worked fine.
I can get a test app to compile, but that is not going to cut it when i have to integrate it into the production code. Still looking for help.
EDIT:
Finally — not sure why it didn’t work before — but I cleaned up all the files all over the directory structure and now it works.
Thanks
The following code compiles and runs correctly.
import java.util.*;
import java.io.*;
class Scanner {
public Scanner(InputStream in) {
}
}
public class Foo{
public static void main(String[] args) {
java.util.Scanner in = new java.util.Scanner(System.in);
System.out.println(in.getClass());
Scanner in2 = new Scanner(System.in);
System.out.println(in2.getClass());
}
}
However, if I change import java.util.*;
to import java.util.Scanner;
, I will get the following compiler error.
Foo.java:1: error: Scanner is already defined in this compilation unit
It seems that in both cases, the compiler should be able to disambiguate equally well, so why does it only complain in the second case?
asked Mar 27, 2014 at 4:48
merlin2011merlin2011
71k44 gold badges192 silver badges325 bronze badges
4
This will happen because you already have a local class named Scanner. You will need to call it with its fully qualified name:
java.util.Scanner scan = new java.util.Scanner(System.in);
Additionally, make your Scanner
a nested static class:
public class Foo {
private static class Scanner {
public Scanner(InputStream in) {
}
}
public static void main(String[] args) {
java.util.Scanner in = new java.util.Scanner(System.in);
System.out.println(in.getClass());
Scanner in2 = new Scanner(System.in);
System.out.println(in2.getClass());
}
}
Why this happens
An import
simply tells the compiler where to look for symbols upon compile time. I don’t remember the stage off the top of my head (Preprocessing/compilation), but package imports are not explicit declarations of those class members. By saying import foo.bar.*
, you are saying «Look in this package directory for Symbols upon compiling», whereas import foo.bar.Scanner
is saying «Point Scanner
symbols to this».
In short, a specific import is apparent that you have a symbol for «Scanner», whereas a package import does not specify this specific relation to a symbol.
answered Mar 27, 2014 at 4:53
RogueRogue
11k5 gold badges45 silver badges71 bronze badges
5
Why import java.util.*
doesn’t give error??
It will not throw error because there is no confusion about the class «java.util.Scanner
» and your class Scanner
.
When you use import as java.util.Scanner
, it conflicts with your class name with the Scanner
in the util
.
And that is the reason for error.
answered Mar 27, 2014 at 5:06
This collision of a single-type-import declaration with a top-level type declaration is described at JSL §7.5.1. Single-Type-Import Declarations:
If a single-type-import declaration imports a type whose simple name
is n, and the compilation unit also declares a top level type (§7.6)
whose simple name is n, a compile-time error occurs.
An example cited from §7.5.1
import java.util.Vector;
class Vector { Object[] vec; }
causes a compile-time error because of the duplicate declaration of Vector.
answered Mar 28, 2014 at 1:37
tenorsaxtenorsax
21.1k9 gold badges60 silver badges107 bronze badges
This happens when your java class name and importing library name is same. In your case Scanner is refer to the class name not for the library. Changing the class name to something else will be the simplest way to solve the error.
answered Oct 13, 2016 at 8:15
Изучаю java, скачал jar архив библиотеки opencsv пытаюсь его импортировать:
package Char2;
import java.io.FileReader;
import Char2.libs.opencsv.CSVReader;
class Ex13 {
public static void main(String[] args) {
CSVReader reader = new CSVReader(new FileReader("csv/t1.csv"));
String[] nextLn;
while((nextLn = reader.readNext()) != null) {
System.out.println(nextLn[0] + nextLn[1] + nextLn[2]);
}
}
}
Структура:
Char2/
….libs/
……..opencsv.jar
….Ex13.java
Запускаю из терминала: javac -cp Char2/libs/opencsv.jar Char2/ex13.java
При компиляции получаю ошибку:
Char2/ex13.java:5: error: package Char2.libs does not exist
import Char2.libs.*;
^
Char2/ex13.java:9: error: cannot find symbol
CSVReader reader = new CSVReader(new FileReader(«csv/t1.csv»));
^
symbol: class CSVReader
location: class Ex13
Char2/ex13.java:9: error: cannot find symbol
CSVReader reader = new CSVReader(new FileReader(«csv/t1.csv»));
^
symbol: class CSVReader
location: class Ex13
3 errors
Не могу понять что я делаю не так, скорее всего просто не до конца понимаю classpath…
Introduction to Symbol Tables
Symbol tables are an important data structure created and maintained by compilers to store information associated with identifiers [1] in a given source code. This information is entered into the symbol tables during lexical and syntax analysis and is used in the later phases of compilation. As the declarations of classes, interfaces, variables, and methods are processed, their identifiers are bound to corresponding entries in the symbol tables. When uses of these identifiers are encountered in the source code, the compiler looks them up in the symbol tables and relies on this information for things such as verifying that a variable has been declared, determining the scope of a variable, and verifying that an expression is semantically correct with type checking. Symbol tables are also used for code generation and optimization [2].
A simplified representation of a symbol table entry (or simply, a symbol) in Java has the following format: <symbol name (identifier), type, scope, [attributes]>
. Given a global variable declaration like final double ratio;
the corresponding symbol would then be <ratio, double, global, [final]>
.
Install the Java SDK to identify and fix exceptions
Cannot Find Symbol Error
As its name implies, the cannot find symbol
error refers to a symbol which cannot be found. While there are multiple ways and reasons this can occur, they all boil down to the fact that the Java compiler is unable to find the symbol associated with a given identifier.
The message produced by the compiler for the cannot find symbol
error includes two additional fields:
- “symbol”—the name and type of the referenced identifier; and
- “location”—the specific class in which the identifier has been referenced.
What Causes the Cannot Find Symbol Error
The most common triggers for the cannot find symbol
compile-time error include:
- missing variable and method declarations;
- out-of-scope references to variables and methods;
- misspelled identifiers; and
- omitted import statements.
Cannot Find Symbol vs Symbol Not Found vs Cannot Resolve Symbol
As different Java compilers use slightly different terminology, the cannot find symbol
error can also be found under the terms symbol not found
and cannot resolve symbol
. Besides the naming, there is no difference between what these terms stand for.
Cannot Find Symbol Error Examples
Undeclared variable
When the Java compiler encounters a use of an identifier which it cannot find in the symbol table, it raises the cannot find symbol
error. Consequently, the most common occurrence of this error is when there is a reference to an undeclared variable. Unlike some other languages that don’t require explicit declaration of variables [3], or may allow declaring a variable after it has been referenced (via hoisting [4]), Java requires declaring a variable before it can be used or referenced in any way.
Fig. 1(a) shows how an undeclared variable, in this case the identifier average
on line 9, results in two instances of the cannot find symbol
error, at the positions where they appear in the code. Declaring this variable by specifying its data type (or, alternatively, inferring its type with the var
keyword in Java 10+) resolves the issue (Fig. 1(b)).
(a)
1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;
public class UndeclaredVariable {
public static void main(String... args) {
int x = 6;
int y = 10;
int z = 32;
average = (x + y + z) / 3.0; // average is not declared
System.out.println(average);
}
}
UndeclaredVariable.java:9: error: cannot find symbol
average = (x + y + z) / 3.0;
^
symbol: variable average
location: class UndeclaredVariable
UndeclaredVariable.java:10: error: cannot find symbol
System.out.println(average);
^
symbol: variable average
location: class UndeclaredVariable
2 errors
(b)
1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;
public class UndeclaredVariable {
public static void main(String... args) {
int x = 6;
int y = 10;
int z = 32;
double average = (x + y + z) / 3.0;
System.out.println(average);
}
}
16.0
Out of scope variable
When a Java program tries to access a variable declared in a different (non-inherited or non-overlapping) scope, the compiler triggers the cannot find symbol
error. This is demonstrated by the attempt to access the variable counter
on lines 17 and 18 in Fig. 2(a), which is accessible only within the for
statement declared on line 11. Moving the counter
variable outside the for
loop fixes the issue, as shown on Fig. 2(b).
(a)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package rollbar;
import java.util.Arrays;
import java.util.List;
public class OutOfScopeVariable {
public static void main(String... args) {
final List<String> strings = Arrays.asList("Hello", "World");
final String searchFor = "World";
for (int counter = 0; counter < strings.size(); counter++) {
if (strings.get(counter).equals(searchFor)) {
break;
}
}
if (counter < strings.size()) {
System.out.println("The word " + searchFor + " was found at index " + counter);
} else {
System.out.println("The word " + searchFor + " wasn't found");
}
}
}
OutOfScopeVariable.java:17: error: cannot find symbol
if (counter < strings.size()) {
^
symbol: variable counter
location: class OutOfScopeVariable
OutOfScopeVariable.java:18: error: cannot find symbol
System.out.println("The word " + searchFor + " was found at index " + counter);
^
symbol: variable counter
location: class OutOfScopeVariable
2 errors
(b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package rollbar;
import java.util.Arrays;
import java.util.List;
public class OutOfScopeVariable {
public static void main(String... args) {
final List<String> strings = Arrays.asList("Hello", "World");
final String searchFor = "World";
int counter;
for (counter = 0; counter < strings.size(); counter++) {
if (strings.get(counter).equals(searchFor)) {
break;
}
}
if (counter < strings.size()) {
System.out.println("The word " + searchFor + " was found at index " + counter);
} else {
System.out.println("The word " + searchFor + " wasn't found");
}
}
}
The word ‘World’ was found at index 1
Misspelled method name
Misspelling an existing method, or any valid identifier, causes a cannot find symbol
error. Java identifiers are case-sensitive, so any variation of an existing variable, method, class, interface, or package name will result in this error, as demonstrated in Fig. 3.
(a)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;
public class MisspelledMethodName {
static int fibonacci(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String... args) {
int fib20 = Fibonacci(20); // Fibonacci ≠ fibonacci
System.out.println(fib20);
}
}
MisspelledMethodName.java:11: error: cannot find symbol
int fib20 = Fibonacci(20);
^
symbol: method Fibonacci(int)
location: class MisspelledMethodName
(b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;
public class MisspelledMethodName {
static int fibonacci(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String... args) {
int fib20 = fibonacci(20);
System.out.println(fib20);
}
}
6765
Missing import statement
Using classes, either from the Java platform or any library, requires importing them correctly with the import
statement. Failing to do so will result in the cannot find symbol
error being raised by the Java compiler. The code snippet in Fig. 4(a) makes use of the java.util.List
class without declaring the corresponding import, therefore the cannot find symbol
error occurs. Adding the missing import
statement (line 4 in Fig. 4(b)) solves the problem.
(a)
package rollbar;
import java.util.Arrays;
public class MissingImportList {
private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");
public static void main(String... args) {
System.out.println(CONSTANTS);
}
}
MissingImportList.java:6: error: cannot find symbol
private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");
^
symbol: class List
location: class MissingImportList
(b)
1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;
import java.util.Arrays;
import java.util.List;
public class MissingImportList {
private static final List<String> CONSTANTS = Arrays.asList("A", "B", "C");
public static void main(String... args) {
System.out.println(CONSTANTS);
}
}
[A, B, C]
Less common examples
The root cause for the cannot find symbol
Java error can occasionally be found in some unexpected or obscure places. Such is the case with accidental semicolons that terminate a statement ahead of time (Fig. 5), or when object creation is attempted without a proper constructor invocation which has to have the new
keyword (Fig. 6).
(a)
package rollbar;
public class LoopScope {
public static void main(String... args) {
int start = 1, end = 10;
for (int i = start; i <= end; i++); {
System.out.print(i == end ? i : i + ", ");
}
}
}
LoopScope.java:7: error: cannot find symbol
System.out.print(i == end ? i : i + ", ");
^
symbol: variable i
location: class LoopScope
LoopScope.java:7: error: cannot find symbol
System.out.print(i == end ? i : i + ", ");
^
symbol: variable i
location: class LoopScope
LoopScope.java:7: error: cannot find symbol
System.out.print(i == end ? i : i + ", ");
^
symbol: variable i
location: class LoopScope
3 errors
(b)
package rollbar;
public class LoopScope {
public static void main(String... args) {
int start = 1, end = 10;
for (int i = start; i <= end; i++) {
System.out.print(i == end ? i : i + ", ");
}
}
}
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
(a)
package rollbar;
public class ObjectCreation {
public static void main(String... args) {
String s = String("Hello World!");
System.out.println(s);
}
}
ObjectCreation.java:5: error: cannot find symbol
String s = String("Hello World!");
^
symbol: method String(String)
location: class ObjectCreation
(b)
package rollbar;
public class ObjectCreation {
public static void main(String... args) {
String s = new String("Hello World!");
System.out.println(s);
}
}
Hello World!
Other causes for the cannot find symbol
error may include:
- using dependencies with old or incompatible versions;
- forgetting to recompile a program;
- building a project with an older JDK version;
- redefining platform or library classes with the same name;
- the use of homoglyphs in identifier construction that are difficult to tell apart;
- etc.
Conclusion
The cannot find symbol
error, also found under the names of symbol not found
and cannot resolve symbol
, is a Java compile-time error which emerges whenever there is an identifier in the source code which the compiler is unable to work out what it refers to. As with any other compilation error, it is crucial to understand what causes this error, pinpoint the issue and address it properly. In the majority of cases, referencing undeclared variables and methods, including by way of misspelling them or failing to import their corresponding package, is what triggers this error. Once discovered, resolution is pretty straightforward, as demonstrated in this article.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!
References
[1] Rollbar, 2021. Handling the <Identifier> Expected Error in Java. Rollbar Editorial Team. [Online]. Available: https://rollbar.com/blog/how-to-handle-the-identifier-expected-error-in-java/. [Accessed Nov. 22, 2021].
[2] ITL Education Solutions Limited, Principles of Compiler Design (Express Learning), 1st ed. New Delhi: Pearson Education (India), 2012.
[3] Tutorialspoint.com, 2021. Python — Variable Types. [Online]. Available: https://www.tutorialspoint.com/python/python_variable_types.htm. [Accessed: Nov. 23, 2021].
[4] JavaScript Tutorial, 2021. JavaScript Hoisting Explained By Examples. [Online]. Available: https://www.javascripttutorial.net/javascript-hoisting/. [Accessed: Nov. 23, 2021]
Я разработчик С++, а не разработчик Java, но мне нужно заставить этот код работать…
У меня есть 2 общедоступных класса, которые будут использоваться другим продуктом. Я использовал директиву пакета в каждом из java файлов.
package com.company.thing;
class MyClass ...
Когда я пытаюсь скомпилировать тестовое приложение, которое использует это, я добавляю
import com.company.thing.*;
Компилятор javac не работает с ошибками о com.company не существует. (даже если я скомпилирую его в том же каталоге, что и файлы классов, которые я только что сделал из пакета)
Я уверен, что делаю что-то костяное и глупое.
Я прочитал страницы http://java.sun.com/docs/books/tutorial/java/package/usepkgs.html и попытался настроить структуру каталогов, такую как/com/company/thing и т.д., но либо Я полностью ввернул все это или пропустил что-то еще.
ИЗМЕНИТЬ
спасибо за предложения — я уже пробовал путь к классам. Это не помогает.
Я пробовал компилировать
javac -classpath <parent> client.java
и результат:
package com.company does not exist
У меня есть код, который я хочу импортировать (два java файла) в comcompanyproduct. Я скомпрометирую их. (они содержат MyClass), я даже сделал для них файл jar. Я скопировал файл jar в родительский каталог.
Затем я сделал (в родительском каталоге с клиентским java файлом)
javac -cp <jarfile> *.java
результат:
cannot access MyClass
bad class file: MyClass.class(:MyClass.class)
class file contains wrong class: com.company.product.MyClass
Please remove or make sure it appears in the correct subdirectory of the classpath.
ИЗМЕНИТЬ
Я получил код клиента для компиляции и запуска, если я использовал полное имя для MyClass и скомпилировал его в родительском каталоге. Теперь я совершенно смущен.
скомпилирован без комплекта pathpath — просто
javac *.java
в родительском каталоге — и он работал нормально.
Я могу получить тестовое приложение для компиляции, но это не собирается сокращать его, когда мне нужно интегрировать его в производственный код. Все еще ищут помощь.
EDIT:
Наконец — не уверен, почему он не работал раньше, но я очистил все файлы по всей структуре каталогов, и теперь он работает.
Спасибо