When I thought about compiling and executing Java commands by myself, Write the source code, create a folder hierarchy, place the source code, and so on. When it comes to compiling with the javac command
"Cannot find symbol"
Isn't it possible that you can't create a class file forever because of this one line? Since syntax errors provide relatively detailed information, it is easy to identify the cause. Regarding the error that the class cannot be found, the correction points are different depending on the implementation content, so There is no such thing as "If you fix this, it will be fixed!"
But what a beginner really needs is It is not information that can be used only in individual cases such as "how to fix" It can be reused as "the cause can be understood by looking here due to the mechanism" I think it's debugging knowledge.
This time, when I studied the mechanism around compilation, for "I can't find the symbol" I've come to see how to approach it, so I would like to introduce my debugging procedure at this time.
The scratches should be shallow. As a result of conducting a grand survey from the perspective of introducing it later, It's too painful on a day when the cause of the error was just a typing mistake, First of all, is the declaration of the Test.java class `` `public class Tst``` (an example)? I suspect a typing mistake. Except for class declaration and package specification, syntax errors will occur. I don't chase that far.
The type here is the class that cannot be found Whether it is a ** bootstrap class ** or a ** class stored in a ** jar file ** Is it a ** user class **?
If you want to know more about bootstrap class and user class, Find out about Java classloaders and compile-time type lookup.
I'll skip the details here and give you a rough introduction.
--Bootstrap class Core features such as the frequently used java.lang package, such as the core API of the JDK, are included here. --User class This class is created by the user (programmer). Also called a user-defined class. --Class stored in jar file There are various third-party libraries, user-defined libraries, etc. It is the one that is often added to the build path with eclipse.
What can be judged here is the class that cannot be found In the case of bootstrap class, set "Java environment variable that specifies JDK" In the case of user classes, you should suspect "classpath variables".
I can't tell if it's a bootstrap class. In that case, refer to Core API Document.
Since the JDK has not been specified, the environment variable "JAVA_HOME" is Let's review whether it is set properly. There are many articles on how to set JAVA_HOME, so I will omit it.
Specifying the classpath in the jar file is slightly different from specifying the classpath in the class file. However, the only difference is whether you specify a directory or the jar file itself. Let's check if the command syntax is correct.
#For jar
$ javac -classpath /lib/example-lib.jar Example.java
#For class files
$ javac -classpath /lib Example.java
In this case, there are a few more perspectives to look at. If this is the case, please continue reading the following content.
Loading user classes and third-party libraries The classpath must be specified correctly in both rabbits and corners, If you don't understand the mechanism of classpath specification properly, it won't work.
Below, we will introduce the viewpoints when reviewing the classpath. You do not have to investigate in the order of introduction.
Other than that, it was pushed by other explanations and ignored. The fact that "if you specify a package hierarchy in your classpath, it will not be imported successfully". I guess it's too obvious to be written, but I got caught here.
What it means is that there is the following folder structure, and in UseCommons.java Suppose you are importing `` `com.example.util``` because you want to use StrFactory.
UseCommons.java
package com.example.util;
In the above case, src is recognized as the package root, com ~ app is recognized as the package hierarchy, and so on. What I did when compiling these
#The current directory is/src
$ javac -classpath /src/com/example/util com/example/app/UseCommons.java
As mentioned above, by specifying `` `/ src / com / example / utilin the classpath, I wanted to compile UseCommons.java by loading the classes under util. However, Java follows the package hierarchy starting from the directory specified by the classpath **, so With the above settings, when UseCommons.java goes to StrFactory.java,
/src/com/example/util/com/example/util```I will go to see it.
In other words, the correct classpath would be: with src, the package root.
#The current directory is/src
$ javac -classpath /src com/example/app/UseCommons.java
From the above point of view, with the package root specified in the -classpath option In the place where the contents of the import statement declared in the class file are concatenated Let's check if the class you want to load is placed.
I think this is the best songwriter. What was set by default is overwritten by specifying options etc. If the necessary settings are disabled, it is difficult to notice because you are not usually aware of it.
-Classpath is usually set to ". (Current directory)". With that in mind, take a look at the example below.
Initially, it had the above configuration, so you can compile it normally with the following command.
#The current directory is/src
$ javac com/example/app/UseCommons.java
However, after this, use the external library "commons-lang3-3.10.jar" in UseCommons.java. I decided to use it, and changed the folder structure as follows. Then, when I added the commons library to the classpath and executed the following command, I get an error that StrFactory cannot be found.
#The current directory is/src
$ javac -classpath /lib/commons-lang3-3.10.jar com/example/app/UseCommons.java
This is the default setting of the classpath option ". (The current directory in the example is / src)" This is because Java can no longer search for classes under src due to overwriting. Therefore, if you modify the above command as follows, the error will be resolved.
#The current directory is/src
$ javac -classpath /lib/commons-lang3-3.10.jar:. com/example/app/UseCommons.java
That's the compile-time debugging perspective I can have today. I think there are various other perspectives, so it's just for beginners to study. I hope you will recognize it as a help for the first step. The broader the perspective, the better, so I would like to deepen my learning.
Also, I wrote about Java compilation in another article, so If you are interested in how compilation works, please also refer to the following articles.
Link to the article: [Introduction to Java Commands Chapter 3 Compiling Source Code](https://qiita.com/maple_syrup/items/c0aa2eacb8f486dc52a8#%E7%AC%AC%EF%BC%93%E7%AB% A0-% E3% 82% BD% E3% 83% BC% E3% 82% B9% E3% 82% B3% E3% 83% BC% E3% 83% 89% E3% 82% 92% E3% 82% B3 % E3% 83% B3% E3% 83% 91% E3% 82% A4% E3% 83% AB% E3% 81% 99% E3% 82% 8B)
Recommended Posts