We have a current web application that is deployed to OAS (Oracle Application Server).
I am trying to implement some functional tests using selenium for this application. I created a new maven project specifically for functional testing, which uses cargo to deploy the application war file (webapp-site.war) to the default container provided by cargo (Jetty). pom.xml attached at the end.
The problem I am facing is in trying to configure jms properties. The current setting in the web application uses OAS specific values from an environment specific jms.properties file (shown below):
java.naming.factory.initial=oracle.j2ee.rmi.RMIInitialContextFactory
java.naming.provider.url=opmn:ormi://localhost:6003:OC4J_DEV/default
java.naming.security.principal=username
java.naming.security.credentials=password
jms.queue.connection.factory.jndi=jms/QueueConnectionFactory
When I start up jetty using cargo, the deployment of the application war fails when it looks for the "RMIInitialContextFactory" and does not find it. This is an OAS specific jar which is not available in the global maven repository. I managed to download and install this jar in the local maven repo, but then it showed a missing class from another oracle specific jar not present in the global maven repo. Also, even I resolved all such dependencies to external jar, I am unsure of how it would perform with Jetty.
It would be really helpful to know how to configure these properties in cargo specific to jetty and have it picked up by the deployable application war.
Attaching the pom.xml of the functional test module 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>
<artifactId>webapp-automation</artifactId>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.webapp</groupId>
<artifactId>webapp</artifactId>
<version>11.0.5</version>
</parent>
<name>Functional tests for webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<servlet.port>9090</servlet.port>
<seleniumHost>localhost</seleniumHost>
<seleniumPort>4444</seleniumPort>
<selenium.version>2.3</selenium.version>
<selenium.background>true</selenium.background>
</properties>
<dependencies>
<dependency>
<groupId>com.webap</groupId>
<artifactId>webapp-site</artifactId>
<type>war</type>
<version>${project.version.number}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.42.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.8.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<version>${selenium.version}</version>
</plugin>
<!-- CARGO is used to deploy the RAPS application for functional testing -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.2</version>
<configuration>
<container>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
</dependency>
</dependencies>
</container>
<configuration>
<properties>
<cargo.servlet.port>${servlet.port}</cargo.servlet.port>
<cargo.datasource.datasource.ojdbc14>
cargo.datasource.driver=oracle.jdbc.driver.OracleDriver|
cargo.datasource.url=jdbc:oracle:thin:#deirbned01.deir.citec.qld.gov.au:1521:RAPSDEV|
cargo.datasource.jndi=jdbc/RAPSDS|
cargo.datasource.username=RAPS_9|
cargo.datasource.password=sm4u
</cargo.datasource.datasource.ojdbc14>
</properties>
</configuration>
<deployables>
<deployable>
<groupId>com.webapp</groupId>
<artifactId>webapp-site</artifactId>
<type>war</type>
</deployable>
</deployables>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skip the normal tests, we'll run them in the integration-test phase -->
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>start-cargo</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-cargo</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<id>start-selenium</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
</execution>
<execution>
<id>stop-selenium</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-server</goal>
</goals>
</execution>
</executions>
<configuration>
<background>${selenium.background}</background>
<port>${selenium.port}</port>
<logOutput>true</logOutput>
</configuration>
</plugin>
</plugins>
</build>
Any help would be great !!
Cheers,
Rahul
I found a way of solving the problem.
We use some environment specific settings in the project. I created a new environment profile in the build for functional tests and created a new jms.properties with the initial context factory pointing to the one provided by jetty.
It worked.
Cheers,
Rahul
Related
I'm working on creating a pom for a project and adding test cases to it. The project is an eclipse plugin.
Compiling the project with tycho works just fine, the only problem is during testing:
If I run both maven-surefire-plugin tests and tycho-surefire-plugin-tests, the former performs all the tests as expected, while the latter gives the following error:
Execution test of goal org.eclipse.tycho:tycho-surefire-plugin:1.7.0:test failed: Tycho build extension not configured for MavenProject
I would be perfectly fine to just add <skipTests>true</skipTests> to the tycho-surefire-plugin while keeping maven-surefire-plugin on; the problem is even that way, jacoco refuses to create the coverage site, with the following (non error) message:
Skipping JaCoCo execution due to missing execution data file.
I tried to look for solutions of both, but any combination of the solutions I found doesn't lead me to having a working coverage site.
Maven really makes me quite confused, especially with tycho around, so I'd apreciate any explanation on top of the actual fix.
Here is my pom:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroupid</groupId>
<artifactId>myartifactid</artifactId>
<name>myname</name>
<packaging>eclipse-test-plugin</packaging>
<properties>
<tycho-version>1.7.0</tycho-version>
</properties>
<parent>
<groupId>parentgroupid</groupId>
<artifactId>parent</artifactId>
<version>0.9.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>src/test/java/</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/Test_*.java</include>
</includes>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/Test_*.java</include>
</includes>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<output>file</output>
<append>true</append>
<includes>
<include>**/path_to_source/**/*</include>
</includes>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And here is my parent pom:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>parentgroupid</groupId>
<artifactId>parent</artifactId>
<version>0.9.5</version>
<packaging>pom</packaging>
<modules>
<module>moduleid</module>
</modules>
<properties>
<tycho-version>1.7.0</tycho-version>
</properties>
<repositories>
<repository>
<id>eclipse-2020-06</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/2020-06</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
<configuration>
<includeAllDependencies>true</includeAllDependencies>
</configuration>
</plugin>
</plugins>
</build>
</project>
Of course there won't be any test result for the JaCoCo due to you are using very old Surefire version 2.12.4. This version was not created for JUnit5.
Use the latest version 3.0.0-M5 and see the tutorial.
If you want to have tiny POM, remove the dependency junit-jupiter-engine due to you do not need to have an access to the JUnit internals in your test code. The Surefire will download it shortly before the test runtime.
Your POM has several errors. Let's start with the root cause and then other priorities from high to low.
Whole problem is that Surefire does not know about JaCoCo. You have to tel "him" this way (see jacoco.agent) which "wires" both. Pls ead the documentation in the JaCoCo project:
<properties>
<jvm.args.tests>-Xmx2048m -Xms1024m -XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true -Djdk.net.URLClassPath.disableClassPathURLCheck=true</jvm.args.tests>
<properties>
...
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
</configuration>
...
The next error is with the way how you use plugins. The plugin jacoco-maven-plugin must be used only in the plugins section. The problem is that you use it also in the dependencies section. You do not want to have it on the classpath. It is job of the property jacoco.agent to put the jacoco agent on the test classpth only but there the JaCoCo plugin must start before the Surefire plugin.
The next thing i do not understand is the config of the compiler. Why you have this?
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
I have second question regarding the packaging. I have never seen this one. It isn't a standard packaging.
<packaging>eclipse-test-plugin</packaging>
Has the Eclipse plugin any special binary form of the archive file?
I am trying to execute my feature files via TestRunner.java files (by mentioning them in pom.xml) , in parallel using maven-surefire-plugin, for which i have set up pom.xml as below, but when i run pom.xml as maven test, its throwing PluginResolutionException when the version is 3.0.0-M3, when i have update the version to 2.19.1, the maven test is not running my feature files but the build is shown as successful
I have tried with different versions but not worked
Also I have tried replacing the configuration part with below changes
still my feature files are not executed but the build is
successful
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<!--
<parallel>classes</parallel>
<forkMode>perthread</forkMode>
<threadCount>3</threadCount>
-->
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<includes>
<include>**/*TestRunner.java</include>
</includes>
</configuration>
PS: After reading the below artical
https://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html#Running_tests_in_parallel
I understand that there is link between the Junit version and surefireflugin i use in my project, bow one thing is for sure, the correct combination of Junit and maven-surefire-plugin is very much necessary, i have tried with below combinations
JUnit 4.7
plugin 3.0.0-M3
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>3.0.0-M3</version>
</dependency>
</dependencies>
</plugin>
JUnit 4.12
plugin 2.20
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<parallel>classes</parallel>
<threadCount>3</threadCount>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<includes>
<include>**/*TestRunner.java</include>
</includes>
</configuration>
</plugin>
but its not helpful, I suppose i am doing mistake in choosing this versions and the config of plugin with proper parameters, please help me
My complete pom is as 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>com.practise.raja</groupId>
<artifactId>SeleniumConcepts</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<fork>true</fork>
<executable>C:\Program Files (x86)\Java\jdk1.8.0_211\bin\javac</executable>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<parallel>classes</parallel>
<forkMode>perthread</forkMode>
<threadCount>3</threadCount>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<includes>
<include>**/*TestRunner.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Expected:
My feature files should run in parallel
Actual:
My feature files are not executed
After changing the dependencies and plugin as suggested by sureshmani, this is how it looks
Finally i am able to solve this, to my initial pom, have started doing below changes. Which ran my feature files in parallel
Change 1: I happen to add the dependency for cucumber-jvm-parallel-plugin along with plugin ,so i have deleted the plugin
Change 2: I have realized that the cucumber-jvm-parallel-plugin is not able to recognize the feature files when I have them placed src/main/java , some of the posts said i have to move all feature files to src/main/resources/feature , where features is package
Change 3: I have realized that cucumber-jvm-parallel-plugin is not able to recognize the resources like step def's and drivers etc, so i have used build-helper-maven-plugin where i have declared the resources as below
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java/</source>
<source>src/main/resources/</source>
<source>features</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Change 4: cucumber-jvm-parallel-plugin in the maven life cycle in my IDE, because for some reason maven is not able to consider this plugin in it execution
Eclipse --> Windoes --> Preferences --> Maven->LifeCycleMappings-> copy paste below code
<pluginExecution>
<pluginExecutionFilter>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<goals>
<goal>generateRunners</goal>
</goals>
<versionRange>[4.2.0,)</versionRange>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
Then , click on "Reload workspace lifecycle mapping metadata" button in Preference
Maven modal
My final pom looks like this
<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.practise.raja</groupId>
<artifactId>JUnitCucumberParallelExecutionPractise</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>JUnitCucumberParallelExecutionPractise</name>
<description>JUnitCucumberParallelExecutionPractise</description>
<dependencies>
<!-- <dependency>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
</dependency>
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.5.3</version>
</dependency>
</dependencies>
<properties>
<src.main.java>src/main/java</src.main.java>
</properties>
<build>
<resources>
<resource>
<directory>${src.main.java}</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/java/</source>
<source>src/main/resources/</source>
<source>features</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<fork>true</fork>
<executable>C:\Program Files (x86)\Java\jdk1.8.0_211\bin\javac</executable>
</configuration>
</plugin>
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version> 4.2.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<featuresDirectory>src/main/resources/features</featuresDirectory>
<glue>
<package>com.qa.stepdef</package>
</glue>
<outputDirectory>${project.build.directory}/generated-test-
sources/cucumber</outputDirectory>
<cucumberOutputDir>${project.build.directory}</cucumberOutputDir>
<format> json </format>
<strict>true</strict>
<monochrome>false</monochrome>
<useTestNG>false</useTestNG>
<namingScheme>simple</namingScheme>
<namingPattern>Parallel{c}IT</namingPattern>
<parallelScheme>FEATURE</parallelScheme>
</configuration>
</execution>
</executions>
</plugin>
<!-- Specify a custom template for the generated sources (this is a path
relative to the project base directory) -->
<!-- <customVmTemplate>src/test/resources/custom-runner-template.java.vm
</customVmTemplate> -->
<!-- Specify a custom package name for generated sources. Default is no
package. -->
<!--<packageName></packageName> <plugins> <plugin> <name>json</name>
</plugin>
<plugin> <name>html</name> </plugin> <plugin> <name>pretty</name> </plugin>
</plugins> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<forkCount>3</forkCount>
<reuseForks>true</reuseForks>
<includes>
<include>**/*IT.class</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Even after these changes, an error started showing at <execution> in pom, it says
Plugin execution not covered by lifecycle configuration: com.github.temyers:cucumber-
jvm-parallel-plugin:4.2.0:generateRunners (execution: generateRunners, phase:
generate-
But, its fine, i am able to run the feature files in parallel even with this above
error
test-sources)
I want to Run Jetty with jetty-maven-plugin and finish the build when jetty is running.
I created a pom.xml that starts jetty and deploying a war file,
after the jetty starts I want maven to finish the build while leaving the jetty running, So that I could start another maven build to run tests on the server I just ran jetty on.
Then I will create another maven build that just stops the jetty server.
Problem is that I didn't managed to start jetty and make the maven build stop after that, Does anyone knows how to do that?
p.s
I used "run-forked" for that, but it still waited for a stop signal so the build was stuck.
This is the jetty-start profile:
<profile>
<id>start-jetty</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<war>${unpacked.war.directory}</war>
<contextXml>${unpacked.war.directory}/WEB-INF/jetty-web.xml</contextXml>
<webApp>
<contextPath>/qabin</contextPath>
</webApp>
<systemProperties>
<systemProperty>
<name>mercy.td.sa_config_dir</name>
<value>${tests.runtime}</value>
</systemProperty>
<systemProperty>
<name>jetty.port</name>
<value>${jetty.start.port}</value>
</systemProperty>
</systemProperties>
<stopPort>${jetty.stop.port}</stopPort>
<stopKey>STOP</stopKey>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-forked</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
It should be clear that Maven is a build tool, not a commands executor tool.
Starting/stopping Jetty should be part of the same build within an integration tests execution phase. Moreover, you are also creating dependencies between two maven builds (which are not effectively builds indeed), which may be a problem as part of your CI environment if ever the stop build fails - for whatever reason - and leave the started jetty up and running and as such consume resources on your CI server for undefined time.
A simple start/test/stop flow could be implemented as following as part of the same Maven build:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.8.v20150217</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<stopWait>2</stopWait>
<webApp>
<contextPath>/examplecomponent</contextPath>
</webApp>
<httpConnector>
<port>7777</port>
</httpConnector>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Basically, you configure the surefire plugin to skip integration tests during the test phase, then start jetty before the integration test fase, execute integration tests (based on suffix) and then stop jetty afterwards.
I would also suggest to move it a profile in order to make the default build faster and independent from integration tests, so that it can also run successfully when offline, then activate the profile when required (i.e. on the CI build).
Updated: if you really need to have a start in a maven project and a stop in an other maven module, you could apply the following approach:
Have an aggregator/multimodule maven project: a module will provide the start, another module will provide the stop, other modules will use the running jetty. However, the maven reactor may not invoke them in the order you wish, you should then make sure the stop module depends on the start module (has it as dependency) and any module requiring the running module will also have the start module as dependency. Moreover, the stop module should also depend on testing module so that it will be executed only at the end. That should do the trick.
Hence, to summarize:
jetty-question (the aggregator project)
start-jetty-module
use-jetty-module (has start-jetty-module as dependency)
stop-jetty-module (has start-jetty-module and use-jetty-module as dependencies)
Updated 2: Below the working approach (tested on Windows machine)
Here is the pom file of the aggregator project, jetty-question:
<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.stackoverflow</groupId>
<artifactId>jetty-question</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>jetty-start</module>
<module>jetty-stop</module>
<module>jetty-use</module>
</modules>
</project>
Note the modules declaration and the packaging as pom (required for aggregators).
Here is the pom file of the jetty-start module, which is a folder nested under jetty-question
<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>
<parent>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-question</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jetty-start</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<configuration>
<target>
<exec executable="cmd.exe" spawn="true">
<arg value="/c" />
<arg value="mvn jetty:run" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.8.v20150217</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<stopWait>2</stopWait>
<webApp>
<contextPath>/jetty-start</contextPath>
</webApp>
<httpConnector>
<port>7777</port>
</httpConnector>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Note: the module is configuring the jetty plugin and then executing a background process via the antrun plugin to execute mvn jetty:run
In my example code, the deployed application simple provided an index.html page printing Hello world.
Here is the pom file of the jetty-use module:
<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>
<parent>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-question</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jetty-use</artifactId>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-start</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.47.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Important: as described above, it needs a dependencies on the jetty-start module so that the reactor maven build will execute it after the jetty-start (and as such we are sure jetty would be running when executing this build).
Note the dependencies for Junit and selenium, I used them to effectively test the running jetty via the junit integration test below:
public class AppIntegrationTest extends TestCase {
public void testApp() throws Exception {
// Create a new instance of the Firefox driver
WebDriver driver = new HtmlUnitDriver();
// Launch the Online Store Website
driver.get("http://localhost:7777/jetty-start");
WebElement element = driver.findElement(By.id("title"));
Assert.assertNotNull(element);
Assert.assertNotNull(element.getText());
Assert.assertEquals("Hello World!", element.getText());
}
}
Finally, here is the pom file of the jetty-stop module
<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>
<parent>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-question</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jetty-stop</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<configuration>
<target>
<exec executable="cmd.exe" spawn="true">
<arg value="/c" />
<arg value="mvn jetty:stop" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.8.v20150217</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<stopWait>2</stopWait>
<httpConnector>
<port>7777</port>
</httpConnector>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-start</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>jetty-use</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Note the similar configuration to the jetty-start module. This module is also configuring the jetty plugin and it is stopping it via the antrun plugin which will execute in background the mvn jetty:stop goal.
Also note the dependencies of this module: it needs to depend on both jetty-start and jetty-use so that the maven reactor build will execute it at the end.
Further notes: the jetty configuration on the jetty-start and jetty-stop module need obviously to share the stop key and stop port. For this example, server port is harcoded in the pom file (which also needs to be the same for both jetty-start and jetty-stop modules), but you could also move it to a property in the parent module.
Moreover, the antrun plugin executes a background process in Windows mode. If you are running on Linux a & suffix should also make the trick.
I would also suggest to keep it in a multimodule project so that you can make sure that dependencies are coupled together.
Although I would not advice this approach as described at the top of this answer, it was challenging and fun to get it to work, so thank you for the fun. Hope you get it work too.
What's the best way to create a simple osgi (deploying into virgo server) project using maven, to create a war structure with pom.xml maven descriptor?
A Structure target is
*.jsp
*.html
META-INF
MANIFEST (OSGI-CONFIG)
WEB-INF
classes
lib
web.xml
Then when I create a project
This is my pom.xml
project properties
<groupId>com.aaaa</groupId>
<artifactId>first-maven-virgo-project</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
Felix Plugin
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<instructions>
<Export-Package>com.roshka.servlet</Export-Package>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-ClassPath>.,WEB-INF/classes,{maven-dependencies}</Bundle-ClassPath>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
<Embed-Dependency>*;scope=compile|runtime;</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Web-ContextPath>/hello</Web-ContextPath>
<Webapp-Context>hello</Webapp-Context>
</instructions>
</configuration>
</plugin>
But, when I execute mvn install the package does not create the MANIFEST file, to package into METAINF folder.
What's the wrong with my felix project? What's is the typical pom.xml template to create an OSGI BUNDLE , and WAR OSGI BUNDLE?
p.s. if I change WAR TO BUNDLE into Packaging Maven descriptor, the JAR generated works OK, with MANIFEST generated OK. But it is not WEB Structure.
My question has been resolve with the next pom.xml
<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.aaaa</groupId>
<artifactId>first-maven-virgo-project</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<description>http://localhost:8090/system/console/bundles</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestFile>./src/main/webapp/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<manifestLocation>./src/main/webapp/META-INF</manifestLocation>
<instructions>
<Export-Package>com.roshka.servlet</Export-Package>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-ClassPath>.,WEB-INF/classes,{maven-dependencies}</Bundle-ClassPath>
<Embed-Directory>WEB-INF/lib</Embed-Directory>
<Embed-Dependency>*;scope=compile|runtime;</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Web-ContextPath>/hello</Web-ContextPath>
<Webapp-Context>hello</Webapp-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<Import-Package>javax.servlet,javax.servlet.http,javax.servlet.*,javax.servlet.jsp.*,javax.servlet.jsp.jstl.*,*</Import-Package>
<outputDirectory>./src/main/resources/WEB-INF/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<actTransitively>true</actTransitively>
<excludeScope>provided</excludeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<!-- Enable this plugin for all modules -->
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
</plugins>
</build>
There is an answer from IBM to be found here which describes the process step by step. A script could be developed to create a bundle given a war, I have written one in java, invoked as a build step.
One crucial difference is that the IBM steps leave the finished product as a jar, whereas jrey leaves his as a war file. This is possibly because the IBM steps might lead to further CICS bundling, which requires jars as far as I am aware, at least when using the RAD environment.
I have had no issue running a maven war project on an embedded server for its own integration tests, but now I need to run multiple wars and test from a different project.
I would like to setup the following scenario...
I have two Maven war projects in my local workspace called War1 and War2. I would like to have a 3rd Maven project, WarIntegration, that contains only integration tests and does the following:
Packages War1
Packages War2
Starts an embedded server
Deploys both wars to same embedded server
Runs integration tests contained within WarIntegration (which will make http calls to War1 and War2)
Stops embedded server
Is this possible? What plugin setup will achieve this? What kind of project should WarIntergration be (packaging)? Should War1 and War2 be modules in WarIntegration or dependencies? Can all of the configuration be aded to the WarIntegration project or would it have to be spread across the projects?
This is similar to this question, except we must use an embedded server that is started and stopped by the project (probably when we run verify) and we need a separate project for integration tests:
I have a multi-module Maven 2 POM that has two WARs, how can I configure it to deploy both wars prior to running tests?
I was able to achieve this using the cargo-maven2-plugin.
Here are the relevant pieces of the pom for anyone who is interested...
...
<groupId>com.test</groupId>
<artifactId>webapp-integration</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
...
<dependency>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<version>1.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>webapp2</groupId>
<artifactId>com.test</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
<configuration>
<type>standalone</type>
<properties>
<cargo.servlet.port>8085</cargo.servlet.port>
</properties>
<deployables>
<deployable>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp/</pingURL>
<properties>
<context>testapp</context>
</properties>
</deployable>
<deployable>
<artifactId>webapp2</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp2/</pingURL>
<properties>
<context>testapp2</context>
</properties>
</deployable>
</deployables>
</configuration>
</configuration>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.12</version>
</dependency>
</dependencies>
<configuration>
<groups>com.test.integration.IntegrationTestMarker</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Watch out, the DEPLOYABLES element is a child of plugin/configuration, NOT plugin/configuration/configuration.
The example above should be :
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<container>...</container>
<configuration>
<type>standalone</type>
<properties>
<cargo.servlet.port>8085</cargo.servlet.port>
</properties>
</configuration>
<deployables>
<deployable>
<artifactId>webapp1</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp/</pingURL>
<properties>
<context>testapp</context>
</properties>
</deployable>
<deployable>
<artifactId>webapp2</artifactId>
<groupId>com.test</groupId>
<type>war</type>
<pingURL>http://localhost:8085/testapp2/</pingURL>
<properties>
<context>testapp2</context>
</properties>
</deployable>
</deployables>
</configuration>
</plugin>
</plugins>
Hope that helps !