Spring MVC application.properties not override by profile file application-dev.properties - spring-mvc

I was looking at a way to configure different application.properties file depending on a JVM environnement variable.
I found this documentation on Spring references.
In addition to application.properties files, profile-specific properties can also be defined using the naming convention application-{profile}.properties.
Profile specific properties are loaded from the same locations as standard application.properties, with profile-specific files always overriding the default ones irrespective of whether the profile-specific files are inside or outside your packaged jar.
Then I did that :
Configuration structure
And then added a -Dspring.profiles.active=dev to my JVM options.
Profile option for JVM
I tried to see that my params in dev are used but it isn't the case. Te application loads the data from the application.properties file.
Any idea why?

Try to modify the default properties file's name to 'application-default.properties', as it is said in the documentation:
The Environment has a set of default profiles (by default [default]) which are used if no active profiles are set (i.e. if no profiles are explicitly activated then properties from application-default.properties are loaded).
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

Related

Generated test can't read property from application.yml

Just trying hands with Spring Cloud Contract. While running the generated test on provider side and when the application context is instantiated, it is unable to read config values from application.yml. When i move the test from generated build folder to src/test/java then issue is not seen anymore.
Which implies since build folder is outside of project src/.. structure, it can't read the config.
How can i fix it?
How do you access the value from application.yml
Let's suppose in application.yml you have the following content:
example:
baseUri: https://jsonplaceholder.typicode.com
You can simply access it in your test using:
#Value("${example.baseUri}")
String exampleBaseUri;
Additionally, if you want a profile just for tests you can create a file application-test.yml where you add properties. To access it values from this file you need to add before your test class:
#ActiveProfiles("test")

Mule 4 : Is there a way to refer Maven POM properties from a Mule Flow?

I want to refer the project name and version in the URL of the API. For example, my app is called sample-mule-project and has a version "v1". So my final URL should be like /sample-mule-project/v1/
Maven pom has these properties called name and version with which we can refer these values inside the pom file. Is there a way how we can refer these values inside the mule flow?
I tried using ${project.name} and ${project.version} but it did not work which I understand is because these are not defined inside properties file. So is there a way to achieve this?
That's because Maven properties do not exists anymore when the application is executed.
You can use some Maven plugins to replace values in a properties files, that can be used inside the application. For example the Maven Resources plugin. Be careful of not override properties inside other files, like the XML Mule configurations of the application.

Grails app.servlet.version OR grails.servlet.version?

Do I need to configure both app.servlet.version and grails.servlet.version?
The former is in application.properties and the latter in BuildConfig.groovy
Better safe than sorry? I just don't like redundancy.
See related:
Changing app.servlet.version does not affect web.xml
It would seem like you do not need to have or set an entry in application.properties IF there is an entry in your BuildConfig.groovy file.
To confirm this I looked in the grails war file creator (GrailsProjectWarCreator.groovy) code and saw that it does indeed use the apps BuildConfig setting to populate the application.properties file when building the war.

Change the default location of Runtime Shared Library files

To make my Ant Generated swf as small as possible, i used the Runtime Shared Library like described in this URL.
By default, the RSL files should be located with the compiled swf (without RSL).
Thus, do you know how can I change the location's property of the SRL files?
Because I have the compiled swf in many directories, that's why we should have only one resource of the RSL as well as in one separated directory
Have a look at an RSL linkage definition:
<runtime-shared-library-path>
<path-element>libs/framework.swc</path-element>
<rsl-url>http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/framework_4.6.0.23201.swz</rsl-url>
<policy-file-url>http://fpdownload.adobe.com/pub/swz/crossdomain.xml</policy-file-url>
<rsl-url>framework_4.6.0.23201.swz</rsl-url>
<policy-file-url></policy-file-url>
</runtime-shared-library-path>
The rsl-url nodes define where the application will look for the library. It will first try to get it from the first URL; if that fails it will try the second; and so on until it finds a link that works or fails.
You can add as many URL's as you like, but for framework RSL's you'll typically have a link to Adobe's repository as the first URL, and one fallback URL on your own server.
These URL's can be absolute or relative. If for instance you'd want you SDK RSL's to be located in a directory called 'sdk' under the same directory your application is in, just change the secondary rsl-url node to:
<rsl-url>sdk/framework_4.6.0.23201.swz</rsl-url>
The same principle applies if you wish to do it through compiler arguments. You could do it like this:
-runtime-shared-library-path=${swc},${swz.primary},http://fpdownload.adobe.com/pub/swz/crossdomain.xml,${swz.secondary}

Where to place and how to read configuration resource files in servlet based application?

In my web application I have to send email to set of predefined users like finance#xyz.example, so I wish to add that to a .properties file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using Netbeans IDE which is having two separate folders for source and JSP files.
It's your choice. There are basically three ways in a Java web application archive (WAR):
1. Put it in classpath
So that you can load it by ClassLoader#getResourceAsStream() with a classpath-relative path:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Here foo.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. webapp's /WEB-INF/lib and /WEB-INF/classes, server's /lib, or JDK/JRE's /lib. If the propertiesfile is webapp-specific, best is to place it in /WEB-INF/classes. If you're developing a standard WAR project in an IDE, drop it in src folder (the project's source folder). If you're using a Maven project, drop it in /main/resources folder.
You can alternatively also put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.
If you have placed the foo.properties it in a Java package structure like com.example, then you need to load it as below
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Note that this path of a context class loader should not start with a /. Only when you're using a "relative" class loader such as SomeClass.class.getClassLoader(), then you indeed need to start it with a /.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
However, the visibility of the properties file depends then on the class loader in question. It's only visible to the same class loader as the one which loaded the class. So, if the class is loaded by e.g. server common classloader instead of webapp classloader, and the properties file is inside webapp itself, then it's invisible. The context class loader is your safest bet so you can place the properties file "everywhere" in the classpath and/or you intend to be able to override a server-provided one from the webapp on.
2. Put it in webcontent
So that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext() and in Filter by FilterConfig#getServletContext(). In case you're not in a servlet class, it's usually just injectable via #Inject.
3. Put it in local disk file system
So that you can load it the usual java.io way with an absolute local disk file system path:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Note the importance of using an absolute path. Relative local disk file system paths are an absolute no-go in a Java EE web application. See also the first "See also" link below.
Which to choose?
Just weigh the advantages/disadvantages in your own opinion of maintainability.
If the properties files are "static" and never needs to change during runtime, then you could keep them in the WAR.
If you prefer being able to edit properties files from outside the web application without the need to rebuild and redeploy the WAR every time, then put it in the classpath outside the project (if necessary add the directory to the classpath).
If you prefer being able to edit properties files programmatically from inside the web application using Properties#store() method, put it outside the web application. As the Properties#store() requires a Writer, you can't go around using a disk file system path. That path can in turn be passed to the web application as a VM argument or system property. As a precaution, never use getRealPath(). All changes in deploy folder will get lost on a redeploy for the simple reason that the changes are not reflected back in original WAR file.
See also:
getResourceAsStream() vs FileInputStream
Adding a directory to tomcat classpath
Accessing properties file in a JSF application programmatically
Word of warning: if you put config files in your WEB-INF/classes folder, and your IDE, say Eclipse, does a clean/rebuild, it will nuke your conf files unless they were in the Java source directory. BalusC's great answer alludes to that in option 1 but I wanted to add emphasis.
I learned the hard way that if you "copy" a web project in Eclipse, it does a clean/rebuild from any source folders. In my case I had added a "linked source dir" from our POJO java library, it would compile to the WEB-INF/classes folder. Doing a clean/rebuild in that project (not the web app project) caused the same problem.
I thought about putting my confs in the POJO src folder, but these confs are all for 3rd party libs (like Quartz or URLRewrite) that are in the WEB-INF/lib folder, so that didn't make sense. I plan to test putting it in the web projects "src" folder when i get around to it, but that folder is currently empty and having conf files in it seems inelegant.
So I vote for putting conf files in WEB-INF/commonConfFolder/filename.properties, next to the classes folder, which is Balus option 2.
Ex: In web.xml file the tag
<context-param>
<param-name>chatpropertyfile</param-name>
<!-- Name of the chat properties file. It contains the name and description of rooms.-->
<param-value>chat.properties</param-value>
</context-param>
And chat.properties you can declare your properties like this
For Ex :
Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.
It just needs to be in the classpath (aka make sure it ends up under /WEB-INF/classes in the .war as part of the build).
You can you with your source folder so whenever you build, those files are automatically copied to the classes directory.
Instead of using properties file, use XML file.
If the data is too small, you can even use web.xml for accessing the properties.
Please note that any of these approach will require app server restart for changes to be reflected.
Assume your code is looking for the file say app.properties. Copy this file to any dir and add this dir to classpath, by creating a setenv.sh in the bin dir of tomcat.
In your setenv.sh of tomcat( if this file is not existing, create one , tomcat will load this setenv.sh file.
#!/bin/sh
CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"
You should not have your properties files in ./webapps//WEB-INF/classes/app.properties
Tomcat class loader will override the with the one from WEB-INF/classes/
A good read:
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Resources