This is an automated email from the ASF dual-hosted git repository.

rzo1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomee.git


The following commit(s) were added to refs/heads/main by this push:
     new 7630819041 TOMEE-4714 - Allow to restart the TomEE embedded runner and 
add a container lifecycle mode to the JUnit 5 extension (#2956)
7630819041 is described below

commit 763081904193fb73e418c475d290a2296f908359
Author: Richard Zowalla <[email protected]>
AuthorDate: Mon Sep 28 20:35:42 2026 +0200

    TOMEE-4714 - Allow to restart the TomEE embedded runner and add a container 
lifecycle mode to the JUnit 5 extension (#2956)
    
    TomEEEmbeddedApplicationRunner#close() did not reset the started flag, so 
the runner could not be started again. The JUnit 5 extension closes the 
container after each test (class), so only the first container start of a JVM 
worked.
    
    @RunWithTomEEEmbedded now has a mode (PER_JVM, PER_ALL, PER_EACH, AUTO) 
similar to @RunWithApplicationComposer and is @Inherited like it. AUTO keeps 
the current behaviour and follows the lifecycle of the test instance.
    
    TomEEEmbeddedBase got a start(Class) overload, as there is no test instance 
yet if the container is started for a test class.
---
 tomee/tomee-embedded/pom.xml                       | 38 +++++++++++
 .../embedded/TomEEEmbeddedApplicationRunner.java   |  1 +
 .../tomee/embedded/junit/TomEEEmbeddedBase.java    |  6 +-
 .../embedded/junit/jupiter/ExtensionMode.java      | 47 +++++++++++++
 .../junit/jupiter/RunWithTomEEEmbedded.java        |  6 ++
 .../junit/jupiter/TomEEEmbeddedExtension.java      | 58 +++++++++++++----
 .../AutoPerClassRunnerExtensionModeTest.java       | 76 ++++++++++++++++++++++
 .../embedded/AutoRunnerExtensionModeTest.java      | 74 +++++++++++++++++++++
 .../embedded/PerAllRunnerExtensionModeTest.java    | 75 +++++++++++++++++++++
 .../embedded/PerEachRunnerExtensionModeTest.java   | 75 +++++++++++++++++++++
 .../PerJvmOtherRunnerExtensionModeTest.java        | 73 +++++++++++++++++++++
 .../embedded/PerJvmRunnerExtensionModeTest.java    | 75 +++++++++++++++++++++
 .../tomee/embedded/RunnerExtensionModeApp.java}    | 25 +++----
 13 files changed, 603 insertions(+), 26 deletions(-)

diff --git a/tomee/tomee-embedded/pom.xml b/tomee/tomee-embedded/pom.xml
index 4641d6d2b2..0863805785 100644
--- a/tomee/tomee-embedded/pom.xml
+++ b/tomee/tomee-embedded/pom.xml
@@ -226,6 +226,7 @@
                 <exclude>**/SingleInstanceRunnerExtensionTest*</exclude>
                 <exclude>**/NoScannerSingleRunnerTest*</exclude>
                 <exclude>**/NoScannerSingleRunnerExtensionTest*</exclude>
+                <exclude>**/*RunnerExtensionModeTest*</exclude>
               </excludes>
             </configuration>
           </execution>
@@ -243,6 +244,43 @@
               </systemPropertyVariables>
             </configuration>
           </execution>
+          <execution>
+            <id>junit5-extension-modes</id>
+            <goals>
+              <goal>test</goal>
+            </goals>
+            <configuration>
+              <!-- the test classes need to share the JVM to start the 
container more than once / to share it -->
+              <forkCount>1</forkCount>
+              <reuseForks>true</reuseForks>
+              <includes>
+                <include>**/*RunnerExtensionModeTest*</include>
+              </includes>
+              <excludes>
+                <exclude>**/PerJvm*RunnerExtensionModeTest*</exclude>
+              </excludes>
+              <systemPropertyVariables>
+                
<tomee.application-composer.application>org.apache.tomee.embedded.RunnerExtensionModeApp</tomee.application-composer.application>
+              </systemPropertyVariables>
+            </configuration>
+          </execution>
+          <execution>
+            <id>junit5-extension-mode-per-jvm</id>
+            <goals>
+              <goal>test</goal>
+            </goals>
+            <configuration>
+              <!-- the test classes need to share the JVM to start the 
container more than once / to share it -->
+              <forkCount>1</forkCount>
+              <reuseForks>true</reuseForks>
+              <includes>
+                <include>**/PerJvm*RunnerExtensionModeTest*</include>
+              </includes>
+              <systemPropertyVariables>
+                
<tomee.application-composer.application>org.apache.tomee.embedded.RunnerExtensionModeApp</tomee.application-composer.application>
+              </systemPropertyVariables>
+            </configuration>
+          </execution>
           <execution>
             <id>single-server-custom-scanning</id>
             <goals>
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/TomEEEmbeddedApplicationRunner.java
 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/TomEEEmbeddedApplicationRunner.java
index 16a1082a1e..3c1b170f58 100644
--- 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/TomEEEmbeddedApplicationRunner.java
+++ 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/TomEEEmbeddedApplicationRunner.java
@@ -378,6 +378,7 @@ public class TomEEEmbeddedApplicationRunner implements 
AutoCloseable {
             SHUTDOWN_TASKS.remove(hook);
             hook = null;
             app = null;
+            started = false; // allow to start again, e.g. for the next test
         }
     }
 
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/TomEEEmbeddedBase.java
 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/TomEEEmbeddedBase.java
index cebd265c94..a6ee1ead50 100644
--- 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/TomEEEmbeddedBase.java
+++ 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/TomEEEmbeddedBase.java
@@ -27,7 +27,11 @@ public class TomEEEmbeddedBase {
     private static final AtomicReference<TomEEEmbeddedApplicationRunner> 
RUNNER = new AtomicReference<>();
 
     public void start(final Object marker) throws Exception {
-        getRunner().start(marker.getClass(), (Properties) null);
+        start(marker.getClass());
+    }
+
+    public void start(final Class<?> marker) throws Exception {
+        getRunner().start(marker, (Properties) null);
     }
 
     public void close() {
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/ExtensionMode.java
 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/ExtensionMode.java
new file mode 100644
index 0000000000..cc92a1535a
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/ExtensionMode.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded.junit.jupiter;
+
+/**
+ * The lifecycle of the TomEE embedded container used by {@link 
RunWithTomEEEmbedded}.
+ * <p>
+ * It offers the same modes as the {@code ExtensionMode} of {@code 
@RunWithApplicationComposer} (openejb-junit5).
+ * A single container is used per JVM, so tests sharing a JVM must not be 
executed in parallel.
+ */
+public enum ExtensionMode {
+
+    /**
+     * When using this mode, a container instance will be created once for the 
JVM lifetime.
+     */
+    PER_JVM,
+
+    /**
+     * When using this mode, a container instance will be created for each 
test class.
+     */
+    PER_ALL,
+
+    /**
+     * When using this mode, a container instance will be created for each 
test.
+     */
+    PER_EACH,
+
+    /**
+     * When using this mode, the container lifecycle follows the lifecycle of 
the test instance:
+     * {@link #PER_ALL} for {@code TestInstance.Lifecycle.PER_CLASS}, {@link 
#PER_EACH} otherwise.
+     */
+    AUTO
+}
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
index 79bf10560e..d4c3ba5d87 100644
--- 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
+++ 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
@@ -20,13 +20,19 @@ package org.apache.tomee.embedded.junit.jupiter;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+@Inherited
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 
@ExtendWith(org.apache.tomee.embedded.junit.jupiter.TomEEEmbeddedExtension.class)
 public @interface RunWithTomEEEmbedded {
 
+    /**
+     * The test container lifecycle <em>mode</em> to use.
+     */
+    ExtensionMode mode() default ExtensionMode.AUTO;
 }
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/TomEEEmbeddedExtension.java
 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/TomEEEmbeddedExtension.java
index 106555fb90..db1ecd3c42 100644
--- 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/TomEEEmbeddedExtension.java
+++ 
b/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/TomEEEmbeddedExtension.java
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.extension.BeforeAllCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.api.extension.TestInstances;
+import org.junit.platform.commons.util.AnnotationUtils;
 
 import java.util.List;
 
@@ -32,34 +33,53 @@ public class TomEEEmbeddedExtension implements 
BeforeAllCallback, AfterAllCallba
 
     private static final TomEEEmbeddedBase BASE = new TomEEEmbeddedBase();
 
+    // the container of PER_JVM is never closed, so the other modes can't be 
used once it is started
+    private static volatile boolean perJvm;
+
     @Override
-    public void afterAll(ExtensionContext context) {
-        if (isPerClass(context)) {
-            BASE.close();
+    public void beforeAll(final ExtensionContext context) throws Exception {
+        final ExtensionMode mode = getMode(context);
+        validate(mode);
+
+        if (mode != ExtensionMode.PER_EACH) {
+            BASE.start(context.getRequiredTestClass());
+            if (mode == ExtensionMode.PER_JVM) {
+                perJvm = true;
+            }
+            if (isPerClass(context)) {
+                doInject(context);
+            }
         }
     }
 
     @Override
-    public void beforeAll(ExtensionContext context) throws Exception {
+    public void afterAll(final ExtensionContext context) {
+        if (getMode(context) == ExtensionMode.PER_ALL) {
+            BASE.close();
+        }
+    }
 
-        if (isPerClass(context)) {
-            BASE.start(context.getRequiredTestInstance());
+    @Override
+    public void beforeEach(final ExtensionContext context) throws Exception {
+        final boolean perEach = getMode(context) == ExtensionMode.PER_EACH;
+        if (perEach) {
+            BASE.start(context.getRequiredTestClass());
+        }
+        if (perEach || !isPerClass(context)) {
             doInject(context);
         }
     }
 
     @Override
-    public void afterEach(ExtensionContext context) throws Exception {
-        if (!isPerClass(context)) {
+    public void afterEach(final ExtensionContext context) {
+        if (getMode(context) == ExtensionMode.PER_EACH) {
             BASE.close();
         }
     }
 
-    @Override
-    public void beforeEach(ExtensionContext context) throws Exception {
-        if (!isPerClass(context)) {
-            BASE.start(context.getRequiredTestInstance());
-            doInject(context);
+    private void validate(final ExtensionMode mode) {
+        if (perJvm && mode != ExtensionMode.PER_JVM) {
+            throw new OpenEJBRuntimeException("Cannot run PER_JVM in 
combination with PER_ALL, PER_EACH or AUTO");
         }
     }
 
@@ -78,6 +98,18 @@ public class TomEEEmbeddedExtension implements 
BeforeAllCallback, AfterAllCallba
         });
     }
 
+    // resolves AUTO to the mode matching the lifecycle of the test instance
+    ExtensionMode getMode(final ExtensionContext context) {
+        final ExtensionMode mode = context.getTestClass()
+                .flatMap(test -> AnnotationUtils.findAnnotation(test, 
RunWithTomEEEmbedded.class))
+                .map(RunWithTomEEEmbedded::mode)
+                .orElse(ExtensionMode.AUTO);
+        if (mode == ExtensionMode.AUTO) {
+            return isPerClass(context) ? ExtensionMode.PER_ALL : 
ExtensionMode.PER_EACH;
+        }
+        return mode;
+    }
+
     boolean isPerClass(final ExtensionContext context) {
         return context.getTestInstanceLifecycle()
                 .map(it -> it.equals(TestInstance.Lifecycle.PER_CLASS))
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoPerClassRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoPerClassRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..a1c4802ab9
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoPerClassRunnerExtensionModeTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container follows the lifecycle of the test instance, so it is started 
once for the test class
+@RunWithTomEEEmbedded
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class AutoPerClassRunnerExtensionModeTest {
+    // an application instance is created for each container start
+    private static final Set<Object> APPLICATIONS = 
Collections.newSetFromMap(new IdentityHashMap<>());
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(1, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..3ec373e9c9
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/AutoRunnerExtensionModeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container follows the lifecycle of the test instance, so it is started 
for each test
+@RunWithTomEEEmbedded
+public class AutoRunnerExtensionModeTest {
+    // an application instance is created for each container start
+    private static final Set<Object> APPLICATIONS = 
Collections.newSetFromMap(new IdentityHashMap<>());
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(3, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerAllRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerAllRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..cd020237ab
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerAllRunnerExtensionModeTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.ExtensionMode;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container is started once for the test class
+@RunWithTomEEEmbedded(mode = ExtensionMode.PER_ALL)
+public class PerAllRunnerExtensionModeTest {
+    // an application instance is created for each container start
+    private static final Set<Object> APPLICATIONS = 
Collections.newSetFromMap(new IdentityHashMap<>());
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(1, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerEachRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerEachRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..140c85d33b
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerEachRunnerExtensionModeTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.ExtensionMode;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container is started for each test
+@RunWithTomEEEmbedded(mode = ExtensionMode.PER_EACH)
+public class PerEachRunnerExtensionModeTest {
+    // an application instance is created for each container start
+    private static final Set<Object> APPLICATIONS = 
Collections.newSetFromMap(new IdentityHashMap<>());
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(3, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmOtherRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmOtherRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..375d8e4520
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmOtherRunnerExtensionModeTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.ExtensionMode;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container is started once for the JVM and shared with 
PerJvmRunnerExtensionModeTest
+@RunWithTomEEEmbedded(mode = ExtensionMode.PER_JVM)
+public class PerJvmOtherRunnerExtensionModeTest {
+    // shared with PerJvmRunnerExtensionModeTest as both tests use the same 
container
+    private static final Set<Object> APPLICATIONS = 
PerJvmRunnerExtensionModeTest.APPLICATIONS;
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(1, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmRunnerExtensionModeTest.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmRunnerExtensionModeTest.java
new file mode 100644
index 0000000000..9181142665
--- /dev/null
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/PerJvmRunnerExtensionModeTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.tomee.embedded;
+
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.RandomPort;
+import org.apache.tomee.embedded.junit.jupiter.ExtensionMode;
+import org.apache.tomee.embedded.junit.jupiter.RunWithTomEEEmbedded;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+// the container is started once for the JVM and shared with 
PerJvmOtherRunnerExtensionModeTest
+@RunWithTomEEEmbedded(mode = ExtensionMode.PER_JVM)
+public class PerJvmRunnerExtensionModeTest {
+    // an application instance is created for each container start
+    static final Set<Object> APPLICATIONS = Collections.newSetFromMap(new 
IdentityHashMap<>());
+
+    @Application
+    private RunnerExtensionModeApp app;
+
+    @RandomPort("http")
+    private int port;
+
+    @Test
+    public void first() {
+        assertStarted();
+    }
+
+    @Test
+    public void second() {
+        assertStarted();
+    }
+
+    @Test
+    public void third() {
+        assertStarted();
+    }
+
+    @AfterAll
+    public static void containers() {
+        assertEquals(1, APPLICATIONS.size());
+    }
+
+    private void assertStarted() {
+        assertNotNull(SystemInstance.get().getComponent(Assembler.class));
+        assertNotNull(app);
+        assertNotEquals(0, app.getPort());
+        assertEquals(app.getPort(), port);
+        APPLICATIONS.add(app);
+    }
+}
diff --git 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/RunnerExtensionModeApp.java
similarity index 64%
copy from 
tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
copy to 
tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/RunnerExtensionModeApp.java
index 79bf10560e..785b514ab6 100644
--- 
a/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/junit/jupiter/RunWithTomEEEmbedded.java
+++ 
b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/RunnerExtensionModeApp.java
@@ -14,19 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.tomee.embedded;
 
-package org.apache.tomee.embedded.junit.jupiter;
+import org.apache.openejb.testing.Application;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.RandomPort;
 
-import org.junit.jupiter.api.extension.ExtendWith;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@ExtendWith(org.apache.tomee.embedded.junit.jupiter.TomEEEmbeddedExtension.class)
-public @interface RunWithTomEEEmbedded {
+// the application of the *RunnerExtensionModeTest, selected by the surefire 
execution
+@Application
+@Classes(context = "app")
+public class RunnerExtensionModeApp {
+    @RandomPort("http")
+    private int port;
 
+    public int getPort() {
+        return port;
+    }
 }

Reply via email to