I have Maven multi-module project with such structure:
parent-pom-project
-- module1
-- module2
At the parent-pom-project I have such pom.xml
<modules>
<module>module1</module>
</modules>
...
<profiles>
<profile>
<id>local</id>
<properties>
<prop>local_prop</prop>
</properties>
</profile>
<profile>
<id>test</id>
<modules>
<module>module2</module>
</modules>
<properties>
<prop>test_prop</prop>
</properties>
</profile>
</profiles>
At all pom.xml files I have such tag:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
At module1 and module2 in resource directory I have properties files with such text:
prop=${prop}
The problem is that after
mvn clean install
or
mvn clean install -Ptest
or even
mvn clean install -P test
I get
prop=local_prop
If I user test profile for build module2 is also builded, but properties are used from local profile.
I use Maven 3.0.3.
Anybody have any ideas?
You could try to use the mvn help:effective-pom -Ptest command to see the paramters used in your build.
See http://maven.apache.org/plugins/maven-help-plugin/plugin-info.html for more details.
Add a ${basedir} in front of your resource directories:
<directory>${basedir}/src/main/resources</directory>
This should fix your problem. My explanation would be that in a multi-module project it's not picking up the path correctly (for within the child module), if you're building from the top-level. Thus when trying to filter, it applies it to a different directory (the actual root-level aggregator), instead of the child.
I hope it helps.
I can't figure out how maven can resolve your property if you do not specify any profile. So, to see what's really there, I tried myself, following exactly the schema you described and... I did not experience the problem you have. In your case, it really behaves like if the property was defined outside the profile -as bugske suggested. What happened if you comment temporarily both profiles ?
I resolve problem uninstalling current maven plugin for eclipse and use another one.
Now I use this ones:
- Maven Integration: http://m2eclipse.sonatype.org/sites/m2e
- Maven Integration for WTP: http://m2eclipse.sonatype.org/sites/m2e-extras/
Early I was using this one http://download.eclipse.org/technology/m2e/releases/. I cannot explain such behavior but may be some configuration was changed by plugin.
Although old I had the same problem and didn't find the solution here. For me the problem was Eclipse which I use parallel to mvn on the command line. Eclipse instantly called process-resources after I did so on the command line.
Thus the solution was to select the profile in Eclipse (Project->Maven->Select Maven Profiles).
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 want to use a different source directory for a specific maven profile, however, when I try to specify it in the profile definition I get this error:
Unrecognised tag: 'sourceDirectory' (position: START_TAG seen ...<build>\r\n\t\t\t\t<sourceDirectory>... )
The definition in the pom is as follows:
<profile>
<id>development</id>
<build>
<sourceDirectory>${project.build.directory}/new-src</sourceDirectory>
.
.
.
</build>
</profile>
What I am trying to do is to process the source files before its compilation if and only if this profile is active. My process will change the source files on the fly, throw the changed sources in the "new-src" directory and compile that directory as if it was the usual "src/main/java". Everything else in the lifecycle should behave normally. If this approach is flawed, could anyone point me into the right direction?
According to the documentation, you can change only few <build> parameters in the profile and <sourceDirectory> is not one of them.
I'd configure the main <build> to take sources from path defined by some property (eg. src.dir), set this property to src/main/java and override it in the custom profile:
<project>
...
<properties>
<src.dir>src/main/java</src.dir>
</properties>
<build>
<sourceDirectory>${src.dir}</sourceDirectory>
...
</build>
<profiles>
<profile>
<id>development</id>
<properties>
<src.dir>${project.build.directory}/new-src</src.dir>
</properties>
</profile>
</profiles>
</project>
See Maven model, it is not allowed to define a sourceDirectory within a profile. The only thing you can do is specify the sourceDirectory within the plugin configuration, assuming it is available.
I have a Maven module with two different database profiles.
<profile>
<id>db-localhost-oracle</id>
<dependencies>
<dependency>
<groupId>ojdbc6</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
</dependencies>
<properties>
<db.driver>oracle.jdbc.driver.OracleDriver</db.driver>
<db.dialect>no.jbv.sergej.util.FixedOracle10gDialect</db.dialect>
<db.url>jdbc:oracle:thin:#//localhost:1521/xe</db.url>
<db.hbm2ddl>update</db.hbm2ddl>
</properties>
</profile>
<profile>
<id>db-localhost-mysql</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<properties>
<db.driver>com.mysql.jdbc.Driver</db.driver>
<db.dialect>org.hibernate.dialect.MySQL5Dialect</db.dialect>
<db.url>jdbc:mysql://localhost/${mysql.schema}</db.url>
<db.hbm2ddl>update</db.hbm2ddl>
</properties>
</profile>
When is run maven install with "db-localhost-mysql" it includes the "mysql-connector-java" jar file in lib directory. Now I do clean install with "db-localhost-oracle" and it includes the both "mysql-connector-java" and "ojdbc6" jars in the lib directory.
How can I make it like, if I build with one profile maven automatically remove the jars for other profile?
Your problem does not match what should happen in practice. Your profile definition sounds about right to me:
mvn clean install will enable the db-localhost-mysql (as it is marked as to be activated by default) and it will add mysql-connector-java. The same will happen if you run mvn clean install -Pdb-localhost-mysql
mvn clean install -Pdb-localhost-oracle will add the ojdbc6 driver. The mysql profile will not be enabled (as it is triggered only if no profile is explicitly active).
That does not mean your current dependency hierarchy hasn't already one of those jars. It might come as a transitive dependency. To isolate this case and know which project needs to be fixed run mvn dependency:tree -Pdb-localhost-oracle to look at your dependencies hierarchy when the mysql profile is not enabled.
I assume you download your downloaded dependencies using maven-dependency-plugin somewhere outside your target dir (${basedir}/lib).
If that is the case, you would need to include your lib dir inside your clean definition (see http://maven.apache.org/plugins/maven-clean-plugin/examples/delete_additional_files.html):
<build>
[...]
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<configuration>
<filesets>
<fileset>
<directory>lib</directory>
</fileset>
</filesets>
</configuration>
</plugin>
[...]
</build>
However: Please consider doing it differently:
do not have your regular build change anything outside the target directory, if possible (which would have prevented your problem in first place), instead download to something like target/lib
Please do not use profiles to change the outcome of your build. This is dangerous. (see http://www.blackbuild.com/how-to-really-use-maven-profiles-without-endangering-your-karma/ for an extended explanation)
If you want different outcame consider Maven Assemblies.
I have a maven project with multiple child projects. I also have a maven dbunit plugin which I invoke from command line like this:
mvn dbunit:operation -P test -pl .
-P is a profile switch where all necessary properties are stored (like db url, etc.)
I.e.:
<profile>
<id>test</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/db</url>
<username>ers</username>
<password>ers</password>
<useQualifiedTableNames>true</useQualifiedTableNames>
<dataTypeFactoryName>org.dbunit.ext.postgresql.PostgresqlDataTypeFactory</dataTypeFactoryName>
<format>flat</format>
<type>INSERT</type>
<src>${basedir}/some_path/test.xml</src>
</properties>
</profile>
The problem I'm having is that I need to specify -pl . parameter to build only one project (root/parent project) so that the dbunit data is loaded only once. Is it possible to specify some property directly in the profile, so only 1 project is being build? I tried <pl>my_project</pl> and <project>... - but no luck. Thanks!
Yes. The <modules> element can be specified in a profile. So the solution would be to move the DBUnit setup code in a module and then:
<profile>
<id>test</id>
<modules>
<module>db-unit-setup<module>
</modules>
</profile>
If you activate this profile with -P test, only the single module db-unit-setup and the parent POM will be built. But since the parent POM is now an empty project (it's just a POM without any code), that shouldn't hurt.
As long as I run my project directly from Eclipse, I have no problem with that:
scene.getStylesheets().add(getClass().getResource("/stylesheet.css").toExternalForm());
But as soon as I run this code inside of a jar file, the resource is not found (NullPointerException).
I tried moving the css file to my src folder and then only stylesheet.cssas path instead of /stylesheet.css, but this leads to the same problem: Works fine using Eclipse, but not from the jar.
Hint: I am using Zonskis Maven JavaFX Plugin for generating the jar.
I just wasted my (your) time writing silly maven profiles.
instead of :
scene.getStylesheets().add(getClass().getResource("/stylesheet.css").toExternalForm());
simply write :
scene.getStylesheets().add("stylesheet.css");
This is how Zonski load css files.
Of course your stylesheet.css file should be in /src/main/resources, or somewhere on the CLASSPATH.
Move your file to src/main/resources and add your css file :
scene.getStylesheets().add(getClass().getClassLoader().getResource("stylesheet.css").toExternalForm());
Well, if you want to run it from the jar, then change stylesheet.css to stylesheet.bss ( binary css), package your application :
mvn clean compile jfx:build-jar
and run your jar.
java -jar app.jar
I have a ugly hack to make this a little usable (I'm using Netbeans,amazing maven integrity):
I create a project.properties file in src/main/resources directory,
file_css= ${file_css} // by default I use *.css file.
And make it filterable, in my POM file:
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version> 1.5 </version>
<configuration>
....
</configuration>
</plugin>
</plugins>
</build>
...
And create two maven profiles, one for dev, and the other for production (packaging to jar):
<profiles>
<profile>
<id>production</id>
<properties>
<file_css>stylesheet.bss</file_css>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<file_css>stylesheet.css</file_css>
</properties>
</profile>
</profiles>
So, you load your css file like this :
scene.getStylesheets().add(getClass().getClassLoader().getResource(ResourceBundle.getBundle("project").getString("file_css")).toExternalForm());
I use production profile for packaging, and dev for usual actions like compile, test, run.
Edit:
a complete example is hosted on github.