Property replacement on modular project - java

I'm working on a modular maven project. The skeleton of my project is the following:
|-- parent
|-- model
--pom.xml
|-- services
--pom.xml
|-- web-app
--pom.xml
In the model module I have the persistence.xml file with some property references:
<persistence>
<persistence-unit name="myUnit">
//Some classes definition
<properties>
<property name="javax.persistence.jdbc.driver" value="${db.driverClass}" />
<property name="javax.persistence.jdbc.url" value="${db.connectionURL}" />
<property name="javax.persistence.jdbc.user" value="${db.username}" />
<property name="javax.persistence.jdbc.password" value="${db.password}" />
</properties>
</persistence-unit>
and I enable the resources filtering in the model's pom.xml through
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Now I should want to define a profile in the web-app's pom.xml
<profiles>
<profile>
<id>Development</id>
<properties>
<db.driverClass>MyDriver</db.driverClass>
<db.connectionURL>jMyUrl</db.connectionURL>
<db.username>MyUsername</db.username>
<db.password>MyPassword</db.password>
</properties>
</profile>
</profiles>
<!-- To launch embded jetty server -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${maven-jetty-plugin.version}</version>
</plugin>
and replacement the references with the values when I run "mvn jetty:run -P Development".
But this not work.
How can I do to solve it?

Maven uses a hierarchical approach.
This means that profiles are only active in the module they are defined and their children. Same goes for properties.
In your case, your file to filter is in a sibling module of the one you are defining the properties. Therefore they are not propagated to the model module

mvn jetty:run does not copy your resources, and thus does not filter. It is mainly designed to work in conjunction with an IDE, i.e. you change something, the IDE compiles/copies your changes.
If you call it from the console, you need to explicitly run the lifecycle (or at least the process-resources phasein your case).
So try something like
mvn process-classes jetty:run
Ideally, you could split the execution into two separate shells, one running jetty:run and the other running mvn process-classes on demand.
Or use an IDE.

Related

Maven: profile properties not be picked up when running test

In pom.xml, I define a property:
<profile>
<id>local</id>
<properties>
<build.profile.id>local</build.profile.id>
<serverBaseUrl>http://127.0.0.1:8080</serverBaseUrl>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
And the serverBaseUrl was referenced in file application-email.xml:
<bean id="MailService" class="someclass">
<property name="aurl" value="${serverBaseUrl}"/>
</bean>
I expect that, when running test, using IntelliJ IDEA or using Maven test, ${serverBaseUrl} can be pick up from pom.xml automatically. However, it does not work like what I expect.
When not running test, the thing works exactly what I expect.
What's the problem here? Does maven or IntelliJ IDEA won't pick up profile properties when running test by default? How can I pick up profile's properties when I running the test?
Currently, I have a workaround: Define serverBaseUrl=xxx in config.properties and the property is picked up. This is a little ugly what I want to avoid.
This is more like a shot in the dark, I could not test it.
Add the resources tag in the build section of your pom.xml:
<build>
.....
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>application-email.xml</include>
</includes>
</testResource>
</testResources>
....
</build>
I suppose your application-email.xml is inside src/test/resources folder.

Profile activation in appengine:deploy

I'm trying to activate profiles of an AppEngine application using the maven command like the following :
mvn appengine:deploy -Dspring.profiles.active=prod
But it is ignored.
Is it possible to activate profiles using maven ?
I succeeded by linking Maven Profiles to Spring Profiles. In the following I explain how I did :
1 - Create Maven Profiles:
In pom.xml I identified my maven profiles, and will link them later to spring profiles by storing them in "spring.profiles.to.activate" property :
<!-- PROFILES -->
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.to.active>dev</spring.profiles.to.active>
</properties>
</profile>
<profile>
<id>uat</id>
<properties>
<spring.profiles.to.active>uat</spring.profiles.to.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.to.active>prod</spring.profiles.to.active>
</properties>
</profile>
</profiles>
2 - Activate Maven filtering :
I activated filtering in folder ${basedir}/src/main/webapp, by adding maven-war-plugin to build.
This will allow us to resolve placeholders ${...} (In this particular case ${spring.profiles.to.activate}) in the mentioned folder.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resources>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resources>
</webResources>
</configuration>
</plugin>
3- Activate profile Spring
In appengine-web.xml declare the system property : "spring.profiles.active" as being the maven property ${spring.profiles.to.activate}
<appengine-web-app
xmlns="http://appengine.google.com/ns/1.0">
<version>1</version>
<threadsafe>true</threadsafe>
<runtime>java8</runtime>
<system-properties>
<property name="spring.profiles.active" value="${spring.profiles.to.active}" />
</system-properties>
</appengine-web-app>
4 - Deploy to Appengine
# Dev
mvn appengine:deploy -Pdev
# UAT
mvn appengine:deploy -Puat
#PROD
mvn appengine:deploy -Pprod
#dev profile, try adding space between -P and dev
mvn appengine:deploy -P dev
#uat profile, try adding space between -P and uat
mvn appengine:deploy -P qa
#prod profile, try adding space between -P and prod
mvn appengine:deploy -P prd

How to change hibernate.cfg.xml file path through maven when building project?

I have Date base project as snapshot in nexus server which is using as dependency in my two web projects(test and production). but I am using two different databases for those two web projects. I want to use test data base for test web project and production data base for production web project. So I want to change hibernate configuration file path based on web project when the project is building in jenkins. My code snippet like this.
DBUtil.java
public class DBUtils {
private static SessionFactory sessionFactory;
private DBUtils() {
}
static {
Configuration configuration = new Configuration();
configuration.configure("/hibenateconfigpath");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
pom.xml
<repositories>
<repository>
<id>snapshots</id>
<name>Snapshots</name>
<url>url/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.my</groupId>
<artifactId>DBAccess</artifactId>
<version>0.0002-SNAPSHOT</version>
</dependency>
Please provide any solution to this with maven profiles or what ever it is.
You can use maven profiles to build your project. You have to define the profiles in your pom.xml:
<profiles>
<profile>
<id>test</id>
<properties>
<db.driverClass>com.mysql.jdbc.Driver</db.driverClass>
<db.jdbcUrl>jdbc:mysql://xxxxx:3306/test</db.jdbcUrl>
<db.user>test-user</db.user>
<db.password>test-pass</db.password>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<db.driverClass>com.mysql.jdbc.Driver</db.driverClass>
<db.jdbcUrl>jdbc:mysql://yyyyy:3306/prod</db.jdbcUrl>
<db.user>prod-user</db.user>
<db.password>prod-pass</db.password>
</properties>
</profile>
</profiles>
In hibernate.cfg.xml file you can use the defined properties like this:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">${db.driverClass}</property>
<property name="connection.url">${db.jdbcUrl}</property>
<property name="connection.username">${db.user}</property>
<property name="connection.password">${db.password}</property>
</session-factory>
</hibernate-configuration>
Then, you have to configure your build section in pom.xml:
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>${project.artifactId}</warName>
<webResources>
<resource>
<filtering>true</filtering> <!-- THIS IS IMPORTANT! It tells maven to replace your variables with the properties values -->
<directory>src/main/webapp</directory>
<includes>
<include>**/hibernate.cfg.xml</include> <!-- the path to hibernate.cfg.xml -->
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
Then you can call mvn clean install -Pdev|prod.
You can also tell jenkins which profile you wish to build in the maven configuration.
create a property file and when your going to start building the project using jenkins, write a bash script to access the property file from your source code and change your desired configuration regarding your build plan (Production, Test).
after your maven build your source code, desired output will be provided.
if your jdbc database jar is wrapped inside another jar and that jar exist inside your nexus server, you should go to the wrapping project source first add your other database jar jdbc dependencies in there, then deploy the project into the nexus again.
when the new version of wrapped jar was provided, you can decide which database you wish to connect using the above explanation with changing these properties using your written bash script (you have to go inside your jenkins and write this bash script before your maven clean install deploy plan start):
hibernate.connection.driver_class (ex: com.mysql.jdbc.Driver)
hibernate.connection.url property (ex: jdbc:mysql://localhost:3306/mehdi)
hibernate.dialect property (ex: org.hibernate.dialect.MySQLDialect)
and because this will make your project to use specific config regarding your plans (Test, Production), even if there be different jdbc drivers jars within your wrapped jar file, It does not create any conflict and problem because each database have different property configs.

Maven - No plugin found for prefix 'tomcat7' in the current project and in the plugin groups

I've created a Maven project. This is the structure:
-parent
-core
-web
but when I try to deploy with the command mvn tomcat7:deploy, I get the following error:
No plugin found for prefix 'tomcat7' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo]
I put this configuration in the pom.xml (of the web project):
<build>
<finalName>MavenWeb</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</build>
Plugins goals can be called using their 'FQN': groupId:artifactId:version:goal or, if applicable, shorter commands (many variants available).
Using only the short name of a plugin (in your tomcat7:deploy, tomcat7 is the short name, deploy being the goal/mojo) is applicable if:
1) the groupId of the plugin is contained in the known plugin groups of Maven. org.apache.maven.plugins being in the list by default.
OR
the pom.xml of the project you're invoking the Maven command on declares the plugin
2) the artifactId is [short-name]-maven-plugin or maven-[short-name]-plugin (maven-[short-name]-plugin being 'reserved' for plugins provided by Maven project.
That explains why mvn compiler:compile can work out of the box on any project, but not tomcat7:deploy
In your case, the second condition is true, so you just have to declare the plugin on the project you're launching the command on, or add this to your user settings.xml file:
<pluginGroups>
<pluginGroup>org.apache.tomcat.maven</pluginGroup>
</pluginGroups>
See here for more info
The reason why you get that error is because you simply have not installed the Tomcat7 plugin. Here's what you can do (I tested this on my test project and it works):
Add tomcat7 plugin dependency in your pom.xml file just like you have done.
Run either mvn installor mvn package to install that tomcat7 plugin
Now you should be able to run mvn tomcat7:deploy
I tested this solution with mvn tomcat7:run and it works like a charm :)
It means tomcat7 plugin not found . Add this to your pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.3-SNAPSHOT</version>
</plugin>
</plugins>
</build>
The error happens to have the plugin inside <reporting>, it should be located in <build>
Before:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</reporting>
After:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
After I checked my pom.xml file, I made sure all my dependencies were selected in the build order under the JAVA Build Path JAVA BUILD PATH
I got the same error from using the file based idp.xml and formatting it!!! Don't format it, use curl, or chrome and save the file from https://idp.ssocircle.com/idp-meta.xml directly to spring-security-saml-1.0.2.RELEASE\sample\src\main\resources\metadata\idm.xml
Then in SecurityContext.cml
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<!-- Example of classpath metadata with Extended Metadata -->
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
<constructor-arg>
<bean class="java.util.Timer"/>
</constructor-arg>
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/metadata/idp.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
</bean>
</constructor-arg>
</bean>
</bean>

Spring Properties files configuration and maven integration in different env

As being develop a big project using Spring and maven. However there will be different environments to be deployed such as dev, test, staging and production.
The project is having a lot of different properties for different environments.
Are there any elegant way to solve this kind of thing, so I can use this as a template and reuse in other projects.
I guess spring features such as profile, placeholders and etc will be used.
Are there any good tutorial or some blog for me to get a better solution for that?
The Maven concept profile can be your friend :
<profile>
<id>DEV</id>
<build>
<resources>
<resource>
<directory>src/test/dev-resources</directory>
</resource>
<resource>
<directory>src/main/dev-resources</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>STAGING</id>
<build>
<resources>
<resource>
<directory>src/test/staging-resources</directory>
</resource>
<resource>
<directory>src/main/staging-resources</directory>
</resource>
</resources>
</build>
</profile>
and run all your Maven build with "-P DEV" for dev propose and "-P STAGING" for staging propose for example .
You can use property configurer. Something like this:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>file:${catalina.home}/conf/your_props.properties</value>
</list>
</property>
</bean>
And you can put your properties (in this case Tomcat servlet container is used) under some config directory in each different environment.
In this case properties are stored under ${catalina.home}/conf where catalina.home refers to Tomcat's installation directory.

Categories

Resources