How do I setup arquillian to test a maven war project by deploying the entire war to WildFly embedded? - wildfly

I 'd like to do macro (not micro!) black box testing of my war on an embedded WildFly instance.
My maven project looks like this
<project>
...
<packaging>war</packaging>
<!-- Lots of classes in src/main/webapp and files in src/main/webapp -->
<dependencies>
<!-- Lots of compile/runtime dependencies that change very frequently -->
<!-- Lots of test dependencies that change very frequently -->
</dependencies>
</project>
My arquillian tests need to fulfill the following requirements:
Deploy the entire war to the app server in the tests. This includes all production classes, all runtime dependencies and all src/main/webapp files. From a maintenance perspective it's impossible to do micro deployments because class dependencies and jar dependencies change very frequently. So we cannot enumerate anything in the ShrinkWrap deployment.
Don't hardcode anything in the test or arquillian.xml that is already known by the maven pom.xml. This includes version strings, dependency lists, package or class lists, app server installation directories, etc.
Don't use more than 1 maven module. My tests to test my war belong in the test folder of the same maven module that produces the war.
Users that checkout my code need to be able so simply run the tests:
Tests needs to run from IntelliJ after simply opening the pom.xml with IntelliJ.
Use WildFly embedded container, so nothing needs to be installed first, no process needs to be run first and definitely no JBOSS_HOME environment variable needs to be set first.
I am only interested in black box testing, so all my tests can run as client.
In theory, this is all possible with Arquillian's Maven resolver, embedded containers, #RunAsClient, maven failsafe plugin, some arquillian.xml magic and a lot of maven magic. But in practice, I cannot get that stuff to work together, nor do I find any documentation that covers this scenario decently, so I am hoping someone can clearly show how they can work together.

Definitely sounds like a case for ShrinkWrap Resolver Maven Importer (not to be confused with the Maven Resolver). Here are some tests showing its usage.
I have a standalone sample for just a case of Gradle Importer ( I know you're using maven ), but the test construction is similiar here.
I don't have currenly a whole example publically available with both #RunAsClient and Maven Importer but I have a project using them together with Graphene and this combination do work :). Generally the test should look like:
#RunWith(Arquillian.class)
public class SomeControllerIT {
#Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(MavenImporter.class).loadPomFromFile("pom.xml").importBuildOutput()
.as(WebArchive.class);
}
#Test
#RunAsClient
public void shouldDoSth() throws Exception {
...
}
}
Why to use Maven Importer instead of the war deployment? War is created after tests execution, this means that if the war exists during test execution, then it comes from previous build and is outdated.

Related

Skinny War file with Maven in Eclipse

I have a Maven project 'Project A' which contains dependencies. I have a requirement to abstract the dependencies from this project into another project called 'Shared Lib' so that I can make what is called a "Skinny War" file from Project A. Both these files will then be uploaded to a Weblogic server.
However, I am having a lot of difficulties being able to get Project A to pick up the dependencies in Shared Lib.
Some guidance on how I should approach this problem would be much appreciated.
Thanks!
I would split the maven project into two modules. If we call one module SharedLib and the second one Skinny War then you will have something like:
<modules>
<module>sharedLib</module>
<module>skinnyWar</module>
</modules>
In the shared lib module pom.xml you will fill all the dependencies required for the project. In the skinnyWar module your first dependency in the list will be for the sharedLib module. You might need to setup the assembly plugin for the sharedLib module to create a jar in the package phase and you are good to go ;)
Some food of though - do you really want to do this? An important part about using maven is to take care of dependencies for you and package a easy to deploy jar. If you create two different jars it would cause all other kinds of troubles like - were both deployed. Are we using an older version of the dependencies etc.

How to package only the necessary libs in Google App Engine Project(Java)?

Let me explain first what I mean by necessary libs. I'm creating my first project using the Google App Engine for Java with the official Google Maven Plugin, the main problem that have Maven as a packaging solution (or maybe the Java development as a whole) is that if the dependency tree grows too much, the release process may be harder.
Let me illustrate it with an example. Let's start with the Jackson JSON library (it's a good starting point since it has no parent dependencies), now someone makes a JSON-RPC library and uses Jackson for the JSON serialization/deserialization. Imagine that this library not just provides a JSON-RPC client implementation, but also a server, that means that the POM of this lib will add some Java EE related libraries such us Jetty as dependencies.
Probably the guidelines say that the application should be either divided into modules or mark the server related deps as optional, but you know that many people don't follow the standards.
Now someone need a JSON-RPC client for his/her project, call it Project X, and uses the lib mentioned above, at compile time there will be no problems, Maven will successfully download the required libs and the application will compile fine, but the problem comes when that person wants to release the application. Which dependencies should be distributed along with the package (in a lib folder for example)?
Actually that's something that happened to me, I wasn't too much familiar with Maven so I used the Eclipse Runnable Jar Exporter, that produced jar file with all the maven libs copied to a lb subfolder, so the workaround that I did then was to just delete the libs that looked unnecessary and then tested if the application was still working. If there are classes that are not executed, as far as I know they are not loaded by the ClassLoader so they could be omitted and are unnecessary
I can't use the same trick now since the scenario is much more complex, we are talking of a Java Web Application, not a desktop application like the other one, and the library that I want to include is a Liquid Template Engine, which uses the ANTLR framework to generate the parsers plus Jackson for the JSON handler and Jsoup for HTML parsing.
Which libs should be packaged inside the WEB-INF/lib folder? I'm sure that I will need Jackson for JSON parsing but I'm not so sure about Jsoup, and what about ANTLR, it is necessary or is used just at compile time?
Update: I think I need to re-formulate my question, actually what I want is to determine which dependencies are really necessary for the application, and package those into the app WEB-INF/lib folder
Solution: It seems that the POM file that is packaged in the WAR file of the web app is used once the app is in the Google App Engine production environment to retrieve the necessary dependencies, and probably the appengine:update goal only packages those dependencies that can't be retrieved from the maven central repo, so there is no need to worry about that.
Thanks to David to point this.
You should check Maven's dependency scopes. Here's an extract from the documentation :
There are 6 scopes available:
compile This is the default scope, used if none is specified. Compile
dependencies are available in all classpaths of a project.
Furthermore, those dependencies are propagated to dependent projects.
provided This is much like compile, but indicates you expect the JDK
or a container to provide the dependency at runtime. For example, when
building a web application for the Java Enterprise Edition, you would
set the dependency on the Servlet API and related Java EE APIs to
scope provided because the web container provides those classes. This
scope is only available on the compilation and test classpath, and is
not transitive.
runtime This scope indicates that the dependency is
not required for compilation, but is for execution. It is in the
runtime and test classpaths, but not the compile classpath.
test This
scope indicates that the dependency is not required for normal use of
the application, and is only available for the test compilation and
execution phases.
system This scope is similar to provided except that
you have to provide the JAR which contains it explicitly. The artifact
is always available and is not looked up in a repository.
import (only
available in Maven 2.0.9 or later) This scope is only used on a
dependency of type pom in the section. It
indicates that the specified POM should be replaced with the
dependencies in that POM's section. Since they
are replaced, dependencies with a scope of import do not actually
participate in limiting the transitivity of a dependency.
So in a Maven project, the developer indicates which dependencies should be bundled in the application and which should not.
Basically there are two cases here :
If you're building a web application (WAR or EAR format) and want to deploy it, or if you're building an actual runnable jar, then you will need to bundle it with all the dependencies with scope compile and runtime.
If you're building a library, then you do not package any dependency with your library. Instead you include the pom.xml so that others know what dependency your library requires. For Maven to know how to find the associated POM for a given jar, the best and most common solution is to deploy the library to a Maven repository. Repos have a directory structure that helps Maven find the right version of a library, and find the POM that indicates the required dependencies.
Depending on wether your library is open source or not, you will be able to be hosted for free by some repositories such as Sonatype (complete list here). But you can also setup your own repository either by installing a dedicated software such as Nexus or by configuring a Github project as the repo, as is explained on this blog.
You can exclude any transitive dependency.
For your case, to remove jetty from this json-rpc-library, you need:
<dependency>
<groupId>com.somecomp</groupId>
<artifactId>jsonrpclib</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</exclusion>
</exclusions>
</dependency>
See docs: http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

Maven/Eclipse - Quick iteration acceptance Testing a project packaged as a WAR file

Eclipse makes working with multi module maven projects easy because you don't have to re-build and re-install a module before dependent modules will see changes to it. So you just change the code and eclipse updates the dependencies magically in the background.
I want to achieve this behaviour for acceptance testing as well.
I have
storage-service
storage-service-war
storage-service-acceptance-tests
If I use embedded jetty or tomcat to test inside the storage-service-war project then obviously code changes are immediately viewable in the tests, but I cannot see any way to achieve the same quick iteration of testing when testing from storage-service-acceptance-tests.
Every way I look at it it seems that I have to build storage-service-war and then use the artefact generated from that, but it seems like overkill when you only want to change one line.
Does anyone have a good method for doing this?
Cheers
Piers
So answering my own question :D The solution I came up with will not work on CI it will likely only work when doing a local build as it makes use of the relative paths of the projects. At the bottom I outline a more robust but more complex approach that should satisfy eclipse and CI.
I was looking at setting attachClasses to true for the war plugin configuration of the war project.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
You can then reference the jar in the dependent project as follows
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>storage-service-war</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
Then I was thinking I could run my tests from within the acceptance test module using embedded jetty or tomcat and pointing them to the web.xml defined in the war project using a relative path.
This works fine with maven via the commandline but fails in eclipse :(
The problem with this is that the jar produced by attach classes is not picked up by the eclipse m2e integration see -https://bugs.eclipse.org/bugs/show_bug.cgi?id=365419 unfortunately it wont be fixed.
So My solution for the moment is to manually add the storage-service-war project to my acceptance test project build path in eclipse. Its not great but it works
The above solution is a bit hacky but the alternative outlined is a bit more involved.
By splitting the project into the following I think it would be possible to have correct eclipse integration and projects that work on CI
storage-service
storage-service-core
storage-service-war
storage-service-acceptance-tests
storage-service-config
The core project contains the logic and source of the webapp and is of type jar, the config contains the web.xml and any other config files and is also of type jar. Then the acceptance-tests and war project are both of type war and serve merely to package the core project into a war and extract the config to the webapp/WEB-INF dir so that they may share a common setup.

How does Maven handle WAR dependencies at compile time?

I'm using Maven 3 to handle a (large) project. This project defines a set of REST services, using Scala, Akka and the Spray framework. Each service is defined as an independent project, producing a WAR thanks to the "mvn package" command.
I have to "assemble" these different services into a "system", that is, a subset of these services to be deployed for a given purpose, in a single WAR. Maven WAR overlay works good as a first impression: simply create a new project, and add the services to be included as dependencies.
<dependencies>
<dependency>
<groupId>net.modelbased.sensapp.service</groupId>
<artifactId>net.modelbased.sensapp.service.metamodel.repository</artifactId>
<version>0.0.1</version>
<type>war</type>
</dependency>
</dependencies>
It works well, and the classes contained in the independent services are included in the final WAR.
jar tf target/net.modelbased.sensapp.system.envision-0.0.1-SNAPSHOT.war
[...]
WEB-INF/classes/net/modelbased/sensapp/service/metamodel/repository/ModelLister.class
[...]
But ... The Spray framework requires the implementation of a bootstrap, that is, a class that load the implemented services. This file has to be compiled, as it is a plain scala class. But it looks like maven did not includes the WAR dependencies in the compilation classpath.
I saw the WARpath plugin (http://static.appfuse.org/maven-warpath-plugin/) ... But It does not look more or less outdated. Is there a "standard" way of doing what I'd like to do (i.e., include a WAr in the compilation classpath).
Ps. One of the requirement of the project is that each service MUST be deployable as an independent artifact. A solution could be to implement the core of the service as a JAR project, and also provide a WAR project that includes a refarence to the JAR and the associated config file. But it will multiply by 2 the number of project defined, which is not optimal in a way ...
The solution you propose looks good.
You can build a jar from your classes, and then build a war using this jar as a dependency.
You probably can also do this in one single project, I can see no need for two different projects.
You can use the configuration of the maven-war-plugin which offers you a way to create a separate jar file out of the files from src/main/java.
You have to add the configuration items:
<configuration>
<archiveClasses>true</archiveClasses>
<attachClasses>true</attachClasses>
</configuration>
This will create a separate jar file with the classifier classes which can be used as a usual dependency.

I want to use maven for a GAE project, how do i do?

i'm new in the world of GAE. I 'm using eclipse and GAE's SDK, i can deploy to the cloud with the GAE icon and everything is fine. The problem arises when I have to import the infinite number of dependency, then I want to use maven for that. I discovered that there is a special GAE maven plugin called:
maven-gae-plugin
Can I use regular maven only to fetch dependencys or I have to use the GAE special plugin to do this?
Thanks
You'll need to define a pom.xml for the project which declares the dependencies.
When you build with maven the dependencies will be downloaded from the remote repositories and stored in you local repository ${userhome}/.m2/repository.
The maven build will also bindle the dependencies in your war file.
The easiest way to get started is by creating a project structure using an archetype.
There are 2 archetypes that I've tried for gae so far:
gae-archetype-gwt, which is built adjacent to the gae-maven-plugin, see this article.
gae-eclipse-maven-archetype, see this article and also note the link at the top of the article for the helios update.
As the name suggests gae-eclipse-maven-archetype has better support for eclipse, I have been finding that the configurations for maven and eclipse have been clashing with each other, which gae-eclipse-maven-archetype goes a long way to alleviate.
If your current project is not using the maven directory structure, then you are going to have an uphill battle. Maven projects are easier to configure if you try to fit in with the defaults which are largely sensible options, rather than going against the grain and having to override all of the default configuration options.
There is no reason you can't use maven for it's dependency management only. The GAE dependencies are all in maven central.
There is a write up about how to set it up here
I personally use the eclipse plugin in dev and the maven plugin when running under continuous integration.
The main gotcha is to follow the advice about ensuring that the maven dependencies are the last thing in your build path under the GAE plugin dependencies.
Add the following to your pom.xml, modifying it to your needs:
<project>
...
<properties>
...
<com.google.appengine-version>1.6.4</com.google.appengine-version>
...
</properties>
<dependencies>
...
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${com.google.appengine-version}</version>
</dependency>
...
</dependencies>
...
</project>
In case you need any additional GAE-related artifacts besides appengine-api-1.0-sdk, have a look for those artifacts in The Central Repository under com.google.appengine, then add them to your pom.xml's dependencies list.