Maven: creating 2 war files each with different web.xml? - java

I need to create two WAR files with two different web.xml files using Maven. The WAR files are the same otherwise.
The WAR files are created as expected, however, the second file has the same web.xml file as the first.
How can I force the Maven WAR plugin to use the second file for the second WAR? I cannot use profiles since I need both files created in one pass.
My current code:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>${basedir}/WEB</warSourceDirectory>
<warName>main</warName>
<webXml>${basedir}/CONF/web.xml</webXml>
</configuration>
<executions>
<execution>
<id>hist-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<warName>hist</warName>
<warSourceDirectory>${basedir}/WEB</warSourceDirectory>
<webXml>${basedir}/CONF/hist.web.xml</webXml>
</configuration>
</execution>
</executions>
</plugin>

Use the overlay feature of the Maven WAR plugin.
You need two WAR projects. The first is your original one, with its web.xml file in the correct place. This doesn't have any specific needs in terms of configuration. Just ensure that it builds as you expect.
The second only contains its POM and the alternate web.xml in the WEB-INF directory. This project's POM must contain a dependency on the first project with type specified as war and scope specified as runtime. You should not need to explicitly configure the Maven WAR plugin.

seems there are a variety of gotchas using the war plugin. in this case, i would just use 2 separate sub-modules to build the appropriate wars.

Related

How to setup a common classpath for all dependencies inside a maven project?

I have a spring project, that is compiled into a jar file. Lets call this project A.
There is another project B which is a dependency of Project A. I have no contol over project B. The project B is available in the form of two files.
One is an executable jar file while the other one is zip file. This zip file contains all the resources of the project.
To invoke the API from B I need to pass a resourceLocation parameter (it is the url of the above mentioned resource folder).
I included both B.jar and B.zip in my A's pom as dependencies.
Now I create an executable jar-with-all-dependencies for my project A.
Along with other dependencies, resources folder from B.zip is present inside my jar.
Now the problem:
What should be the resourcePath that I should give while invoking API of B from inside of A.
I have tried . and ./resources. But B doesn't get it. How can I get the absolute path for resources folder and give it to B. Or setup a common classpath for A and B.
you could try maven-dependency-plugin unpack zip to classpath
unpack dependency zip resources folder, which will add the artifacts to classpath of A
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>unpack-sigar</id>
<phase>package<!-- or any other valid maven phase --></phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>somegroupid</includeGroupIds>
<includeArtifactIds>B</includeArtifactIds>
<outputDirectory>
${project.build.directory}/src/main/resources
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Creating ear package using one pom with maven

I want to create ear application with one ejb project and dependencies (without war file). Is it possible to specify build configuration in one pom.xml to avoid unnecessary multiplication of application modules (I have about 8 projects witch will be packaged this way and if I would do this "standard" way I would have to create 8*3=24 modules/poms). I don't want to put all my applications into one ear, because I need to could undeploy/redeploy them separately.
Right now I have two solutions:
Create ear in standard way with module structure:
project
ejb
src
pom.xml
ear
pom.xml
pom.xml
But as I mentioned it's creating multiplication of modules.
Create jar with dependencies using maven-shade-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<finalName>project</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
But with this solution I get jar instead of ear and my dependencies are mixed with my code.
Is there any other way to create deployable application with only ejb and dependencies with maven using single pom.xml?

maven copy a particular dependency jar to a specific directory in the .war file

I am trying out a Simple Java Web Start project based on the Oracle Tutorial. I am using maven to package it as a webapp and deploy it to application server. The full source code is available here
https://github.com/KiranMohan/dynamic-tree-javaws-sample-project
The maven project structure is like
parent
|--lib
|--webapp
The webapp module is a maven war module. It is required to package lib.jar at the root of webapp.war. NOT under WEB-INF/lib.
How to achieve this in maven?
I found that the right way to do this is to use the maven-dependency-plugin.
Since "lib.jar" is not used in the compile phase of "webapp" module, it is only a package time dependency. Using maven-dependency-plugin, I can copy lib.jar to any required directory during the prepare-package phase. The maven-war package would then include the lib.jar in the .war package.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>[ group id ]</groupId>
<artifactId>[artifact id]</artifactId>
<version>[ version ]</version>
<outputDirectory>${project.build.directory}/${project.artifactId}</outputDirectory>
</artifactItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</execution>
</executions>
</plugin>
Update:
There is a webstart-maven-plugin that does a better job of packaging javaws applications. See my sample project
https://github.com/KiranMohan/dynamic-tree-javaws-sample-project
for details
Well how i said in the comments for sake of readability here is a part of the answer:
Since Maven will always store the dependencies of a web project under its WEB-INF/lib folder by default i (i am no Maven expert ...) would try to place my lib.jar inside the /target folder of the project before the phase package is executed.
NOTE: I havent tried it out so you will have to adjust the paths - expecially the output path so your lib.jar is placed properly to be packed into the root of the war (e.g. if you open your war there will be a lib.jar next to folders such as WEB-INF).
<!--
lets assume the root of my project would be under C:/devjba/projectX this equals the maven
variable ${project.basedir}.
from there the output-directory would be located under C:/devjba/projectX/target which equals the
maven variable ${project.build.directory}. This is the location a .war would be placed in after
the build
lets assume the required jar lib.jar is located under C:/devjba/projectX/misc which would equal to
the expression: ${project.basedir}/misc
-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>foo</id>
<!-- may adjust to another phase before package but make sure your plugin is bound to a phase
because otherwise it wont be invoked during build! Now its bound to the first phase of the
default lifecycle for packaging type war -->
<phase>process-resources</phase>
<goals>
<!-- use the copy-resources goal of this plugin - it will copy resources :) -->
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- this points to /target of the current project, you may adjust it to wherever it must be placed to be packed into the root of the war (just try&error) -->
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<!-- this points to a folder /misc under the project root where we expect the lib.jar -->
<directory>${project.basedir}/misc</directory>
<!-- unless you specify what to include anything of the above directory will be included -->
<includes>
<include>lib.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
As i said i have no experience in signing JARs at all but there is a plugin called maven-jarsigner-plugin which i guess will do the job (i would sign it, then move it, then package the war) with a manual - i recomend you try to configure it according to my "example configuration of the maven-resource-plugin and post a new question directly containing your two plugin configurations. Dont forget to link to this question in that case. And also leave this question open so someone with a better approach may correct my way).

Maven, Vaadin and the resources folder

I have an existing maven project, in which i started to use vaadin, by adding the dependency in the POM file. However, when i place the VAADIN/themes folder under src/main/resources, when building with maven it gets copied to the WEB-INF/classes folder in the .war file, instead of placing it in the war root like it is supposed to be. I already tried all obvious combinations like src/main/webapp/VAADIN or src/main/VAADIN or even src/main/webapp/WEB-INF/VAADIN but none of them seems to be the correct place to put the themes and other vaadin resources.
I also tried to generate a vaadin project like it is described in here https://vaadin.com/wiki/-/wiki/Main/Using%20Vaadin%20with%20Maven but no success. maven behaves in the same way.
Does anyone have an idea of how to correctly setup Vaadin themes on a maven project ? I am using osx 10.6 with maven 3
Any help would be much appreciated. Best Regards
I'm not sure about Vaadin specifically, but you can use the Maven Resources plugin to copy resources to a specific place (anywhere you like, not just the target folder). So if you wanted to copy a folder called VAADIN from the root of your project to the root of your war, you could set it up like this:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/war</outputDirectory>
<resources>
<resource>
<directory>VAADIN</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Generally the src/main/resources folder is intended for resources which are supposed to be on the classpath, and src/main/webapp is for resources which are supposed to be in the WEB-INF folder of your webapp. I'd recommend putting other resources elsewhere (maybe src/main/vaadin?). If you do really want to put it in src/main/resources and you use the approach I've just outlined, you'll also need to exclude it Maven copies the other things in there - easier just to avoid it.
You should get at the root of your war everything you put in
src/main/webapp/
without any customization.

How to change the default output from a Maven 2 / Cobertura instrument goal?

when i instrument my classes using Maven 2 using the command
mvn cobertura:instrument
The output (the instrumented classes) are put in \target\generated-classes. Is there a way to change the output location to \target\classes?
I checked the instrumentation tasks of the cobertura-maven plugin but this does not give me a solution sofar.
You have not said why you want to overwrite the default location, but I assume it is so that you can use the instrumented classes from another project, or perhaps include them in a web archive or something similar.
I added the following to my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>instrumented-classes</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>instrumented</classifier>
<classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
</configuration>
</execution>
</executions>
</plugin>
This makes maven generate an additional jar file called projectname-instrumented.jar
It is then possible to depend on this jar file from any other pom (including for example a web module) using
<depends>
<group>mygroup</group>
<project>projectname</project>
<version>1</version>
<classifier>instrumented</classifier>
</depends>
I did not test this 100% but have used similar mechanisms in the past
As far as I understand, the instrumented classes are only needed by cobertura for report generation. If you create them in target/classes, they will overwrite the original class files.
If you need the instrumented files in a jar as a result, you can configure the maven-jar-plugin to pick up the files from the target/generated-classes directory instead of or in addition to the files from the standard ${build.project.outputDirectory}.
Edit
Have a look at the maven-jar-plugin description. To only use target/generated-classes, the following addition to your POM should work - try it and modify it to your needs:
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version> <!-- replace with correct version nbr! -->
<configuration>
<includes>
<include>${project.build.directory}/generated-classes/**/*.class</include>
</includes>
<excludes>
<exclude>${project.build.directory}/classes/**/*.class</include>
</excludes>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
${project.build.directory} points to your target folder, ${project.build.ouputDirectory} to target/classes. I do not know if you can simply set ${project.build.ouputDirectory} to a new value - have a look at the this chapter of the maven book, maybe you find some hints
Edit 2
Alternativly or additionally you can use maven to copy the files from target/generated-classes to target/classes after coberture:instrument has finished. This question has one answer with an example POM (fragment), you just have to identify the correct phase (process-resources is definitely too early for your case)
Did you try "mvn cobertura:instrument install"? It will generate a jar file including all the cobertura version classes.
If you want to change back original version, just run the command without "cobertura:instrument".
I just implemented the solution proposed by Andreas_D, modified my pom and uses the maven-resources-plugin. So on some stage of my build the Cobertura generated files are copied to the /target/classes directory.
You can configure it using <classesDirectory>[Your DIR]</classesDirectory>
In cobertura-maven-plugin version 2.4 this is still not supported. I've just created an improvement ticket, patch is attached to the ticket.

Categories

Resources