How to read application.properties from POM.xml - java

I'm not able to find out if it is possible to read any data in Spring's application.properties in the pom.xml file.
In my application-dev.properties file, I have an attribute:
google.project.id = 123456789
In my application-test.properties file, I have an attribute:
google.project.id = 987654321
In my application.properties file, I have an attribute. At one point I set it up for DEV at another time for TEST:
spring.profiles.active=dev
In my pom.xml file, I would like to read this project id according to the configuration in the spring.profiles.active attribute:
<configuration>
<projectId> PROJECT ID ???</projectId>
<version>1</version>
</configuration>
Please, could someone help me?
Thank you.

POM.xml is part of maven project build and has nothing to do with spring.
Spring framework has no idea about pom file.

Related

Read POM values in external application properties

I have the following properties in the pom file
<name>DemoApplication</name>
<description>Demo spring project</description>
<version>1.0.0-SNAPSHOT</version>
And I have a class that reads the properties from application.yml
But instead of using the application.yml under src/main/resources I am specifying the properties through an external file as follows
java -jar DemoApplication-1.0.0-SNAPSHOT.jar --spring.config.location=application.yml
In this external application properties, I have the following attributes
swagger:
apiTitle: '#project.name#'
apiDescription: '#project.description#'
apiVersion: '#project.version#'
The issue is that the #project.name# and other properties are not being replaced as expected, but are read as-is.
How should the problem be approached?
According that section of the official documentation of Spring Boot v2, you can configure it with :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
With useDefaultDelimiters set to false or to true depending on your configuration.
The others sections of that official documentation will be helpful for your use case, especially these one : "77.5 Use YAML for External Properties".
If nothing is working, why don't you are loading a custom Properties file ? It could be loaded as you need without any problem. Just reference it with the correct path when you are starting your program, and inside your program, test if your file config.properties is available and contains what you need to work with.
Of course, the Maven way of loading resources files is the best easy way to go, and it should be a simple Properties file too. I have done exactly that way inside the software I am released to manage my configuration :
Writing a app.properties
Loading that file with Maven at runtime with resource configuration
Expanding properties with classical syntax ${my.prop}
Run the program with a Maven task.
Of course, when you distribute your app as a jar, it is a bit different.
Maybe you can try to write your properties files within a Maven goal.

SpringBoot: How to make profile specific resources

I have profiles: dev, prod.
And my homepage located at /src/main/resources/static/index.html
How to make different homepage with different profile?
For example, /src/main/resources/static-dev/index.html and /src/main/resources/static-prod/index.html.
Any advice?
Finally I got a simple solution.
Use different config file application.properties and application-prod.properties.
Each of them I config a different resource location. For example spring.resources.static-locations=classpath:/static-dev/.
If your project supports the Maven dependency manager, Maven's build profiles may be able to help you:
<profile>
<id>live</id>
<properties>
<environment>live</environment>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${environment}</directory>
</resource>
</resources>
</build>
</profile>
The code above should be in your pom.xml. In your Spring properties you can specify the active profile in one line:
spring.profiles.active=live
This should be enough to conditionally load any resources.
Both resources should be put under /src/main/resources/static (since this is the default static resource folder IIRC) and then categorized into /prod and /dev. Then in your #GetMapping controller, choose to return /prod/index or /dev/index based on your condition
You can create a Filter that changes the request URL from /index.html to /dev/index.html or /prod/index.html as needed.
The filter can also do the /dev or /prod prefixing for .css and .js files.
Unless all your files are split between dev and prod, you'd probably need an explicit list of which requests should be prefixed.

How to locate Thymeleaf template from spring boot

I am trying to follow this tutorial at http://www.thymeleaf.org/doc/articles/springmvcaccessdata.html to learn how to send responses to Thymeleaf template. But I get this error: Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
I put the message.html file in Other Sources directory and inside src/main/resources under <default package>.
So the structure looks like :
SomeProject
-Other Sources
--src/main/resources
---<default package>
----message.html
I was wondering why it shows under <default package> but not under <template> ? Could it be the problem? If so how am I supposed to change it? I am using netbeans and maven. Any ideas please? These are the dependencies I have in my pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
In the controller I have
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("messages", messageRepository.findAll());
return "message";
}
And in the view:
<ul th:each="message : ${messages}">
<li th:text="${message.id}">1</li>
<li>Title ...</li>
<li th:text="${message.text}">Text ...</li>
</ul>
Spring Boot includes auto-configuration support for the thymeleaf templating engines, your templates will be picked up automatically from src/main/resources/templates.
if you are customize you template location then use below thymeleaf property configuration available in Spring Boot.
spring.thymeleaf.check-template=true # Check that the template exists before rendering it.
spring.thymeleaf.check-template-location=true # Check that the templates location exists.
spring.thymeleaf.enabled=true # Enable MVC Thymeleaf view resolution.
spring.thymeleaf.prefix=classpath:/templates/ # Prefix that gets prepended to view names when building a URL.
spring.thymeleaf.suffix=.html # Suffix that gets appended to view names when building a URL.
The default directory location for thymeleaf templates is:
src/main/resources/templates
The other paths are standard conventions for Spring Boot.
2 things here :
1. If you are using Maven, and I assume no customizations to folder names. Then the folder name should be src instead of source.
2. Once the folder has been renamed move your templates into 'templates' folder inside src/resources this should run fine.
For Thymeleaf template files put in folder src/main/resources/templates/ and it will work for you also do check out http://www.mkyong.com/spring-boot/spring-boot-hello-world-example-thymeleaf/ . Hope you will find it easy to kick start thymeleaf with spring boot.
I had the same problem with Spring boot + Gradle and these are the steps that I followed to resolve it:
Print out the classpath
Once I established that the resources folder was not being included in the classpath, I reloaded the application from disk:
Gradle clean the project
I see a lot of issues regarding the ThymeLeaf /templates not found problem.
For everyone using Eclipse or STS the solution is maybe simpler then any type of configuration.
In the course of the project operation with maven, that is compile, clean, build and others, the final deployment Output Directory on your eclipse workspace (or staging area)
[eclipseprojectrootfolder]/target/
can erase some of the output directory structure and not re-created them it properly.
In my case I went for all sorts of solutions on application.properties, changing the autoconfig on the Spring app to no avail.
The solution was simple:
Just look inside
[eclipseprojectrootfolder]/target/classes
and see if in that directory you can find the directories
[eclipseprojectrootfolder]/target/classes/templates/
and
[eclipseprojectrootfolder]/target/classes/static/
Those are the folders inside the resources directory:
[eclipseprojectrootfolder]/src/main/resources
simply Copy the folders inside [eclipseprojectrootfolder]/src/main/resources, that is the
/templates
/static
into [eclipseprojectrootfolder]/target/classes
That is the Solution.
Spring is complaining exactly because of that ..can not find /templates ... because the directory on the Output deployment folder/directory may indeed not be there ...
Just recreate the directory manually and all will be fine.
Important note, Of course when I mention that a manual copy of the directories may be necessary this means we need to recreate the directories And the files inside that are the templates and static content for thymeleaf.

How to access the values set in profiles (in pom.xml) via java code

I have a maven project with different profiles set in pom.xml with different values. But I don't know how to access those values set in profile via java code.
For example-
My pom.xml:
<profile>
<id>scaler</id>
<properties>
<user>xxxxxxx</user>
<secret>yyyyyyyy</secret>
<proxyHost>172.19.17.13</proxyHost>
<proxyPort>9444</proxyPort>
<environment>SCALER</environment>
</properties>
</profile>
Java code-
String serviceurl = "http://"<proxyhost>":<proxyPort>/";
In the above java code, i want to use proxy host as 172.19.17.13 & port as 9444 as defined in pom.xml but how to access those values from pom??
I will appreciate your help
You should use the maven filtering feature.
http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
Just add a property file in src/main/resources with some placeholders:
key=${myvalue}
then myvalue should be defined as a property in your pom.xml
Be sure to activate the filter on your resources:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
I'm not sure it depends on maven profile. You can try to use properties-maven-plugin (or other solution) like it described here. Just to write your properties into file and then use it in java code.

Adding classpath to jetty running in maven integration-test

I'm trying to set up integration tests for a Maven project that produces a war file. (As seen here http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin/.) However I the war file requires a bunch of .properties files on the classpath, that I don't want to bundle in the war.
Is there a way (preferably through plugin configuration) to add a folder to the classpath used by jetty?
I Googled this and found http://markmail.org/message/awtqrgxxttra3uxx but this, as far as I can tell, does not actually work at all. The .properties files are not found.
This should be possible using the webAppConfig configuration element (sample below taken from this thread):
<webAppConfig>
<contextPath>/nportal</contextPath>
<!-- All I want to do here is add in the /etc/jetty/classes for runtime files. For some reason I have to also add back in the /target/classes directory -->
<extraClasspath>${basedir}/target/classes/;${basedir}/etc/jetty/classes/</extraClasspath>
</webAppConfig>
If you find that the above solution doesn't work for you, consider including the test classpath into your Jetty configuration.
<configuration>
<useTestClasspath>true</useTestClasspath>
...
</configuration>
This will then allow you to place all manner of resources/classes on the test classpath and have them visible to the Jetty server without them creeping into the production code.
You can place your additional configuration files under /src/test/resources and set a property <useTestScope>true</useTestScope> in the plugin configuration as specified here:
useTestScope
If true, the classes from testClassesDirectory and dependencies of scope "test" are placed first on the classpath. By default this is false.

Categories

Resources