简体   繁体   中英

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?

This is not a direct answer to your question but may solve your task:

You could try to read the properties in two steps:

  1. Read your jar-internal env.properties as you do already from classpath.

  2. 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).

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 .)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM