Can't build maven project using different profiles - maven

I'm trying to build project through maven using different profiles.
I store data to connect to database in file jdbc.properties:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://${db.connectionURL}/shopsstore?useUnicode=yes&characterEncoding=UTF-8
jdbc.username=${db.username}
jdbc.password=${db.password}
And here is my mvc-dispatcher.xml
<bean id="propertyConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
And pom.xml
<profiles>
<profile>
<id>dev</id>
<properties>
<db.username>root</db.username>
<db.password>root</db.password>
<db.connectionURL>localhost:3306</db.connectionURL>
<db.driverClass>com.mysql.jdbc.Driver</db.driverClass>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<db.username>prod-root</db.username>
<db.password>prod-admin</db.password>
<db.connectionURL>localhost:3306</db.connectionURL>
<db.driverClass>com.mysql.jdbc.Driver</db.driverClass>
</properties>
</profile>
</profiles>
And when i run build i get following exception:
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'dataSource' defined in ServletContext resource [/WEB-INF/mvc-dispatcher-servlet.xml]: Could not resolve placeholder 'db.password' in string value "${db.password}"
Seems like properties are not available. Any ideas what's going on?
P.S I'm using Intellij IDEA
EDITED
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- specify UTF-8, ISO-8859-1 or any other file encoding -->
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- Enabling and configuring web resources filtering -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp/WEB-INF/</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/webapp/WEB-INF/</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

You will have to use the maven-resources-plugin to automatically update the jdbc.properties during build based on the properties set in the profile.
Refer
http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
You have to set <filtering>true</filtering> to enable property replacement in the resources files
As you are using web resources,try changing the maven-war-plugin configuration to
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
<includes>
<include>**/jdbc.properties</include>
</includes>
</resource>
</webResources>
</configuration>

Related

Unable to remove specific files from Maven build

I am currently working over Maven build. I want to remove specific file from my Maven build. I am currently trying with below code:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources</directory>
<!-- override the destination directory for this resource -->
<targetPath>WEB-INF/classes</targetPath>
<!-- enable filtering -->
<filtering>true</filtering>
<includes>
<include>*.pem</include>
<include>*.pfx</include>
<include>META-INF/jpa-persistence.xml</include>
<include>META-INF/spring-persistence.xml</include>
<include>com/abc/config/build-config-${propertyenv}.properties</include>
</includes>
<excludes>
<exclude>%regex[(?!.*${propertyenv}/)*]</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
I have defined propertyenv as property value in my POM:
<properties>
<propertyenv>abc</propertyenv>
</properties>
I only want abc.properties file from com/abc/config folder. But after build all .properties files are present. Kindly help.
Use packagingExcludes or packagingIncludes Parameters to include or exclude files from the final war
Example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
....
<configuration>
....
<packagingExcludes>
WEB-INF/lib/pax-logging-*.jar, WEB-INF/lib/jaxb-*-2.2.7.jar
</packagingExcludes>
</configuration>
</plugin>

Can't add dynamic property to Maven's resource located at build path

I'm trying to setup properties in my config.ini which located in src/main/config by using pom.xml as described in this answer, but it doesn't work.
I've placed to src/main/config file config.ini where the following line is present: runtime_mode=${runtime.mode} when I try to access at runtime runtime_mode key I get string ${runtime.mode} instead of DEBUG or PRODUCTION as defined in pom.xml. When I use ${runtime.mode} in *.html file it's being replaced by appropriate value as expected.
So, it doesn't work only when resource located at build path.
I suspect that I define resource in a wrong way, but can't realize what's wrong.
This is build part of my pom.xml:
<project>
<properties>
<runtime.mode>DEBUG</runtime.mode>
</properties>
<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/config</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>bower.json</include>
<include>index.html</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
My app is a war project created by using the following archetype:
<archetype>
<groupId>com.ibm.tools.archetype</groupId>
<artifactId>webapp-jee7-liberty</artifactId>
<version>1.0</version>
<description>JEE7 web application targeting WebSphere Liberty archetype</description>
</archetype>
UPDATE:
Moved my config.ini to src\main\resources and changed my <resource> tag as following:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>config.ini</include>
</includes>
</resource>
</resources>
But now I can't read any resource located in src/main/resources from code, for example I put there sql.xml where all my sql queries.
Trying read by following code:
private static Properties readProperties(String xmlFileName) throws Exception {
Properties properties = new Properties();
InputStream is = SQLProvider.class.getClassLoader().getResourceAsStream(xmlFileName);
properties.loadFromXML(is);
return properties;
}
But it throws an error:
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203) ~[?:1.8.0_45]
at java.util.Properties.loadFromXML(Properties.java:881) ~[?:1.8.0_45]
at ***.SQLProvider.readProperties(SQLProvider.java:26) ~[classes/:?]
try to use maven-replacer-plugin you can replace any token defined in external file.
Example
<properties>
<runtime.mode>DEBUG</runtime.mode>
</properties>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<ignoreMissingFile>false</ignoreMissingFile>
<file>path to file/config.ini</file>
<regex>false</regex>
<replacements>
<replacement>
<token>$runtime.mode$</token>
<value>${runtime.mode}</value>
</replacement>
</replacements>
</configuration>
</plugin>

How to exclude separate files with nonFilteredFileExtension

I have this bundle.
admin.common.upper_case=Uma ou mais letras maiúsculas
During building project this bundle becomes corrupted.
admin.common.upper_case=Uma ou mais letras mai�sculas
In order to fix issue we use this configuration for maven-resources-plugin
Namely we added nonFilteredFileExtension tag for properties extension.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>properties</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
This configuration caused issue with another property file like build.properties :
build.version=${project.version}
static.url.version=${project.build.timestamp}
We tried to use this configuration(namely added filter tag in order to filter build.properties file):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<filters>
<filter>properties/build.properties</filter>
</filters>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>properties</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
Also we tried with this configuration in order to avoid filtering for current bundles:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources</directory>
<!-- enable filtering -->
<filtering>true</filtering>
<excludes>
<exclude>${basedir}/src/main/resources/one.properties</exclude>
<exclude>${basedir}/src/main/resources/two.properties</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
The question is how to allow filtering only for this property file build.properties
First of all, you should try to fix the root of your problem by Specifying a character encoding scheme:
<project ...>
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
...
</properties>
..
</project>
One way to do what you want is to specify files to include and files to excludes. From the documentation:
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/my-resources</directory>
<includes>
<include>**/*.txt</include>
</includes>
<excludes>
<exclude>**/*test*.*</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
The elements include and exclude should also works with specific files such as path/to/abc.properties.

Not getting values from properties files in context.xml file

I am unable to retrieve value from .properties file into my context.xml
pom.xml ( didn't mention dependencies )
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>myproj</artifactId>
<version>0.1.1</version>
<packaging>war</packaging>
<name>myproj</name>
<url>http://maven.apache.org</url>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>dev</env>
<build.number>0</build.number>
<svn.revision.number>0</svn.revision.number>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/environment</directory>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.8</version>
<configuration>
<printSummary>false</printSummary>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<excludes>
<exclude>**/*_Roo_*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.7</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
<wtpversion>2.0</wtpversion>
<additionalBuildcommands>
<buildCommand>
<name>org.eclipse.ajdt.core.ajbuilder</name>
<arguments>
<aspectPath>org.springframework.aspects</aspectPath>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
</buildCommand>
</additionalBuildcommands>
<additionalProjectnatures>
<projectnature>org.eclipse.ajdt.ui.ajnature</projectnature>
<projectnature>com.springsource.sts.roo.core.nature</projectnature>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warName>myproj</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
context.xml (inside src/main/webapp/META-INF)
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- Specify a JDBC datasource -->
<Resource name="jdbc/mydb" auth="Container"
type="javax.sql.DataSource" username="${database.usernameee}" password="${database.password}"
driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sybase://localhost:9000/common_db"
maxActive="10" maxIdle="4" />
</Context>
I have some .properties files inside under:
src/main/resources
src/main/environment/dev
I am unable to get values inside my context.xml of ${database.usernameee} and ${database.password}
please suggest what went wrong?
Do the following:
1) Remove the <resources> section. It's not needed for the filtering you want to do and src/main/resources is the default - it doesn't need to specified separately.
<build>
<!-- Delete the <resources> section -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/environment</directory>
<filtering>false</filtering>
</resource>
</resources>
2) Add a <filters> element under <build> specifying the environment specific properties file
<build>
<filters>
<filter>src/main/environment/${env}/some.properties</filter>
</filters>
...
The above assumes your properties files are called some.properties - so change this to the real name of your file.
3) Modify the configuration of the maven-war-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/META-INF/context.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<warName>myproj</warName>
</configuration>
</plugin>
That will now filter the context.xml using the environment specific properties - depending upon what profile you used.
(note that you may have a typo in 'database.usernameee' - as it has extra ee at the end)
If you want to get your Maven properties from external files (not from properties inside POM's), you should use Maven Filters: see here and here.

Maven multi-module multi-profile project with shared resources

I'm trying to have my resources copied into a classpath depending on which profile was selected using maven. My resources folder structure is as following:
src/main/resources:
config
production
development
staging
My current not-working config is
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>envtype</name>
<value>dev</value>
</property>
</activation>
<build>
<finalName>Corelay</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<excludes>
<exclude>**/production/**</exclude>
<exclude>**/staging/**</exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<excludes>
<exclude>**/production/**</exclude>
<exclude>**/staging/**</exclude>
</excludes>
</testResource>
</testResources>
</build>
</profile>
In hibernate configuration file under config/hibernate/hibernate-config.xml i request some properties from same package
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:**/jdbc.properties</value>
<value>classpath*:**/hibernate.properties</value>
</list>
</property>
</bean>
but there is an error:
Could not resolve placeholder 'jdbc.driverClassName' in string value "${jdbc.driverClassName}"
this property is defined in that file. What's wrong? And another question is how to make resources copied from those profile folders appear in exactly same output classpath structure? I mean there should be no /production, /development or /staging : just /env
I know I could just put them into separate in but then if there are shared ones (like config in the presented structure) how could I include it too?
Create a folder src/main/config at the same level as src/main/resources. Inside create 3 sub-folders common, dev and production:
|__common
| |__common.properties
|__dev
| |__dev.properties
|__prod
| |__prod.properties
Then configure two profiles, dev and production:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/config/common</directory>
</resource>
<resource>
<directory>src/main/config/dev</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>prod</id>
<build>
<resources>
<resource>
<directory>src/main/config/common</directory>
</resource>
<resource>
<directory>src/main/config/prod</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
With this, mvn clean install copies common.properties and dev.properties to the root of the classpath, as the dev profile is active by default.
mvn clean install -Pprod will then install common.properties and production.properties, but no dev.properties, and also to the root of the classpath.

Resources