Is it possible to use relative path when compiling the java files? - java

Hi I am trying to learn to compile a java class with make file. My make file looks like this:
build:
javac test_java.java
clean:
rm -rfv *~ test_java.class
run:
java test_java
Now I have moved the test_java.java into a folder, called classes I am trying to compile the file using a relative path, is it possible?
I have tried:
javac -d classes test_java.java
but I am getting errors:
javac -d classes test_java.java
javac: file not found: test_java.java
Usage: javac <options> <source files>
use -help for a list of possible options
I have also tried: -d ./classes and also -d /home/the/whole/path (but I would like to have the relative path), and the errors are the same. It seems to work only the
javac classes/test_java.java
What am I doing wrong?

Update: The original answer here was completely wrong. You must specify the path to your source files. -sourcepath is for another purpose:
Specify the source code path to search for class or interface
definitions. As with the user class path, source path entries are
separated by semicolons (;) and can be directories, JAR archives, or
ZIP archives. If packages are used, the local path name within the
directory or archive must reflect the package name.
Note that there are many other build tools for Java applications that are very mature and well regarded. Maven, Gradle, and Ant are the ones that spring to mind immediately. If you don't have to use make I would take a look at one of those.

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.

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.

Use my own classes in a servlet (Java/Tomcat/Linux)

For the last 3 days I couldn't find a single answer for this problem. I need to be able to use my own classes in my servlets.
I am pretty sure that my files hierarchy is correct:
|-WEB-INF/
|---classes/
|------com/
|---------myProject/
|------------user/
|---------------User.java
|---------------Location.java
|---------------Comment.java
|------------servlet/
|---------------DoComment.java
Since User.java, Location.java and Comment.java are defined in one package as com.myProject.user I know I should go to the main root of the java project and compile them this way:
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo javac com/myProject/user/Location.java
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo javac com/myProject/user/User.java
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo javac com/myProject/user/Comment.java
However, javac cannot identify the other objects (cannot find symbol error) when I use a classpath in my compilation.
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo javac -cp /usr/share/tomcat6/lib/servlet-api.jar com/myProject/servlet/DoComment.java
Please help!
You're putting java source in a location where compiled java classes are expected. Try compiling the source and then adding the class files (.class vs .java) where you're putting them currently.
For this to work, you'd have to be sure that the classes have no dependencies and that the package declaration of your classes match up with the folder hierarchy you're placing them under.
Even so, this generally isn't how web projects are put together. You would be better off packaging the classes into a JAR and placing the JAR in your WEB-INF/lib folder.
For more information on creating a JAR, check this out: http://docs.oracle.com/javase/tutorial/deployment/jar/build.html
From the javac manpage:
-cp classpath
Sets the user class path, overriding the user class path in the CLASSPATH environment
variable. If neither CLASSPATH or -class-
path is specified, the user class path consists of the current
directory.
Basically, you are overriding the classpath when you use the -cp flag, so you need to make sure you specify ALL the required classes in your classpath. The delimiter for classpath entries is a : and it takes wildcards.
Problem solved!
I created a JAR file for the com.myProject.user package and saved it in the WEB-INF/lib. Than I compiled the servlet using two classpath seperated by a colon.
Here is the code:
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo jar cvf myproject-user.jar com/myProject/user/User.class com/myProject/user/Location.class com/myProject/user/Comment.class
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ mv myproject-user.jar ../lib/myproject-user.jar
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo service tomcat6 restart
/var/lib/tomcat6/webapps/ROOT/WEB-INF/classes$ sudo javac -cp /usr/share/tomcat6/lib/servlet-api.jar:../lib/myproject-user.jar com/myProject/servlet/DoComment.java
Thank you durron597 and kwikness your answers combined was the correct answer.
Have a nice day.

-sourcepath vs -classpath

Studying for the oracle certification I am trying all the possible scenarios that might occur during the exam.
For example, here there is a little doubt about shell command line (unix based):
Let's imagine there is a folder called myProject and a sub folder called myProject/source.
File SubFile.java is in the folder myProject/source and another file File.java is in myProject folder.
By typing the following commands I get to different behaviors:
cd source (therefore, currently I am on "myProject/source")
javac -sourcepath ../ File.java
// The command ../ does not work to access "Folder"
then after compiling File.java from myProject folder and returning to the sub Folder if I try:
javac -classpath ../ SubFile.java
// with the flag -classpath it seems to accept the ../ syntax to access the super folder.
Do you know why it works like this? and moreover is there any chance to access the super folder with the -sourcepath flag?
It depends on whether SubFile also references File.
Consider the following code:
public class SubFile {
private static File file = new File();
}
Assumed that this file is located in your source folder, and assumed that you are in the source folder, then
javac -sourcepath ../ SubFile.java
will compile SubFile.java into SubFile.class inside the source folder, and will compile File.java into File.class in the parent folder. If there is no dependency between those files, then the compiler will not compile File.java (means, the compiler will not automatically compile all files on the sourcepath).
When compiling with -classpath, then the classpath is also searched for source files, unless you explicitly specify a separate sourcepath - in the following case, the compiler will throw an error (assumed that you have cleaned the File.class file before):
javac -classpath .. -sourcepath \temp SubFile.java
See also javac - Java programming language compiler and Differences between classpath and sourcepath options of javac for more information.
The important point from these two links is:
Note: Classes found through the class path may be subject to automatic recompilation if their sources are also found.

Package not found; javac

This is annoying.
I have a directory structure like this
-lib
--some jar files
-packageName
--Main.java
--SomeOtherPackage
--SomeOtherJavaClass.java
Main.java imports SomeOtherPackage. And both java files uses jars in the lib.
What I do is add the jar files independently in the CLASSPATH. And then run as:
javac packageName/Main.java
but it gives the error that Package not found SomeOtherPackage . Shouldn't it automatically realize the dependency and build SomeOtherPackage as well? What would be the javac command and the classpath for the above case?
Thanks
The normal practice is to add the package root to the classpath.
When you're already in the package root, use -cp .. E.g.
cd /path/to/all/packages
javac -cp . packageName/Main.java
If you want to include JAR files as well, use the ; (or in *nix, the :) as classpath path separator:
javac -cp .;lib/file.jar packageName/Main.java
To save the time in repeating all the typing of shell commands, use a .bat (or in *nix a .sh) file. Or just an IDE if you're already familiar with java/javac and so on.
You need to add packageName to the CLASSPATH so it can find SomeOtherPackage

Categories

Resources