I know that it is possible to configure Decorators in the "beans.xml" file that is embedded in the EAR to be deployed.
The problem is that I use the same EAR for all the environments, and the set of properties or specific configurations are stored in some folder outside the package.
I need to determine if a Decorator will be used or not "external beans.xml" or some similar mechanism (something that is outside the EAR).
Any ideas?
Thank you very much.
Normally, this won't work - standard means of enablement are beans.xml for per-archive approach and #Priority for global enablement. There is nothing like "external beans.xml".
Although there is a way to enable it with extension. You need to set up an extension and observe AfterTypeDiscovery event. From there you can
make use of public List<Class<?>> getDecorators(); which returns MUTABLE list of decorators - so you can add your own into the list (in a form of a Class). That should enable it.
Another scenario you can use, is to utilize build-time inclusion and processing.
If you know before hand, what properties activate specific decorators at build-time, then you can use maven resources, together with system properties, to define additional resources to be filtered, thus:
<?xml version="1.0" encoding="UTF-8"?>
<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.mycompant</groupId>
<artifactId>my-project-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/development</some.kind.of.selector.properties>
</properties>
<build>
<resources>
<resource>
<directory>${some.kind.of.selector.properties}</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>test</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/test</some.kind.of.selector.properties>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<some.kind.of.selector.properties>$basedir}/src/main/resources/prod</some.kind.of.selector.properties>
</properties>
</profile>
</profiles>
</project>
The at build time, you can specify different beans.xml for every environment:
mvn clean install -Pprod
or even specify the property directly
mvn clean install -Dsome.kind.of.selector.properties=/path/to/additional/resources
Related
I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.
I am trying to setup an integration-test environment using Maven for my project but am getting the below error when I run the Compile goal.
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-resources-plugin:3.0.2:resources
(default-resources) on project mavenintegrationtest: Error loading
property file
'/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties'
-> [Help 1]
The error seems to be complaining that it cant find the config.properties file in that location which is correct. For some reason it has removed the "src/main/resources" bit from the file path.
So the correct full path is,
/Users/xxx/dev/poc/java/mavenintegrationtest/src/main/resources/profiles/dev/config.properties
but for some reason its removed src/main/resources and so is looking in,
/Users/xxx/dev/poc/java/mavenintegrationtest/profiles/dev/config.properties
Does anyone know whats causing this ?
My POM is as shown below and I get this error when I uncomment the following "filter" tag,
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
I've tried removing the ${basedir} statement and still get the same error.
<?xml version="1.0" encoding="UTF-8"?>
<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.stackoverflow</groupId>
<artifactId>mavenintegrationtest</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mavenintegrationtest</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<filters>
<filter>${basedir}/profiles/${build.profile.id}/config.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
<!-- Profile configuration -->
<profiles>
<!-- The configuration of the development profile -->
<profile>
<id>dev</id>
<!-- The development profile is active by default -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<!-- The configuration of the integration-test profile -->
<profile>
<id>integration-test</id>
<properties>
<build.profile.id>integration-test</build.profile.id>
</properties>
</profile>
</profiles>
</project>
The filter (link) element will parse your files and apply a content filter on them.
The profiles (link) element helps you define different environments for the build.
All of this as to do with your resources. These can be configuration files, or other type of files. If you filter then you can change the content of this files with other values - e.g. pom properties. When using profiles you can have different replacement properties for each environment.
You should move the profiles up in the tree for the default path, or add a configuration in your pom for the resource location.
The base dir is the folder containing your pom. You should have your profile folder here.
Also, here is some good information about profiles and its configurations.
I am writing a Java application which is almost ready for release, but I don't know how to create different .properties files for Debug and Release.
Let me clarify this for you.
I am storing the database host, username, password and other properties in the .properties files.
When I am writing and debugging the application these properties are configured to work with my development machine and database, but when the application is released they need to point to the release database and contain the release properties.
Is there any way to achieve this with Java and Maven?
I once did something similar, I wanted to have several resources packs in a Java webapp: one for IDE development, one for local (but outside IDE) development for graphic designers, and finally one for release, with all the packing controlled by Maven.
My solution is to declare several extra resources folders in the <build> node, and tell Maven which one to pick up using profiles (like #biziclop already suggested you); those folders are controlled through properties.
This is the POM I've used:
<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>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>war</packaging>
<name>...</name>
<!-- My prerequisite was that when working in Eclipse no extra steps
should be required to make the IDE use the right configuration than
Configure -> Convert to Maven Project, so I didn't like having
default settings in a profile that must be enabled in Eclipse project
configuration -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<war-name>/</war-name>
<!-- These solve the problem: AFAICT, each <resource /> is added to the final POM,
so declaring a resources folder in a profile didn't exclude other resources
folders declared in the default (i.e. without profiles active) configuration.
So, the solution is to change what Maven brings in from each folder depending
on the profile currently active. What follows is the default, no-profile
active configuration. -->
<res.devel.includes>**/*</res.devel.includes>
<res.devel.excludes></res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
<build>
<resources><!-- Here I declare all the resources folders, so that they will all be shown in Eclipse. Property values drive what is included and excluded. -->
<resource><!-- This is the default Maven main resource directory -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.devel.includes}</include>
</includes>
<excludes>
<exclude>${res.devel.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resources directory for when the WAR is deployed on a local standalone Tomcan installation (useful for web pages editing) -->
<directory>${basedir}/src/main/resources-local</directory>
<filtering>true</filtering>
<includes>
<include>${res.local.includes}</include>
</includes>
<excludes>
<exclude>${res.local.excludes}</exclude>
</excludes>
</resource>
<resource><!-- This is the resource directory for when the WAR will be deployed -->
<directory>${basedir}/src/main/resources-release</directory>
<filtering>true</filtering>
<includes>
<include>${res.release.includes}</include>
</includes>
<excludes>
<exclude>${res.release.excludes}</exclude>
</excludes>
</resource>
</resources>
<plugins>
<!-- Plugins configurations -->
</plugins>
</build>
<dependencies>
<!-- Dependencies declarations -->
</dependencies>
<profiles><!-- Here are the profiles. When working in Eclipse no profile is active, so the resources will be taken only from src/main/resources (as per default properties values). -->
<profile>
<id>local</id><!-- This is for when the WAR is deployed on a local standalone Tomcat instance (i.e. outside of Eclipse) -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-local -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes>*</res.local.includes>
<res.local.excludes></res.local.excludes>
<res.release.includes></res.release.includes>
<res.release.excludes>*</res.release.excludes>
</properties>
</profile>
<profile>
<id>release</id><!-- This is for when the WAR is deployed on the production server -->
<properties>
<war-name>ROOT</war-name>
<!-- The resources will be taken only from src/main/resources-release -->
<res.devel.includes></res.devel.includes>
<res.devel.excludes>*</res.devel.excludes>
<res.local.includes></res.local.includes>
<res.local.excludes>*</res.local.excludes>
<res.release.includes>*</res.release.includes>
<res.release.excludes></res.release.excludes>
</properties>
</profile>
</profiles>
</project>
You may get further details in my answer here.
I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.
If I have a pom.xml like
<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.example</groupId>
<artifactId>test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<resource.filtering>true</resource.filtering>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>${resource.filtering}</filtering>
<includes>
<include>environment.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
Eclipse marks the <filtering>${resource.filtering}</filtering> line with a validation error, because the schema tells it this should be a boolean, and that doesn't look like a boolean. I would rather not shut off the pom.xml validation, and it's annoying to see the error on the project. My goal is to be able to control whether resource filtering occurs based on Maven profiles. Is there a way of doing this that passes Eclipse's validation? I'm using Eclipse Luna (4.4).
I asked a similar question, and even tried filing a bug report with the Eclipse team. The answer I got was, "This is a result of an inherent conflict between the xsd that describes the pom format, and the aims of the pom file." So other than turning off validation, there isn't much one can do about these error messages.