File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Classpath Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Classpath" Watch "Classpath" New topic
Author

Classpath

Christoffer Blyerts
Greenhorn

Joined: Jun 03, 2012
Posts: 10
Hi,

I am trying to understand how and why to use the -classpath when compiling from the command promt. I am not clear on this part of the OCJP exam.

If have two classes, MyClass.java and B.java. B.java is in folder c:\...\myProject and MyClass.java in in folder c:\...\myProject\com\foo.

package com.foo;
public class MyClass {

public void hi(){}
}

import com.foo.*;
public class B {

public static void main(String[] args) {

System.out.println("hello");
MyClass m = new MyClass();
}
}

If I am in myProject folder and compile B.java it works fine. However if I remove import com.foo.*; and run javac - cp .com/foo B.java i get error bad class file com\foo\MyClass.class, why do i get this error?
If I remove package com.foo; from MyClass it works fine with the javac - cp .com/foo B.java command it works fine, why does it work when I remove the package statement?

Is the -cp supposed to be used when a class needs other classes but doesent import them?


I would be thankful for any help
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Hi Christoffer, welcome to CodeRanch!

No, packages and class paths are completely unrelated. Packages are name spaces where related classes are bundled together. Class paths just specify where to find a loose hierarchy of packages. The import statement tells the compiler that a class wants to use a class from a specific package, without using the package name all the time. Import has nothing to do with where the actual files are located.

So consider the classes B and com.foo.MyClass. Their respective source files are c:\...\myProject\B.java and c:\...\myProject\com\foo\MyClass.java.

If you remove the import statement from the B class, the compiler won't know that MyClass refers to com.foo.MyClass, because its in a different package. If you remove package com.foo from MyClass, then the compiler *will* know, because they are in the same package. It will also be able to find both class definitions, because the compiler looks for files on the class path, and in the current working directory.

Import statements and package names have to do with the logical grouping of classes. The class path is only related to finding source files.
gurpeet singh
Ranch Hand

Joined: Apr 04, 2012
Posts: 924
    
    1

Stephan van Hulst wrote:Hi Christoffer, welcome to CodeRanch!

No, packages and class paths are completely unrelated. Packages are name spaces where related classes are bundled together. Class paths just specify where to find a loose hierarchy of packages. The import statement tells the compiler that a class wants to use a class from a specific package, without using the package name all the time. Import has nothing to do with where the actual files are located.

So consider the classes B and com.foo.MyClass. Their respective source files are c:\...\myProject\B.java and c:\...\myProject\com\foo\MyClass.java.

If you remove the import statement from the B class, the compiler won't know that MyClass refers to com.foo.MyClass, because its in a different package. If you remove package com.foo from MyClass, then the compiler *will* know, because they are in the same package. It will also be able to find both class definitions, because the compiler looks for files on the class path, and in the current working directory.

Import statements and package names have to do with the logical grouping of classes. The class path is only related to finding source files.


hi stephan. i think it should be that class path is related to finding class files and not source files.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Sorry, I should have written class and source files. The rest of my explanation stands. I hope that makes it clear?
Christoffer Blyerts
Greenhorn

Joined: Jun 03, 2012
Posts: 10
Hi and thank you for your response.
If i remove package com.foo from MyClass and remove the import statement from the B class it comiles using classpath .;com/foo B.java And i do not think it compiles because they are in the same package, the files are still in different folders. MyClass.class is in the C:\...\myProject\com\foo folder and B.class is in the myProject folder.

If i have the package declaration com.foo in myClass.java it will not comile using the same classpath, then i am getting bad source file com\foo\MyClass.java.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

I'll try to explain it in more detail.

Each Java class belongs to a certain package. The reason is twofold. First, related classes can be bundled together, and have more access to each other than classes outside the package do. Secondly, a package is also a name space, so you can distinguish two different classes that happen to have the same class name. For instance, java.util.List is a different class than java.awt.List.

The fully qualified name of a class is its package name followed by its class name. java.util.List is a fully qualified name, it specifies both the package and the class name.

You don't need import statements to use other classes! You can always use another class by using its fully qualified name. However, this can get very tedious and distract the reader from the meaning of a program. The *only* thing that import statements do, is make it so you don't have to use fully qualified names when you're frequently using a class. If I import java.util.List, or java.util.*, I can use List anywhere in the following code, and the compiler will know it's a reference to java.util.List.

Java automatically imports classes from the java.lang package, and from the same package as the current class. If B and MyClass were both in the com.foo package, you still wouldn't need the import statement, because the compiler will automatically import the com.foo package for the B and MyClass source files.

Now let's move on the class paths. The javac compiler compiles source files to class files. You specify the path of the source files you wish to compile. This location is independent from the class path. You either specify an absolute path, or a path relative to the working directory. However, the compiler still needs to know the location of classes you reference from your source code, so it can do proper checking. It finds these relative to the class path, not the current working directory.

In your example, B belongs to the default package, and is located at C:\...\myProject\B.java. MyClass belongs to the com.foo package, and is located at C:\...\myProject\com\foo\MyClass.java.

What happens when your current directory is C:\...\myProject\ and you run javac B.java is the following: The compiler finds B.java relative to the working directory. It finds the source file and attempts to compile it. It finds a reference to MyClass so the compiler needs to figure out which MyClass it is. It first looks for com.foo.MyClass, MyClass and finally java.lang.MyClass. It looks for com.foo.MyClass relative to the class path. Since you didnĀ“t specify a class path, the class path defaults to the current working directory. The compiler looks for a definition of com.foo.MyClass at C:\...\myProject\com\foo. It will find either MyClass.java or MyClass.class, either will do.

So what happens when you remove import com.foo.*; from B.java? The compiler will then try to look for MyClass in the default package, and in the java.lang package. It doesn't find a definition of MyClass in the working directory, nor in a folder java\lang\ relative to the working directory, so compilation fails.

Now we also remove package com.foo from MyClass and specify -classpath com/foo. The compiler finds B.java because you *explicitly* tell the compiler which file to compile, relative to the working directory. The class path never influences this. B references MyClass, and the compiler looks for it in the default package and in java.lang. It does this relative to the class path. The default package here is C:\...\myProject\com\foo, because that's where you said it would be in the class path. The compiler finds a definition of MyClass here, so it's happy.

Note that if the compiler was looking for a class named com.foo.MyClass, and you had set the class path to com\foo, it would have looked for the class at C:\...\myProject\com\foo\com\foo.
Christoffer Blyerts
Greenhorn

Joined: Jun 03, 2012
Posts: 10
Thank you for your explanation! It helped me clear out my questions regarding classpath.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  17

Happy to help
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Classpath