Category Archives: jboss / wildfly

Shrinkwrap add maven dependency for Arquillian and WildFly

When building deployable for Arquillian with Shrinkwrap, it is very useful to be able to add your maven dependencies. Fortunately this is possible using

PomEquippedResolveStage pom = Maven.resolver().loadPomFromFile(pathPrefix + "pom.xml");
File[] commonsLang = pom.resolve("org.apache.commons:commons-lang3").withTransitivity().asFile();
 
WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war");
war.addAsLibraries(commonsLang);

This requires the following dependency

<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>org.jboss.arquillian</groupId>
        <artifactId>arquillian-bom</artifactId>
        <version>1.1.2.Final</version>
        <scope>import</scope>
        <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>
 
<dependencies>
    <dependency>
        <groupId>org.jboss.shrinkwrap.resolver</groupId>
        <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Unfortunately, this does not work when you use the WildFly bom. You then get an error like

java.lang.RuntimeException: Could not invoke deployment method: public static org.jboss.shrinkwrap.api.Archive be.fluxtock.back.impl.AbstractIT.createDeployment() throws java.lang.Exception
	at org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator.invoke(AnnotationDeploymentScenarioGenerator.java:177)
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Caused by: java.lang.RuntimeException: Could not create object from user view
	at org.jboss.shrinkwrap.resolver.api.ResolverSystemFactory.createFromUserView(ResolverSystemFactory.java:95)
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Caused by: java.lang.RuntimeException: Could not create new service instance
	at org.jboss.shrinkwrap.resolver.spi.loader.SpiServiceLoader.createInstance(SpiServiceLoader.java:240)
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Caused by: java.lang.NoClassDefFoundError: org/apache/maven/repository/internal/MavenRepositorySystemSession
	at org.jboss.shrinkwrap.resolver.impl.maven.bootstrap.MavenRepositorySystem.getSession(MavenRepositorySystem.java:84)
 
Caused by: java.lang.ClassNotFoundException: org.apache.maven.repository.internal.MavenRepositorySystemSession
	at java.net.URLClassLoader$1.run(URLClassLoader.java:359)

If you use the enforer plugin with the requireUpperBoundDeps test, you will see exceptions pointing in the right direction.

Failed while enforcing RequireUpperBoundDeps. The error(s) are [
Require upper bound dependencies error for org.apache.maven:maven-model:3.0.5 paths to dependency are:
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-model:3.0.5
and
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-aether-provider:3.1.1
      +-org.apache.maven:maven-model:3.1.1
and
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-model-builder:3.0.5
      +-org.apache.maven:maven-model:3.0.5
, 
Require upper bound dependencies error for org.apache.maven:maven-model-builder:3.0.5 paths to dependency are:
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-model-builder:3.0.5
and
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-aether-provider:3.1.1
      +-org.apache.maven:maven-model-builder:3.1.1
, 
Require upper bound dependencies error for org.apache.maven:maven-repository-metadata:3.0.5 paths to dependency are:
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-repository-metadata:3.0.5
and
+-be.fluxtock:fluxtock-back-impl:1.0-SNAPSHOT
  +-org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.0.0
    +-org.apache.maven:maven-aether-provider:3.1.1
      +-org.apache.maven:maven-repository-metadata:3.1.1
]

It seems some settings in the WildFly and the Arquillian boms interfere, causing an invalid set of dependencies being included by maven.

To solve this, include the following section in your dependencyManagement section:

<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-aether-provider</artifactId>
    <version>3.0.5</version>
</dependency>
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-model</artifactId>
    <version>3.0.5</version>
</dependency>
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-model-builder</artifactId>
    <version>3.0.5</version>
</dependency>
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-repository-metadata</artifactId>
    <version>3.0.5</version>
</dependency>

Using cargo to use the latest WildFly container

I am using java8 in this project I am working on. Unfortunately finding a servlet engine which fully works on Java8 is non-trivial. I was originally using Jetty8 (using the maven plug-in), but this throws exceptions when starting. It does not seem to impact the web application, but I would rather be safe than sorry. When migrating to Jetty9 (and loading using cargo as the maven plug-in does not directly support Jetty9) the container does not start at all.

So I tried WildFly. The current WildFly container uses one of the earlier WildFly version (not the current beta1), which is not good enough. Even beta1 needs a patch for java8. So I built a patched zip and tell cargo to use that zip file as application server.

<plugin>
    <groupId>org.codehaus.cargo</groupId>
    <artifactId>cargo-maven2-plugin</artifactId>
    <version>1.4.5</version>
    <configuration>
        <container>
            <containerId>wildfly8x</containerId>
            <zipUrlInstaller>
                <!--<url>http://download.jboss.org/wildfly/8.0.0.Beta1/wildfly-8.0.0.Beta1.tar.gz</url>-->
                <!--<url>file:///home/joachim/java/wildfly-8.0.0.Beta1/wildfly-8.0.0-beta1-jandex-1.1.0.zip</url>-->
                <url>http://www.progs.be/wildfly-8.0.0-beta1-jandex-1.1.0.zip</url>
                <downloadDir>${project.basedir}/.cargo/downloads</downloadDir>
                <extractDir>${project.basedir}/.cargo/extracts</extractDir>
            </zipUrlInstaller>
            <log>${basedir}/target/cargo.log</log>
            <output>${basedir}/target/wildfly.log</output>
            <dependencies>
                <dependency>
                    <groupId>postgresql</groupId>
                    <artifactId>postgresql</artifactId>
                </dependency>
            </dependencies>
        </container>
 
        <configuration>
            <!--
            <type>existing</type>
            <home>/home/joachim/java/wildfly-8.0.0.Beta1/</home>
            -->
            <properties>
                <cargo.servlet.port>8080</cargo.servlet.port>
                <cargo.logging>high</cargo.logging>
                <cargo.jvmargs>-Denv=test -Dtapestry.execution-mode=development</cargo.jvmargs>
            </properties>
        </configuration>
 
        <deployables>
            <deployable>
                <pingURL>http://localhost:8080/application/index</pingURL>
                <pingTimeout>120000</pingTimeout> <!-- 2 min -->
                <properties>
                    <context>fluxtock</context>
                </properties>
            </deployable>
        </deployables>
    </configuration>
    <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>

JBoss maven repository, Paul Gier and John Casey

JBossWorld Boston notes, JBoss maven repository, Paul Gier and John Casey

Good news, the jboss.org maven repository refactoring is complete, bad is that the JBoss products have no maven repository, but working on it.

Maven repository is a file server with a standard layout, there are two types, release and snapshot repository.

Why use a repository
– store dependencies outside of project
– central location for build artifacts, find and re-use, single storage to manage
– manage dependencies

Configuring maven repositories
– super POM, adds central repository automatically to all builds
– add custom repositories in your project POM (you could override central by redefining the repository with id “central”)
– maven settings
— global: M2_HOME/conf/settings.xml
— user: ~/.m2/settings.xml
— profiles

Maven also uses repositories defined in the dependency poms.

Taking control :
– check effective pom : mvn help:effective-pom
– which does not show dependency repositories
– use user settings.xml
– use mirror settings for more control

Mirror settings in settings.xml

<mirror>
  <id>superfast</id>
  <mirrorOf>central</mirrorOf>
  <name>Fast mirror of central</name>
  <url>http://superfast.org/maven2</url>
</mirror>

Or replace all…

<mirror>
  <id>superfast</id>
  <mirrorOf>*</mirrorOf>
  <name>Fast mirror of central</name>
  <url>http://superfast.org/maven2</url>
</mirror>

Maven repository managers
– web server providing maven repositories
– real, proxy, virtual repositories
– pom validation
– products: archiva, artifactory, nexus

Rebuilding jboss.org repository
– old two servers, one for releases, one for snapshots
– problems
— deployment over SVN
— manual uploading thirdparty jars
— manual search indexing
— bad artifacts
— no staging

Goals for new repository
– sort out good from bad
– split in several parts, jboss.org, copied, bad artifacts
– improved deployment/releases
– automated validation/cleanup

Improving the repository
– single public group for all builds
– allow standard http for public group
– use repositories in POMs during development, stricter settings during QA and release
– don’t require authentication for downloads

Dependency management

Scoping
– compile
– provided: not part of final build
– runtime: provided at runtime, but not during compile time
– test: only for testing

Dependency resolution
– provided dependencies in dependent projects are not included as dependency in main project!

Shared dependencies
– parent POMs are ideal for consolidating dependencies -> dependencyManagement
– dependencyManagement : parent defines GAV, child only defines groupId and artifactId, rest is copied

Publishing shared dependencies
– Bill-of-materials POM (BOMs)
– shared dependencyManagement section in POM
– use dependencymanagement and declare pom using scope “import”
– publish coordinated dependency sets
– new platform version -> change BOM version

When things go wrong: upstream polluters
– add exclusions in your dependency for unwanted transitive dependencies
– version conflicts : maven prefers the nearest declaration
– “mvn dependency:analyze” tries to find what is declared and not used or used and not declared

Plans for maven product repository
– publish JBoss products in maven repository format
— support artifacts for product builds
— provide EXACT artifacts used in product distributions
— harness product build to populate repository
– minimize pain of switching from community version
– code ownership

Audit trail
– certification of build process and resulting product
– preserve unbroken chain of custody from source code to running software

Certified binaries
– preserve information about every step from source to binary
– secure all steps and machinery used
– build outputs signed
– restricted network access

Coordinate design
– preserve groupId and artifactId from community, changing would require dependency exclusions
– coordinate has to be different
– visual cue, add “-redhat” in version”

How : use BOM, will require maven 3 to work properly