Will JVM only pick up .jar files? - java

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.

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

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.

Why classpath=/tomcat_lib/ doesn't work

HI guys,
There is an abc.jar under /tomcat_lib. I need use this in my def.java
I tired
javac -classpath /tomcat_lib/ -d
../classes def.java
but it doesn't work
But if it works if I use
javac -classpath /tomcat_lib/abc.jar
-d ....
Can anyone help explain it?
To add a jar to your classpath, you need to specify the path up to and including the .jar file.
Quoting the official Java SE 6 documentation at Oracle.com:
Each [item in your 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).
...and from the "Folders and Archive Files" section of the same documentation:
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.

Java classpath, jar file with no .jar extension in Weblogic over Unix

If I place a file called libA.jar in a classpath folder, and rename the old one to:
libA.jar.old
Will the classloader load the classes?
I'm using weblogic over Solaris 8.
Thank you!
Udo
No.
If you're using Java 5 or earlier, you must explicitly name all classes and jar files to be loaded. Obviously, since the old one, libA.jar.old isn't named, it won't be loaded.
It's a bit of a different story if you're using Java 6, since concept of wildcard matching exists there.
Still, non jar files won't be loaded. Info taken from official site. Quote:
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. A class path entry
that contains * will not match class
files. To match both classes and JAR
files in a single directory foo, use
either foo;foo/* or foo/*;foo. The
order chosen determines whether the
classes and resources in foo are
loaded before JAR files in foo, or
vice versa.

Categories

Resources