0

While running a unit test with Arquillian using Glassfish embedded plugin, I get the following CDI error :

2015-09-18 06:25:24,376 DEBUG | main | org.jboss.weld.Reflection                               | WELD-000620: interface com.SupportedLocales is not declared @Target(METHOD, FIELD, PARAMETER, TYPE). Weld will use this annotation, however this may make the application unportable.  
sept. 18, 2015 6:25:24 AM com.sun.enterprise.v3.server.ApplicationLifecycle deploy  
GRAVE: Exception during lifecycle processing  
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Set<Locale> with qualifiers @SupportedLocales  
  at injection point [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject protected com.MyClass(@SupportedLocales Set<Locale>)  
  at com.MyClass.<init>(MyClass.java:0)  

Set(Locale) with qualifier @SupportedLocales is defined in a module deployed in the tested WebArchive. The Archive content is :

/WEB-INF/
/WEB-INF/lib/
/WEB-INF/lib/commons-lang3-3.3.2.jar
/WEB-INF/lib/commons-configuration-1.10.jar
/WEB-INF/lib/reflections-0.9.9-RC2.jar
/WEB-INF/lib/jcl-over-slf4j-1.7.10.jar
/WEB-INF/lib/slf4j-api-1.7.10.jar
/WEB-INF/lib/deltaspike-core-api-1.5.0.jar
/WEB-INF/lib/commons-util-1.0.0-SNAPSHOT.jar
/WEB-INF/lib/commons-io-2.4.jar
/WEB-INF/lib/guava-16.0.1.jar
/WEB-INF/lib/log4j-over-slf4j-1.7.10.jar
/WEB-INF/lib/javassist-3.18.2-GA.jar
/WEB-INF/lib/logback-classic-1.1.2.jar
/WEB-INF/lib/logback-core-1.1.2.jar
/WEB-INF/lib/jul-to-slf4j-1.7.10.jar
/WEB-INF/lib/commons-cdi-1.0.0-SNAPSHOT.jar
/WEB-INF/lib/xml-apis-1.0.b2.jar
/WEB-INF/lib/deltaspike-core-impl-1.5.0.jar
/WEB-INF/lib/dom4j-1.6.1.jar
/WEB-INF/lib/commons-codec-1.9.jar
/WEB-INF/lib/commons-lang-2.6.jar
/WEB-INF/lib/annotations-2.0.1.jar
/WEB-INF/lib/libphonenumber-7.0.3.jar
/WEB-INF/classes/
/WEB-INF/classes/com/
/WEB-INF/classes/com/timm/
/WEB-INF/classes/com/timm/common/
/WEB-INF/classes/com/timm/common/cdi/
/WEB-INF/classes/com/timm/common/cdi/web/
/WEB-INF/classes/com/timm/common/cdi/web/i18n/
/WEB-INF/classes/com/timm/common/cdi/web/i18n/ShiroCurrentLocale.class
/WEB-INF/beans.xml

This object is provided by a producer method located in "common-cdi" module. The same module provide CDI extension feature like ThreadScoped. This producer is not discovered by Weld during test startup and Weld does not discover beans from "commons-cdi" module. How is it possible? Can we provide CDI extension features and CDI bean in the same module ?

@SupportedLocales is declares in "commons-cdi" with:

@Qualifier  
@Target({  
        ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD  
})  
@Retention(RetentionPolicy.RUNTIME)  
public @interface SupportedLocales {  
}

The producer is declared in "commons-cdi" with:

@Dependent  
public class I18NProducer {  
    @Produces  
    @ApplicationScoped  
    @Default  
    @SupportedLocales  
    public Set<Locale> getSupportedLocales() {  
        Set<Locale> supportedLocales;  
        supportedLocales = new HashSet<Locale>();  
        supportedLocales.add(Locale.US);  
        return supportedLocales;  
    }  
}

JUnit test case definition:

@RunWith(Arquillian.class)
public class LocaleInjectionTest {

    @Deployment
    public static Archive<?> deploy() {
        final String moduleName = LocaleInjectionTest.class.getSimpleName();

        PomEquippedResolveStage resolver = Maven.resolver().loadPomFromFile("pom.xml");

        File[] libs = resolver.resolve("com.myname:commons-cdi").withTransitivity().asFile();

        WebArchive testWar = ShrinkWrap
                .create(WebArchive.class, moduleName + ".war")
                .addClass(MyCurrentLocale.class)
                .addAsLibraries(libs)
                .addAsWebInfResource(ArchiveUtils.getResourceBeanXMLWithAlternativeAndDiscoveryModeAnnotated(MyCurrentLocale.class),
                        "beans.xml");

        return testWar;
    }

    @Inject
    private CurrentLocale bean;

    @Test
    public void testInjection() throws Exception {
        ...
    }
}

MyCurrentLocale class definition:

    @SessionScoped
    @Alternative
    public class MyCurrentLocale extends DefaultCurrentLocale implements Serializable {

        @Inject
        protected MyCurrentLocale(@SupportedLocales Set<Locale> supportedLocales) {
            super(supportedLocales);
        }
       ...
   }

Is there something wrong in declaration ?

ruddy32
  • 21
  • 7

1 Answers1

0

Looks like you're using GlassFish v3, so you'll need the beans.xml file in the jar as well as it is a bean archive too.

LightGuard
  • 5,298
  • 19
  • 19
  • component includes a beans.xml resource. The project is using GF Embedded 4.1. – ruddy32 Sep 21 '15 at 06:30
  • Hmm, the stacktrace says v3. Do you have the sane problem with a managed or remote container? – LightGuard Sep 21 '15 at 14:20
  • The project references GF embedded 4.1 and Arquillian GF Embedded 3.1 CR4 - this version has been tested with GF4 yet. The project uses manage container only. There is a package in GF embedded 4.1 archive. – ruddy32 Sep 21 '15 at 15:33
  • Usage of `@Singleton` for a CDI bean is suspicious - the proper annotation to use is `@ApplicationScoped`. But the difference is very subtle and I do not think it causes this problem. – OndroMih Sep 21 '15 at 18:39
  • Is it possible to provide CDI extension and CDI beans in the same library ? – ruddy32 Sep 22 '15 at 16:25
  • Sure! There's no problem doing that. – LightGuard Sep 22 '15 at 16:40
  • It seems not possible to include beans and extension in the same module. Moving extension to another module solve the problem. – ruddy32 Sep 23 '15 at 06:51