I'm building a web-application with Maven3 and run it via mvn jetty:run-war. Now I'd like to open the web-app from my maven build in the system browser.
I solved my problem on os windows, which is currently my only build system. After the jetty server is started and hosting my web-app the build makes a start call via antrun:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>Run URL in system browser.</id>
<phase>install</phase>
<configuration>
<target>
<exec executable="start" vmlauncher="false">
<arg line="http://localhost:8080/rap?startup=entrypoint"/>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
I have written a Maven plugin that can open browser on each platform/JDK as part of my bck2brwsr VM work. It can be used to show any static page in your project. Following example opens browser with content of pom.xml file:
<plugin>
<groupId>org.apidesign.bck2brwsr</groupId>
<artifactId>bck2brwsr-maven-plugin</artifactId>
<version>0.22</version>
<executions>
<execution>
<id>show-a-file</id>
<phase>verify</phase>
<goals>
<goal>show</goal>
</goals>
<configuration>
<directory>${basedir}</directory>
<startpage>pom.xml</startpage>
</configuration>
</execution>
</executions>
</plugin>
I know opening a static page isn't perfect, but it can contain appropriate redirect, right? Moreover, if there is an interested, the plugin can easily be improved to open any URL. Pull Requests welcomed.
Use Jetty server. Add Jetty plugin in your pom.xml under build tag like this:
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/shinchan</contextPath>
</webApp>
</configuration>
</plugin>
<!-- more plugin tags if any -->
<plugins>
now build using
mvn clean install jetty:run
this will start Jetty server at port 8080, and you can access using http://localhost:8080/shinchan URL on the machine the mvn command is executed.
PS:
For more details read Jetty wiki here: http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin
you may want to consider jetty:deploy-war, but I think it's an overkill.
Related
I need to setup Maven to:
a) compile the GWT module
b) copy the *.java files in the jar (so it can be imported in another GWT module)
c) copy the result of the compilation step in the jar (so it can be used on a server as is)
Does any one know how this can be done ?
The basic idea is that I want to decouple my GWT project from my Spring MVC project and remove any dependencies that the Spring application might have to GWT jars & plug-ins.
That way I can use the GWT modules as pure javascript libraries and load them with org.springframework.js.resource.ResourceServlet directly from the Jar files while still maintaining the flexibility to re-use modules in other GWT projects.
Any help would be appreciated.
I'm attaching the solution I came up with so others can use it:
<!-- Set the output directory to something gwt:run can use in hosted mode -->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<finalName>gwt-build-name</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<hostedWebapp>${project.build.directory}/${project.build.finalName}</hostedWebapp>
</configuration>
</plugin>
<!-- Attach the resources plugin to the prepare-package phase to include the host page & generated javascript files -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>package-generated-javascript</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- shove everything the compiler produced into the JAR/META-INF/ folder so that Spring resourceServlet can find it -->
<outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/${project.build.finalName}</directory>
<includes>
<include>org.yournamehere.Main/**</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>include-host-page</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
What the above does is change the output directory to target/finalName so that everything ends up under the same directory and attach the resources plugin to the compile, prepare-package phases to copy the GWT compiler output to the build directory. Once everything is there it will end up in the final jar by default.
This way the build directory contains everything that hosted mode needs to run and everything Spring resources servlet needs to serve the GWT module without any direct dependencies to GWT.
I'm setting up an integration test module for a good sized web project. The integration test module is separated from the web project itself, and it has it's own pom.
The idea is to use the maven-soapui-plugin to send requests and verify the response. Setting up the soapui-plugin is no hassle. However, I'm having trouble with figuring out how I can tell the jetty-maven-plugin to deploy a war from a remote repository.
If I have understood correctly, the jetty-maven-plugin has a property called '<webApp>/<webApp>' which lets me specify the war file to deploy. The problem is that the war file is not present in the module itself.
I have heard that I can use the maven assembly plugin to retrieve the war from a repository via the projects artifactId, but I am yet to figure out how I would go about doing so.
Here's a summary of what I want:
Retrieve a specific war from a repository or the like, in example via its artifactId.
Deploy this war to the jetty-maven-plugin (goal deploy-war?)
get maven-soapui-plugin to run tests and report the results back in the integration-test phase.
I am pretty sure I've got step 3 covered, but I am very unsure how to achieve step 1 and 2.
Any help is greatly appreciated
It is maybe possible to use dependency:copy to retrieve the war, unpack it and to get the whole thing working with the maven jetty plugin, but this would be hacky and kinda ugly. A cleaner solution would be to use the Maven Cargo plugin and this is my suggestion. Below, a sample POM showing how to retrieve a WAR artifact using its coordinates and how to deploy it on an embedded Jetty container using Cargo:
<dependencies>
<dependency>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<version>war version</version>
</dependency>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<!-- Container configuration -->
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
<!-- Configuration to use with the container or the deployer -->
<configuration>
<deployables>
<deployable>
<groupId>war group id</groupId>
<artifactId>war artifact id</artifactId>
<type>war</type>
<properties>
<context>war context</context>
</properties>
</deployable>
</deployables>
</configuration>
<!-- Don't wait, execute the tests after the container is started -->
<wait>false</wait>
</configuration>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
Finally, just bind the soapui plugin on the integration-test phase.
I'm doing the same thing, John, but I took a different approach with the Jetty plugin. I think the end result is the same. I'm developing an integration-test suite to run against several web service WARs. I'm using dependency:copy in the package phase and then a list of <contextHandler/>s configured for maven-jetty-plugin:
<project>
…
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-wars</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/wars-to-be-tested</outputDirectory>
<stripVersion>true</stripVersion>
<artifactItems>
…
<artifactItem>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>version</version>
<type>war</type>
</artifactItem>
…
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.1.3.v20100526</version>
<configuration>
…
<contextHandlers>
…
<contextHandler implementation="org.mortbay.jetty.plugin.JettyWebAppContext">
<war>${project.build.directory}/wars-to-be-tested/artifactId.war</war>
<contextPath>/context</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I would prefer to declare the various wars as dependencies and then use dependency:copy-dependencies to set up the wars-to-be-tested directory; this would allow the Maven reactor to figure out that it needs to build my integration-test module after the wars it'll be testing. The problem I ran into was that the Jetty plugin thought that I wanted to "overlay" all of the wars that were listed as dependencies (a concept that I'd never even heard of until I saw it happen); I don't know if allowing that to happen would have hurt anything, but I didn't like it, so I went with the dependency:copy method.
This is just an alternative to using Cargo. I'll be looking into that myself, but I just wanted to provide another way of doing it.
I have a project (here called my-artifact) which needs to generate sources from a model file. I've created a maven-plugin (my-code-generator) which is used as described in the pom.xml excerpt below. It loads and processes the model.xml from my-artifact's resources and generates code using some predefined templates stored within the plugin. The question is how my-code-generator could access these templates as they are not in the project resources but within its own resources.
Thanks in advance
<plugin>
<groupId>my-group</groupId>
<artifactId>my-code-generator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<configuration>
<modelfile>
src/main/resources/model.xml
</modelDir>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate-model</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
<sources>
<source>target/generated-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Just use the ClassLoader, to get resources from the MyCodeGenerator Maven plugin.
Add something like this to your MyCodeGeneratorMojo
URL getTemplate(String fileName) {
return this.getClass().getResource(fileName);
}
Within the MyCodeGenerator Maven plugin, add the template(s) to the src/main/resources directory (don't forget to use the correct package entry (directories) within that directory).
By including them in the jar file for the plugin and referencing them via classpath, via ClassLoader.getResourceAsStream.
By packaging them as another artifact, declaring them as a dependency, and calling the dependency-resolution API, which is a lot more work.
I have defined the following profile in pom.xml:
<profiles>
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>dev</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="src/main/application/META-INF/data-sources.xml"/>
<copy file="src/main/resources/data-sources-dev.xml" tofile="src/main/application/META-INF/data-sources.xml"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The issues is that it doesn't seem to work!
mvn help:effective-pom -P dev
Does echo also the profile.
However, if I do
mvn -X -Pdev install
The delete / copy part is not visible in the logs.
There is no phase with the name dev. Please specify a correct phase.
I've just copy-pasted your configuration into a basic pom and it works just fine. Are you sure it doesn't appear in the config as well as the profile? If you redirect the output to a file and search for "antrun" I suspect you'll see that it is declared in the build section of the effective pom.
Your antrun plugin configuration needs to bind to a valid phase for its packaging type before it will be executed. If you want the contents to be available in the jar (assuming jar packaging), this needs to be before the package phase. I would suggest process-resources.
So change:
<phase>dev</phase>
to:
<phase>process-resources</phase>
We have a hundreds of tests defined for our integration-test phase lifecycle in maven, and they take a long time to finish.
What I want to do is run just one test in the integration-test. I tried doing :
mvn -Dtest=<my-test> integration-test
but that does not work. The -Dtest runs only the tests in the unit test goal, not the integration-test phase. I tried the -Dintegration-test=<my-test> instead, and that was ignored.
Is there a way to do that ?
My configuration is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/api/**</include>
</includes>
.....
If you're using the Maven failsafe plugin, you can run a single integration test by setting the it.test property to your fully qualified test class name:
mvn -D it.test=your.TestCase verify
See the failsafe plugin docs for more info.
The Failsafe documentation would have you specify the test like so:
mvn -Dit.test=BrokenIT verify
However, -Dit.test does not appear to work any longer. Rather, the same parameter used to specify a Surefire test will apparently work for Failsafe as well. For example:
mvn -Dtest=WorksIT verify
I've filed a bug (EDIT: which was closed as "Cannot Reproduce" in 2.12) to correct the documentation.
just add -DfailIfNoTests=false works for me with testNG. Something like this:
mvn integration-test -Dtest=aITest -DfailIfNoTests=false
I struggled through this, and I created an additional profile to use when I wanted to run just one integration test. I hope that I've successfully extracted just the right part here:
<profile>
<id>integrationTestSingle</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/integration/**/${test}.java</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
<configuration>
<argLine>-Xms256M -Xmx768M -XX:MaxPermSize=256M</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Now, I call maven with the integrationTestSingle profile and with -DfailIfNoTests=false -Dtest=NameOfTest, and it doesn't run any of the regular tests during the regular "test" phase, and runs just the NameOfTest test during the integration-test phase.
I'm not sure about JUnit, but for TestNG the strategy would be to define a suite XML file with only the one test, and then in your POM configure the surefire plugin to only run that. In your POM, you would have something like this (disclaimer, this is untested):
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>single-test.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
To configure the suite file, see http://testng.org/doc/documentation-main.html
Just ran into this myself. Something like this worked well for me:
mvn -Pintegration-test -Dtest=<my-test>
The trick was to ensure that the test-group was mentioned before the -Dtest portion.
I am using:
Apache Maven 3.6.3
openjdk version "11.0.2" 2019-01-15
<groupId>org.codehaus.mojo</groupId>
<artifactId>failsafe-maven-plugin</artifactId>
<version>2.4.3-alpha-1</version>
This command worked for me:
mvn failsafe:integration-test -Dsurefire.skip=true -DskipIntegrationTests=false -DskipTests=false -Dtest=com.myxyz.func.ITestGate
Was actually simpler that the answers above by going back to basics with the actual documentation.
Running Junit 5 integration tests:
openjdk version "11.0.11" 2021-04-20
Apache Maven 3.6.3
In the main build just drop in documented failsafe config:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then you can run only a specific integration test with:
mvn -Dtest=\*cs1_\* verify
Note that this version will run your tests in the target folder and if you need to load any external files that are something like src\test\resources\x.y then they are copied to target\test-classes\x.y
This works for me, when I gonna run only one test method in integration test
mvn clean -Dit.test=some.package.SomeTestClass#testMethodName integration-test