Extended classes compile perfectly in Eclipse but not in cmd - java

My program consists of classes that extend other classes. The problem is, when I try to compile them in cmd, system says "Cannot find symbol". Some sites discussing similar problems mention including the source folder in the CLASSPATH. I did as they said and it still gives the same error. However, it runs smoothly in Eclipse. Any ideas why?

Make sure that you compile the top level class first. If you try to compile a class extending other class, and you don't have compiled .class file for that class, you will get that error.
package pkg1;
class A { }
package pkg2;
import pkg1.A;
class B extends A { }
For the above code, you should compile the .java file containing your class A first to get your .java file containing class B compiled. Also, set the path containing your class files in your classpath.
In Eclipse, it works because it automatically compiles your classes as you save them.
NOTE: -
If you are having your classes under some packages, then compile your java files using this command: - javac -d . A.java. This will create a folder for the package name and put the class file in that folder automatically. Then your class B would be able to find it

Related

How does Javac work for multiple files, directories, classes and source?

I'm trying to figure out how javac works with regard to stuff like sourcepath, classpath and prebuilt classes etc. I'm trying to read the documentation, but can't really make sense of it.
I've tried to think of some sample cases below.
If I'm compiling a single file onlyfile.java which has no dependencies, which has 2 classes A and B , and class A uses class B , does class B need to be defined/declared before A ? Or is javac smart and does multiple passes or something like that ?
root.java uses another class in a file file2.java located in the same folder. If I execute javac root.java , how does javac know to search the folder for the class file and if not found , for source file instead ?
How does the above work if the file2 is located in a subdirectory ?
EDIT:
I read somewhere that import is just a way to cut down on typing rather than "loading" anything like in python.
Suppose that I'm building only 1 java file which uses multiple other classes, and that these class files already exist. Without import, the a.b.c.d part of the class object already tells me where to search for the class file, then why a cp option ?
1) If you compile class A which uses class B then class B will be compelled as well. If you compile class B (which is used inside A, but A is not used inside B), class A will not be compelled. Find more details end examples here.
2) javac searches inside source-path and class-path. If you run javac without arguments like javac A.java it sets classpath and sourcepath to current directory. If requested class is not found neither in classpath nor in sourcepath you'll have compilation error.
3) Java has strict rules for project structure. You can't simply place source file to another folder without updating file content.
Every folder in the project should have folder hierarchy with respect of package declaration.
Definition: A package is a grouping of related types providing access protection and name space management.
for instance if you have class A.java with package declaration like this
package com.mycompany;
The corresponding folder structure should look like this:
com/mycompany/A.java
If you follow this rules compiler will be able to resolve dependencies just like I explained in #1. Find more information here.
For first two options try with javac *.java
Duplicate of Compiling Multiple Classes (Console) in Java

Command line confusion when importing .jar and other .class files

I am trying to compile and run the main method in class A. Class A imports classes from both both class B and classes contained in C.jar. These files are all located in the same folder, and the java files are located in the default package.
After trying everything single permutation of "javac" and "java" with different values of "-cp" and various orderings of the afforementioned files and their .class counterparts, I was able to run the main method successfully, but I'm left confused over why the following now works...
java -cp :C.jar A
Can somebody explain to me why there is no reference to class B whose classes are imported and used by class A?
If B.class is in the current working directory, and you were able to make it work with the command java -cp :C.jar A, that implies that your full java class path includes both the current working directory and the classes inside C.jar.
There is no need to directly mention B because it is already inside a directory (the working directory) on the class path.
If the working directory was not included on the class path, then Java would have a problem finding A as well.

Java compilation error cannot find symbol of interface

I am trying to implement an interface in my java code as such:
package PJ1;
public class Fraction implements FractionInterface, Comparable<Fraction>{
Now, FractionInterface.class in the same directory as the Fraction.java file, and it is also in package PJ1:
package PJ1;
public interface FractionInterface{
Yet when I try to compile my Fraction.java file, I get the following error:
D:\CSC220\PJ1\Fraction.java:36: error: cannot find symbol
public class Fraction implements FractionInterface, Comparable<Fraction>
^
I'm stumped, since all of my related files are in the same directory and I'm trying to put all of my class files in the same package. Any ideas?
try to compile like this:
e.g. in c: you do have both the java files - Fraction.java and FractionInterface.java , and you have not created any folder for packages yet, then try as:
c:> javac -d . *.java
This will compile all the files with creating required packages. You no need to create any folders for packages manually.
If you already have created the folder for packages, and you are already in the package say:
c:\PJ1, you can simply compile using javac as:
c:\PJ1> javac *.java
Hope this will work.
My guess is that the files are not in a directory called PJ1 relative to where the compiler expects them to be. Create the folder and move both files to that location. To make it a bit clearer, let's say your folder structure looks like this
myfolder
+-PJ1
Fraction.java
FractionInterface.java
Then you need to be compiling from myfolder using
javac PJ1\Fraction.java
Be sure that both files are in PJ1 folder and run javac *.java.
Just go to a directory above the directory in which your files exist and compile your java files from there (so that you can see if they compile correctly), e.g.
javac dir1\file.java.

Package name is different than the folder structure but still Java code compiles

I am using Notepad++ to write my Java code and Command Prompt to compile and run it.
Following is my sample Java code,
package abraKadabra;
public class SuperClass{
protected int anInstance;
public static void main(String [] abc){
System.out.println("Hello");
}
}
However, this file is in the following folder structure :
"usingprotected\superPkg" (usingProtected is a folder somewhere in the hierarchy in C:)
So, my package name here should be something like usingProtected.superPkg instead of abraKadabra as I wrote it.
But, when I compile this Java code from command prompt, it compiles fine with no error or warnings. Why is it so? Shouldn't the package name adhere to the folder structure?
And if it should, how would it adhere?
For e.g. if my package name is usingProtected.superPkg, will the compiler check in the reverse order. The present working directory should be superPkg, then the parent directory should be usingProtected and its done. Is it how it checks the folder structure with package name?
The Java language specification doesn't force files to be in a certain directory. It optionally allows the compiler to require that public classes are in files with the same name of the class, but I don't think there's anything similar for packages. Section 7.2.1 talks about possible storage options in a file system, but it doesn't say anything about enforcing source code structure, as far as I can see.
However, it's best practice - and a pretty much universally accepted convention - to reflect the package structure in the source directory structure... and javac will use this to try to find source files which aren't explicitly specified to be compiled.
Note that if you're compiling from the command line, by default each class will appear in the same location as the corresponding source file, but if you use the "-d" option (e.g. "-d bin") the compiler will build an appropriate output directory structure for you, rooted in the specified directory.
After experimenting a bit, I got the way how to use package name and run Java class files from command prompt.
Suppose following is my Java source file:-
package mySample;
public abstract class Sample{
public static void main(String... a){
System.out.println("Hello ambiguity");
}
}
This file is in directory "D:\Code N Code\CommandLine".
Now, when compile the source code (by going to the above directory from cmd) using following command:-
javac -d . Sample.java
This automatically creates "mySample" folder in my current directory. So, my class file Sample.class is present in directory "D:\Code N Code\CommandLine\mySample". Compiler created this new folder "mySample" from the package name that I gave in my source code.
So if I had given my package name to be "package com.mySample", compiler would create two directories and place my class file in "D:\Code N Code\CommandLine\com\mySample".
Now, I am still in the present working directory i.e. in "D:\Code N Code\CommandLine". And to run my class file, I give the following command:
java mySample.Sample
So, I give the complete hierarchy of package and then the class name. The Java Interpreter will search the current directory for "mySample" directory and in that for "Sample.class". It gets it right and runs it successfully. :)
Now, when I asked that why it compiles my wrong package source code, it would compile the code successfully though, but it gives NoClassDefFoundError when I run my class file. So above method can be used to use package names from command line.
If you're compiling a single class, javac doesn't need to look elsewhere for it. It'll just compile the file as is and put the resulting .class into the same folder. However, you generally won't be able to use the class til you put it into an "abraKadabra" directory in one of the directories in the class path.
If your class uses another class in the package, though, you might have problems compiling it where it is, for the same reason (javac wants to find the class and make sure it has the methods and such that your class uses).
Java compiler does not check the directory structure when it compiles source files. As you mentioned, suppose you have a source file that starts with the directive
package abraKadabra;
You can compile the file even if it is not contained in a subdirectory .../abraKadabra . The source file will compile without errors if it doesn’t depend on other packages. However, the resulting program will not run (unless also including package name in execution). The virtual machine won’t find the resulting classes when you try to run the program.

Compiling Java Classes Together

I thought I new this, but when I create an object out of an class in a seperate file, it only compiles if that class is defined in the same directory, or if I import it from the library. I assumed it used classpath to search for the included class files, but when I add a random directory to classpath(and only place that file there), it still complains that the class is not defined and won't compile. Where does it know to look for classes at compile time?
Example
public class SomeClass {
public SomeOtherClass SoC; // If this class is not in library or same directory -- won't compile.
}
// If this class is not in library or same directory -- won't compile
Correct. Your classes need to be in the classpath, or in a .jar that you specify.
When compiling you would use
javac -classpath .:/some/other:/another:/some/foo.jar
You then import whatever you need in your .java files (your code)
Besides the import you also have to have folders on the classpath that represent the class' package.
Example:
Class com.whatever.SomeClass is located in src/java/com/whatever/SomeClass.class.
Now, the classpath should contain src/java/ and from there the package com.whatever is looked up.
If the classes are in a .jar file, you'd put the jar in the classpath. Inside the .jar you'd again have com/whatever/SomeClass.class (note that .jar is basically a zip like format).

Categories