Automating Integration Tests with WebSphere Liberty and Maven

I spent some hours to figure out how to deploy my webapp to the Liberty from my Maven project.

I looked into the feature restConnector-1.0 . restConnector provides a REST based JMX MBeans interface to WebSphere Liberty.  You add  <feature>restConnector-1.0</feature> to your server, and make sure you have a user set in the admin role.

<administrator-role>
 <user>admin</user>
</administrator-role>

You need to add write access for the administrator-role user.  You’ll need to specify a relative path (use the Liberty Directory Locations) or use the absolute path (it’s a bit more complicated).

 <remoteFileAccess>
   <writeDir>${server.output.dir}/dropins</writeDir>
 </remoteFileAccess>

You can login and see the various APIs [ https://localhost:9443/IBMJMXConnectorREST/api ] or check the documentation [API1][API2][MBean]  .  You’ll want to check any upload with https://localhost:9443/IBMJMXConnectorREST/file/status

I used it with maven-antrun-plugin to execute against curl.

<plugin>
 <artifactId>maven-antrun-plugin</artifactId>
 <version>1.8</version>
 <executions>
 <execution>
 <id>upload-pre-integration</id>
 <phase>pre-integration-test</phase>
 <goals>
 <goal>run</goal>
 </goals>
 <configuration>
 <target name="post-war-to-server" unless="maven.test.skip">
 <!-- Remove War File from the Server -->
 <exec executable="curl">
 <arg
 line="-u 'admin:dmin' -H 'Content-Type: application/war' -X DELETE 'https://localhost:9443/IBMJMXConnectorREST/file/%24%7Bserver.output.dir%7D%2Fdropins%2Ftransformation.war?recursiveDelete=true' 
 --insecure -v" />
 </exec>
 <!-- Should check that this is a 204 -->
 
 <!-- Post the War file to the Server -->
 <!-- Expand the War file on the Server -->
 <exec executable="curl">
 <arg
 line="-u 'admin:admin' -H 'Content-Type: application/war' -X POST 'https://localhost:9443/IBMJMXConnectorREST/file/%24%7Bserver.output.dir%7D%2Fdropins%2Ftransformation.war?expandOnCompletion=true' 
 --data-binary '@target/example.war' --insecure -v" />
 </exec>
 
 </target>

 </configuration>
 </execution>
 </executions>
 </plugin>

Execute maven with mvn clean integration-test package in order to trigger the deployment during the integration-test.

Hamcrest Matchers Issue

I’ve been using Rest-Assured as a simple Integration Test tool for the last few months, and suddenly I started seeing this issue.

java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package
at java.lang.ClassLoader.checkCerts(ClassLoader.java:895)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:665)
at java.lang.ClassLoader.defineClass(ClassLoader.java:758)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.test.restassured.TestCode.testaCreateTenant(TestCode.java:128)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

I wiped my .m2 repository of org.hamcrest.Matchers jar files, and rebuilt the maven repository (mvn clean package install -DskipTests).   The problem remained.

I ran across a simple for my code (on the rest-assured site thanks to johanhaleby)

I changed the code to

import static org.hamcrest.CoreMatchers.equalsTo;

Now the code passes the tests without a problem

Localized Maven Repositories – A Hot Tip

I’ve been building a Maven Project that uses some jar files which are not in Maven Central (or any repository). I ran across this article – Local Maven Dependencies. I found it very helpful.

Simply, do the following:

create a directory (d:/folder/repo)

Run a maven deploy to url (it’ll create the repository details based on the flags)

mvn deploy:deploy-file -Durl=file://d:/folder/repo/ -Dfile=Common.jar -DgroupId=xyz -DartifactId=Common -Dpackaging=jar -Dversion=1.0

and add to your Maven Project’s POM
<repository>
<id>Local Repository</id>
<name>project</name>
<url>file:${project.basedir}/../mylibrary.project/src/repo</url>
</repository>

Then reference your jar file with a new dependency.

The code should almost write itself from there 🙂

Maven Tips

Here are some tips for Maven Java Projects in Eclipse.

#1 If you pom.xml is missing maven-compiler-plugin, Eclipse (when you do Maven > Update Project), defaults the compiler level for the project to 1.5.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

Now, it gets even more tricky… if your project has defined features that are from Java 1.6, 1.7 or 1.8

#2 if you your web.xml defines a version not compatible with a project facet you depend on, you get a lot of problems/errors

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"/>

Convert the web.xml to 3.1, and compatibility should now be fixed

<web-app id="WebApp_ID" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

I found this stackoverflow entry helpful and this one.

#3 Update > Maven Project overwrites manual changes to #1/#2.

I found this stackoverflow entry helpful.

#4 Make sure you don’t have two web.xml files… the convert dynamic web project to maven project does some funky stuff.