WELD SE with JUnit 5 require enabling bean discovery programmatically
Asked Answered
E

1

5

I'm setting up an example project for testing purposes which uses Weld SE and JUnit5 and for some reason, in my test classes, after initializing weld I observ that, for some reason, it's bean discovery is disabled, which in the end, it lead me to this error:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Person with qualifiers @Default;

This is my test class :

@EnableWeld
public class SimpleTestA {

@Inject
Person p;

@Test
public void testThatItWorks() {
    System.out.println("Hey");
 }
}

located in :

projectName\core\model\src\test\java\com\aCompany\projectName\core\model\testmodel\SimpleTestA.java

This is my beans.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_1.xsd" version="1.1" bean-discovery-mode="all" />

located in :

projectName\core\model\src\main\resources\META-INF\beans.xml

The project structure is fairly simple, I just have a main module named "projectName" which is the parent of the sub-module named "core" which contains all that i pasted earlier. My dependencies list is this :

 <dependencies>

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>${junit-jupiter.aggregator.version}</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jboss.weld.se</groupId>
  <artifactId>weld-se-core</artifactId>
  <version>${weld.se.core.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.jboss.weld/weld-junit5 -->
<dependency>
  <groupId>org.jboss.weld</groupId>
  <artifactId>weld-junit5</artifactId>
  <version>${weld.junit5.version}</version>
  <scope>test</scope>
</dependency>

and those are my properties :

  <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<weld.se.core.version>3.0.1.Final</weld.se.core.version>
<weld.junit5.version>1.3.1.Final</weld.junit5.version>
<junit-jupiter.aggregator.version>5.4.0</junit-jupiter.aggregator.version>

If I modify the test adding the weld initialization attribute with explicit bean discovery activation, everything works very well:

    @WeldSetup
WeldInitiator weldInitiator =     WeldInitiator.of(WeldInitiator.createWeld().enableDiscovery());

What I'm missing ? If the beans.xml is present, shouldn't the bean discovery activated automatically? Thank you in advance.

Ecchymosis answered 3/3, 2019 at 11:30 Comment(0)
K
8

So the thing here is that you are using Weld SE (well, weld-junit is), not Weld EE which you might know from servers such as WildFly.

In SE, the discovery is by default off and so called synthetic archive is used. Synthetic archive only contains whatever you yourself feed it - classes as beans, packages to scan through etc. It doesn't scan whole classpath.

So to make your example work, you can either have the discovery on, or you can add the classes and packages you need via Weld.addPackages(), Weld.addClasses() and so on. In context of Weld-junit this translates into WeldInitiator.createWeld().addPackages().

The reason why Weld SE (and weld-junit) doesn't perform the whole discovery is because you would effectively scan whole classpath including JDK packages and all. That takes time and on top of that you also discover tons of beans you don't need. Or you can pick up interceptors/alternatives that you didn't mean to. Last but not least, these are meant to be unit tests, so minimal deployments that test your beans.

Koloski answered 4/3, 2019 at 15:12 Comment(1)
Thank you so much for giving me such a clear answer.Ecchymosis

© 2022 - 2024 — McMap. All rights reserved.