I have maven pom with 2 profiles: dev and production
I have some xml files in my project. For example persistence.xml . Settings for dev and production environments are different
I need a way to have right files in dev and production assemblies
Maybe possible to have 2 copies of each xml file and put into assemblies right one? Or maybe possible to use settings from pom file inside xml file ?
Any other ideas or best practices?
What you are looking for was already answered here: Maven: include resource file based on profile
Instead of having two files, another solution would be to use properties directly inside the properties.xml:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="${db.username}"/>
<property name="hibernate.connection.password" value="${db.password}"/>
<property name="hibernate.connection.url" value="${db.connectionURL}/database"/>
In your pom.xml, define a value for each property for each environment:
<profile>
<id>development</id>
<properties>
<db.username>dev</db.username>
<db.password>dev_password</db.password>
<db.connectionURL>http://dev:3306/</db.connectionURL>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<db.username>prod</db.username>
<db.password>prod_password</db.password>
<db.connectionURL>http://prod:3306/</db.connectionURL>
</properties>
</profile>
You could then use filtering to enable token replacement by the right value in each environement:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
For mode details on this solution look at this page.
If you really need to have two copy of the same file, you could also use the
Related
I have multiple TestSuites files.
And I want to set parameter variable in my suite files from POM file. But I couldn't get any suggestion from Google search.
Could anyone help me how can I perform it.
For example.
ABC.xml [File #1]
<parameter name="property_file" value="C:/a.properties" />
DEF.xml [File #2]
<parameter name="property_file" value="C:/a.properties" />
And I want to set Property_file parameter value from Maven pom.
I want to set "C:/123.properties" for File #1 and "C:/456.properties" for File #2.
My suite file may look like_
<suiteXmlFiles>
<suiteXmlFile>ABC.xml</suiteXmlFile>
<suiteXmlFile>DEF.xml</suiteXmlFile>
</suiteXmlFiles>
I don't want to set parameter in TestNG file, I want to do it from POM file.
Is it possible?
Yes, it is possible. You can filter with the maven ressources plugin. Have a look:
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
If the article doesn't answer all your questions, don't hesitate to ask.
In summary you can do something like this:
<project>
...
<properties>
<suiteXmlFile>ABC.xml</suiteXmlFile>
</properties>
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
...
</resources>
...
</build>
...
</project>
and in your xml file within the resources folder you use
<parameter name="property_file" value="${suiteXmlFile}" />
What is not possible (at least in a simple way) is to implement a maven magic that interprets the same property differently within each xml file. In this case you have to use differently named properties. (e.g. suiteXmlFile1, suiteXmlFile2)
#niklas-p 's answer is good but in the case of test resources, you should use testResources instead.
<project>
...
<properties>
<property_file>C:/a.properties</property_file>
</properties>
...
<build>
...
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
...
</testResources>
...
</build>
...
</project>
Then, the filtered resources will be located in the ${project.build.testOutputDirectory} directory:
<suiteXmlFiles>
<suiteXmlFile>${project.build.testOutputDirectory}/ABC.xml</suiteXmlFile>
<suiteXmlFile>${project.build.testOutputDirectory}/DEF.xml</suiteXmlFile>
</suiteXmlFiles>
And in suite files:
<parameter name="property_file" value="${property_file}" />
I have a JDBC.properties file that contains db connection information
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://127.0.0.1/mydb
jdbc.username=root
jdbc.password=
Now when I use it in the server my info changes
jdbc.username=root
jdbc.password=mypassword
What I do now is manually change this information before making war file and upload it to the server.
Now I was wondering if there is any way I could set this information so that i don't have to change this information every time before upload
How to do this??
Don't put your properties inside your war file. Externalize them. Put them somewhere in a well known path (/etc/myapp/jdbc.properties).
You shouldn't be creating different artifacts for your production,development and test environment. It should be the same. Recreating the artifact means a new version which (in theory) means new testing. Even if you use maven profiles.
The approach I tend to use is to put some defaults in an internal properties file and optionally load a file from outside the war. That way you provide your users with the possibility to override the default configuration.
<context:property-placeholder location="classpath:/jdbc.propertes,file:/etc/myapp/jdbc.properties" igonre-resource-not-found="true" />
That way your defaults are inside the application and users can override it by specifying other properties in the /etc/myapp/jdbc.properties file.
You could use spring profiles. This blog post should give you the idea: http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/
You should use a build tool like Maven and do this with resource filtering and profiles.
Doing it through Spring profiles is probably one way, but in my opinion it makes more sense to be handling it through the build.
Consider the following with Maven:
src/main/resources/jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=${jdbc.databaseurl}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}
pom.xml:
<project ...>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
...
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<jdbc.databaseurl>jdbc:mysql://127.0.0.1/mydb</jdbc.databaseurl>
<jdbc.username>username</jdbc.username>
<jdbc.password>password</jdbc.password>
</properties>
...
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<jdbc.databaseurl>jdbc:mysql://212.123.45.6/mydb</jdbc.databaseurl>
<jdbc.username>username</jdbc.username>
<jdbc.password>secret-password</jdbc.password>
</properties>
...
</profile>
</profiles>
...
</project>
For development, invoke:
mvn clean package ... -Pdev
Likewise for production:
mvn clean package ... -Pprod
Maven filtering allows you to replace properties in your .properties resources based on properties defined in Maven via <properties/> (either in a profile, or not).
References:
- Resource filtering
- Profiles
mvn -P dev
If I build my project using profile dev, then I want to use dev.properties in my spring bean like below. Is it possible ? If so , how could I get profile name ?
<bean id="xyz" class="abc.xyz">
<property name="propertyFile" value="${maven_profile_id}.properties" />
</bean>
Thanks in advance.
You can use Maven profiles to add a 'profile' property to the build:
<profiles>
<profile>
<id>dev</id>
<properties>
<profile>dev</profile>
</properties>
</profile>
</profiles>
Then pass the value into your application using a system property, here's an example with surefire:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<profile>${profile}</profile>
</systemPropertyVariables>
</configuration>
</plugin>
Finally this can be referenced in you application:
<bean id="xyz" class="abc.xyz">
<property name="propertyFile" value="${profile}.properties" />
</bean>
Alternatively, if you are using Spring 3.1 or later you might find the XML profile feature meets your needs (although it may be overkill).
Create a properties file that will be populated using Maven's resource filtering that specifies the profile you are using at build time.
build.properties
activatedProfile=${profileId}
pom.xml (You don't need to filter the complete directory, customise as required)
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resources>
</build>
Add a profileId (or whatever you want to call it) property under each different profile:
<profile>
<id>dev</id>
<properties>
<profileId>dev</profileId>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<profileId>qa</profileId>
</properties>
</profile>
You can then use ${activatedProfile}.properties as value for a bean
<bean id="xyz" class="abc.xyz">
<property name="propertyFile" value="${activatedProfile}.properties" />
</bean>
I have a jms connection settings that is defined in jndi.properties file on my classpath which I used to connect to ActiveMQ in my local development environment. I would like to rename this file to "activemq.jndi.properties" as I am planning to have another jms connection settings to WebsphereMQ ( say webshperemq.jndi.properties ). However I have no success so far in telling spring in my applicationContext.xml to look at activemq.jndi.properties.
Here is a snippet of my applicationContext.xml which works for jndi.properties
<!-- Define how to connect to the Message Queueing system -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${jms.connectionFactory}" />
<property name="resourceRef" value="true" />
</bean>
<bean id="defaultDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${jms.topic}" />
<property name="resourceRef" value="true" />
</bean>
<!-- Define a connection template that links to the factory -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestination" ref="defaultDestination" />
<property name="receiveTimeout" value="6000" />
</bean>
Both ${jms.connectionFactory} and ${jms.topic} are being filtered from maven. Any input on what needs to be changed in my applicationContext.xml to make it load from activemq.jndi.properties would be much appreciated.
Thanks!
Well, Ithink you should configure maven resources so use one of another configuration file depending of the profile instead change anything in your Spring configuration file.
For example:
<profiles>
<profile>
<id>local</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>jndi.properties</exclude>
</excludes>
</resource>
</resources>
</build>
</profile>
<profile>
<id>webshpere</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>webshperemq.jndi.properties</exclude>
</excludes>
</resource>
</resources>
</build>
</profile>
</profiles>
at my project there is 2 profiles and each profile has one property.
But I could not use master's properties at child's resources.
Here is described clearly but it seems that there is only one pom file and the sample shown at there is not an multi-module maven project.
All I want to do is use this properties at spring level like changing the location of properties file.
<profile>
<id>p1</id>
<properties>
<properties.location>file:/apps-core1.properties</properties.location>
</properties>
</profile>
<profile>
<profile>
<id>p2</id>
<properties>
<properties.location>file:/apps-core2.properties</properties.location>
</properties>
</profile>
<profile>
and I want to use "properties.location" at every pom file I had, either main-resources or test-resources.
here is the spring usage
<context:property-placeholder location="\${properties.location}" />
i got it working with a multi-module project with:
parent pom with <modules /> config and your profiles
module pom with following config
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
see maven resources and filtering