Running Java command including all JARs in current folder - java

I have just shifted back from an IDE to Notepad to write a Java program. The program is using 20 JARs. I compiled successfully. When I decided to run the Java class file using
java -cp ".\\*" MyProgram
it was giving the standard error "Couldn't find or load main class....".
I was confused because when I used to run the java command with all files in an existing folder, it would just get those JARs as the current folder is already in the classpath. As the program is running from the current folder, I tried using -cp "." to include it explicitly in the classpath but that didn't work either.
Finally I was able to run the program with this command:
java -cp ".\\*;." MyProgram.java
I am asking this question to understand the actual logic behind Java's classpath.
Correct me if I am wrong, but I think that the JAR is just a standard archive in which all the packages are encapsulated in respective folders. If all the JARs are in my current folder including my main class file then why can't I run it with:
java -cp "." MyProgram
or simply:
java MyProgram
If the problem is with the multiple JAR files to include and that's why we used ".\\*" to include all the JARs in the classpath, then why do we have to explicitly include the current folder again in the classpath using:
java ".\\*;." MyProgram

To include all jar required to run your program in command prompt use wildcard *:
java -classpath E:\lib\* HelloWorld
You are using "." that defines current directory and "./*" defines all files in current directory.

The class path is a list of jar files and directories containing the classes and resources of your program. Mentioning a jar file adds its contents to the class path.
"./*" will get you only the jar files in the current directory, "." adds the current directory to the class path. This allows to access all classes (and the jar files as raw file resources but not its contents, i.e. the classes contained in them).
If you need both in the class path, you have to specify both.

You've answered your own question, sort of.
. means that it will look for .class files in the current directory.
JARs act just like a directory. So to have the abc.jar "directory" you would specify abc.jar in your classpath.
If you need both the .class files present in the current directory, and the .class files packaged into JARs found in the current directory, you would have the following classpath: -cp ".:*.jar
All the answers here are telling you to use the wildcard without extension (* or ./*) but this is a bad practice, you don't want Java to go look into irrelevant files, so specify the extension: *.jar.

"." means current directory not files in the directory
"./*" means all files in current directory.
So you want to use all jars in current directory so 2nd will work

Related

How to use java classpath in windows command line?

I have created a java source file in Source folder and also created a folder named classes which is supposed to contain my class files .
javac -d classes Source/TestMyAnnotation.java
puts my files in the directory structure classes/Source/...
Now I want to run that compiled classes but
java -cp classes/Sources TestMyAnnotation
throwing NoClassDefFoundError
Where am I doing wrong? How to do it in a correct way?
Sources is not a package folder; it's just the directory that holds your java source, so you don't need to put it on your classpath. If you take a look inside your classes directory after you have compiled your java source, you will see a file TestMyAnnotation.class - there's no Sources directory underneath it, so you don't specify it on the classpath.
You will be able to run your class like this:
java -cp classes TestMyAnnotation
You can find more information on how all this works on Oracle's Managing Source and Class Files Page

Java NoClassDefFoundError even when Jars in same folder

I have created a simple Java program (1 java file that contains the main() ), and I've included all Jar files in the same directory as the .class file. It is giving the NoClassDefFoundError message.
I've tried updating the Classpath to point to the directory, and I've also set "-cp ." to suggest that it look in the same directory as the .class file. However, the program still says it can't find the class def.
Any thoughts on what I should do?
Adding a folder tells java to look in that folder for .class files.
You can't reference .jar files via a folder name... Each .jar file's path must be listed on the CLASS_PATH explicitly.
this question's answer may be useful
When you try running a class from command line then a NoClassDefFound exception usualy means there is something wrong with your classpath.
You have explicitly define the classpath. You can do this in a few ways but the following way is the least prone to error:
Open a command shell and do the following:
1.) set classpath = {path to class files};{path to jars}
2.) java com.example.mainclass
Note: Even if your classes path and jar path is the same you need to specify them explicitly.
Note: If you have more then one jars place them in a folder say lib and add it to the classpath like: {path}/lib/* This will include all of the jar otherwise you have to specify them individually.
References: https://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html
Import the following package:
Import java.lang.NoClassDefFoundError;

Why this javac: File Not Found error?

Working with some basic java apps on CentOS 5 linux and I have my classpath set to point to home/pathToJava/bin which contains javac and java
and I have .java files in home/pathToFolderA/src
and home/pathToFolderB/gen-java
When I run javac and java in home/pathToFolderA/src everything works perfectly
But when I run javac from within home/pathToFolderB/gen-java on fileName.java I get a file not found error, specifically
javac: file Not found: fileName.java
Usage: javac <options> <source files>
Why could this be happening?
Thanks for all help
The classpath is used to find class files, not source files. (Nor is it used to find the java and javac binaries; those are found in your normal path.) You need to specify the files to compile explicitly:
javac /home/pathToFolderA/src/fileName.java
Obviously if you're already in /home/pathToFolderA/src then you can just use fileName.java because that's treated as being relative to your current directory.
You shouldn't set your classpath to point to your JDK bin directory -- instead it should be the PATH environment variable, which serves a different purpose to classpath. (The classpath defines a list of jars and directories containing compiled Java .class code; the PATH variable defines a list of paths where the shell needs to look and locate programs to execute when they are not found in the current directory -- so if you type for instance zip -- it would look in all the directories defined in PATH and figure out that zip program is located under /usr/bin)
Secondly if you want to compile sources from both directory you need to specify:
all the paths where the sources are (both home/pathToFolderA/src and home/pathToFolderB/gen-java)
the path where the compiled .class files to be generated
specify in the classpath any library you might use in your source files
To sum it up, it would be something like this to compile:
javac -d /home/pathToFolderWithResultsOfCompilation -classpath /path/to/some.jar:/path/to/another.jar home/pathToFolderA/src/*.java home/pathToFolderB/gen-java/*.java
and to run your compiled programs:
java -classpath /path/to/some.jar:/path/to/another.jar:/home/pathToFolderWithResultsOfCompilation full.name.of.your.Java
Working with some basic java apps on CentOS 5 linux and I have my classpath set to point to home/pathToJava/bin which contains javac and java
That's wrong. The classpath is used to find *.class files, not operating system specific executables. The bin directory of your JDK does not belong in the classpath. Note that the classpath is also not for finding *.java source files.
When you run javac you need to specify the path to the source file, if it isn't in the current directory.
make sure that your file name contain no spaces
Eg:
HelloWorld.java
usually the errors occur when you rename the file by copy past that will cause a space between the name and the dot (this is the mistake:HelloWorld .java).
and make sure you changed the directory to the same folder your file in
Without a listing of the directory "gen-java" and the exact command you're typing,my guess would be that you're trying to compile a file that doesn't exist. Linux is case sensitive, so maybe that's your problem. Or the file doesn't exist.

prog.java and prog.class in Prog.jar file - How can I easily update this code?

Back story:
Long ago, before dinosaurs were around, there was a contractor that wrote a small Java program, that does some stuff, and prints some stuff to the screen.
Current: No one here knows much about Java but me - and I am not fluent.
The program works, but we kind of need just a bit more information on the screen. From the documentation available, I think I know how to go about that, and I definitely know how to print stuff, as it's simply using System.out.println() for this.
I have a .jar file, which I'm 99% certain is being loaded/used, which contains .java files matching every .class file within.
Is there an easy way to (and how might I) slightly modify one of the .java files, and "compile" the new version to replace the current matching .class file within the .jar?
I'm able to open and read the java source file, of course, but don't remember to procedures to turn java into "class" files, and especially not sure if I can just drop the resulting .class file into the .jar file as a replacement.
at the basic level, javac is the compiler; that will produce the .class files. There is also a "jar" command that will regenerate your jar file. Depending on the number of dependencies, that can get complicated quick. You can just type "javac" and "jar" (w/o quotes) to get the args to run it. Another option is to setup an ant build script...
so you could do something like (assuming windows OS):
javac -cp %MY_CLS_PTH% *.java
where MY_CLS_PTH is where any dependent classes are. If you have a package structure, this gets a little more complicated.
jar -cvf .\my_class_dir MyJarFile.jar
where my_class_dir is the directory that contains the .class files.
I think that is right (didn't run it myself) but that should be about the basics...
EDIT: There is a way to just add/re-add a single .class file to an existing jar file. Check out the "jar" command's usage, looks like "-u" will update it (of course you have to pass in the .class file). Also remember that any package structure you have in these classes, you need that directory structure and you reference the class via that dir structure. (Hope that is clear...)
Add myclass.class to the top level directory in myjar.jar:
jar uf myjar.jar myclass.class
Add myclass.class to the subdir directory in myjar.jar:
jar uf myjar.jar -C subdir myclass.class
Add a Version attribute to the manifest of myjar.jar:
First create a file somefile containing the line Version: "X.Y.Z", then
jar umf somefile myjar.jar

javac: package org.apache.poi.hssf.usermodel does not exist

I have a program attempting to use classes from the jakarta-poi-3.0.2.jar in my /usr/share/java directory:
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
etc...
When I compile, I get a package org.apache.poi.hssf.usermodel does not exist error for each of the imports above.
I have /usr/share/java on my classpath. Am I missing anything else?
/usr/share/java on the classpath does not bring in all jars in /usr/share/java.
Try putting /usr/share/java/jakarta-poi-3.0.2.jar in your classpath instead.
First up, you might want to upgrade - Apache POI 3.0.2 is over 3 years old, and there have been a lot of fixes since then!
As for your issue, you either need to list each jar file individually on your classpath, or you need to place all your jars into the jre lib directory (the contents is which is automatically included). The latter isn't generally recommended though...
You can't just list a directory on the classpath, and have the jars from within it picked up, sorry. Only individual class files will be loaded from a classpath directory, jars won't be
Bootstrap classpath is $JAVA_HOME/lib
but for user applications use user classpaths setting -classpath parameter like that:
java -classpath /usr/share/java/myclasses.jar
The following solution helped me
The class path is the path that the Java runtime environment searches for classes and other resource files. The class search path (more commonly known by the shorter name, "class path") can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable. The -classpath option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value.
C:> sdkTool -classpath classpath1;classpath2...
-or-
C:> set CLASSPATH=classpath1;classpath2...
where:
sdkTool
A command-line tool, such as java, javac, javadoc, or apt. For a listing, see JDK Tools.
classpath1;classpath2 Class paths to the .jar, .zip or .class files. Each classpath should end with a filename or directory depending on what you are setting the class path to:
For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file.
For .class files in an unnamed package, the class path ends with the directory that contains the .class files.
For .class files in a named package, the class path ends with the directory that contains the "root" package (the first package in the full package name).
Multiple path entries are separated by semi-colons. With the set command, it's important to omit spaces from around the equals sign (=).
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.
Classpath entries that are neither directories nor archives (.zip or .jar files) nor * are ignored.
Reference :http://download.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html

Categories