Repository: weld/weld-junit
Pull request #130 (2022-04-05 16:06:07)

Jupiter support improvements
This PR improves various things in the JUnit Jupiter module.

manovotn: Thanks for sending the PR.
I am aware of it and will look into it in the coming days once I have some spare cycles so please bear with me :)
manovotn: @Vampire I have been sick so this got delayed more. I started reviewing it now but the sheer size of the PR is fairly daunting.
Do you think it would make sense to split it into two PRs? The first two commits are very much standalone work not related to Spock integration. Therefore, we could get those merged in first PR and then look into Spock integration afterwards in a separate PR. WDYT?

BTW I really like and appreciate those changes - lots of good cleanup and documentation! :)
I am somewhat biased about the parallel execution but determined to give it a try once I find more about it (which I am doing now).

I can split it myself if you are busy.
Also, no need to care about `3.0` branch ATM. I say we do this on `master` and once done we backport it.

Patch:
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java b/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
index 0957e63..53350f8 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
@@ -245,7 +245,7 @@ public abstract class AbstractWeldInitiator implements Instance<Object>, Contain
      * @return <code>true</code> if the container was initialized completely and is not shut down yet, <code>false</code> otherwise
      */
     public boolean isRunning() {
-        return container.isRunning();
+        return (container != null) && container.isRunning();
     }
 
     /**
diff --git a/junit5/README.md b/junit5/README.md
index 9a9696f..0cc2c36 100644
--- a/junit5/README.md
+++ b/junit5/README.md
@@ -1,11 +1,18 @@
-# Weld JUnit 5 Extensions
+# Weld JUnit 5 (Jupiter) Extensions
 
 There are two extension here, both of which follow the extension mechanism introduced in JUnit 5.
 Therefore, in order to use this extension in your test, you have to annotate your test class with `@ExtendWith(WeldJunit5Extension.class)` or `@ExtendWith(WeldJunit5AutoExtension.class)` respectively.
 In their default behaviour, the extensions will automatically start/stop Weld SE container and inject into all your `@Inject` fields and method parameters in the given test instance.
-Furthermore you can provide configuration and modify Weld bootstrapping process in various ways - extensions, scope activation, interception, ...
+Furthermore, you can provide configuration and modify Weld bootstrapping process in various ways - extensions, scope activation, interception, ...
 
-This JUnit extension supports both test lifecycles [as described by JUnit 5](https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle) - per method and per class.
+These JUnit extensions supports both test lifecycles [as described by JUnit 5](https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle) - per method and per class.
+
+These extensions fully support parallel execution mode of JUnit Jupiter, except for if `WeldContainer.current()` is
+used which does not work if multiple containers are running from the same class loader. This includes the usage of
+`MockBean.Builder#useUnmanaged` with the default create function and also `MockBean.read` which calls `useUnmanaged`
+internally, as soon as the according beans are resolved and thus created. If either of these are used, you will
+get a `WELD-ENV-002016` error if another container is running at the same time, so you should use `@Isolated`
+for these features to make sure they are running individually.
 
 Requirements are JUnit 5 and Java 8.
 
@@ -16,8 +23,8 @@ Requirements are JUnit 5 and Java 8.
 * [WeldJunit5Extension](#weldjunit5extension)
   * [WeldInitiator](#weldinitiator)
     * [Convenient Starting Points](#convenient-starting-points)
-      * [Test class injection](#test-class-injection)
-      * [Activating context for a normal scope](#activating-context-for-a-normal-scope)
+      * [Test Class Injection](#test-class-injection)
+      * [Activating Context for a Normal Scope](#activating-context-for-a-normal-scope)
       * [Adding mock beans](#adding-mock-beans)
       * [Adding mock interceptors](#adding-mock-interceptors)
       * [Mock injection services](#mock-injection-services)
@@ -55,15 +62,15 @@ While both are ultimately achieving the same thing, each opts for a different ap
 
 `WeldJunit5Extension.class` is the original one where you declaratively configure the container, much like booting Weld SE itself.
 There are some additional builder patterns on top of that allowing for easy addition of mocked beans and such.
-The advantage of this approach is that you have complete control over what gets into Weld container and can easily change that.
+The advantage of this approach is that you have complete control over what gets into the Weld container and can easily change that.
 On the other hand, it may be rather verbose and requires you to add a specifically annotated field to every test (described below).
 
 `WeldJunit5AutoExtension.class` is more of an annotation based approach where you don't need any special field in your test class.
-In fact, you don't need anything except the JUnit `@ExtendWith` and our extension will try its best to find out what classes should be added to Weld container as beans.
-This of course makes some assumptions on your tests which may not always be met, hence there is bunch of annotations which allow you to configure the container.
-Pros of this approach are quick setup for basic cases, less verbose code and that eerie feeling that things are happening automagically.
-On the not so bright side, automatic config is not almighty and in some cases will falter forcing you to add some configuration via annotations.
-Last but not least, overly complex test scenarios may mean loads of annotations and you may be better off with the former extension.
+In fact, you don't need anything except the JUnit `@ExtendWith` and our extension will try its best to find out what classes should be added to the Weld container as beans.
+This of course makes some assumptions on your tests which may not always be met, hence there is a bunch of annotations which allow you to configure the container further.
+Advantages of this approach are quick setup for basic cases, less verbose code and that eerie feeling that things are happening automagically.
+On the not so bright side, automatic config is not almighty and in some cases will falter, forcing you to add some configuration via annotations.
+Last but not least, overly complex test scenarios may mean loads of annotations, and you may be better off with the former extension.
 
 No matter what extension you choose, do not mix them together!
 
@@ -71,21 +78,19 @@ No matter what extension you choose, do not mix them together!
 
 The simplest way to use this extension is to annotate your test class with `@ExtendWith(WeldJunit5Extension.class)`.
 If you are in for shorter annotations, you can also use `@EnableWeld`.
-With just these annotations, Weld container will be started before each test is run and stopped afterwards.
-This default behaviour includes:
+With just these annotations, the Weld container will be started before each test is run and stopped afterwards.
 
-* Bootstrapping Weld SE container with
+This default behaviour includes:
+* Bootstrap Weld SE container with
   * Disabled discovery
-  * Added test class package as source of beans
   * Disabled concurrent deployment
-* Injecting into test instance, e.g. into all `@Inject` fields
-* Injecting into method parameters of your test methods
-  * In case the type of the parameter matches a known and resolvable bean
-  * By default, Weld is greedy and will try to resolve all parameters which are known as bean types in CDI container
-  * If you wish to change this behaviour, please refer to [additional configuration section](#explicit-parameter-injection)
-* Shutting down the container after test is done
-
-And this is how you achieve it:
+  * Added test class package as source of beans
+* Inject into all fields of the test instance that are annotated with `@Inject`
+* Inject into method parameters of your test methods
+  * If the type of the parameter matches a known and resolvable bean
+  * By default, Weld is greedy and will try to resolve all parameters which are known as bean types in the container
+  * If this behaviour should be different, refer to [additional configuration section](#explicit-parameter-injection)
+* Shut down the container after test is done
 
 ```java
 import org.jboss.weld.junit5.WeldJunit5Extension;
@@ -95,13 +100,13 @@ import org.junit.jupiter.api.extension.ExtendWith;
 @ExtendWith(WeldJunit5Extension.class)
 class BasicUsageTest {
 
-    @Inject
-    MyBean myBean;
+  @Inject
+  MyBean myBean;
 
-    @Test
-    public void testFoo(MyOtherBean otherBean) {
-      // Weld SE container is bootstrapped here and the injection points are resolved
-    }
+  @Test
+  public void testFoo(MyOtherBean otherBean) {
+    // Weld SE container is bootstrapped here and the injection points are resolved
+  }
 }
 ```
 
@@ -113,7 +118,7 @@ By default, the container is optimized for testing purposes, i.e. with automatic
 However, it is possible to provide a customized `Weld` instance  - see also `WeldInitiator.of(Weld)` and `WeldInitiator.from(Weld)` methods.
 `WeldInitiator` also implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup of bean instances.
 
-`WeldInitiator` should be a public field annotated with `@org.jboss.weld.junit5.WeldSetup`.
+`WeldInitiator` should be available in a field annotated with `@org.jboss.weld.junit5.WeldSetup`.
 From there you can use static methods:
 
 ```java
@@ -181,7 +186,7 @@ class AnotherSimpleTest {
 
 Furthermore, `WeldInitiator.Builder` can be used to customize the final `WeldInitiator` instance, e.g. to *activate a context for a given normal scope* or to *inject the test class*.
 
-##### Test class injection
+##### Test Class Injection
 
 Everytime `WeldJunit5Extension` processes your test instance, it will automatically resolve all `@Inject` fields as well as attempt to resolve any test method parameters, should they be injectable beans.
 
@@ -192,7 +197,7 @@ class InjectTest {
     @WeldSetup
     public WeldInitiator weld = WeldInitiator.from(Foo.class).build();
 
-  // Gets injected before executing test
+    // Gets injected before executing test
     @Inject
     @MyQualifier
     Foo foo;
@@ -205,7 +210,7 @@ class InjectTest {
 }
 ```
 
-##### Activating context for a normal scope
+##### Activating Context for a Normal Scope
 
 `WeldInitiator.Builder.activate(Class<? extends Annotation>...)` makes it possible to activate and deactivate contexts for the specified normal scopes for each test method execution:
 
@@ -231,9 +236,9 @@ class ContextsActivatedTest {
 ##### Adding mock beans
 
 Sometimes you might need to add a mock for a bean that cannot be part of the test deployment, e.g. the original bean implementation has dependencies which cannot be satisfied in the test environment.
-Very often, it's an ideal use case for mocking libraries, ie. to create a bean instance with the desired behavior.
+Very often, it's an ideal use case for mocking libraries, i.e. to create a bean instance with the desired behavior.
 In this case, there are two options.
-The first option is to add a [producer method](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#producer_method) to the test class and add the test class to the deployment.
+The first option is to add a [producer method](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#producer_method) or [field](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#producer_field) to the test class and add the test class to the deployment.
 The test class will be recognized as a bean and therefore the producer will also be discovered.
 
 ```java
@@ -270,9 +275,9 @@ class TestClassProducerTest {
 }
 ```
 
-This should work in most of the cases (assuming the test class [meets some conditions](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#what_classes_are_beans)) although it's a little bit cumbersome.
+This should work in most of the cases (assuming the test class [meets some conditions](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#what_classes_are_beans)) although it's a little bit cumbersome.
 The second option is `WeldInitiator.Builder.addBeans(Bean<?>...)` which makes it possible to add beans during `AfterBeanDiscovery` phase easily.
-You can provide your own `jakarta.enterprise.inject.spi.Bean` implementation or make use of existing solutions such as DeltaSpike [BeanBuilder](https://github.com/apache/deltaspike/blob/master/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java) or for most use cases a convenient `org.jboss.weld.junit.MockBean` should be sufficient.
+You can provide your own `jakarta.enterprise.inject.spi.Bean` implementation or, for most use cases, a convenient `org.jboss.weld.junit.MockBean` should be sufficient.
 Use `org.jboss.weld.junit.MockBean.builder()` to obtain a new builder instance.
 
 ```java
@@ -318,11 +323,12 @@ Sometimes it might be useful to add a mock interceptor, e.g. if an interceptor i
 For this use case the `org.jboss.weld.junit.MockInterceptor` is a perfect match:
 
 ```java
+
 @FooBinding
 class Foo {
-   boolean ping() {
-      return true;
-   }
+  boolean ping() {
+    return true;
+  }
 }
 
 @Target({ TYPE, METHOD })
@@ -330,34 +336,33 @@ class Foo {
 @InterceptorBinding
 @interface FooBinding {
 
-   @SuppressWarnings("serial")
-   static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
-      public static final Literal INSTANCE = new Literal();
-    };
-   }
+  @SuppressWarnings("serial")
+  final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+    public static final Literal INSTANCE = new Literal();
+  }
+}
 }
 
 @EnableWeld
 class MockInterceptorTest {
 
-    @WeldSetup
-    public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
-            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
-                return false;
-                })).build();
-
+  @WeldSetup
+  public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
+          MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
+            return false;
+          })).build();
 
-    @Test
-    public void testInterception() {
-       Assert.assertFalse(weld.select(Foo.class).get().ping());
-    }
+  @Test
+  public void testInterception() {
+    Assert.assertFalse(weld.select(Foo.class).get().ping());
+  }
 }
 ```
 
 ##### Mock injection services
 
 If a bean under the test declares a non-CDI injection point (such as `@Resource`) a mock injection service must be installed.
-`WeldInitiator` builder comes with several convenient methods which allow to easily mock the Weld SPI:
+`WeldInitiator.Builder` comes with several convenient methods which allow to easily mock the Weld SPI:
 
 * `bindResource()` - to handle `@Resource`
 * `setEjbFactory()` - to handle `@EJB`
@@ -488,18 +493,21 @@ To use this approach, annotate your test class with `@ExtendWith(WeldJunit5AutoE
 By default, the extension will:
 
 * Inspect your test class and try to figure out what bean classes it needs based on injection points (field and parameter injection both work)
-  * This is done by finding classes and verifying if they have [bean defining annotation](http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#bean_defining_annotations) so make sure they do
-* Add those classes to Weld container
-* Process additional annotations on test class
+  * This is done by finding classes and verifying whether they have a [bean defining annotation](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#bean_defining_annotations) so make sure they do
+* Add those classes to the Weld container
+* Process additional annotations on the test class and also on each discovered class
   * `@AddPackages`, `@AddExtensions`, `@ActivateScopes`, ...
 * Annotates test classes with `@Singleton` and prevents another instantiation by Weld and instead substitutes the test instances provided by JUnit
-* Bootstrap Weld container
-* Inject into test instances, e.g. into all `@Inject` fields
+* Bootstrap Weld SE container with
+  * Disabled discovery
+  * Disabled concurrent deployment
+  * Added test class package as source of beans
+* Inject into all fields of the test instance that are annotated with `@Inject`
 * Inject into method parameters of your test methods
-  * In case the type of the parameter matches a known and resolvable bean
-  * By default, Weld is greedy and will try to resolve all parameters which are known as bean types in CDI container
-  * If you wish to change this behaviour, please refer to [additional configuration section](#explicit-parameter-injection)
-* Shutting down the container after test is done
+  * If the type of the parameter matches a known and resolvable bean
+  * By default, Weld is greedy and will try to resolve all parameters which are known as bean types in the container
+  * If this behaviour should be different, refer to [additional configuration section](#explicit-parameter-injection)
+* Shut down the container after test is done
 
 Here is a simple example using the default plus one additional annotation (`@AddPackages`):
 
@@ -525,14 +533,14 @@ public class BasicAutomagicTest {
 
   @Test
   void test() {
-    assertNotNull(V8Engine);
+    assertNotNull(v8Engine);
     assertNotNull(v6Engine);
   }
 
 }
 ```
 
-The default behaviour is powerful enough to handle basic cases where you simply want to inject a bean make assertions on it.
+The default behaviour is powerful enough to handle basic cases where you simply want to inject a bean and make assertions on it.
 However, it will not be enough if you want to, say, test your CDI extensions, enable custom interceptors or make sure certain scopes are active.
 Or if you want to inject interfaces instead of implementations of beans.
 For those cases, and many others, there are special annotations you can use - we will go over them, one at a time.
@@ -541,7 +549,7 @@ At the end there is an example showing several of them.
 ### `@ActivateScopes`
 
 Normally, only `@ApplicationScoped` and `@Dependent` beans work without any additional settings.
-`@ActivateScopes` annotation allows you to list scopes which are to be actived for the duration of the test.
+`@ActivateScopes` annotation allows you to list scopes which are to be activated for the duration of the test.
 Note that the duration is dependent on your setting of JUnit test lifecycle - it can be either per method or per class.
 
 ### `@AddBeanClasses`
@@ -562,33 +570,33 @@ Adds the interceptor class into deployment and enables it.
 
 ### `@AddExtensions`
 
-Registers one or more extensions within Weld container; this is programmatic replacement for placing the extension in `META-INF`.
+Registers one or more extensions within the Weld container. This is the programmatic replacement for placing the extension in `META-INF`.
 
 ### `@AddPackages`
 
-Adds all bean classes from listed packages to Weld container.
+Adds all bean classes from listed packages to the Weld container.
 Packages are selected by providing any bean class in the package.
 You can also specify if this should be done recursively using the `recursive` parameter.
 
 ### `@EnableAlternativeStereotypes`
 
-Enables given alternative stereotype.
+Enables given alternative stereotypes.
 
 ### `@EnableAlternatives`
 
-Selects and alternative for the test bean archive.
+Selects given alternatives for the test bean archive.
 
 ### `@ExcludeBean`
 
-Excludes a bean, or multiple beans, that include a bean defining annotation (e.g. scope) from automatic discovery. 
-This can be helpful to allow replacing a bean class with a different implementation; typically a mock.
+Excludes a bean, or multiple beans, that include a bean defining annotation (e.g. scope) from automatic discovery.
+This can be helpful to allow replacing a bean class with a different implementation, typically a mock.
 
-The type of bean to exclude is implied by the annotated field's type or annotated method's return type. 
+The type of bean to exclude is implied by the annotated field's type or annotated method's return type.
 If the type is a base class or interface all beans extending/implementing that type will be excluded.
 
-NOTE: This annotation will only exclude beans defined by class annotations. 
-It will not exclude beans of the implied type that are defined by `@Produces` producer methods/fields or synthetic beans. 
-Also, current implementation excludes beans based on type, disregarding any qualifiers that are specified.
+NOTE: This annotation will only exclude beans defined by class annotations.
+It will not exclude beans of the implied type that are defined by `@Produces` producer methods/fields or synthetic beans.
+Also, the current implementation excludes beans based on type, disregarding any qualifiers that are specified.
 
 ```java
 import org.jboss.weld.junit5.auto.ExcludeBean;
@@ -622,12 +630,12 @@ class TestSomeFoo {
 
 ### `@ExcludeBeanClasses`
 
-Excludes a set of classes with bean defining annotations (e.g. scopes) from automatic discovery. 
+Excludes a set of classes with bean defining annotations (e.g. scopes) from automatic discovery.
 This can be helpful to allow replacing bean classes with a different implementation; typically a mock.
 
 This annotation works as an inverse of [`@AddBeanClasses`](#addbeanclasses) hence usually requires actual bean implementation classes as parameters.
 
-NOTE: This annotation will only exclude beans defined by class annotations. 
+NOTE: This annotation will only exclude beans defined by class annotations.
 It will not exclude beans of the specified type that are defined by `Produces` producer methods/fields or synthetic beans.
 
 ## Additional Configuration
@@ -667,17 +675,16 @@ class ExplicitParamInjectionTest {
 ```
 
 As you might know, if you want to inject a bean where you would normally not use any qualifier, you can do that using `@Default` qualifier (as shown in the code above).
-This is in accordance with CDI specification, feel free to [read more about it](http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#builtin_qualifiers).
+This is in accordance with the CDI specification, feel free to [read more about it](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#builtin_qualifiers).
 
-#### Flat Deployment
+### Flat Deployment
 
 Unlike [Arquillian Weld embedded container](https://github.com/arquillian/arquillian-container-weld), weld-junit has bean archive isolation enabled by default.
-This behaviour can be changed by setting a system property `org.jboss.weld.se.archive.isolation` to `false` or through the `Weld.property()` method.
-If set, Weld will use a _"flat"_ deployment structure - all bean classes share the same bean archive and all beans.xml descriptors are automatically merged into one.
-Thus alternatives, interceptors and decorators selected/enabled for a bean archive will be enabled for the whole application.
-Note that this configuration only makes difference if you run with *enabled discovery*; it won't affect your deployment if you use synthetic bean archive.
-
+This behaviour can be changed by setting the system property `org.jboss.weld.se.archive.isolation` to `false` or through the `Weld.property()` method.
+If set to `false`, Weld will use a _"flat"_ deployment structure - all bean classes share the same bean archive and all `beans.xml` descriptors are automatically merged into one.
+Thus, alternatives, interceptors, and decorators selected / enabled for a bean archive will be enabled for the whole application.
+Note that this configuration only makes a difference if you run with *enabled discovery*; it won't affect your deployment if you use the synthetic bean archive.
 
 ## Limitations
 
-* `@Produces`, `@Disposes`, and `@Observes` don't work in `@Nested` test classes which fail to meet [valid bean](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#what_classes_are_beans) requirements due to the lack of a no-arg constructor and Weld ignores them silently. However, `@Inject` and parameter injection also work with `@Nested` classes.
+* `@Produces`, `@Disposes`, and `@Observes` don't work in `@Nested` test classes which fail to meet [valid bean](https://jakarta.ee/specifications/cdi/3.0/jakarta-cdi-spec-3.0.html#what_classes_are_beans) requirements due to the lack of a no-arg constructor and Weld ignores them silently. However, `@Inject` and parameter injection also work with `@Nested` classes.
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/WeldInitiator.java b/junit5/src/main/java/org/jboss/weld/junit5/WeldInitiator.java
index 1e17c42..a1d91df 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/WeldInitiator.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/WeldInitiator.java
@@ -33,6 +33,7 @@ import org.jboss.weld.junit.AbstractWeldInitiator;
 /**
  * JUnit 5 initiator - can be used to customize the Weld SE container started by {@link WeldJunit5Extension}.
  *
+ * <p><b>Example:</b>
  * <pre>
  * &#64;ExtendWith(WeldJunit5Extension.class)
  * public class SimpleTest {
@@ -185,6 +186,7 @@ public class WeldInitiator extends AbstractWeldInitiator {
     WeldContainer initWeld(Object testInstance) {
         Weld weld = WeldInitiator.this.weld;
         if (weld == null) {
+            // null in case of fromTestPackage() was used
             weld = createWeld().addPackage(false, testInstance.getClass());
         }
 
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java b/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java
index d3ea5a1..d89df89 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/WeldJunit5Extension.java
@@ -38,6 +38,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -54,9 +55,9 @@ import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
 import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_METHOD;
 
 /**
- * JUnit 5 extension allowing to bootstrap Weld SE container for each @Test method (or per once per test class
- * if running {@link org.junit.jupiter.api.TestInstance.Lifecycle#PER_CLASS}) and tear it down afterwards. Also allows to
- * inject CDI beans as parameters to @Test methods and resolves all @Inject fields in test class.
+ * JUnit 5 extension allowing to bootstrap Weld SE container for each @Test method (or once per test class
+ * if running {@link org.junit.jupiter.api.TestInstance.Lifecycle#PER_CLASS}) and tear it down afterwards. Also allows
+ * injecting CDI beans as parameters to @Test methods and resolves all @Inject fields in test class.
  *
  * <p>
  * If no {@link WeldInitiator} field annotated with {@link WeldSetup} is present on a test class, all service providers of
@@ -109,7 +110,10 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
     @Override
     public void afterAll(ExtensionContext context) {
         if (determineTestLifecycle(context).equals(PER_CLASS)) {
-            getInitiatorFromStore(context).shutdownWeld();
+            WeldInitiator initiator = getInitiatorFromStore(context);
+            if (initiator != null) {
+                initiator.shutdownWeld();
+            }
         }
     }
 
@@ -128,7 +132,10 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
     @Override
     public void afterEach(ExtensionContext context) {
         if (determineTestLifecycle(context).equals(PER_METHOD)) {
-            getInitiatorFromStore(context).shutdownWeld();
+            WeldInitiator initiator = getInitiatorFromStore(context);
+            if (initiator != null) {
+                initiator.shutdownWeld();
+            }
         }
     }
 
@@ -149,7 +156,7 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
 
     @Override
     public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
-        // if weld container isn't up yet or if its not Method, we don't resolve it
+        // if weld container isn't up yet or if it's not Method, we don't resolve it
         if (getContainerFromStore(extensionContext) == null || (!(parameterContext.getDeclaringExecutable() instanceof Method))) {
             return false;
         }
@@ -234,19 +241,38 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
     private WeldInitiator findInitiatorInInstance(Object testInstance) {
         // all found fields which are WeldInitiator and have @WeldSetup annotation
         List<Field> foundInitiatorFields = new ArrayList<>();
+        WeldInitiator initiator = null;
         // We will go through class hierarchy in search of @WeldSetup field (even private)
         for (Class<?> clazz = testInstance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
             // Find @WeldSetup field using getDeclaredFields() - this allows even for private fields
             for (Field field : clazz.getDeclaredFields()) {
                 if (field.isAnnotationPresent(WeldSetup.class)) {
-                    if (WeldInitiator.class.isAssignableFrom(field.getType())) {
+                    Object fieldInstance;
+                    try {
+                        fieldInstance = field.get(testInstance);
+                    } catch (IllegalAccessException e) {
+                        // In case we cannot get to the field, we need to set accessibility as well
+                        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+                            field.setAccessible(true);
+                            return null;
+                        });
+                        try {
+                            fieldInstance = field.get(testInstance);
+                        } catch (IllegalAccessException e2) {
+                            // we should never get to this point, because setAccessible would have thrown earlier if access could
+                            // not be granted.
+                            throw new AssertionError();
+                        }
+                    }
+                    if (fieldInstance instanceof WeldInitiator) {
+                        initiator = (WeldInitiator) fieldInstance;
                         foundInitiatorFields.add(field);
                     } else {
-                        // Field with other type than WeldInitiator was annotated with @WeldSetup
-                        throw new IllegalStateException("@WeldSetup annotation should only be used on a field of type"
-                                                        + " WeldInitiator but was found on a field of type "
-                                                        + field.getType() + " which is declared in class "
-                                                        + field.getDeclaringClass());
+                        // Field with other value than WeldInitiator was annotated with @WeldSetup
+                        throw new IllegalStateException("@WeldSetup annotation should only be used on a field with a "
+                                + "WeldInitiator value but was found on field " + field.getName() + "with a "
+                                + ((fieldInstance == null) ? "null" : fieldInstance.getClass())
+                                + " value which is declared in class " + field.getDeclaringClass());
                     }
                 }
             }
@@ -254,32 +280,17 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
         if (foundInitiatorFields.isEmpty()) {
             return null;
         }
+        validateInitiator(foundInitiatorFields);
         // Multiple occurrences of @WeldSetup in the hierarchy will lead to an exception
         if (foundInitiatorFields.size() > 1) {
             final String msg = foundInitiatorFields.stream()
-                    .map(f -> "Field type of type" + f.getType() + " which is declared in " + f.getDeclaringClass())
+                    .map(f -> "Field '" + f.getName() + "' with type " + f.getType() + " which is declared in " + f.getDeclaringClass())
                     .collect(Collectors.joining("\n", "Multiple @WeldSetup annotated fields found, "
                                                       + "only one is allowed! Fields found:\n", ""));
             throw new IllegalStateException(msg);
         }
 
-        Field field = foundInitiatorFields.get(0);
-        try {
-            return (WeldInitiator) field.get(testInstance);
-        } catch (IllegalAccessException e) {
-            // In case we cannot get to the field, we need to set accessibility as well
-            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
-                field.setAccessible(true);
-                return null;
-            });
-            try {
-                return (WeldInitiator) field.get(testInstance);
-            } catch (IllegalAccessException e2) {
-                // we should never get to this point, because setAccessible would have thrown earlier if access could
-                // not be granted.
-            }
-        }
-        return null;
+        return initiator;
     }
 
     private WeldInitiator getDefaultInitiator(ExtensionContext context, Object testInstance) {
@@ -300,4 +311,7 @@ public class WeldJunit5Extension implements AfterAllCallback, BeforeAllCallback,
         return builder.build();
     }
 
+    protected void validateInitiator(List<Field> foundInitiatorFields) {
+        // a found initiator is always good for this variant
+    }
 }
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/ActivateScopes.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/ActivateScopes.java
index faa4430..9434072 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/ActivateScopes.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/ActivateScopes.java
@@ -42,6 +42,9 @@ public @interface ActivateScopes {
 
     Class<? extends Annotation>[] value();
 
+    /**
+     * Container annotation for repeatable {@link ActivateScopes}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.TYPE})
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddBeanClasses.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddBeanClasses.java
index dcf8ebc..4011fb4 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddBeanClasses.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddBeanClasses.java
@@ -36,6 +36,9 @@ public @interface AddBeanClasses {
 
     Class<?>[] value();
 
+    /**
+     * Container annotation for repeatable {@link AddBeanClasses}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledDecorators.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledDecorators.java
index 1dc7e32..3a42b97 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledDecorators.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledDecorators.java
@@ -35,6 +35,9 @@ public @interface AddEnabledDecorators {
 
     Class<?>[] value();
 
+    /**
+     * Container annotation for repeatable {@link AddEnabledDecorators}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledInterceptors.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledInterceptors.java
index 1eb805f..a3dc067 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledInterceptors.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddEnabledInterceptors.java
@@ -35,6 +35,9 @@ public @interface AddEnabledInterceptors {
 
     Class<?>[] value();
 
+    /**
+     * Container annotation for repeatable {@link AddEnabledInterceptors}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddExtensions.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddExtensions.java
index a6cadec..d32fa8a 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddExtensions.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddExtensions.java
@@ -37,6 +37,9 @@ public @interface AddExtensions {
 
     Class<? extends Extension>[] value();
 
+    /**
+     * Container annotation for repeatable {@link AddExtensions}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddPackages.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddPackages.java
index 36d6748..9aaaf98 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/AddPackages.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/AddPackages.java
@@ -27,8 +27,8 @@ import java.lang.annotation.Target;
 
 /**
  * Adds all bean classes from the listed packages to the deployed testing container.
- * <p>
- * Packages are selected by providing <i>any</i> bean class in the package.
+ *
+ * <p>Packages are selected by providing <i>any</i> bean class in the package.
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
@@ -40,6 +40,9 @@ public @interface AddPackages {
 
     boolean recursively() default true;
 
+    /**
+     * Container annotation for repeatable {@link AddPackages}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternativeStereotypes.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternativeStereotypes.java
index 652353f..66e7420 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternativeStereotypes.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternativeStereotypes.java
@@ -37,6 +37,9 @@ public @interface EnableAlternativeStereotypes {
 
     Class<? extends Annotation>[] value();
 
+    /**
+     * Container annotation for repeatable {@link EnableAlternativeStereotypes}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternatives.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternatives.java
index 5a97392..e03d499 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternatives.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/EnableAlternatives.java
@@ -36,6 +36,9 @@ public @interface EnableAlternatives {
 
     Class<?>[] value();
 
+    /**
+     * Container annotation for repeatable {@link EnableAlternatives}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBean.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBean.java
index 7e52ad8..f0f4b9d 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBean.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBean.java
@@ -6,19 +6,21 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import jakarta.enterprise.inject.Produces;
+
 /**
- * {@code ExcludeBean} excludes a bean, or multiple beans, that include a bean defining annotation (
- * e.g. scope) from automatic discovery. This can be helpful to allow replacing a bean class with a different
- * implementation; typically a mock.
+ * {@code @ExcludeBean} excludes a bean, or multiple beans, that include a bean defining annotation
+ * (e.g. scope) from automatic discovery. This can be helpful to allow replacing a bean class with a different
+ * implementation, typically a mock.
  *
- * The type of bean to exclude is implied by the annotated field's type or annotated method's return type. If the type
- * is a base class or interface all beans extending/implementing that type will be excluded.
+ * <p>The type of bean to exclude is implied by the annotated fields' type or annotated methods' return type. If the type
+ * is a base class or interface all beans extending / implementing that type will be excluded.
  *
- * NOTE: This annotation will only exclude beans defined by class annotations. It will not exclude beans of the
- * implied type that are defined by {@link jakarta.enterprise.inject.Produces} producer methods/fields or synthetic
+ * <p>NOTE: This annotation will only exclude beans defined by class annotations. It will not exclude beans of the
+ * implied type that are defined by {@link Produces} producer methods / fields or synthetic
  * beans. Also, current implementation excludes beans based on type, disregarding any qualifiers that are specified.
  *
- * Example:
+ * <p><b>Example:</b>
  * <pre>
  * &#64;EnableAutoWeld
  * class TestSomeFoo {
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBeanClasses.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBeanClasses.java
index 2af2d69..369c031 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBeanClasses.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludeBeanClasses.java
@@ -7,28 +7,29 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import jakarta.enterprise.inject.Produces;
+
 /**
- * {@code ExcludeBeanClasses} excludes a set of classes with bean defining annotations (e.g. scopes) from automatic
- * discovery. This can be helpful to allow replacing bean classes with a different implementation; typically a mock.
+ * {@code @ExcludeBeanClasses} excludes a set of classes with bean defining annotations (e.g. scopes) from automatic
+ * discovery. This can be helpful to allow replacing bean classes with a different implementation, typically a mock.
  *
- * This annotation works as an inverse of {@link AddBeanClasses} hence usually requires actual bean implementation
+ * <p>This annotation works as an inverse of {@link AddBeanClasses} hence usually requires actual bean implementation
  * classes as parameters.
  *
- * NOTE: This annotation will only exclude beans defined by class annotations. It will not exclude beans of the
- * specified type that are defined by {@link jakarta.enterprise.inject.Produces} producer methods/fields or synthetic
- * beans.
+ * <p>NOTE: This annotation will only exclude beans defined by class annotations. It will not exclude beans of the
+ * specified type that are defined by {@link Produces} producer methods / fields or synthetic beans.
  *
- * Example:
+ * <p><b>Example:</b>
  * <pre>
  * &#64;EnableAutoWeld
- * &#64;ExcludeBeanClasses(Foo.class) // Excludes Foo bean class from automatic discovery
+ * &#64;ExcludeBeanClasses(Foo.class)     // Excludes Foo bean class from automatic discovery
  * class TestSomeFoo {
  *
  *   &#64;Inject
- *   SomeFoo someFoo;   // SomeFoo depends upon application scoped bean Foo
+ *   SomeFoo someFoo;                 // SomeFoo depends upon application scoped bean Foo
  *
  *   &#64;Produces
- *   Foo mockFoo = mock(Foo.class);  // mockFoo is now produced in place of original Foo impl
+ *   Foo mockFoo = mock(Foo.class);   // mockFoo is now produced in place of original Foo impl
  *
  *   &#64;Test
  *   void test(Foo myFoo) {
@@ -37,7 +38,7 @@ import java.lang.annotation.Target;
  *   }
  * }
  * </pre>
-
+ *
  * @see ExcludeBean
  */
 @Retention(RetentionPolicy.RUNTIME)
@@ -48,6 +49,9 @@ public @interface ExcludeBeanClasses {
 
     Class<?>[] value();
 
+    /**
+     * Container annotation for repeatable {@link ExcludeBeanClasses}.
+     */
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.TYPE)
     @Inherited
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java
index 3399bba..77f2d44 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java
@@ -32,8 +32,8 @@ import java.util.Set;
  */
 public class ExcludedBeansExtension implements Extension {
 
-    private Set<Type> excludedBeanTypes;
-    private Set<Class<?>> excludedBeanClasses;
+    private final Set<Type> excludedBeanTypes;
+    private final Set<Class<?>> excludedBeanClasses;
 
     ExcludedBeansExtension(Set<Type> excludedBeanTypes, Set<Class<?>> excludedBeanClasses) {
         this.excludedBeanTypes = excludedBeanTypes;
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/WeldJunit5AutoExtension.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/WeldJunit5AutoExtension.java
index 02af769..3145f16 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/WeldJunit5AutoExtension.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/WeldJunit5AutoExtension.java
@@ -23,17 +23,25 @@ import org.jboss.weld.junit5.WeldJunitEnricher;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.platform.commons.support.AnnotationSupport;
 
+import static java.lang.String.format;
+import static java.util.stream.Collectors.joining;
 import static org.jboss.weld.junit5.ExtensionContextUtils.getExplicitInjectionInfoFromStore;
 
+import java.lang.reflect.Field;
 import java.util.List;
 import java.util.stream.Collectors;
 
 /**
- * An alternative to {@link WeldJunit5Extension} allowing to fully leverage annotation based configuration approach.
+ * An alternative to {@link WeldJunit5Extension} allowing to fully leverage an annotation based configuration approach.
  * When used, the extension will attempt to resolve all beans used in your test class and automatically adds them to
- * Weld container while bootstrapping it.
- * 
- * There is quite a few annotations which can be used to configure it further still:
+ * the Weld container while bootstrapping it.
+ *
+ * <p>There are quite some annotations which can be used to configure it further.
+ *
+ * <p>Furthermore, all discovered {@link WeldJunitEnricher}s are invoked after the annotations are processed.
+ *
+ * <p>Note that this approach cannot be combined with {@link WeldJunit5Extension}, choose one or the other approach, not both.
+ *
  * @see ActivateScopes
  * @see AddBeanClasses
  * @see AddEnabledDecorators
@@ -42,13 +50,21 @@ import java.util.stream.Collectors;
  * @see AddPackages
  * @see EnableAlternatives
  * @see EnableAlternativeStereotypes
- *
- * Note that this approach cannot be combined with {@link WeldJunit5Extension}, choose one or the other approach, not both.
- *
+ * @see ExcludeBean
+ * @see ExcludeBeanClasses
  * @see EnableAutoWeld
  * @see WeldJunitEnricher
  */
 public class WeldJunit5AutoExtension extends WeldJunit5Extension {
+    @Override
+    protected void validateInitiator(List<Field> foundInitiatorFields) {
+        if (foundInitiatorFields.size() > 0) {
+            throw new IllegalStateException(foundInitiatorFields
+                    .stream()
+                    .map(f -> format("Field '%s' with type %s which is in %s", f.getName(), f.getType(), f.getDeclaringClass()))
+                    .collect(joining("\n", "When using automagic mode, no @WeldSetup annotated field should be present! Fields found:\n", "")));
+        }
+    }
 
     @Override
     protected void weldInit(ExtensionContext context, Weld weld, WeldInitiator.Builder weldInitiatorBuilder) {
diff --git a/pom.xml b/pom.xml
index edb3e98..ec17dd3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,11 +41,11 @@
       <maven.compiler.target>1.8</maven.compiler.target>
       <!-- Versions -->
       <version.junit4>4.13.1</version.junit4>
-      <version.junit.jupiter>5.4.1</version.junit.jupiter>
+      <version.junit.jupiter>5.8.2</version.junit.jupiter>
       <version.weld>4.0.0.Final</version.weld>
       <version.mockito>2.25.1</version.mockito>
       <version.jakarta.ejb.api>4.0.0</version.jakarta.ejb.api>
-      <version-jpa-api>3.0.0</version-jpa-api>
+      <version.jpa-api>3.0.0</version.jpa-api>
       <!-- SpotBugs properties -->
       <version.spotbugs>3.1.11</version.spotbugs>
       <version.spotbugs.plugin>3.1.10</version.spotbugs.plugin>
@@ -110,7 +110,7 @@
          <dependency>
             <groupId>jakarta.persistence</groupId>
             <artifactId>jakarta.persistence-api</artifactId>
-            <version>${version-jpa-api}</version>
+            <version>${version.jpa-api}</version>
             <optional>true</optional>
          </dependency>
 
@@ -168,12 +168,9 @@
                     <!--Minimal version with Junit 5 engine support-->
                     <version>2.22.1</version>
                     <configuration>
-                        <systemProperties>
-                            <property>
-                                <name>java.util.logging.config.file</name>
-                                <value>${project.build.testOutputDirectory}/logging.properties</value>
-                            </property>
-                        </systemProperties>
+                        <systemPropertyVariables>
+                            <java.util.logging.config.file>${project.build.testOutputDirectory}/logging.properties</java.util.logging.config.file>
+                        </systemPropertyVariables>
                     </configuration>
                 </plugin>
             </plugins>


Test patch:
diff --git a/junit5/src/main/java/org/jboss/weld/junit5/auto/TestInstanceInjectionExtension.java b/junit5/src/main/java/org/jboss/weld/junit5/auto/TestInstanceInjectionExtension.java
index e22efe9..fc509d9 100644
--- a/junit5/src/main/java/org/jboss/weld/junit5/auto/TestInstanceInjectionExtension.java
+++ b/junit5/src/main/java/org/jboss/weld/junit5/auto/TestInstanceInjectionExtension.java
@@ -37,15 +37,15 @@ public class TestInstanceInjectionExtension<T> implements Extension {
 
     private static final AnnotationLiteral<Singleton> SINGLETON_LITERAL = new AnnotationLiteral<Singleton>() {};
 
-    private Class<?> testClass;
-    private T testInstance;
+    private final Class<?> testClass;
+    private final T testInstance;
 
     TestInstanceInjectionExtension(T testInstance) {
         this.testClass = testInstance.getClass();
         this.testInstance = testInstance;
     }
 
-    void rewriteTestClassScope(@Observes ProcessAnnotatedType<T> pat, BeanManager beanManager) {
+    void rewriteTestClassScope(@Observes ProcessAnnotatedType<T> pat) {
 
         if (pat.getAnnotatedType().getJavaClass().equals(testClass)) {
             pat.configureAnnotatedType().add(SINGLETON_LITERAL);
@@ -55,7 +55,7 @@ public class TestInstanceInjectionExtension<T> implements Extension {
 
     private class TestInstanceInjectionTarget extends ForwardingInjectionTarget<T> {
 
-        private InjectionTarget<T> injectionTarget;
+        private final InjectionTarget<T> injectionTarget;
 
         TestInstanceInjectionTarget(InjectionTarget<T> injectionTarget) {
             this.injectionTarget = injectionTarget;
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/auto/AutoConfigWithWeldSetupTest.java b/junit5/src/test/java/org/jboss/weld/junit5/auto/AutoConfigWithWeldSetupTest.java
new file mode 100644
index 0000000..4a91db9
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/auto/AutoConfigWithWeldSetupTest.java
@@ -0,0 +1,63 @@
+package org.jboss.weld.junit5.auto;
+
+import java.lang.reflect.Field;
+import java.util.Optional;
+
+import org.jboss.weld.junit5.WeldInitiator;
+import org.jboss.weld.junit5.WeldSetup;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.platform.engine.support.hierarchical.ThrowableCollector;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * NOTE - this test is one massive hack because JUnit, at the time of writing, doesn't allow to assert that an
+ * exception was throws inside an extension. The test is fragile and can break because of internal JUnit 5 changes
+ * in which case we might want to revisit if we want to keep it or whether there is a better way.
+ *
+ * @author bkautler
+ */
+@EnableAutoWeld
+class AutoConfigWithWeldSetupTest {
+
+  @WeldSetup
+  public WeldInitiator weld = WeldInitiator.of(WeldInitiator.createWeld());
+
+  @Test
+  @ExtendWith(AssertExceptionExtension.class)
+  @DisplayName("Ensure that @WeldSetup is not compatible with automagic mode")
+  void test() {
+    fail("IllegalStateException expected before test method is entered");
+  }
+
+  /**
+   * @author bkautler
+   */
+  static public class AssertExceptionExtension implements AfterEachCallback {
+
+    @Override
+    public void afterEach(ExtensionContext context) throws NoSuchFieldException, IllegalAccessException {
+      Optional<Throwable> executionException = context.getExecutionException();
+      if (executionException.isPresent()) {
+        Field throwableCollectorField = context.getClass().getDeclaredField("throwableCollector");
+        throwableCollectorField.setAccessible(true);
+        ThrowableCollector throwableCollector = (ThrowableCollector) throwableCollectorField.get(context);
+        Field throwableField = ThrowableCollector.class.getDeclaredField("throwable");
+        throwableField.setAccessible(true);
+        throwableField.set(throwableCollector, null);
+
+        Throwable throwable = executionException.get();
+        assertInstanceOf(IllegalStateException.class, throwable);
+        assertEquals("When using automagic mode, no @WeldSetup annotated field should be present! Fields found:\n"
+                     + "Field 'weld' with type class org.jboss.weld.junit5.WeldInitiator which is in class org.jboss.weld.junit5.auto.AutoConfigWithWeldSetupTest",
+                throwable.getMessage());
+      }
+    }
+  }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/auto/extension/AddedExtension.java b/junit5/src/test/java/org/jboss/weld/junit5/auto/extension/AddedExtension.java
index d00537c..a63e253 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/auto/extension/AddedExtension.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/auto/extension/AddedExtension.java
@@ -25,7 +25,7 @@ public class AddedExtension implements Extension {
 
     private static boolean enabled = false;
 
-    public void observePAT(@Observes AfterBeanDiscovery abd) {
+    public void observeABD(@Observes AfterBeanDiscovery abd) {
         enabled = true;
     }
 
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/basic/DisabledMethodsTest.java b/junit5/src/test/java/org/jboss/weld/junit5/basic/DisabledMethodsTest.java
index d23dcd1..1d4a27f 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/basic/DisabledMethodsTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/basic/DisabledMethodsTest.java
@@ -11,6 +11,7 @@ import org.junit.jupiter.api.MethodOrderer;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestMethodOrder;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -22,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  *
  * @author Matej Novotny
  */
+@Isolated
 @ExtendWith(WeldJunit5Extension.class)
 @TestMethodOrder(value = MethodOrderer.Alphanumeric.class) // enforces ordering of methods, required!
 public class DisabledMethodsTest {
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/AddBeanTest.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddBeanTest.java
index 2d6b883..c203eea 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/bean/AddBeanTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddBeanTest.java
@@ -37,6 +37,7 @@ import org.jboss.weld.junit5.WeldJunit5Extension;
 import org.jboss.weld.junit5.WeldSetup;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
 
@@ -44,6 +45,7 @@ import org.mockito.Mockito;
  *
  * @author Matej Novotny
  */
+@Isolated
 @ExtendWith(WeldJunit5Extension.class)
 public class AddBeanTest {
 
@@ -99,7 +101,7 @@ public class AddBeanTest {
         myService.doBusiness("Adalbert");
         Mockito.verify(myService, Mockito.atLeastOnce()).doBusiness(ArgumentMatchers.anyString());
 
-        // Test applicaction scoped bean
+        // Test application scoped bean
         assertEquals(weld.select(IdSupplier.class).get().getId(), weld.select(IdSupplier.class).get().getId());
 
         // The scope is changed to @Dependent
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java
index 76ffe07..3a09d1c 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java
@@ -7,6 +7,7 @@ import org.jboss.weld.junit5.WeldSetup;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
 import org.mockito.Mockito;
 
 import jakarta.enterprise.inject.spi.Bean;
@@ -20,6 +21,7 @@ import java.util.Set;
  *
  * @author Matej Novotny
  */
+@Isolated
 @ExtendWith(WeldJunit5Extension.class)
 public class AddGloballyEnabledAlternativeTest {
 
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/contexts/InvalidScopeTest.java b/junit5/src/test/java/org/jboss/weld/junit5/contexts/InvalidScopeTest.java
index ff43ab0..fcb1ec9 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/contexts/InvalidScopeTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/contexts/InvalidScopeTest.java
@@ -33,7 +33,7 @@ public class InvalidScopeTest {
     public void testFoo() {
         Assertions.assertThrows(IllegalArgumentException.class, () -> {
             // the container doesn't really even start here and it's not proper way to start it
-            // but it's suffiecient to check that only scopes can be activated
+            // but it's sufficient to check that only scopes can be activated
             WeldInitiator.from(Foo.class).activate(SomeAnnotation.class);
         });
     }
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/enricher/WeldJunitEnricherTest.java b/junit5/src/test/java/org/jboss/weld/junit5/enricher/WeldJunitEnricherTest.java
index a3e33fb..75ecfa4 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/enricher/WeldJunitEnricherTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/enricher/WeldJunitEnricherTest.java
@@ -17,14 +17,18 @@
 package org.jboss.weld.junit5.enricher;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.parallel.ResourceAccessMode.READ;
+import static org.junit.jupiter.api.parallel.Resources.SYSTEM_PROPERTIES;
 
 import jakarta.inject.Inject;
 
 import org.jboss.weld.junit5.EnableWeld;
 import org.jboss.weld.junit5.basic.Foo;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
 
 @EnableWeld
+@ResourceLock(value = SYSTEM_PROPERTIES, mode = READ)
 public class WeldJunitEnricherTest {
 
     @Inject
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/enricher/disabled/WeldJunitEnricherDisabledTest.java b/junit5/src/test/java/org/jboss/weld/junit5/enricher/disabled/WeldJunitEnricherDisabledTest.java
index 474a63c..934d444 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/enricher/disabled/WeldJunitEnricherDisabledTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/enricher/disabled/WeldJunitEnricherDisabledTest.java
@@ -17,6 +17,7 @@
 package org.jboss.weld.junit5.enricher.disabled;
 
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.parallel.Resources.SYSTEM_PROPERTIES;
 
 import jakarta.enterprise.inject.Instance;
 import jakarta.inject.Inject;
@@ -27,8 +28,10 @@ import org.jboss.weld.junit5.enricher.FooWeldJunitEnricher;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
 
 @EnableWeld
+@ResourceLock(SYSTEM_PROPERTIES)
 public class WeldJunitEnricherDisabledTest {
 
     @Inject
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/explicitInjection/ExplicitParameterInjectionViaPropertyTest.java b/junit5/src/test/java/org/jboss/weld/junit5/explicitInjection/ExplicitParameterInjectionViaPropertyTest.java
index 02eb835..1d1cdab 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/explicitInjection/ExplicitParameterInjectionViaPropertyTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/explicitInjection/ExplicitParameterInjectionViaPropertyTest.java
@@ -25,11 +25,13 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
 
 /**
  *
  * @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
  */
+@Isolated
 @EnableWeld
 public class ExplicitParameterInjectionViaPropertyTest {
 
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/ObjectWeldInitiatorTest.java b/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/ObjectWeldInitiatorTest.java
new file mode 100644
index 0000000..5d39aa5
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/ObjectWeldInitiatorTest.java
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2018, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.junit5.initiator.discovery;
+
+import org.jboss.weld.environment.se.Weld;
+import org.jboss.weld.junit5.EnableWeld;
+import org.jboss.weld.junit5.WeldInitiator;
+import org.jboss.weld.junit5.WeldSetup;
+import org.jboss.weld.junit5.initiator.bean.Foo;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests a case where WeldInitiator is an Object typed field
+ *
+ * @author Björn Kautler
+ */
+@EnableWeld
+public class ObjectWeldInitiatorTest {
+
+    @WeldSetup
+    public Object weld = WeldInitiator
+        .of(new Weld()
+            .addBeanClass(Foo.class));
+
+    @Test
+    public void testObjectWeldInit() {
+        final Foo foo = ((WeldInitiator) weld).select(Foo.class).get();
+        assertNotNull(foo);
+    }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/PrivateWeldInitiatorInSuperclassTest.java b/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/PrivateWeldInitiatorInSuperclassTest.java
index b44dca9..a770c4f 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/PrivateWeldInitiatorInSuperclassTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/initiator/discovery/PrivateWeldInitiatorInSuperclassTest.java
@@ -22,12 +22,14 @@ import org.jboss.weld.environment.se.WeldContainer;
 import org.jboss.weld.junit5.EnableWeld;
 import org.jboss.weld.junit5.initiator.bean.Foo;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
 
 /**
  * Tests a case where WeldInitiator resides in a private field within a superclass
  *
  * @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
  */
+@Isolated
 @EnableWeld
 public class PrivateWeldInitiatorInSuperclassTest extends SuperclassWithPrivateWeldInitiator {
 
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/testLifecycle/PerClassLifecycleTest.java b/junit5/src/test/java/org/jboss/weld/junit5/testLifecycle/PerClassLifecycleTest.java
index f6901c5..9e7ca68 100644
--- a/junit5/src/test/java/org/jboss/weld/junit5/testLifecycle/PerClassLifecycleTest.java
+++ b/junit5/src/test/java/org/jboss/weld/junit5/testLifecycle/PerClassLifecycleTest.java
@@ -25,18 +25,20 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
 
 /**
  * Note that we cannot be sure which method executes first - only one of them will do actual verification.
  *
  * @author <a href="mailto:manovotn@redhat.com">Matej Novotny</a>
  */
+@Isolated
 @ExtendWith(WeldJunit5Extension.class)
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 public class PerClassLifecycleTest {
 
     @WeldSetup
-    public WeldInitiator initiator = WeldInitiator.of(new Weld(String.valueOf(System.currentTimeMillis()))
+    public WeldInitiator initiator = WeldInitiator.of(new Weld(String.valueOf(System.nanoTime()))
         .disableDiscovery().addBeanClass(PlainBean.class));
 
     String containerId = null;
diff --git a/junit5/src/test/resources/junit-platform.properties b/junit5/src/test/resources/junit-platform.properties
new file mode 100644
index 0000000..f2ed301
--- /dev/null
+++ b/junit5/src/test/resources/junit-platform.properties
@@ -0,0 +1,3 @@
+junit.jupiter.execution.parallel.enabled = true
+junit.jupiter.execution.parallel.mode.default = concurrent
+junit.jupiter.execution.parallel.mode.classes.default = concurrent