I have a Spring 3.0 MVC project that uses a JAR file from a different project as a dependency. This JAR file has an "auth.properties" file in it's resource and has a string in it like this.
Ex: packages.redirectUrls.gotoUrl = 'http://myUrl.com';
Now, I am referring to this string in JAR File in my controller using:
#Value("${packages.redirectUrls.gotoUrl}")
I also have a local "auth.properties" file that consists of the same string with a different value in it.
Ex: packages.redirectUrls.gotoUrl = 'http://newUrl.com';
However, my Java code is not able to read this new configuration and always loads from the JAR File. Is there a way to override the JAR file setting with this new setting?
Thanks,
Related
I have a Maven scala project with a config file located here: src/main/resources/reference.yaml. This file contains particular configurable parameters that are used throughout the entire application.
Currently, I package the jar and read the file in the following manner, which is found in the classpath.
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import java.io.{File, InputStream}
val configInput: InputStream = getClass.getResourceAsStream("/" + configFileName)
val mapper = new ObjectMapper(new YAMLFactory)
mapper.registerModule(DefaultScalaModule)
mapper.readValue(configInput, classOf[Map[String, Any]])
I have custom functions to be able to parse the yaml file and load the variables into an object that stores all my config values.
object Paths {
// Config
val table: String = getConfigValue("sql.finance_table", "finance_v1")
}
This object is imported in various other scala files that define the pipeline, and use the config parameters to follow the specification of the user.
To execute the pipeline, the jar is packaged up and deployed to a cluster on databricks where it runs as part of a job. Thus, all config values are static and provided during build time.
While this works, I would like to separate the resource file customisation and the packaging and deployment of the jar. Is it possible to simply get the jar to read a resource file from an external location? This would allow the user to modify the config even after the jar has been built.
I'm not using lightbend or pureconfig.
There are several options:
add an "external" file in the classpath when running the code. The classpath does not only consists of the JARs of your app, it can also contain regular files. This way you don't even have to modify your current code. But.. I don't know if/how to customize the classpath with Databricks.
modify your code to read from "external" file in the first place rather than the classpath. You could hardcodd the path of the file or make it configurable via a system property.
I have a properties file in one of the .jar of my maven dependencies. I would like to override the values in my application so I created a file with the same name and the same package, but the values from the jar file are still being used. If I delete the properties file from the jar, the values of the file in my application are used. How can I always use the properties from my application instead of the .jar ?
As long as code takes your property file from class path it depends how your class path configured.
If you externalized your file out of any jar files - Try to put path to directory where your actual file located upfront of any other jar files in your java command -cp parameter.
If you keep your file inside your own jar file, in classpath - your jar file must be before that dependency jar file with default properties file.
Still those are not good solutions (sometime it is hard to control which path JVM will use first).
So, try to find documentation about your dependency jar - it may have a property to point from where and which properties file to use.
You can use Maven Resource Plugin and parametrize your configuration file so you can pass the parameters as arguments through command line
Use the properties resource in the jar as template, initial file for the properties file you will use:
Path propertiesFile = Paths.get(System.getProperty("user.home"),
".myapp/config.properties");
Files.createDirectories(propertiesFile.getParent());
if (!Files.exists(propertiesFile)) {
Files.copy(getResourceAsStrem("/config.properties"), propertiesFile);
}
Properties props = new Properties();
props.load(new FileInputStream(propertiesFile.toString());
How about this ?
rename the properties file with overridden values,
like this _override.properties (if the actual file is
called original.properties.
Now, in your code, read a system property, called 'toOverrideProps', if true, to load the overridden properties file
when running your program, you can set this property using the -Dprop=value method
This way, you have a choice on startup, to use the actual properties file or the overridden one, without conflict.
I have a Spring Java 1.8 project exported in a .jar. When I want to run this Java .jar application, I'd like to give a file into the argument which .xml config file should the program use in the relative folder. I tried so many ways, but none of them works.
For example:
sampleJavaPorgram.jar config1.xml
(config1.xml and sampleJavaProgram.jar is in the same directory)
shoud load config1.xml like that:
ApplicationContext context = new ClassPathXmlApplicationContext("config1.xml");
Maybe use Command-Line Argument, to get name of this XML file and then pass it to AppContext.
Or you might use System properties
In C#,when I want to create a configuration file, it's so easy,just right click the mouse and add a new configuration file, this file will be added into the solution and it's so easy to maintain.
But in java, I don't know what method is standard. I see some people use the properites file.If this is the most popular method, can some one tell me where to place this file? I saw some guy put it in the src folder, others put it in an external folder.
Can you tell me which is the standard? And what is the best practice to maintain a configuration.
I don't know if this is the "standard" way but I think it's the easiest. If you place your properties file in your project's root folder
- project
- config.properties
- src
- main
- ...
- test
When you create a File instance in Java and specify a relative filename, then the name is resolved against the directory that Java was launched from
e.g. if you launch java in your command prompt as follows:
cd C:\Users\Tom\example-project
java example-project
and this is your code:
File file = new File("tom.txt");
then the file variable will be resolved to the abolsute path: C:\Users\Tom\example-project\tom.txt
When you Run a project through Eclipse, Eclipse launches java from the root directory of the project, meaning that if you put your config file in the project's root folder then
File file = new File("name-of-config-file.properties");
will resolve to the correct config file on your system.
This has an added benefit if you create a runnable JAR, as you can just place your config file in the same directory as your JAR and the code will continue to work (the config file location will be resolved relative to the JAR).
If you put your config file in /src folder then you need to have separate code for when running from Eclipse and when running as a JAR
With regards to sample code:
//Read properties from disk
File propertiesFile = new File("config.properties");
FileReader reader = new FileReader(propertiesFile);
Properties props = new Properties();
props.load(reader);
//Set and get properties
props.setProperty("NewProperty", "value");
String propValue = props.getProperty("propToGet");
//Write properties to disk
FileWriter writer = new FileWriter(propertiesFile);
props.store(writer, "Added x properties");
Configuration files are used to store,read write user settings.
I think for web apps you can use web.xml.And for other you should use Properties class to read and write settings.
As for where to place it,If you dont specify path it is stored in your root folder other than that you have to provide explicit path.
I have simple java project with structure:
package com.abc:
a.java
b.java
c.properties
I have database configuration parameters configured in c.properties file.
Inside a.java and b.java, I am loading properties file using:
Properties p = new Properties();
InputStream in = this.getClass().getResourceAsStream("c.properties");
p.load(in);
This works fine. But the main question is, once I prepare executable jar by exporting this code, properties file also gets packaged in jar file. If someone else wants to modify properties file for different database configuration, how can he do it?
Do I have to store properties file in some fixed location in local machine. e.g. "c:/". Then give jar along with properties file to the other person. Then he needs to copy properties file inside C:/ location?
Also one more question, how can i make this location generic for windows and linux machine?
The typical way of handling this is to load the base properties from your embedded file, and allow users of the application to specify an additional file with overrides. Some pseudocode:
Properties p = new Properties();
InputStream in = this.getClass().getResourceAsStream("c.properties");
p.load(in);
String externalFileName = System.getProperty("app.properties");
InputStream fin = new FileInputStream(new File(externalFileName));
p.load(fin);
Your program would be invoked similar to this:
java -jar app.jar -Dapp.properties="/path/to/custom/app.properties"
First keep the default properties in your properties file, which gets packed into the jar. When the application starts try reading a same named properties file from some default location in filesystem, preferrable the user's home folder which you can obtain by System.getProperty("user.home");. If the file exists at the filesystem load it, if it doesn't exist then load your packed properties file and write a copy to the filesystem.
So if your properties file name is myprops.properties, initially only your jar file will contain it. When the application starts up it will check whether /home/xyz/myprops.properties file exists. Since it doesn't, it will read the packed properties file and write a copy to /home/xyz/myprops.properties file. From next time onwards, it will read from /home/xyz/myprops.properties.
Why not pass the location of the properties file as a command line argument (following a flag)? if it's not present, then use the default one in the jar file.
You're loading the properties file from the class path. I'd suggest something like this:
Properties location