What's the difference between -cp and -classpath - java

What's the difference between using
javac -cp classes helloworld.java
and
javac -classpath classes helloworld.java
in CMD?

They are the same, check http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html
-classpath classpath
-cp classpath Specifies a list of directories, JAR files, and ZIP archives to search for class files. Separate class path entries with
semicolons (;). Specifying -classpath or -cp overrides any setting of
the CLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, then the
user class path consists of the current directory (.).
As a special convenience, a class path element that contains a base
name of * is considered equivalent to specifying a list of all the
files in the directory with the extension .jar or .JAR. A Java program
cannot tell the difference between the two invocations.
For example, if directory mydir contains a.jar and b.JAR, then the
class path element mydir/* is expanded to a A.jar:b.JAR, except that
the order of jar files is unspecified. All jar files in the specified
directory, even hidden ones, are included in the list. A class path
entry consisting simply of * expands to a list of all the jar files in
the current directory. The CLASSPATH environment variable, where
defined, will be similarly expanded. Any class path wildcard expansion
occurs before the Java VM is started. No Java program will ever see
wild cards that are not expanded except by querying the environment.
For example, by calling System.getenv("CLASSPATH").

There's absolutely no difference. It just tells the Java compiler you want to use a custom classpath specified on the command line argument.
So -cp and -classpath are fully equivalent.
You can find more info on javac - Java programming language compiler page.

There is none. They're both options for setting the classpath. See the man page.

Related

About this servlet + tomcat example, can not compile servlet using javac

I am currently following the book Head First Servlets and JSP, and I got to the point on page 81 where the author asks to compile the servlet using javac.
I am having problems to execute that line of code. I think that my JAVA_HOME and etc must be set up correctly since I created a sample HelloWorld.java and
compiled it useing javac and it created the correspondent .class file.
I am failing to see the logic of this command, you specify a class path to the servlet-api.jar file and then you give it another path so it can execute the .java file?
I would like to get out of this hole I am in right now. These are the paths to my files:
C:\Users\Carlos L\Tomcat\apache-tomcat-8.0.28\bin\servlet-api.jar
and this is where my BeerSelect.java file is:
C:\Users\Carlos L\Tomcat\My Tomcat Projects\beer-v1\src\com\example\web\BeerSelect.java
so far i have been imputing:
javac -classpath C:\Users\Carlos L\Tomcat\apache-tomcat-8.0.28\bin\servlet-api.jar; classes:. d-classes src\com\example\web\BeerSelect.java
and I am getting this error:
javac: invalid flag: d-classes
usage:javac
This should not be this hard.
First, yes it is valid to compile against one jar and later run against a different one(s). In particular a jar named something-api.jar usually contains only the classes that constitute the Application Program Interface aka API, and is sufficient to compile programs that want to call something, but actually executing those calls requires additional internal classes that are packaged in jars using various names such as something-impl, something-body, plain something, or multiple jars such as something-basic something-core something-addon something-option etc.
Second, your book is apparently using the common (but not required or universal) scheme where the java source code files and compiled class files are in separate, parallel subtrees here named src and classes. Your particular sourcefile is apparently src\com\example\web\BeerSelect.java. The syntax to run the java compiler for this case is:
javac -classpath (classpath) -d classes src\com\example\web\BeerSelect.java
# or abbreviate -classpath as -cp, or use envvar CLASSPATH instead
That's hyphen then d, then a space, then the directory name here classes, then another space and the sourcepath (or multiple sourcepaths).
You shouldn't need to specify classes in the classpath initially, only the servlet-api.jar file. If you later compile some but not all sourcefiles of the src subtree, and previously-compiled classfiles for other sourcefiles are already in the classes subtree, you do need both the servlet-api.jar and the classes directory. On Windows you separate classpath entries by semicolon ; and on Unix you use colon : but you should never mix them. So your case would include:
javac -classpath \path\to\servlet-api.jar;classes (rest as above)
except that your path name apparently includes a space C:\users\Carlos L\... so you must put the value in quotes:
javac -classpath "C:\users\Carlos L\tomcat-8.0.28\bin\servlet-api.jar;classes" (rest as above)`
As an alternative to typing this numerous times, you can put the value in envvar CLASSPATH
set CLASSPATH="C:\users\Carlos L\tomcat-8.0.28\bin\servlet-api.jar;classes"
and then simply do
javac -d classes src\com\example\web\BeerSelect.java
and similarly for any other classes in the the project as you come to them.

Java run without jar

I wonder if it's possible to run a program without packaging it into a jar.
For instance we have this:
-AppRoot
Main.class
-Misc
Math.class
OtherTools.class
-YetAnotherFolder
UsefulFunctions.class
Is this possible? The main method should be executed from command line or similar.
You can run this way from the AppRoot directory
javac -cp Misc/*:YetAnotherFolder/* Main.java //To compile
java -cp Misc/*:YetAnotherFolder/* Main // To run
Below is some documentation
-classpath classpath
-cp classpath
Specifies a list of directories, JAR archives, and ZIP archives to search for class files. Class
path entries are separated by colons (:). Specifying -classpath or -cp overrides any setting of the
CLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the cur-
rent directory (.).
Add all (sub-)directories containing class files to classpath and use the class with the main method as argument of the java executable.
The directory structure is your package structure.
java -cp ./:./AppRoot:./AppRoot/Misc:./AppRoot/YetAnotherFolder AppRoot.Main
This should work if all dependencies are resolved and on the classpath.

Compiling a java file using javac and the command line

I am trying to learn more about javac and how to use developer tools for Java using the command line.
As far as I understood, the option -classpath is needed to specify the path where javac searches for our classes and resource files, if we are not in the current directory, because usually the class path is set to our current working directory.
This is my current working directory:
/Users/user1/Desktop
And I am trying to compile a .java file which is in:
/Users/user1/Desktop/PF/
and the file is called MainClass.java.
I am trying to compile it using the following command:
javac -classpath /PF MainClass.java
But it does not seem to work, in fact I keep receiving the following:
javac: file not found: MainClass.java
Usage: javac <options> <source files>
use -help for a list of possible options
What am I doing wrong?
Classpath is for .class files, not for .java files.
javac command needs correct path to the .java file to compile it. So
javac ./PF/MainClass.java
Will create the class file in current directory.
If your MainClass.java depends on any class files to compile correctly, then you put those class/jar files in classpath.
That isn't how the classpath works. You use the classpath to point to classes that your Java file needs in order to compile. You don't use the classpath to point to the Java file itself.
Either go into the PF directory and do this:
javac MainClass.java
That will create the MainClass.class file inside the PF directory. If instead you want to create the MainClass.class file on your desktop, then from your desktop, do this:
javac PF/MainClass.java
-classpath
Specifies the path javac uses to look up classes needed to run javac
or being referenced by other classes you are compiling. Overrides the
default or the CLASSPATH environment variable if it is set.
Directories are separated by colons. It is often useful for the
directory containing the source files to be on the class path. You
should always include the system classes at the end of the path.
class path is used to specify the compiled sources that need to be used in your class. For example in this code if you are accessing another class then you should specify the location of the compiled sources of the that class.
In your case if don't have any class dependency then simply remove classpath option and compile using[navigate inside folder]
javac Mainclass.java
Remove the -classpath. And if you are in the place where the java file is required (which currently you arent) you can remove that PF/ too.

What does java -cp "*" mean?

I was working on the Stanford sentiment classifier on windows. I wanted to retrain my own model, and here's how it was specified on the website:
java -mx8g edu.stanford.nlp.sentiment.SentimentTraining -numHid 25 -trainPath train.txt -devPath dev.txt -train -model model.ser.gz
But this gave me the error:
could not find or load main class
But on changing it to java -cp "*" it worked.
Class path entries can contain the basename wildcard character ,
which is considered equivalent to specifying a list of all the files
in the directory with the extension .jar or .JAR. For example, the
class path entry foo/ specifies all JAR files in the directory named
foo. A classpath entry consisting simply of * expands to a list of
all the jar files in the current directory.
From Oracle Docs
-cp < class search path of directories and zip/jar files>
Search all jar and zip files in the current directory for a given class file
The cp flag specifies the classpath, that is, which other archives are to be considered for this program.
Usually, you'd give it a colon-separated list of jar files, but this particular example is a special case according to the documentation:
If -classpath and -cp are not used and CLASSPATH is not set, then the user class path consists of the current directory (.). As a special convenience, a class path element that contains a base name of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. A Java program cannot tell the difference between the two invocations.
Note that the quotes are necessary, beause otherwise the shell would exapand it to all the files in the directory rather than only jar files.

Making java packages

My Java classes organization has gotten a little messy so I'm going over something I've skipped in my Java learning: the classpath. I can't quiet get beloved classes to compile in the packages I have created for them. Here's my folder hierarchy:
.
com/
david/
Greet.java
greeter/
SayHello.java
SayGoodbye.java
Where SayHello's constructor just prints "hello" and SayGoodbye's prints "Goodbye" and Greet's main method just creates those two objects. At the top of SayHello is package com.david.greeter; and likewise with SayGoodbye and Greet's is package com.david;
In the greeter folder I was able to compile both java files but if I go to the current directory (the directory that holds com) and do javac -cp "com.david.greeter.*" com/david/Greet.java it says it can't find the classes as well as saying package com.david.greeter doesn't exist. I've also tried setting the $CLASSPATH manually.
I'm at my wit's end here, Stackoverflow (as I normally am when I post here). Do any of you know what I am doing wrong?
The java compiler will traverse the sub-directories of the classpath looking for the packages it needs.
So, your command line should be as follows:
javac -cp "." com/david/Greet.java
When the compiler sees a reference to com.david.greeter.SayHello while compiling Greet.java it will start with the directory in the classpath and traverse the hierarchy looking for the package it needs.
First, as documented in Setting the Classpath, the way you're currently setting your class path is wrong. Class path entries should be filename or directory. So using com.david.greeter.* doesn't make any sense. Second, the current directory is in the class path by default:
The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, you must include "." in the new settings.
So if you execute javac (here is the man page by the way) from the folder containing com, you don't have to tweak anything, just type:
javac com/david/Greet.java
And javac will go through the directory tree to find references (e.g. SayHello if you're using it from Greet) and compile them too.
And by the way, if you have to set the class path, don't use the $CLASSPATH environment variable, this is just a bad practice in most case, prefer the -cp option.
If you are in the folder containing com, then try this:
javac -cp . com\david\Greet.java
This is incorrect (as the compiler has already told you):
javac -cp "com.david.greeter.*
Open a command shell and navigate to the directory that contains the "com" directory.
I think you really want this to compile SayHello.java and SayGoodbye.java:
javac -cp . com/david/greeter/*.java
This to compile Greet.java:
javac -cp . com/david/*.java
And this to run:
java -cp . com.david.Greet
The "com" directory should not be current, it should be a child directory to current. You need step one level upper and launch again. No extra care about classpath should be needed at this point.

Categories

Resources