What does java -cp "*" mean? - java

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.

Related

java load order of jars and other files in a folder

I have a file and a jar in same folder.
a.jar
env.properties
a.jar also contains env.properties file with different values.
When I use java -cp path_to_folder/* ClassName then java is reading the a.jar -> env.properties file content. When I use java -cp .:path_to_folder/* ClassName then java is reading env.properties file's content.
Can we determine the load order of files and jars used by java?
There are two things going on here: shell pathname expansion (aka "globbing") and then the java commands interpretation of the arguments that it sees.
Example 1:
java -cp path_to_folder/* ClassName
The shell turns that into
java -cp path_to_folder/a.jar path_to_folder/env.properties ClassName
Then java treats the path_to_folder/env.properties as if it was the class name, and fails.
Example 2:
java -cp .:path_to_folder/* ClassName
This one is a bit more tricky. The problem is that the shell tries to expand .:path_to_folder/* by interpreting .:path_to_folder/ as the name of a directory. (It doesn't know that it represents a colon-separated path.) That expansion fails, and what java sees is this:
java -cp .:path_to_folder/* ClassName
But java interprets a wildcard in the classpath as matching only JAR files. See Setting the Classpath
So the above is equivalent to this:
java -cp .:path_to_folder/a.jar ClassName
and the properties file is not on the effective classpath.
Solution:
If you want both the JAR and properties file on the classpath, you need to do this:
java -cp .:path_to_folder/a.jar:path_to_folder ClassName
Now both the JAR file and the folder containing the properties file are on the effective classpath, and the application will be able to read the properties file as a resource using the resource path /env.properties. (It should also read the JAR file as a resource as /a.jar.)
This is not a direct answer to your question but may solve your task:
You could try to read the properties in two steps:
Read your jar-internal env.properties as you do already from classpath.
Read your jar-external env.properties (which you should place then outside your classpath) via filesystem access:
Properties properties = new Properties();
properties.load(new FileInputStream(new File("./env.properties")));
And then decide (dependent of which is available) which properties to use.
java -cp path_to_folder/* ClassName
Yes, because this means the 'raw' env file (the one not in the jar) is not even on the classpath. The above line of code doesn't work at all except on windows (it should be put on quotes on all other platforms): That star needs to arrive unmolested by the shell as an argument straight to the java executable, and this means: all jars in this directory. Not the directory itself.
Hence, yes, of course, this means only the env file in the jar is on the classpath. By definition.
java -cp .:path_to_folder/* ClassName
Yes, now both are on the classpath. I think it then goes in order; ./env.properties works, so that wins, as . is the first entry in the classpath. Yeah, path_to_folder/foo.jar!/env.properties would also work, but classpath scanning stops on a hit, unless you are using a ClassLoader's findResources option (which would find both of them).

How to specify a wildcard path for jar libraries for a java command line application?

I'm writing a command line utility to extract Adobe Form Data from PDF's
This command line fails.
java -classpath jars/*.jar:. extractpdfformdata.ExtractPDFFormData --pdf csmu-asfm.pdf
where as this works.
java -classpath jars/commons-cli-1.3.1.jar:. extractpdfformdata.ExtractPDFFormData --pdf csmu-asfm.pdf
What is the correct way to pass in wildcard paths for jar libraries to java?
The correct way is to use simply jars/*. Classpath wildcards in the Oracle JRE represent a list of .jar files, and not part of the file name. Here's a quote from the documentation:
Class path entries can contain the base name wildcard character (*),
which is considered equivalent to specifying a list of all of the
files in the directory with the extension .jar or .JAR. For example,
the class path entry mydir/* specifies all JAR files in the directory
named mydir. A class path entry consisting of * expands to a list of
all the jar files in the current directory. Files are considered
regardless of whether they are hidden (have names beginning with '.').
Reference: Class Path Wild Cards at http://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html

Will JVM only pick up .jar files?

When I give the -classpath argument to java to start will it pick up only files which have .jar extensions or will it attempt to look into other files in -classpath path as well?
Meaning if I specify -classpath to be /mypath which contains
/mypath/IAmANormalJar.jar
/mypath/IAmAJarWithoutExtension
where IAmAJarWithoutExtension is an actual jar file but without the .jar extension. Will only /mypath/IAmANormalJar.jar be loaded by JVM or will /mypath/IAmAJarWithoutExtension be loaded as well?
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html
Classpath entries that are neither directories nor archives (.zip or
.jar files) nor * are ignored.
The wildcard symbol explained:
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. Files will be considered
regardless of whether or not they are hidden (that is, have names
beginning with '.').
Java classpath requires jar to be completed specified with extension. Without the extension Java treats that as a directory to which there are class files present to be added to the Java classpath. The Wikipedia article on the Java classpath provides some good information in this regard:
https://en.wikipedia.org/wiki/Classpath_(Java)
It will only pick up files with the extension .class, .jar or .zip. One trick I used to use when I wanted to flip between two jars for testing would be to add another extension to the file I wanted to be "out". If the version I wanted to test was mylib.jar, I would modify the old one as mylib.jar.old and they could co-exist in the directory.

What's the difference between -cp and -classpath

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.

Java: tips to add classpath

I have both a library.jar and program.jar in Java folder.
What is the correct command line to run? One method I tried is:
C:>java -cp c:\java\library.jar;.\java\program.jar program [param]
Try
java -cp c:\java\library.jar;.\java\program.jar package.the.MainClass [param]
From http://download.oracle.com/javase/1.3/docs/tooldocs/win32/classpath.html
Folders and archive files
When classes are stored in a directory
(folder), like
c:\java\MyClasses\utility\myapp, then
the class path entry points to the
directory that contains the first
element of the package name. (in this
case,C:\java\MyClasses, since the
package name is utility.myapp.)
But when classes are stored in an
archive file (a .zip or .jar file) the
class path entry is the path to and
including the .zip or .jar file. For
example, to use a class library that
is in a .jar file, the command would
look something like this:
C:> java -classpath C:\java\MyClasses\myclasses.jar utility.myapp.Cool
Multiple specifications
To find class files in the directory
C:\java\MyClasses as well as classes
in C:\java\OtherClasses, you would set
the class path to:
C:> java -classpath C:\java\MyClasses;C:\java\OtherClasses ...
Note that the two paths are separated
by a semicolon.
If you intend for your program.jar to be an executable JAR, you'll have to run it this way (and read this):
java -jar program.jar
Classpath entries can also contain the wildcard(*) character. For example, the class path entry C:\java\* specifies all JAR files in the C:\java directory and will be expanded into C:\java\library.jar;C:\java\program.jar.

Categories

Resources