I'm trying to load a custom log.properties file when my application is started.
My properties file is in the same package as my main class, so I assumed that the -Djava.util.logging.config.file=log.properties command line parameter should get the properties file loaded.
But the properties are only loaded when i specify a full absolute path to the properties file. Any suggestions how to use a relative path?
You can dynamically load java.util.logging properties files from a relative path very easily. This is what I put inside a static {} block in my Main class. Put your logging.properties file in the default package and you can access it very easily with the following code.
final InputStream inputStream = Main.class.getResourceAsStream("/logging.properties");
try
{
LogManager.getLogManager().readConfiguration(inputStream);
}
catch (final IOException e)
{
Logger.getAnonymousLogger().severe("Could not load default logging.properties file");
Logger.getAnonymousLogger().severe(e.getMessage());
}
Java logging doesn't search your whole hard disk for a file; there are very simple rules how files are looked up. You want Java to see that the two files belong to each other but you didn't say so anywhere. Since Java sees no connection between the properties file and your class other than that they are in the same folder on your disk, it can't find the file.
-Djava.util.logging.config.file=log.properties only works if the file log.properties is in the current directory of the Java process (which can be pretty random). So you should use an absolute path here.
An alternate solution would be to move the file logging.properties into $JAVA_HOME/lib/ (or edit the file which should be there). In that case, you don't need to set a System property.
util logging does not load from classpath, it needs an absolute path which is why other logging packages like log4j are far easier to configure and better for web apps where it's a pain to get abs paths.
this is not explained at all in the java.util.logging.LogManager doco.
Related
I'm using the log4j2 library to manage the logging process.
I created a configuration file named log4j2.xml containing the Appenders and Loggers configurations. Then, I defined a Logger in each class
private static Logger my_logger = LogManager.getLogger(my_class);
I did not specify anywhere the name of the conf file, so I think that the library implicitly get and read it.
Now, I need to provide my application in the form of a jar file, so I need to make the config file available so that the user can modify and configure it.
In my case, I suggest to create a XXX folder at the level of the jar file, containing all the configuration files used by my app.
My question is how can I say to the app "get XXX/log4j2.xml" rather than the xml contained into the jar.
that config file must be located in the class path, if you want the app to read the configuration from any other location then you need to specify that using
PropertyConfigurator.configure("/myPath/log4j.properties");
Make any folder and put your property or xml file in that. In order to read the property file you can do something like this:
Properties objProperties = new Properties();
<your-class>.class.getClassLoader().getResource("folder/log4j.properties");
objProperties.load(isFile);
or, Also this:
InputStream ist = Thread.currentThread().getContextClassLoader().getResourceAsStream("folder/log4j.properties");
In case of java web application please use the link
I had a similar task a few weeks ago.
I solved it this way:
Store a template of your log4j2.xml inside your jar files resource folder
When running your application, check for a file named log4j2.xml in the jar files current directory
If there is one, use that to create your logger
If not, copy your template from within your jar to the jar files directory and then use that to create your logger.
Cheers
How to configure properties file in Eclipse java?
How can we provide relative addresses in the properties file?
These two lines are working
modelsPath=C:\\Users\\rishika.shrivastava\\workspace\\CSVWEB\\src\\com\\models
csvFilePath=c:/users/rishika.shrivastava/workspace/CSVWEB/
But when i use relative addresses like this:
modelsPath=/CSVWEB\\src\\com\\models
csvFilePath=/CSVWEB/
it doesn't work.
If your files are to be resource on the classpath, then you should read them as resources, not as files on the file system, (which is what happens when you use File or a FileXxx variant).
To read resources from the classpath, you could do
getClass().getResource("/com/models/file")
Or if you need an InputStream you can do
getClass().getResourceAsStream("/com/models/file")
Some Resources
Class API to see what those methods do
How to really read text file from classpath in Java
I am using Config. properties file for passing parameters to my methods Now i am loading file from
Properties Config= new Properties();
Config.load(new FileInputStream("C:\\Config. properties "));
As i don't want to keep it hard coded how can i set it with package level. or within application.
Thanks in Advance.
Make use of ResourceBundle Class. You just need to specify the properties file name. It will take the file from any path,provided the path should be in the classpath.
Example:
// abc.properties is the properties file,which is placed in the class path.You just need to
// specify its name and the properties file gets loaded.
ResourceBundle s=ResourceBundle.getBundle("abc");
s.getString("key"); //any key from properties file...
I was also just going to suggest that but you can also pass in the full path to the config file via a command line argument for example:
java YourApp -config C:\\config.properties
A properties file packaged with the application should not be loaded using the file system, but using the class loader. Indeed, the properties file, once the application is packaged, will be embedded inside a jar file, with the .class files.
If the config.properties file is in the package com.foo.bar, then you should load it using
InputStream in = SomeClass.class.getResourceAsStream("/com/foo/bar/config.properties");
Or with
InputStream in = SomeClass.class.getClassLoader().getResourceAsStream("com/foo/bar/config.properties");
You may also load it with a relative path. If SomeClass is also in the package com.foo.bar, then you may load it with.
InputStream in = SomeClass.class.getResourceAsStream("config.properties");
Note that Java variables should always start with a lowercase letter: config and not Config.
If it's just the path you're worried about then you can use a relative path:
Config.load(new FileInputStream("Config.properties"));
This will look in the current working directory. The upsdie: dead simple. The downside: it's not that robust. If you start your application from somewhere else without changing the working directory before, the file won't be found.
Put the config file in the classpath (where your .class files are), and access it using
getClass().getClassLoader().getResourceAsStream(_path_to_config_file);
There are two ways to get the path of the config files at runtime.
a) Getting it from database.
b) Getting it from custom properties of JVM configured at server level
Best process is "b" , you can change the properties of JVM at any time if path is changed and just restart the server.
I'm trying to have my application load a resource (binary file) transparently:
If the file exists under the current directory, open it.
If not, try looking in the current JAR file if applicable.
If not, try looking in other JAR files. (This is optional and I don't mind explicitly specifying which JAR files.)
So far I know of File which opens a local file and ClassLoader which has getResource* for JAR contents.
Is there a class which combines the two? If not, how should I go about writing it myself? Should I write a ClassLoader which also checks the local filesystem? Using File? (I'm very unfamiliar with Java and don't even know what's a good type to return. InputStream?)
Thanks
P.S. By "file" I mean "path", e.g. "data/texture1.png".
Doing #1 and #3 is pretty easy. Doing #2 (just looking in the current JAR only) is much harder as it requires you figuring out what JAR you
If you wanted to check the filesystem first, otherwise load from classpath, it would be something like:
public java.io.InputStream loadByName(String name) {
java.io.File f = new java.io.File(name);
if (f.isFile()) {
return new FileInputStream(f);
} else {
return getClass().getResource(name);
}
}
If you want to prefer loading from the same JAR file first, you will need to figure out where it is. Check out Determine which JAR file a class is from for more info on figuring out the JAR file you want to load the resource from.
A URLClassLoader should be able to load both and try the file path first if the file path is on the class path ahead of the jar.
Regarding your comments:
I know that relative jar URLs don't
work. That's why the Spring guys came
up with the Resource abstraction.
Read about it here.
You might want to check the answers
to this Question: Loading a file
relative to the executing jar
file. The problem is similar to
yours.
Current jar file and current directory are not concepts in the JVM like they are when you're running a shell script. You would need to specify a directory to be used for loading the files that you're interested in, such as with a system property while executing the JVM:
java -Ddirectory.to.scan=/home/aib
Then retrieve this property:
String dir = System.getProperty("directory.to.scan");
Now when talking about JAR files, all JAR files specified explicitly on the classpath when you start the JVM are loaded by the ClassLoader. You can get the ClassLoader of a specific class by:
InputStream is = <Your class>.class.getClassLoader().getResourceAsStream("binary file");
Note that any jar file loaded by the current class loader is searched.
In Ruby I frequently use File.dirname(__FILE__) to open configuration files and such. For those that don't know Ruby, this will give the location on the file system of the file it's called from. This allows me to package libraries with data and config files and open those files with relative paths.
What's the Java equivalent of this? If there is a data file I want to package with a jar how would I open the data file from Java code that is also in the jar?
The equivalent API in Java is getResourceAsStream. This will open a stream to a file stored in the JAR relative to the class on which it is invoked.
There are variants, such as getResource, which returns a URL, or methods on ClassLoader that use an absolute path inside the JAR file.
Please see Java Applications and the "Current Directory":
In Java, you use File objects to
construct a relative view of the file
system. Two of the constructors for
the File object take a 'parent'
argument that specifies a parent path
that is prefixed to the path of the
file itself to create the full
abstract path to the file. What you do
is, create a File object with the path
that represents your current directory
and then create all your file objects
using that File object as the parent.
Voila, a current directory.
Also I would recommend Reading and Writing a Properties File:
// Read properties file.
Properties properties = new Properties();
try {
properties.load(new FileInputStream("filename.properties"));
} catch (IOException e) {
}
// Write properties file.
try {
properties.store(new FileOutputStream("filename.properties"), null);
} catch (IOException e) {
}
if you just specify the file name, the JVM will look for that file in the same directory your application was started (not necessarily the same directory your application is located).
I voted for #andrew, but I'd like to point out that in Java, the directory the file itself is pretty meaningless except for a few highly reflective (and most likely wrong) purposes.
It will be in a directory based on a package structure, and could be located in a jar or pretty much anywhere.
Java's a little less ad-hock, allowing for less shortcuts, but usually improving consistency and reliability at deployment time.