I am trying to dynamically set all properties at run-time in a java spring application. I am successfully doing that with program arguments/System Properties (a different SO post explaining this in detail here), but I haven't figured out a way to dynamically read all properties in .properties files and edit their values. The property sources stored under the spring application context do not contain properties in the previously mentioned files.
Is it possible to load up a spring app and before creating any beans, step in and edit the values across all properties files being loaded in the project?
The properties added to the properties file are read when the app starts. Once it is up and running, changes to the properties file wouldn't reflect unless you restart the app. There is no way to dynamically update the properties file to reflect in the app.
The only way to dynamically update properties of an app would be to use something like a configuration server. Read about it here.
https://spring.io/guides/gs/centralized-configuration/
Related
I have one WAR file with application.
What I need to do is to deploy this WAR twice in one application server (Wildfly) under two different names - deployment1.war and deployment2.war. So far, this is no problem.
The application in the WAR is reading configuration from configuration file and the path to the configuration is currently hardcoded in the application. I need to change this so the deployment1.war is reading deployment1.conf file and deployment2.war is reading deployment2.conf file.
I don't want to keep two different source codes (differing only in the location of the properties file).
So my question is - is there any possibility to pass specific parameter to deployment instead of whole server? Or any other way how to parametrize concrete deployment?
Thanks
You can use overlay to override a file in your deployment thus using 2 different web.xml each pointing to the proper configuration file. https://docs.wildfly.org/20/Admin_Guide.html#Deployment_Overlays
I read #yorkw answer at this topic. He said:
The purpose of .properties file is to provide the capability of
configuring database connections at application runtime (for web
application, usually require restarting application container/server
after .properties file changes).
The question is if we can change properties on the fly without restarting container/server? Provide me an example please (I ask because in my demo it doesn't work, means value isn't changed).
I mean if we have some kind of admin tool than we can move all our configured settings to .properties files and change them via that admin tool.
Spring property files are designed to change the Spring Config of an application. The spring config is read when the spring container is initialised - this will form part of the application startup.
If a change is made to one of the spring config files (includes the *.properties files) the spring container would need to be reloaded to pick up the change.
Properties put into spring properties files should typically be properties that are tied to the life cycle of the application - i.e. the kind of properties that when changed require an application/spring container re-initialised - things like the database url/config etc.
So values that you want to change at runtime without requiring a restart of the application are not good candidates for placement in a spring properties file.
I'd like to extend/replace the Spring PropertyPlaceholderConfigurer to read from a web server as opposed to properties files.
A bit of background:
I work on a project, and we're finding the number of properties files located on the users systems is getting a little unwieldy. We'd like to replace these files with a 'config server' which will store basic key/value pairs and serve them when the user starts up the app.
To avoid making too many changes, I'd like to change the way the PropertyPlaceholderConfigurer finds properties - rather than implementing an entirely new way to manage properties. So on startup - Spring will read all properties from a url, and feed these into my spring config xml in the same way as it would have with actual files.
Bonus!
If anyone has any ideas how to do this where properties are reloaded from the server only when they change, will get bonus points (I have no idea if I have the ability to assign bonus points, but I'll try!). That would be a 'nice to have, if there's not too much effort involved' solution.
Spring's PropertyPlaceholderConfigurer (PPC) already uses the Resource interface to specfiy the location from where to read properties (via the setLocation(Resource) method inherited from PropertiesLoaderSupport.
There is an implementing class of this interface called URLResource which probably does what you want. You could simply create a PPC and set the location property with a bean of this type to load the properties from a URL instead of a file. This class also supports file:// type URLs, so you could switch between on- and offline properties loading depending on the URL you use.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
Any hints? I've tried Google but found very little that seemed relevant - and what I did find appeared hideously over-engineered for my needs.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
That's the web.xml. You can define settings as <context-param> entries.
<context-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</context-param>
It's available by ServletContext#getInitParameter(). The ServletContext is in turn available anywhere.
String foo = getServletContext().getInitParameter("foo"); // Contains "bar"
You can also access it by EL.
#{initParam.foo} <!-- prints "bar" -->
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
As per the emphasis, I'd use a properties file for this particular purpose which is then placed in a path outside the WAR. You just need to add this path to the Java runtime classpath. Then you can obtain it as classpath resource:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
// ...
However, with the particular sole purpose to serve a DB connection, you're indeed better off with a servletcontainer-managed datasource as answered by Qwerky. All you possibly would need to configure is then just the datasource name.
If this is a web app then you'd be better served configuring the database connection as a resource on the server, then getting your app to retrieve it using JNDI. Your app server will have documentation on how to do this, its a basic task.
99% of serious web apps do this, the other 1% should.
You can have your application load an arbitrary external file by simply passing the path as a command-line parameter (to the servlet container startup script). Then store the values in the ServletContext
I have two xml files I'm looking at which define an mbean that uses org.jboss.varia.property.SystemPropertiesService. One is properties-service.xml and lives directly in the deploy directory, the other is further down within my application's ear - let's call it myapp-properties-service.xml.
This mean can define two attributes - a URLList which might take properties of the form ./conf/props/myapp.properties and a Properties attribute which just takes the properties directly (e.g. myproperty=myvalue).
The problem is that while both attributes in both files load properties into the System properties at startup, the behaviour differs when I make a change while JBoss is running.
The Properties attribute in properties-service.xml successfully reloads the properties. The URRList fails to reload the properties and both attributes in myapp-properties-service.xml fail to reload.
Am I mistaken in thinking all four cases should reload properties? My ideal solution would be to provide a URL to myapp-properties-service.xml.
Any suggestions? Thanks.
It will only reload them when you change *-service.xml file. Changing of the files it references is not enough. You must simply touch *-service.xml. I suspect the reason why it does not automatically detect changes is because this list can contain URLs and how do you expect it to know when these files have changed. Changing properties defined within the file works because your modifying the *-service.xml file itself which is watched by JBoss.