Java 8 on Windows 10 - CLASSPATH does not work - java

Windows 10 1803 64-bit, Java JRE 8. No JDK installed.
I have a .jar in a folder:
c:\users\myuser\KickAssembler\KickAss.jar
Under System environment variables I have the CLASSPATH as:
c:\users\myuser\KickAssembler\
At a command prompt the CLASSPATH is set (checked with ECHO).
At a prompt when I try:
java -jar KickAss.jar
It returns:
Error: Unable to access jarfile KickAss.jar
If I CD into the directory first, then run it, it works fine. So it looks like CLASSPATH is not being used somehow. I have added the location into the standard Windows PATH also, still doesn't work.
Different combinations of casing for the filename doesn't work. Windows is set to show hidden files. It can't be a permissions issue because it works when I change into the directory first.
Anything else I can try?

CLASSPATH is used to define the path from which Java will load classes. CLASSPATH can contain folders and JAR files, such as: C:\mybin;c:\myjars\some.jar This classpath would load any fully qualified class file residing in or beneath c:\mybin and any fully qualified class within c:\myjars\some.jar. CLASSPATH will not allow JAVA to find your JAR file as you are expecting when using the -jar switch, it does not search for any JAR file along the classpath, it will only look in the ones explicitly stated in the CLASSPATH and then only for class files within them. Note, fully qualified means package + class, such as: com.myorg.somepackage.someclass, not just someclass.
As you observed, if you are in the folder where kickass.jar resides your command line works as the JAR file is present. If you fully reference the JAR file while executing the command from another folder the command line should work as well.
See https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html for more detail on how CLASSPATH works. It is important to have a solid understanding of CLASSPATH when using JAVA.

Related

Running Java command including all JARs in current folder

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

Java CLASSPATH Not working?

I am trying to use other jars for a program I am writing.
I installed all the required files and added them to CLASSPATH, but Java doesn't recognize the packages.
I put semicolons in between the jar locations but Java doesn't recognize the packages from the jar. Why does that happen?
For example,
my classpath looks like:
.;C:\Program Files (x86)\Java\jre7\lib\ext\QTJava.zip;C:\Users\JOE\Downloads\easymock-3.2\easymock-3.2\easymock-3.2.jar;C:\Users\JOE\Downloads\cglib-3.1.jar;C:\Users\JOE\Downloads\objenesis-2.1-bin\objenesis-2.1.jar
but if I try to import package org.easymock.EasyMock for example, the package is not recognized.
If your trying to load dependencies from external jars, specify the paths using -classpath (or) -cp command line argument. It's not ideal to change the CLASSPATH environment variable for each and every program that you execute.
The default ClassPath for java program is dot (.) which means current directory
Remember that when you're using -cp/-classpath arguments, they'll override the default classpath settings, so you should explicitly add the default path as well like below.
On Windows
javac -cp pathToYourJar Main.java
while executing don't forget to add your current directory
java -cp .;pathToYourJar Main
To make things easier, I'd recommend to use an IDE like Eclipse/NetBeans/IntellijIDEA.
If your already using Eclipse, add the jars to your Project's Build Path
Right Click on Project -- Properties -- Java Build Path -- Libraries -- Add External JARs

Running Java Program linking to thirdpary library (java -jar) issue ( Multiple methods tried )

This issue is related to running a Java program (jar) dependent on thirdparty jar library even after setting classpath and trying so many other methods by reading articles in Internet.
I want to use a thirdparty Pack1.jar (it is not a part of jvm) as dependency of my programme.
I do not know where the Pack1.jar file could be in the deployment machine and I want the deployer to specify the path for the thirdparty libraries
I have tried the following alternatives in vain
Setting the java.class.path programatically
String class_path = args[0];
System.setProperty("java.class.path",class_path);
Here I am assuming that deployer would supply the classpath as first argument while running the program
Setting the CLASSPATH env_var to locate the thirdparty directory
While running, using the classpath option
java -classpath /path/to/Pack1.jar -jar Pack2.jar
I think this would not work because documentation says that classpath is ignored when program is run with "java -jar"
Setting the java.ext.dirs programatically.
Setting the java.library.path programatically.
I do not want to specify the Class-Path in manifest because that takes only relative path and I do not know where the thirdparty library would be kept in deployment machine
But I am unable to get the jar running.
How can I fix this problem any help please.
Go for option 3. Put both jars on the classpath like this:
java -classpath '/path/to/Pack1.jar:/path/to/Pack2.jar' com.packagename.yourclassname
Note, that this is for Linux. on Windows, you would separate classpath elements with semicolons:
java -classpath "/path/to/Pack1.jar;/path/to/Pack2.jar" com.packagename.yourclassname
http://en.wikipedia.org/wiki/Classpath_%28Java%29
You can use Pack2.jar without running it using -jar--put it on the classpath and call the entry point listed in its manifest file.
I usually wrap that up in a launcher script to avoid those kinds of problems, and allow jar paths to be set using an argument.
Name the secondary JAR(s) in the Class-path entry of the Manifest.MF of the main JAR file, and use java -jar.
Your objection to this technique doesn't make sense. If you supply and deploy the secondary JAR files, as you should, you have the same degree of control over their location as you do over that of the major JAR file. It doesn't matter where else the user may have copies of them.

Java - Difficulty installing program from 3 separate .jar files (involves CLASSPATH)

I'm having a little trouble running some Java code, which requires three .jar files to be used. I'm at a lost as to what to do with them--I've tried setting the CLASSPATH (and following the instructions for how to do so in the readme files), but to no avail.
I was wondering if someone could walk me through it? I'd imagine three .jar files would be an easy install for someone who knows what they're doing.
If it helps, I'm using Ubuntu pretty much right out of the box (but I do have JDK and Eclipse installed!)
Runtime library: http://cogcomp.cs.illinois.edu/download/software/20
Additional .jar needed: http://cogcomp.cs.illinois.edu/download/software/23
Program I ultimately need to run: http://cogcomp.cs.illinois.edu/download/software/26
If you're willing to help, I can't thank you enough--you deserve a million kudos!
G
Those are all JAR files. When you execute a JAR file by doubleclicking or using java -jar, the CLASSPATH environment variable and the -cp and -classpath arguments are ignored. The classpath should be defninied in META-INF/MANIFEST.MF file of the JAR. In this particular case, only the second and third JAR have a Class-Path entry in the manifest file:
Class-Path: LBJ2Library.jar
Which is the first JAR. The classpath is telling that it is expecting the LBJ2Library.jar to be in the same folder as the JAR you'd like to execute (either the second or third one).
So, just drop them all in the same folder and execute by java -jar LBJPOS.jar.
If you are using java -jar to run your jar files, then the CLASSPATH variable is ignored. If you are using java -jar, you have two options:
Combine the three jars into one jar.
Run the main class directory and don't use -jar.
Use of the CLASSPATH environment variable is generally discouraged nowadays. This is how it's done (on Linux):
java -cp library1.jar:library2.jar:mainapp.jar <fully qualified name of main class>
You need to set the CLASSPATH .place all the 3 jars in a folder , name it as lib
See below to set classpath
set CLASSPATH=%CLASSPATH%:lib;

How can I find a package?

In my code I have the following statement import com.apple.dnssd.*; and compiler (javac) complains about this line. It writes that the package does not exist. But I think that it could be that "javac" search the package in a wrong place (directory). In this respect I have two questions:
How can I know where javac search for the packages?
I think that it is very likely that I have the above mentioned package but I do not know where it is located. What are the typical place to look for the packages?
ADDED:
On another Windows machine I tried the same thing and the "javac" does not complain (as before I compiled without any options like "-cp"). I check values of the "classpath" environment variable. It is equal to "C:\Program Files\Java\jdk1.6.0_18\bin;.;..". I went to the first classpath directory and did not find there something that could be the "com.apple.dnssd" library (no jar files, no files containing "apple"). So, I do not understand why javac do NOT complain on the second Windows machine.
ADDED 2:
On the machine #2 I have installed Bonjour after JDK. On the machine #1 JDK was installed after Bonjour.
ADDED 3:
On the machine #1 (where I cannot import the package) I found the jar file (it is located in "C:\Program Files\Bonjour" and its name is "dns_sd.jar"). I tried to add the above mentioned directory to the PATHCLASS environment variable on Windows 7 (and I restarted the system). It does not help. I still cannot import the package. I also tried to specify the "-classpath" in the command line. It also does not help. Now I will try to reinstall Bonjour (as it was advised).
ADDED 4:
I have uninstall Bonjour and Bonjour SDK. I have reload Window. Then I have installed Bonjour and Bonjour SDK. I have reload the Window. It did not solve the problem. I still cannot import the package (javac writes that package does not exist). I have also copied the *.jar file to the same directory there the source is located. It does not work. I used "javac -cp .". It does not work. Now I am out of options. I do not know what else can I try. Can anybody help me pleas?
ADDED 5:
My classpath is: C:\Program Files\Java\jdk1.6.0_18\bin;.;..;"C:\Program Files\Bonjour"
I try to compile from this directory: C:\Users\myname\java\bonjour\example
I compile by the following command: javac ServiceAnnouncer.java
I get the following error message: ServiceAnnouncer.java:1: package com.apple.dnssd does not exist
ADDED 6:
Finally I have managed to import the library. I did it in the following way:
javac -cp "C:\Program Files\Bonjour\dns_sd.jar" ServiceAnnouncer.java
The important thing is that I have specified the jar file after the -cp (not the directory where the jar file is located). It works also if I replace "dns_sd.jar" by "*". So, my conclusion is that after the "-cp" I need to specify jar files (not directories).
Java/javac will search for classes in the classpath.
The default classpath covers the /path/to/jre/lib and /path/to/jre/lib/ext folders. Any classes and JAR files which are found there will be taken in the classpath. You can in theory put your classes and JAR files there so that you don't need to do anything to get java/javac to find them. But this is actually an extremely bad practice. It's recipe for portability trouble, because this isn't the same in all machines. Leave those folders intact.
Then there's the environment variable %CLASSPATH% wherein you can specify full paths to root folders where classes are located and/or full paths to JAR files (including the JAR file name itself!). Multiple paths are in Windows to be separated by semicolon ; and in *Nix by colon :. Paths with spaces inside needs to be quoted with "". Here's an example:
SET CLASSPATH = .;/path/to/File.jar;"/spacy path to some pkg/with/classes"
Note the period . at the beginning of the argument. This indicates the current path (the current working directory from where the java/javac command is to be executed). It will only find classes in the current path that way, and thus not JAR files! You need to specify full path for them. Since Java 1.6 you can also use wildcards to specify multiple JAR files in some path. E.g.
SET CLASSPATH = .;/path/to/all/jars/*;"/spacy path to some pkg/with/classes"
This environment variable is actually a convenience way to manage the classpath so that you don't need to type the same thing down again and again in the command console everytime. But this is only useful for new-to-java users and the cause of all future confusion because they will think that this is "the" classpath. This assumption is actually wrong and again the cause of portability trouble because this isn't the same in all machines.
The right way to define the classpath is using the -cp or -classpath argument wherein you actually specify the same information as you'd like to enter for %CLASSPATH%, i.e. (semi)colon separated and paths-with-spaces quoted, for example:
javac -cp .;/path/to/File.jar;"/spacy path to some pkg/with/classes" Foo.java
Note that when you use either -cp or -classpath (or -jar) arguments, then java/javac will ignore the %CLASSPATH% environment variable (which is actually a Good ThingTM).
To save the time in retyping the same again and again, just create a bat or cmd file (or if you're on *Nix, a sh file). Basically just put therein the same commands as you'd enter "plain" in the console and then execute it the usual platform specific way.
To save more time, use an IDE. The classpath which is to be used during both compiletime and runtime inside the IDE is called the "build path". Explore the project properties and you'll see.
http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html
To answer your first question (How to know where javac searches for packages):
Check what your $CLASSPATH variable is set to.
echo $CLASSPATH
This is where you JRE will search for class files and resources. You can either set it as an environment variable,
set CLASSPATH=path1;path2 ...
or set it when your run javac.
C:> javac -classpath C:\java\MyClasses src_dir
(Great examples for javac are found here)
In this case, your jar file containing 'com.apple.dnssd.*' should be located in your classpath. Just download that jar, and put it in the place where your classpath is searching.
Assuming that dns_sd.jar is installed in 'C:\Program Files\Bonjour', then try to compile your code like this:
cd C:\Users\myname\java\bonjour\example
javac -classpath C:\Program Files\Bonjour ServiceAnnouncer.java
This link suggests that the JAR containing this package is part of Bonjour for Windows. Look for it there.
javac.exe only searches where you tell it with the CLASSPATH. If you don't understand how to set CLASSPATH, I'd recommend reading something like this.

Categories