diff --git a/glassfish-runner/jpa-platform-tck/src/test/resources/rest-arquillian.xml b/glassfish-runner/jpa-platform-tck/src/test/resources/rest-arquillian.xml
new file mode 100644
index 0000000000..fee0cc9a93
--- /dev/null
+++ b/glassfish-runner/jpa-platform-tck/src/test/resources/rest-arquillian.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ target/deployments
+
+
+ target/
+
+
+
+
+
+ target/glassfish8
+
+
+
+
+
diff --git a/glassfish-runner/persistence-platform-tck/pom.xml b/glassfish-runner/persistence-platform-tck/pom.xml
index 300cf75f87..fa068eb646 100644
--- a/glassfish-runner/persistence-platform-tck/pom.xml
+++ b/glassfish-runner/persistence-platform-tck/pom.xml
@@ -205,7 +205,13 @@
org.omnifaces.arquillian
arquillian-glassfish-server-managed
- 1.6
+ 1.7
+ test
+
+
+ org.omnifaces.arquillian
+ glassfish-client-ee11
+ 1.7.1
test
@@ -519,7 +525,27 @@
3.5.0
false
+ jakarta.tck:persistence-platform-tck-tests
+
+
+ ${project.build.directory}/${glassfish.toplevel.dir}
+ set server-config.network-config.protocols.protocol.http-listener-1.http.trace-enabled=true
+ create-file-user --groups guest --passwordfile ${project.basedir}/javajoe.pass javajoe
+ create-file-user --groups staff:mgr --passwordfile ${project.basedir}/j2ee.pass j2ee
+ create-jdbc-connection-pool --restype javax.sql.DataSource --datasourceclassname org.apache.derby.jdbc.ClientDataSource --property DatabaseName=derbyDB:serverName=localhost:portNumber=1527:user=cts1:password=cts1:connectionAttributes="create=true" --steadypoolsize 32 --maxpoolsize 64 cts-derby-pool
+ create-jdbc-connection-pool --restype javax.sql.DataSource --datasourceclassname org.apache.derby.jdbc.ClientDataSource --property DatabaseName=derbyDB:serverName=localhost:PortNumber=1527:User=cts1:Password=cts1 --steadypoolsize 32 --maxpoolsize 64 cts-derby-pool_no_tx
+ create-jdbc-resource --connectionpoolid cts-derby-pool jdbc/DB1
+ create-jdbc-resource --connectionpoolid cts-derby-pool_no_tx jdbc/DB_no_tx
+ list-jdbc-connection-pools
+ list-jdbc-resources
+ list-file-users
+ true
+ true
+ true
+ ${project.basedir}
+
+
jpa-tests-appclient
@@ -556,6 +582,24 @@
+
+
+ jpa-tests-cdi
+
+ integration-test
+ verify
+
+
+
+ ee/jakarta/tck/persistence/ee/cdi/*Test.java
+
+
+
+ rest-arquillian.xml
+
+
+
+
jta-tests-javatest
diff --git a/glassfish-runner/persistence-platform-tck/src/test/resources/arquillian.xml b/glassfish-runner/persistence-platform-tck/src/test/resources/arquillian.xml
index 5d2b3007fe..2c6c234782 100644
--- a/glassfish-runner/persistence-platform-tck/src/test/resources/arquillian.xml
+++ b/glassfish-runner/persistence-platform-tck/src/test/resources/arquillian.xml
@@ -7,7 +7,7 @@
target/deployments
- target/
+ target/
diff --git a/glassfish-runner/persistence-platform-tck/src/test/resources/rest-arquillian.xml b/glassfish-runner/persistence-platform-tck/src/test/resources/rest-arquillian.xml
new file mode 100644
index 0000000000..162892507d
--- /dev/null
+++ b/glassfish-runner/persistence-platform-tck/src/test/resources/rest-arquillian.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ target/deployments
+
+
+ target/
+
+
+
+
+
+ target/glassfish8
+
+
+
+
+
\ No newline at end of file
diff --git a/jpa/platform-tests/pom.xml b/jpa/platform-tests/pom.xml
index e46561b1d6..856f953f30 100644
--- a/jpa/platform-tests/pom.xml
+++ b/jpa/platform-tests/pom.xml
@@ -77,6 +77,15 @@
arquillian-protocol-common
${arquillian.jakarta.tck.version}
+
+
+ jakarta.enterprise
+ jakarta.enterprise.cdi-api
+
+
+ jakarta.ws.rs
+ jakarta.ws.rs-api
+
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEm2Qualifier.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEm2Qualifier.java
new file mode 100644
index 0000000000..5c8d20f255
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEm2Qualifier.java
@@ -0,0 +1,21 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.inject.Qualifier;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Qualifier for selecting the CTS-EM2 persistence unit.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+@Target({ FIELD, METHOD })
+public @interface CtsEm2Qualifier {
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmNoTxQualifier.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmNoTxQualifier.java
new file mode 100644
index 0000000000..4d17384411
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmNoTxQualifier.java
@@ -0,0 +1,21 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.inject.Qualifier;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Qualifier for selecting the CTS-EM persistence unit.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+@Target({ FIELD, METHOD })
+public @interface CtsEmNoTxQualifier {
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmQualifier.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmQualifier.java
new file mode 100644
index 0000000000..5f172e4d53
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/CtsEmQualifier.java
@@ -0,0 +1,21 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.inject.Qualifier;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Qualifier for selecting the CTS-EM persistence unit.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+@Target({ FIELD, METHOD })
+public @interface CtsEmQualifier {
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/JaxRsActivator.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/JaxRsActivator.java
new file mode 100644
index 0000000000..6e8e82fb20
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/JaxRsActivator.java
@@ -0,0 +1,9 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
+
+@ApplicationPath("/rest")
+public class JaxRsActivator extends Application {
+
+}
\ No newline at end of file
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/RestEndpoint.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/RestEndpoint.java
new file mode 100644
index 0000000000..6e1f31330e
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/RestEndpoint.java
@@ -0,0 +1,23 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+/**
+ * Called by test client using the arquillian rest protocol
+ */
+@Path("/cdi-jpa")
+public class RestEndpoint {
+ @Inject
+ TestBeanEM testBean;
+
+ @GET
+ @Path("/injectEmUsingQualifier")
+ public String injectEmUsingQualifier() throws Exception {
+ testBean.injectEmUsingQualifier();
+ return "PASSED";
+ }
+
+
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/ServletEMLookupTest.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/ServletEMLookupTest.java
new file mode 100644
index 0000000000..a265ed5b8b
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/ServletEMLookupTest.java
@@ -0,0 +1,76 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Response;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import tck.arquillian.porting.lib.spi.TestArchiveProcessor;
+
+import java.net.URI;
+import java.net.URL;
+
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+
+/**
+ * Test for EntityManager lookup via CDI
+ */
+@ExtendWith(ArquillianExtension.class)
+public class ServletEMLookupTest {
+ @ArquillianResource
+ URL contextPath;
+
+ @Deployment(name = "jpa-cdi-em-inject", testable = false)
+ public static WebArchive deployment(@ArquillianResource TestArchiveProcessor archiveProcessor) {
+ WebArchive war = ShrinkWrap.create(WebArchive.class)
+ .addClasses(CtsEmQualifier.class, CtsEm2Qualifier.class, CtsEmNoTxQualifier.class, JaxRsActivator.class,
+ TestBeanEM.class, RestEndpoint.class);
+
+ // Par
+ // the jar with the correct archive name
+ JavaArchive jpa_ee_entityManager = ShrinkWrap.create(JavaArchive.class, "jpa_ee_entityManager.jar");
+ // The class files
+ jpa_ee_entityManager.addClasses(
+ ee.jakarta.tck.persistence.ee.entityManager.Order.class
+ );
+ // The persistence.xml descriptor
+ URL parURL = ServletEMLookupTest.class.getResource("persistence.xml");
+ jpa_ee_entityManager.addAsManifestResource(parURL, "persistence.xml");
+ // Call the archive processor
+ archiveProcessor.processParArchive(jpa_ee_entityManager, ServletEMLookupTest.class, parURL);
+
+ // Web content
+ war.addAsLibrary(jpa_ee_entityManager);
+
+ // Call the archive processor
+ archiveProcessor.processWebArchive(war, ServletEMLookupTest.class, null);
+ return war;
+ }
+
+ /*
+ * @testName: injectEmUsingQualifierTest
+ *
+ * @assertion_ids: PERSISTENCE:JAVADOC:3318; PERSISTENCE:SPEC:1801;
+ * PERSISTENCE:SPEC:1804; PERSISTENCE:SPEC:1883.2;
+ *
+ * @test_Strategy: Inject an EntityManager using a qualifier and injection
+ */
+ @Test
+ public void injectEmUsingQualifierTest() throws Exception {
+ URI appIdURI = contextPath.toURI().resolve("rest/cdi-jpa/injectEmUsingQualifier");
+ final Client client = ClientBuilder.newBuilder().build();
+ final Response response = client.target(appIdURI)
+ .request(APPLICATION_JSON_TYPE)
+ .get();
+ int status = response.getStatus();
+ Assertions.assertEquals(200, status);
+ response.close();
+ }
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/TestBeanEM.java b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/TestBeanEM.java
new file mode 100644
index 0000000000..90ada4fab4
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/TestBeanEM.java
@@ -0,0 +1,70 @@
+package ee.jakarta.tck.persistence.ee.cdi;
+
+import jakarta.inject.Inject;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+
+import java.util.logging.Logger;
+
+/**
+ * A request scoped bean that uses the CTS-EM and CTS-EM-NOTX persistence units
+ */
+@RequestScoped
+public class TestBeanEM {
+ Logger logger = Logger.getLogger(TestBeanEM.class.getName());
+
+ //@PersistenceContext(unitName = "CTS-EM")
+ @CtsEmQualifier
+ @Inject
+ private EntityManager em1;
+ //@PersistenceContext(unitName = "CTS-EM2")
+ @CtsEmQualifier
+ @Inject
+ private EntityManager em2;
+
+ public void logMsg(String msg) {
+ logger.info(msg);
+ }
+ public void logTrace(String msg) {
+ logger.fine(msg);
+ }
+ public void logErr(String msg) {
+ logger.severe(msg);
+ }
+ public void logErr(String msg, Throwable e) {
+ logger.log(java.util.logging.Level.SEVERE, msg, e);
+ }
+
+ public void injectEmUsingQualifier() throws Exception {
+ boolean pass1 = false;
+ boolean pass2 = false;
+ try {
+ logMsg( "Test CtsEmNoTxQualifier");
+ if (em1 != null) {
+ logTrace( "Received non-null EntityManager");
+ pass1 = true;
+ } else {
+ logErr( "Received null EntityManager");
+ }
+ } catch (Exception e) {
+ logErr( "Received unexpected exception", e);
+ }
+ try {
+ logMsg( "Test CtsEmNoTxQualifier");
+ if (em2 != null) {
+ logTrace( "Received non-null EntityManager");
+ pass2 = true;
+ } else {
+ logErr( "Received null EntityManager");
+ }
+ } catch (Exception e) {
+ logErr( "Received unexpected exception", e);
+ }
+ if (!pass1 || !pass2) {
+ throw new Exception("createEntityManagerSynchronizationTypeMapTest failed");
+ }
+ logMsg( "Test PASSED");
+ }
+
+}
diff --git a/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/persistence.xml b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/persistence.xml
new file mode 100644
index 0000000000..cc16b22a9e
--- /dev/null
+++ b/jpa/platform-tests/src/main/java/ee/jakarta/tck/persistence/ee/cdi/persistence.xml
@@ -0,0 +1,46 @@
+
+
+
+
+ Persistence Unit for CTS Vehicle Tests
+ ee.jakarta.tck.persistence.ee.cdi.CtsEmQualifier
+ jdbc/DB1
+ ee.jakarta.tck.persistence.ee.entityManager.Order
+
+
+
+ Persistence Unit for CTS Vehicle Tests
+ ee.jakarta.tck.persistence.ee.cdi.CtsEm2Qualifier
+ jdbc/DB1
+ ee.jakarta.tck.persistence.ee.entityManager.Order
+
+
+
+ The persistence.xml file may be used to designate
+ more than one persistence unit within the same scope.
+ Persistence Unit for Application Managed Resource Local
+ jdbc/DB_no_tx
+ ee.jakarta.tck.persistence.ee.entityManager.Order
+
+
+