I have to build a war file using maven to include jars conditionally,
each jar is created by a seperate maven project which deploys jar to nexus(our organisations remote) repository
Eg : I have jars like these core.jar,reward.jar,payment.jar,domains.jar so on
I need to build a final war based on conditions(environmnet) to include above jars
Combination of final war(w1)
w1.war : core.jar,domains.jar
w1.war : core.jar,domains.jar,rewards.jar(Any way to specify to include this jar if rewards is applicable)
The Maven WAR Plugin allows you to include/exclude JARs. For example:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/excluded.jar
</packagingExcludes>
<packagingIncludes>
WEB-INF/lib/included.jar
</packagingIncludes>
</configuration>
</plugin>
You can associate the inclusions/exclusions with a condition by using profiles. For example, let the WAR plugin use properties (${excludedResources}, ${includedResources}) ...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<packagingExcludes>
${excludedResources}
</packagingExcludes>
<packagingIncludes>
${includedResources}
</packagingIncludes>
</configuration>
</plugin>
... and define values for those properties via profiles:
<profiles>
<profile>
<id>prod</id>
<properties>
<excludedResources>WEB-INF/lib/a.jar,WEB-INF/lib/b.jar</excludedResources>
<includedResources>WEB-INF/lib/c.jar</includedResources>
</properties>
</profile>
<profile>
<id>tst</id>
<properties>
<excludedResources>WEB-INF/lib/x.jar,WEB-INF/lib/y.jar</excludedResources>
<includedResources>WEB-INF/lib/z.jar</includedResources>
</properties>
</profile>
</profiles>
So, you can use the Maven WAR Plugin's built-in ability to tweak the WAR contents and you can make these tweaks conditional by using Maven profiles.
You can try to use profiles capabilities in maven. Each dependency can be included into its own profile block e.g. domains will be included only if you switch this profile on and services - by services profile.
At the same time you can identify common jars through the common dependency block (in our case core.jar will be common)
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>conditional-war</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>War Which Includes Jar By Conditions</name>
<!-- Common dependency block which will be always included -->
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<!-- Profile for domains jars. Will be included by
profile\condition "domains" -->
<profile>
<id>domains</id>
<activation>
<property>
<name>domains</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>domains</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
<!-- Profile for domains jars. Will be included by
profile\condition "services" -->
<profile>
<id>services</id>
<activation>
<property>
<name>services</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>services</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Command line for the activation can be following:
By this command line will be included core.jar and domains.jar
mvn clean install -Pdomains
In such case war will include core.jar and services.jar
mvn clean install -Pservices
And finally by this command line will be included all the jars
mvn clean install -Pdomains,services
Related
So this is probably a stupid question, but I have created an own library "testlib" which I want to include in other of my own Maven projects.
This is my own librarys .pom
<?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.test.testlib</groupId>
<artifactId>testlib</artifactId>
<version>1.0-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>testlibrary</description>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
In order to include my library in another new project, I have created a local repository in my new projects .pom
...
<repositories>
<repository>
<id>data-local</id>
<name>data</name>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.test.testlib</groupId>
<artifactId>testlib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
Installing my own library "testlib" via mvn install is working fine for testlib itself. The problem is, that Maven will not detect that "testlib" requires org.slf4j, hence won't get it when I run install.
I have checked other dependencies in my .m2 folder and saw they have a .pom file with the same name as the .jar (for log4j that'd be log4j-1.2.17.pom). I tried copying testlibs .pom next to its .jar and changed the name accordinly, but that doesn't do it.
What do I have to do in order to get the same functionality as any other library from maven central? In other words, I don't want a fat .jar that has all dependencies included. I want a Maven project that adds my library as a dependency to discover that it needs sl4j and include it when mvn install is run.
I am working on Maven RPM Plugin and I have my directory structure as below
dir1
dir2
dir3
src
pom.xml
dir1,dir2,dir3 directories contain my custom files and the src directory has my Java source code.
I want to create the Jar file by building the Java application and then bundle everything to an RPM(dir1,dir2,dir3,src, jar file generated). I have tried the below
<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>xyz</groupId>
<artifactId>abc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>xyz</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<build.number>1</build.number>
<maven.rpm.plugin.version>2.0.1</maven.rpm.plugin.version>
</properties>
<profiles>
<profile>
<id>rpm</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>${maven.rpm.plugin.version}</version>
<executions>
<execution>
<id>generate-rpm</id>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
<configuration>
<name>${project.artifactId}</name>
<copyright>XYZ</copyright>
<release>${build.number}</release>
<group>DOC/COD</group>
<mappings>
<mapping>
<directory>/tmp</directory>
</mapping>
</mappings>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
</repositories>
</project>
The target directory is being created with the JAR file of the Java source code but the RPM is not getting created. It throws the below error
Failed to execute goal org.codehaus.mojo:rpm-maven-plugin:2.0.1:rpm (generate-rpm) on project xyz: RPM query for default vendor returned: '127' executing '/bin/sh -c rpm -E '%{_host_vendor}'' -> [Help 1]
Please let me know if I am in the right direction and how to proceed on this.
Maven works best when conventions are followed, and when they are, very little configuration is needed. That being said, the convention of Maven is one artifact per module (and of course on pom.xml per module).
Therefore, the best way to structure your project would be like the following:
ProjectName
|
|--ChildJarModule
| |
| |--pom.xml
|
|--ChildRPMModule
| |
| |--pom.xml
|
|--pom.xml
If you do this, you'll have an easier time generating your RPM from the pom.xml in the ChildRPMModule (and you may very well solve your problem).
I have Eclipse Indigo and M2E plugin installed.
So essentially I have a standard maven web project (let's call it proj-service) that is built into a war file in the package phase. This all works fine. My issue comes in when I have my other project (lets call it proj1) that needs to use classes from proj-service. I know that this is possible in maven+eclipse but it does not seem to be working at the moment. I have the following in proj1's pom right now:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj1</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>proj1</name>
<properties>
<spring.version>3.1.0.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Maven Repo Libraries -->
.........
<!-- Interproject dependencies -->
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<finalName>lsoap</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Unfortunately with Maven's war packaging you can't reuse classes from war project, because there is no direct build artifact you can use for the class path.
So, in order to do share classes properly you need to extract those common classes into a 3rd common project (jar packaging) and make it as dependency in both of your other projects.
First you have to change the configuration of your proj-service project in the way to change the configuration of the maven-war-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<attachClasses>true</attachClasses>
<archiveClasses>true</archiveClasses>
...
</configuration>
</plugin>
This will it make possible to use the classes from the proj-service project in other projects via the following dependencies:
<dependency>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>myVersion</myVersion>
<classifier>classes</classifier>
</dependency>
This will result in changing your dependency from:
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
into:
<dependency>
<groupId>com.mycompany.foo</groupId>
<artifactId>proj-service</artifactId>
<version>1.0</version>
<classifier>classes</classifier/>
</dependency>
I have two projects in eclipse, both are maven controlled. A references B and they are on a flat system. What we currently have setup is that we have to a build on B - generate a jar on the system, and A references that jar.
I'd like to change this to be we just have to build A and it will go automatically build B? Can I do this in Maven/eclipse such that I don't have to create some higher project?
I have looked into some of the maven docs - but they just really confuse me :). Thanks for your help.
The pom's look like this
(B)
<project xmlns="..." xmlns:xsi="..."
xsi:schemaLocation="...">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thetus</groupId>
<artifactId>irisMDK</artifactId>
<packaging>jar</packaging>
<name>irisMDK</name>
<version>0.1</version>
<url>...maven.apache...</url>
<build>
<sourceDirectory>java/src/main</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<testExcludes>
<exclude>**/*.java</exclude>
</testExcludes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>java/src/main</directory>
</resource>
</resources>
</build>
<dependencies>
...
</dependencies>
</project>
------ And (A):
<project xmlns="..." xmlns:xsi="..."
xsi:schemaLocation="...">
<modelVersion>4.0.0</modelVersion>
<groupId>local.b</groupId>
<artifactId>projectB</artifactId>
<packaging>jar</packaging>
<name>B</name>
<version>RELEASE</version>
<url>...</url>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>...download.java.net/maven...</url>
</repository>
</repositories>
<build>
<plugins>
...
</plugins>
<sourceDirectory>java/src/main</sourceDirectory>
<testSourceDirectory>java/src/test</testSourceDirectory>
<resources>
</resources>
</build>
<dependencies>
<dependency>
<groupId>local.b</groupId>
<artifactId>projectB</artifactId>
<scope>system</scope>
<version>RELEASE</version>
<systemPath>${basedir}/../B/target/B-0.1.jar</systemPath>
</dependency>
...
</dependencies>
<reporting>
...
</reporting>
</project>
If you could show me an example of how to change ^^^ I would be most grateful!!
Original Answer:
The M2Eclipse plugin, if you are not using it already, allows you to do this. Once installed, remove
<systemPath>${basedir}/../B/target/B-0.1.jar</systemPath>
from A's pom.xml and make sure the groupid, artifactid, version match up with what is defined in B's pom.xml
Then right-click on the project, Maven-> Enable Dependency Resolution. The build should now look at B's local project
Edit:
If B's pom.xml looks like this (from your example):
<project xmlns="..." xmlns:xsi="..."
xsi:schemaLocation="...">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thetus</groupId>
<artifactId>irisMDK</artifactId>
<packaging>jar</packaging>
<name>irisMDK</name>
<version>0.1</version>
...
</project>
In A's pom (which depends on Project B) your dependency should look like:
<project>
...
<dependencies>
<!--Attributes of project that this project is dependent upon, as defined in that projects POM -->
<dependency>
<groupId>com.thetus</groupId>
<artifactId>irisMDK</artifactId>
<version>0.1</version>
</dependency>
...
</dependencies>
....
</project>
This will tell maven and eclipse that project A explicitly depends on that version of Project B. With M2Eclipse, if you have a matching groupId, artifactId, and version in your workspace and you have "Dependency Resolution" enabled, Project B's contents will automatically be built and included into Project A.
Also, opening the Maven console in eclipse (console view->new console dropdown->new maven console) could help in debugging why project B isn't be picked up by Project A.
Sounds like you want to use a multi-module project, here is a simple tutorial. You would create a parent POM, and have both A and B as children, with A keeping its dependency on B.
I am using maven war plugin to exclude some common jar and put them in the classpath. I am able to generate war file properly which excludes specified libs and add them in the classpath but exploded war directory still contains excluded libararies. How can I generate exploded war file which use configuration of maven war plugin.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.ekaplus.ctrm.mdm</groupId>
<artifactId>core-presentation</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>presentation layer core</name>
<dependencies>
<dependency>
<groupId>com.ekaplus.ctrm.mdm</groupId>
<artifactId>eka-core-mdm-presentation</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>exploded</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/dto-common-1.0.jar,
WEB-INF/lib/eka-action-1.0.jar
</packagingExcludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
(...) How can I generate exploded war file which use configuration of maven war plugin.
The war:exploded goal does use the (global) configuration of the maven war plugin but it doesn't admit the packagingExcludes parameter of war:war. This can't work.
But why you are using packagingExcludes anyway? This parameter should be used to implement the very special skinny war use case, and I'm not sure it's your case. Why do you need it?
Depending on your exact needs, my suggestion would be to play with dependency scopes (provided in your case?) or profiles (to add dependencies) or a combination of both.