Is it possible to have multiple context roots in Maven generated application.xml? - maven

Maven is able to generate the application.xml file for an EAR and puts the context root in it that has been defined in the EAR's pom.xml.
Is it possible to have an application.xmlgenerated that has multiple context roots?
Or is the only possible way to achieve this to write the application.xml myself and use this rather than the generated one?

Sure, use applicationXml option in goal ear of Maven ear plugin. For more information on how to use it take a look at its usage page.
Regards.

I assume you mean different context roots for different WARs inside your ear (since each web module can have exactly one context-root). In that case, you can explicilty configure your war modules inside the ear's pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.9</version>
<configuration>
<modules>
<webModule>
<groupId>artifactGroupId</groupId>
<artifactId>module1</artifactId>
<contextRoot>/context-root-module1</contextRoot>
</webModule>
<webModule>
<groupId>artifactGroupId</groupId>
<artifactId>module2</artifactId>
<contextRoot>/context-root-module2</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>

Related

Maven EAR plugin: Generated EAR file does not contain WAR or EJB or RAR modules

I've been using the EAR plugin to package a WAR, EJB & RAR module, however, while they all package successfully when i run mvn clean package, I notice the following gets output in the target directory.
application.xml (generated application.xml)
my-application-ear-1.0-SNAPSHOT (directory with correctly packaged WAR, EJB & RAR dependencies, META-INF with generated application.xml and additional resources from the EAR project)
my-application-ear-1.0-SNAPSHOT.ear (9kb .ear file that only has the META-INF with the generated application.xml & additional resources from the EAR project)
None of the modules are packaged in the final EAR file.
Here is the <build> node of the EAR project's POM.
<build>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<finalName>my-application-ear</finalName>
<version>7</version>
<earSourceDirectory>src/main/application</earSourceDirectory>
<packagingIncludes>**/*</packagingIncludes>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<filtering>false</filtering>
<packagingIncludes>Default_HTTP_WC/**,Default_IIOP_WC/**,Default_JMS_WC/**,META-INF/**,</packagingIncludes>
<modules>
<ejbModule>
<groupId>com.abc.def</groupId>
<artifactId>ejb-module</artifactId>
<bundleDir>/</bundleDir>
<bundleFileName>ejbModule.jar</bundleFileName>
<moduleId>EjbModule_1</moduleId>
</ejbModule>
<rarModule>
<groupId>com.abc.def</groupId>
<artifactId>rar-module</artifactId>
<bundleDir>/</bundleDir>
<bundleFileName>RARModule</bundleFileName>
<uri>/RARModule.rar</uri>
<unpack>true</unpack>
<moduleId>RARModule_1</moduleId>
</rarModule>
<webModule>
<groupId>com.abc.def</groupId>
<artifactId>my-web-app</artifactId>
<uri>/WebApplication.war</uri>
<bundleDir>/</bundleDir>
<bundleFileName>WebApplication.war</bundleFileName>
<contextRoot>/foo</contextRoot>
<moduleId>WebModule_1</moduleId>
</webModule>
</modules>
</configuration>
<goals>
<goal>ear</goal>
</goals>
</plugin>
</plugins>
Am i missing something? Any assistance is appreciated.
I figured out my problem, I had completely overlooked the use of <packagingIncludes> from an earlier iteration. removed it and its fine.

Intellij IDEA artifact 'XXXX:war exploded' has invalid extension

Every time I make even the tiniest change to my POM Intellij removes the .war extension for my exploded artifact in the Project Structure output directory setting. This causes an error in Intellij's Run/Debug configuration:
Artifact 'XXXX:war exploded' has invalid extension.
In order to resolve the issue I must manually override the Project Structure output directory setting. Every time I make even the tiniest change to the POM I must go back to the Output directory setting and manually append ".war" to the end of the Output directory setting. This is getting very old and frustrating.
e.g. I must change this:
E:\workarea\enterp\application\target\application
to this:
E:\workarea\enterp\application\target\application.war
If I manually set the Maven WAR plugin outputDirectory configuration as follows, this does not help at all:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<!-- Output directory of artifact:war exploded keeps losing the .war extension -->
<outputDirectory>${project.build.directory}.war</outputDirectory>
</configuration>
</plugin>
How can I resolve this problem?
EDIT:
Here's the complete build config:
<build>
<!-- Maven will append the version to the finalName (which is the name
given to the generated war, and hence the context root) -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation
processors -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<!-- Output directory of artifact:war exploded keeps losing the .war extension -->
<outputDirectory>${project.build.directory}/${project.artifactId}.war</outputDirectory>
<!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- The WildFly plugin deploys your war to a local WildFly container -->
<!-- To use, run: mvn package wildfly:deploy -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
</plugin>
</plugins>
</build>
SECOND EDIT:
I discovered that one solution is to append ".war" to ${project.artifactId} in the build configuration, e.g.:
<finalName>${project.artifactId}.war</finalName>
and remove outputDirectory from the plugin configuration. So the build config should look like this:
<build>
<!--
Maven will make finalName the name of the generated war.
NOTE: Output directory of artifact:war exploded keeps losing the .war extension
http://youtrack.jetbrains.com/issue/IDEA-86484
http://youtrack.jetbrains.com/issue/IDEA-95162
The solution is to append ".war" to ${project.artifactId}, below:
-->
<finalName>${project.artifactId}.war</finalName>
<plugins>
<!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation
processors -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- The WildFly plugin deploys your war to a local WildFly container -->
<!-- To use, run: mvn package wildfly:deploy -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
</plugin>
</plugins>
</build>
DISCLAIMER: If you use this workaround just be aware that when you deploy an unexploded WAR artifact the file name will be named XXXX.war.war. It works -- I deployed the artifact as a WAR file in Intellij -- but it's ugly.
INFO [org.jboss.as.server.deployment] (MSC service thread 1-7) JBAS015876: Starting deployment of "XXXX.war.war" (runtime-name: "XXXX.war.war)"
If someone can tell me how to configure the Intellij project to work with Maven to select one or the other finalName values depending on whether I'm deploying a WAR file vs. exploded artifact then this question will be sufficiently answered.
<!-- Exploded artifact -->
<finalName>${project.artifactId}.war</finalName>
<!-- WAR file (unexploded) artifact -->
<finalName>${project.artifactId}</finalName>
There's a way to fix this in IntelliJ, without changing your pom.xml file(s), by adding an artifact with a reference to the exploded war (or in my case, the exploded ear) and it won't get stomped every time IntelliJ re-imports the maven pom(s). Here's how:
Stop/undeploy your current artifact deployment
Edit your run config, and in the Deployment tab, remove the current exploded war/ear artifact
Open the project's Artifacts settings and add a new artifact
Use the plus button to add a new war or (in my case) ear exploded artifact
Give it a name, then edit the Output directory to add the appropriate extension (.war or .ear)
In the Output Layout section where you see <output root>, use the plus button to add an Artifact
Select the desired exploded artifact
Edit your run config again, and in the Deployment tab, add the new workaround exploded artifact
Thanks to Nikolay Chashnikov for describing this in his comment on the bug report
Actually, you should leave the finalName attribute alone, otherwise you'll get the problems you describe. Rather, you should change the config for the maven war plugin to use the webappDirectory like this:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webappDirectory>${project.build.directory}/${project.artifactId}.${project.packaging}</webappDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
If we are talking about WAR inside EAR there is another way to resolve your problem by using correct configuration inside maven-ear-plugin. WAR pom.xml should be left as is, without any changes, but EAR pom.xml should contains something like this. (please, pay your attention to <unpack>${unpack.wars}</unpack>)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.9</version>
<configuration>
<version>6</version>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<generateApplicationXml>false</generateApplicationXml>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<modules>
<webModule>
<groupId>com.test.app</groupId>
<artifactId>test-app-war</artifactId>
<unpack>${unpack.wars}</unpack>
</webModule>
</modules>
</configuration>
</plugin>
and then you can add profiles default and debug for proper artifact assembling.
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<unpack.wars>false</unpack.wars>
</properties>
</profile>
<profile>
<id>debug</id>
<activation>
<property>
<name>debug</name>
</property>
</activation>
<properties>
<unpack.wars>true</unpack.wars>
</properties>
</profile>
</profiles>
use debug profile inside IntelliJ IDEA for expanding wars and default profile for building artifacts in command line or CI (default profile would be active if no profile were provided, so your build will works as previously).
With this solution HotSwap and resources updates works as expected.
Hope this helps.
I think it's the same as this question: IntelliJ Artifact has invalid extension
Add a .war extension to the output directory as shown in my answer: https://stackoverflow.com/a/25569266/968988

Why would a maven-war-plugin generate a JAR instead of a WAR?

I am following this Contract first using CXF tutorial and while the resulting pom.xml generates sources and even completes build successfully, it fails to create a WAR file.
Instead, it creates a JAR file.
My understanding is that the part in the pom.xml that's responsible for creating the WAR is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<outputDirectory>D:/path/to/profile/autodeploy</outputDirectory>
</configuration>
</plugin>
I don't see any <goal> or <execution> element there (unlike in the build-helper-maven-plugin one), but I also understand that with this plugin this is implied as even the official usage page demonstrates:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
So... what am I missing?
What could possibly explain a maven-war-plugin that behaves in unexpected way like this and produces a JAR instead of a WAR by default?
Is there a way to force it to produce a WAR?
packaging should be as below.
<packaging>war</packaging>
if it won't help then try binding your plug-in configuration with a lifecycle phase.
in your project definition , please check if packaging is missing or not , it should be some thing like this .
<groupId>some.groupid</groupId>
<artifactId>My Web Application</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<description>My First Web Application</description>
By default maven war plugin binds to package phase of the lifecycle ,so its important that we should mention the type of packaging we want once the build is done.
I would like to suggest to have a look at the Maven specs for war plugin.

How to exclude jars from ear

I am bundling EAR from a WAR file. The JARS are placed both in WARFile/WEB-INF/lib folder as well as EARFile/lib folder with duplication.
Do we need the JARS again in EARFile/lib folder inspite of having in WARFile/WEB-INF/lib?
If we do not need in EAR/lib filder, How can we remove them? The EAR file size became double due to duplication JARs presence in both WAR and EAR.
Please help me.
Thanks
Good read here on "skinny" wars. Basically, you put the jars in the ear, but not the war files:
http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html
You have to define the dependency to your war project in the following way:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>xyz-web</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
and furthermore you have to configure the ear plugin like the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<version>6</version>
<modules>
<!-- Register our War as a web module, and set the context root -->
<webModule>
<groupId>${project.groupId}</groupId>
<artifactId>xyz-web</artifactId>
<contextRoot>/xyz</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>

Maven - Calling a module from Parent POM based on the profile

I have a module which is supposed to produce two artifacts (war's). The only difference between the two WAR's is the web.xml being used.
I did this with the help of Maven Profiles...
<parent>
<artifactId>com</artifactId>
<groupId>myProj</groupId>
<version>1.0</version>
</parent>
<groupId>myProj.module1</groupId>
<artifactId>module1</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<profiles>
<profile>
<id>module1</id>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>module1</warName>
<webXml>src\main\webapp\WEB-INF\web_module1.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>module2</id>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>module2</warName>
<webXml>src\main\webapp\WEB-INF\web_module2.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Q1: How can I call this POM from super POM so that both the Profiles are activated?
Q2: Is it possible to install both the generated artifacts in Local repository?
Thanks!
When you want to activate several profiles at the same time, you simply have to run mvn ... -Pprofile1,profile2 command.
However, in your case, this is against one main Maven convention, which states that one project = one artifact. This means that you can't create 2 WAR at the same time. If you activate both profiles, one configuration of the maven-war-plugin will be overriden by the second profile, and then, you will finally get 1 WAR, with one web.xml.
If you want to get 2 WARs, the solution are to use WAR overlay (i.e. the second war is another project that depends on war #1), or run two separate Maven commands, one per profile.

Resources