We're very pleased that you want to get in touch with us. Please fill in the form below:



or   Close this form  
Some content

Peter Pilgrim :: Java Champion :: Digital Developer Architect

I design Java EE and Scala software solutions for the blue-chip clients and private sector

Hey all! Thanks for visiting. I provide fringe benefits to interested readers: checkout consultancy, training or mentorship Please make enquiries by email or call +44 (0)7397 067 658.

Due to the Off-Payroll Working plan for the UK government, I am enforcing stricter measures on contracts. All potential public sector GOV.UK contracts engagements must be approved by QDOS and/or SJD Accounting. Please enquire for further information.

Upgrade DeltaSpike, Gradle and CDI Container with Test Module

16 February 2016 Comments off

5 minutes

1072

I am puzzled by the Java EE 7 Developer Handbook that I wrote about two years ago. Well I researched it in 2013 and published it. I was looking at the code for Chapter 2, which has an old example of Apache DeltaSpike, JBoss Weld and Gradle. I want to upgrade it to work with the latest stable releases circa 2016.

So where am I? I am stuck for once, because I received this exception whilst executing gradle build --stacktracer.

 

Feb 16, 2016 2:50:34 PM org.apache.deltaspike.testcontrol.api.junit.CdiTestSuiteRunner$LogRunListener testFailure
INFO: [failed] je7hb.standalone.CreditProcessorTest#null message: WELD-ENV-002000: Weld SE container STATIC_INSTANCE is already running!

java.lang.IllegalStateException: WELD-ENV-002000: Weld SE container STATIC_INSTANCE is already running!

	at org.jboss.weld.environment.se.WeldContainer.initialize(WeldContainer.java:138)
	at org.jboss.weld.environment.se.Weld.initialize(Weld.java:562)
	at org.apache.deltaspike.cdise.weld.WeldContainerControl.boot(WeldContainerControl.java:68)
	at org.apache.deltaspike.cdise.weld.WeldContainerControl.boot(WeldContainerControl.java:76)
	at org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner$ContainerAwareTestContext.applyBeforeClassConfig(CdiTestRunner.java:463)
	at org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner$BeforeClassStatement.evaluate(CdiTestRunner.java:366)
	at org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner$AfterClassStatement.evaluate(CdiTestRunner.java:393)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner.run(CdiTestRunner.java:142)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	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.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
	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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

 

They say always run on the command line, and so I did. I also verified this also issue inside IDEA 15.0.3.

The unit test code is actually the simplest in the book:

 

package je7hb.standalone;

import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.inject.Inject;

import static org.junit.Assert.*;

@RunWith(CdiTestRunner.class)
public class CreditProcessorTest {
    private @Inject @Economy CreditProcessor agent;

    @Test
    public void shouldInjectStreetCredit() {
        assertNotNull(agent);
        agent.check("12354678");
        System.out.printf("agent=%s\n", agent );
    }
}

 

I threw out my older AbstractCdiContainerTest implementation, because Delta Spike has replaced it with a new JUnit 4 Runner implementation. I upgraded to JBoss Weld 2.3.2 against Delta Spike 1.5.2.

At the moment, I am refactoring the Gradle build into a proper MULTI-MODULE build for all the students. There is something strange going on? The codebase is help on GitHub.

Extract of the build file is:

archivesBaseName = 'ch02-cdi-standalone'

dependencies {    
    compile     "javax:javaee-api:${javaeeVersion}"

    compile     "org.slf4j:slf4j-simple:${slf4jVersion}"
    compile     "org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api:${deltaspikeVersion}"
    compile     "org.apache.deltaspike.cdictrl:deltaspike-cdictrl-weld:${deltaspikeVersion}"

    compile     "org.jboss.weld.se:weld-se-core:${weldSEVersion}"
    compile     "org.apache.deltaspike.modules:deltaspike-test-control-module-api:${deltaspikeVersion}"

    testCompile     "org.apache.deltaspike.modules:deltaspike-test-control-module-impl:${deltaspikeVersion}"
}

test {
    testLogging.showStandardStreams = true

    // set heap size for the test JVM(s)
    minHeapSize = "128m"
    maxHeapSize = "768m"

    // Ensure that the working directory for the test is the same as the project directory in order to run the Spike Delta container tests
    // *PP* 11/02/2016
    workingDir = project.projectDir
}

The dependencies are now set in the root Gradle project. Here is the extract:

allprojects {
    apply plugin: 'java'
    apply plugin: 'maven'
    apply plugin: 'eclipse'
    apply plugin: 'idea'

    // Define equivalent Maven GAV coordinates.
    group = 'uk.co.xenonique.javaee7handbook'
    version = '1.0-SNAPSHOT'

    ext {
        arquillianVersion                   = "1.1.11.Final"
        arquillianJunitVersion              = "1.1.11.Final"
        arquillianPersistenceVersion        = "1.0.0.Alpha6"
        arquillianGlassfishEmbeddedVersion  = "1.0.0.Final-SNAPSHOT"
        arquillianGlassfishManagedVersion   = "1.0.0.CR4"
        arquillianGlassfishRemoteVersion    = "1.0.0.CR4"
        deltaspikeVersion                   = "1.5.2"
        glassfishVersion                    = "4.1"
        hamcrestVersion                     = "1.3"
        javaeeVersion                       = "7.0"
        jodaTimeVersion                     = "2.2"
        junitVersion                        = "4.12"
        ozarkVersion                        = "1.0.0-m01"
        mockitoVersion                      = "1.10.19"
        shrinkWrapVersion                   = "1.0.1"

        //'org.slf4j:slf4j-api:1.7.14'
        slf4jVersion                        = "1.7.14"
        weldEEEmbeddedVersion               = "1.0.0.CR3" 
        weldSEVersion                       = "2.3.2.Final"
    }

    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url 'https://maven.java.net/content/groups/promoted'
        }
        maven {
            url 'http://repository.jboss.org/nexus/content/groups/public'
        }        
    }

    // Java version compatibility to use when compiling Java source 
    sourceCompatibility = '1.8'
    // Java version to generate classes
    targetCompatibility = '1.8'
...
}

This failure is a complete mystery, why code that worked in 2013 and no longer executes in 2016. However, I am sure that it will be revealed.

UPDATE

I was chatting on the DeltaSpike IRC and @os890 informed me about a trick that works around the issue.

You can also find a description in the Java EE 7 Tutorial about the @Priority annotation and Alternatives.


“The alternatives that you specify in the beans.xml file apply only to classes in the same archive. Use the @Priority annotation to specify alternatives globally for an application that consists of multiple modules …”

And also


“The alternative with higher priority value is selected if several alternative beans that implement the same interface are annotated with @Priority. You do not need to specify the alternative in the beans.xml file when you use the @Priority annotation.”

To work around the issue, I use the @Priority and Gradle builds everything fine.

@Alternative
@Priority(Interceptor.Priority.APPLICATION+100)
public class XenoniqueFoodProcessor implements FoodProcessor {
    @Override
    public String sayBrand() {
        return "Xenonique";
    }
}

I added the above annotation to the Weld specific project, then I executed the test successfully.

I do not believe DeltaSpike is broken and so the question remains, is the Java EE 7 reference implementation of CDI 1.1 specification correct or incorrect with respect with Alternative configured in a beans.xml?

I also created source code to exercise Open Web Beans container as a parallel sub-project, see standalone-owb in Github. Indeed removed the @Priority annotation from the XenoniqueFoodProcessor bean and Gradle builds successfully! Ah ha this is an issue with JBoss Weld 1.5.3! It is not respecting @Alternatives as CDI 1.0 specification according to my examples.

 

+PP+

 

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Contents of this blog entry are under copyright © 2017 by Peter Pilgrim and associates. For enquiries after republishing, please contact us for permission. All requests for syndicated content will be ignored /dev/null, consider yourself warned!

I help to design, create and build JVM components and services that are behind popular e-commerce websites.

My Blurb

Please get in touch , directly, to establish hire availability, contract & consulting opportunities.

Speaking at Your Conference

Contact by invitation

What Peter Does

Contact