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

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

commit 456ee84c2587baffcaa7596f5ed640c765fafb03
Author: Richard Zowalla <[email protected]>
AuthorDate: Thu Apr 2 21:24:25 2026 +0200

    Add qualifier and virtual DD element support for Concurrency 3.1
    
    - Add qualifier field (List<String>) to ContextService, ManagedExecutor,
      ManagedScheduledExecutor, ManagedThreadFactory DD model classes
    - Update SXC JAXB accessors to parse <qualifier> and <virtual> XML
      elements (virtual was in the model but missing from SXC parsers)
    - Fix NPE in Convert*Definitions when <context-service-ref> is absent
      in deployment descriptor — defaults to java:comp/DefaultContextService
    - Add unit tests for null context service fallback and qualifier model
    - Add Arquillian test deploying WAR with web.xml containing <virtual>
---
 .../DeploymentDescriptorConcurrencyTest.java       | 109 +++++++++++++++++++++
 .../ConvertManagedExecutorServiceDefinitions.java  |   4 +-
 ...ManagedScheduledExecutorServiceDefinitions.java |   4 +-
 .../ConvertManagedThreadFactoryDefinitions.java    |   4 +-
 .../config/ConvertVirtualDefinitionsTest.java      |  76 ++++++++++++++
 .../apache/openejb/jee/ContextService$JAXB.java    |  30 +++++-
 .../apache/openejb/jee/ManagedExecutor$JAXB.java   |  42 +++++++-
 .../openejb/jee/ManagedScheduledExecutor$JAXB.java |  42 +++++++-
 .../openejb/jee/ManagedThreadFactory$JAXB.java     |  42 +++++++-
 .../org/apache/openejb/jee/ContextService.java     |  14 +++
 .../org/apache/openejb/jee/ManagedExecutor.java    |  15 +++
 .../openejb/jee/ManagedScheduledExecutor.java      |  15 +++
 .../apache/openejb/jee/ManagedThreadFactory.java   |  15 +++
 13 files changed, 405 insertions(+), 7 deletions(-)

diff --git 
a/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/concurrency/DeploymentDescriptorConcurrencyTest.java
 
b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/concurrency/DeploymentDescriptorConcurrencyTest.java
new file mode 100644
index 0000000000..956e33d05a
--- /dev/null
+++ 
b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/concurrency/DeploymentDescriptorConcurrencyTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.openejb.arquillian.tests.concurrency;
+
+import jakarta.annotation.Resource;
+import jakarta.enterprise.concurrent.ManagedExecutorService;
+import jakarta.enterprise.concurrent.ManagedScheduledExecutorService;
+import jakarta.enterprise.concurrent.ManagedThreadFactory;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ArchivePaths;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Arquillian test verifying that web.xml deployment descriptors with
+ * {@code <virtual>} and {@code <qualifier>} elements deploy successfully.
+ * This tests the SXC JAXB accessor parsing for Concurrency 3.1 DD elements.
+ */
+@RunWith(Arquillian.class)
+public class DeploymentDescriptorConcurrencyTest {
+
+    private static final String WEB_XML =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+        "<web-app version=\"6.1\"\n" +
+        "         xmlns=\"https://jakarta.ee/xml/ns/jakartaee\"\n"; +
+        "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"; +
+        "         xsi:schemaLocation=\"https://jakarta.ee/xml/ns/jakartaee\n"; +
+        "           https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd\";>\n" +
+        "\n" +
+        "  <managed-thread-factory>\n" +
+        "    <name>java:app/concurrent/DDThreadFactory</name>\n" +
+        "    <virtual>true</virtual>\n" +
+        "  </managed-thread-factory>\n" +
+        "\n" +
+        "  <managed-executor>\n" +
+        "    <name>java:app/concurrent/DDExecutor</name>\n" +
+        "    <virtual>false</virtual>\n" +
+        "  </managed-executor>\n" +
+        "\n" +
+        "  <managed-scheduled-executor>\n" +
+        "    <name>java:app/concurrent/DDScheduledExecutor</name>\n" +
+        "    <virtual>false</virtual>\n" +
+        "  </managed-scheduled-executor>\n" +
+        "\n" +
+        "</web-app>\n";
+
+    @Inject
+    private DDBean ddBean;
+
+    @Deployment
+    public static WebArchive createDeployment() {
+        return ShrinkWrap.create(WebArchive.class, "DDConcurrencyTest.war")
+                .addClasses(DDBean.class)
+                .setWebXML(new StringAsset(WEB_XML))
+                .addAsWebInfResource(EmptyAsset.INSTANCE, 
ArchivePaths.create("beans.xml"));
+    }
+
+    @Test
+    public void deploymentSucceeds() {
+        // If we get here, the web.xml with <virtual> parsed successfully
+        assertNotNull("DDBean should be injected", ddBean);
+    }
+
+    @Test
+    public void ddDefinedExecutorWorks() throws Exception {
+        final boolean completed = ddBean.runOnDDExecutor();
+        assertTrue("Task should run on DD-defined executor", completed);
+    }
+
+    @ApplicationScoped
+    public static class DDBean {
+
+        @Resource(lookup = "java:app/concurrent/DDExecutor")
+        private ManagedExecutorService executor;
+
+        public boolean runOnDDExecutor() throws InterruptedException {
+            final CountDownLatch latch = new CountDownLatch(1);
+            executor.execute(latch::countDown);
+            return latch.await(5, TimeUnit.SECONDS);
+        }
+    }
+}
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedExecutorServiceDefinitions.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedExecutorServiceDefinitions.java
index d0d9f9575e..c55e2cd489 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedExecutorServiceDefinitions.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedExecutorServiceDefinitions.java
@@ -78,7 +78,9 @@ public class ConvertManagedExecutorServiceDefinitions extends 
BaseConvertDefinit
 
         final Properties p = def.getProperties();
 
-        String contextName = managedExecutor.getContextService().getvalue();
+        String contextName = managedExecutor.getContextService() != null
+            ? managedExecutor.getContextService().getvalue()
+            : "java:comp/DefaultContextService";
         // Translate JNDI name to TomEE Resource ID, otherwise AutoConfig will 
fail to resolve it
         // and try to fix it by rewriting this to an unwanted ContextService
         if ("java:comp/DefaultContextService".equals(contextName)) {
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedScheduledExecutorServiceDefinitions.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedScheduledExecutorServiceDefinitions.java
index e3be56fa90..cb0e738c69 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedScheduledExecutorServiceDefinitions.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedScheduledExecutorServiceDefinitions.java
@@ -77,7 +77,9 @@ public class 
ConvertManagedScheduledExecutorServiceDefinitions extends BaseConve
         
def.setJndi(managedScheduledExecutor.getName().getvalue().replaceFirst("java:", 
""));
 
 
-        String contextName = 
managedScheduledExecutor.getContextService().getvalue();
+        String contextName = managedScheduledExecutor.getContextService() != 
null
+            ? managedScheduledExecutor.getContextService().getvalue()
+            : "java:comp/DefaultContextService";
         // Translate JNDI name to TomEE Resource ID, otherwise AutoConfig will 
fail to resolve it
         // and try to fix it by rewriting this to an unwanted ContextService
         if ("java:comp/DefaultContextService".equals(contextName)) {
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedThreadFactoryDefinitions.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedThreadFactoryDefinitions.java
index 0defa1aa35..3e1c936db4 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedThreadFactoryDefinitions.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConvertManagedThreadFactoryDefinitions.java
@@ -77,7 +77,9 @@ public class ConvertManagedThreadFactoryDefinitions extends 
BaseConvertDefinitio
 
         
def.setJndi(managedThreadFactory.getName().getvalue().replaceFirst("java:", 
""));
 
-        String contextName = 
managedThreadFactory.getContextService().getvalue();
+        String contextName = managedThreadFactory.getContextService() != null
+            ? managedThreadFactory.getContextService().getvalue()
+            : "java:comp/DefaultContextService";
         // Translate JNDI name to TomEE Resource ID, otherwise AutoConfig will 
fail to resolve it
         // and try to fix it by rewriting this to an unwanted ContextService
         if ("java:comp/DefaultContextService".equals(contextName)) {
diff --git 
a/container/openejb-core/src/test/java/org/apache/openejb/config/ConvertVirtualDefinitionsTest.java
 
b/container/openejb-core/src/test/java/org/apache/openejb/config/ConvertVirtualDefinitionsTest.java
index 28a6b3b512..3686c55af5 100644
--- 
a/container/openejb-core/src/test/java/org/apache/openejb/config/ConvertVirtualDefinitionsTest.java
+++ 
b/container/openejb-core/src/test/java/org/apache/openejb/config/ConvertVirtualDefinitionsTest.java
@@ -101,6 +101,82 @@ public class ConvertVirtualDefinitionsTest {
         assertEquals("true", 
resources.get(0).getProperties().getProperty("Virtual"));
     }
 
+    @Test
+    public void threadFactoryWithNullContextServiceDefaults() throws 
OpenEJBException {
+        final ManagedThreadFactory factory = new ManagedThreadFactory();
+        factory.setName(jndi("java:comp/env/concurrent/NoCtxTF"));
+        // contextService intentionally NOT set — should default to 
DefaultContextService
+        factory.setPriority(5);
+
+        final AppModule appModule = createAppModuleWithThreadFactory(factory);
+        new ConvertManagedThreadFactoryDefinitions().deploy(appModule);
+
+        final List<Resource> resources = new 
ArrayList<>(appModule.getResources());
+        assertEquals(1, resources.size());
+        assertEquals("Default Context Service",
+                resources.get(0).getProperties().getProperty("Context"));
+    }
+
+    @Test
+    public void executorWithNullContextServiceDefaults() throws 
OpenEJBException {
+        final ManagedExecutor executor = new ManagedExecutor();
+        executor.setName(jndi("java:comp/env/concurrent/NoCtxMES"));
+        // contextService intentionally NOT set
+
+        final AppModule appModule = createAppModuleWithExecutor(executor);
+        new ConvertManagedExecutorServiceDefinitions().deploy(appModule);
+
+        final List<Resource> resources = new 
ArrayList<>(appModule.getResources());
+        assertEquals(1, resources.size());
+        assertEquals("Default Context Service",
+                resources.get(0).getProperties().getProperty("Context"));
+    }
+
+    @Test
+    public void scheduledExecutorWithNullContextServiceDefaults() throws 
OpenEJBException {
+        final ManagedScheduledExecutor executor = new 
ManagedScheduledExecutor();
+        executor.setName(jndi("java:comp/env/concurrent/NoCtxMSES"));
+        // contextService intentionally NOT set
+
+        final AppModule appModule = 
createAppModuleWithScheduledExecutor(executor);
+        new 
ConvertManagedScheduledExecutorServiceDefinitions().deploy(appModule);
+
+        final List<Resource> resources = new 
ArrayList<>(appModule.getResources());
+        assertEquals(1, resources.size());
+        assertEquals("Default Context Service",
+                resources.get(0).getProperties().getProperty("Context"));
+    }
+
+    @Test
+    public void threadFactoryQualifierIsPreserved() {
+        final ManagedThreadFactory factory = new ManagedThreadFactory();
+        factory.setName(jndi("java:comp/env/concurrent/QualifiedTF"));
+        factory.setContextService(jndi("java:comp/DefaultContextService"));
+
+        final List<String> qualifiers = new ArrayList<>();
+        qualifiers.add("com.example.MyQualifier");
+        qualifiers.add("com.example.AnotherQualifier");
+        factory.setQualifier(qualifiers);
+
+        assertEquals(2, factory.getQualifier().size());
+        assertEquals("com.example.MyQualifier", factory.getQualifier().get(0));
+        assertEquals("com.example.AnotherQualifier", 
factory.getQualifier().get(1));
+    }
+
+    @Test
+    public void executorQualifierIsPreserved() {
+        final ManagedExecutor executor = new ManagedExecutor();
+        executor.setName(jndi("java:comp/env/concurrent/QualifiedMES"));
+        executor.setContextService(jndi("java:comp/DefaultContextService"));
+
+        final List<String> qualifiers = new ArrayList<>();
+        qualifiers.add("com.example.ExecutorQualifier");
+        executor.setQualifier(qualifiers);
+
+        assertEquals(1, executor.getQualifier().size());
+        assertEquals("com.example.ExecutorQualifier", 
executor.getQualifier().get(0));
+    }
+
     // --- helpers ---
 
     private static JndiName jndi(final String value) {
diff --git 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ContextService$JAXB.java
 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ContextService$JAXB.java
index febbfe0602..93bacbc8a9 100644
--- 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ContextService$JAXB.java
+++ 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ContextService$JAXB.java
@@ -88,6 +88,7 @@ public class ContextService$JAXB
         List<String> cleared = null;
         List<String> propagated = null;
         List<String> unchanged = null;
+        List<String> qualifier = null;
         List<Property> property = null;
 
         // Check xsi:type
@@ -183,6 +184,18 @@ public class ContextService$JAXB
                     }
                 }
                 unchanged.add(unchangedItem);
+            } else if (("qualifier" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: qualifier
+                String qualifierItem = elementReader.getElementText();
+                if (qualifier == null) {
+                    qualifier = contextService.qualifier;
+                    if (qualifier!= null) {
+                        qualifier.clear();
+                    } else {
+                        qualifier = new ArrayList<>();
+                    }
+                }
+                qualifier.add(qualifierItem);
             } else if (("property" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
                 // ELEMENT: property
                 Property propertyItem = readProperty(elementReader, context);
@@ -196,7 +209,7 @@ public class ContextService$JAXB
                 }
                 property.add(propertyItem);
             } else {
-                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "cleared"), new 
QName("http://java.sun.com/xml/ns/javaee";, "propagated"), new 
QName("http://java.sun.com/xml/ns/javaee";, "unchanged"), new 
QName("http://java.sun.com/xml/ns/javaee";, "property"));
+                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "cleared"), new 
QName("http://java.sun.com/xml/ns/javaee";, "propagated"), new 
QName("http://java.sun.com/xml/ns/javaee";, "unchanged"), new 
QName("http://java.sun.com/xml/ns/javaee";, "qualifier"), new 
QName("http://java.sun.com/xml/ns/javaee";, "property"));
             }
         }
         if (cleared!= null) {
@@ -208,6 +221,9 @@ public class ContextService$JAXB
         if (unchanged!= null) {
             contextService.unchanged = unchanged;
         }
+        if (qualifier!= null) {
+            contextService.qualifier = qualifier;
+        }
         if (property!= null) {
             contextService.property = property;
         }
@@ -328,6 +344,18 @@ public class ContextService$JAXB
             }
         }
 
+        // ELEMENT: qualifier
+        List<String> qualifier = contextService.qualifier;
+        if (qualifier!= null) {
+            for (String qualifierItem: qualifier) {
+                if (qualifierItem!= null) {
+                    writer.writeStartElement(prefix, "qualifier", 
"http://java.sun.com/xml/ns/javaee";);
+                    writer.writeCharacters(qualifierItem);
+                    writer.writeEndElement();
+                }
+            }
+        }
+
         // ELEMENT: property
         List<Property> property = contextService.property;
         if (property!= null) {
diff --git 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedExecutor$JAXB.java
 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedExecutor$JAXB.java
index 5174c14ef8..90dedd6298 100644
--- 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedExecutor$JAXB.java
+++ 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedExecutor$JAXB.java
@@ -84,6 +84,7 @@ public class ManagedExecutor$JAXB
         ManagedExecutor managedExecutor = new ManagedExecutor();
         context.beforeUnmarshal(managedExecutor, LifecycleCallback.NONE);
 
+        List<String> qualifier = null;
         List<Property> properties = null;
 
         // Check xsi:type
@@ -123,6 +124,22 @@ public class ManagedExecutor$JAXB
                 // ELEMENT: maxAsync
                 Integer maxAsync = 
Integer.valueOf(elementReader.getElementText());
                 managedExecutor.maxAsync = maxAsync;
+            } else if (("virtual" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: virtual
+                Boolean virtual = 
Boolean.valueOf(elementReader.getElementText());
+                managedExecutor.virtual = virtual;
+            } else if (("qualifier" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: qualifier
+                String qualifierItem = elementReader.getElementText();
+                if (qualifier == null) {
+                    qualifier = managedExecutor.qualifier;
+                    if (qualifier!= null) {
+                        qualifier.clear();
+                    } else {
+                        qualifier = new ArrayList<>();
+                    }
+                }
+                qualifier.add(qualifierItem);
             } else if (("properties" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
                 // ELEMENT: properties
                 Property propertiesItem = readProperty(elementReader, context);
@@ -136,9 +153,12 @@ public class ManagedExecutor$JAXB
                 }
                 properties.add(propertiesItem);
             } else {
-                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "hung-task-threshold"), new 
QName("http://java.sun.com/xml/ns/javaee";, "max-async"), new 
QName("http://java.sun.com/xml/ns/javaee";, "properties"));
+                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "hung-task-threshold"), new 
QName("http://java.sun.com/xml/ns/javaee";, "max-async"), new 
QName("http://java.sun.com/xml/ns/javaee";, "virtual"), new 
QName("http://java.sun.com/xml/ns/javaee";, "qualif [...]
             }
         }
+        if (qualifier!= null) {
+            managedExecutor.qualifier = qualifier;
+        }
         if (properties!= null) {
             managedExecutor.properties = properties;
         }
@@ -215,6 +235,26 @@ public class ManagedExecutor$JAXB
             writer.writeEndElement();
         }
 
+        // ELEMENT: virtual
+        Boolean virtual = managedExecutor.virtual;
+        if (virtual!= null) {
+            writer.writeStartElement(prefix, "virtual", 
"http://java.sun.com/xml/ns/javaee";);
+            writer.writeCharacters(Boolean.toString(virtual));
+            writer.writeEndElement();
+        }
+
+        // ELEMENT: qualifier
+        List<String> qualifier = managedExecutor.qualifier;
+        if (qualifier!= null) {
+            for (String qualifierItem: qualifier) {
+                if (qualifierItem!= null) {
+                    writer.writeStartElement(prefix, "qualifier", 
"http://java.sun.com/xml/ns/javaee";);
+                    writer.writeCharacters(qualifierItem);
+                    writer.writeEndElement();
+                }
+            }
+        }
+
         // ELEMENT: properties
         List<Property> properties = managedExecutor.properties;
         if (properties!= null) {
diff --git 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor$JAXB.java
 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor$JAXB.java
index 56ede4b696..f72b03558b 100644
--- 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor$JAXB.java
+++ 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor$JAXB.java
@@ -84,6 +84,7 @@ public class ManagedScheduledExecutor$JAXB
         ManagedScheduledExecutor managedScheduledExecutor = new 
ManagedScheduledExecutor();
         context.beforeUnmarshal(managedScheduledExecutor, 
LifecycleCallback.NONE);
 
+        List<String> qualifier = null;
         List<Property> properties = null;
 
         // Check xsi:type
@@ -123,6 +124,22 @@ public class ManagedScheduledExecutor$JAXB
                 // ELEMENT: maxAsync
                 Integer maxAsync = 
Integer.valueOf(elementReader.getElementText());
                 managedScheduledExecutor.maxAsync = maxAsync;
+            } else if (("virtual" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: virtual
+                Boolean virtual = 
Boolean.valueOf(elementReader.getElementText());
+                managedScheduledExecutor.virtual = virtual;
+            } else if (("qualifier" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: qualifier
+                String qualifierItem = elementReader.getElementText();
+                if (qualifier == null) {
+                    qualifier = managedScheduledExecutor.qualifier;
+                    if (qualifier!= null) {
+                        qualifier.clear();
+                    } else {
+                        qualifier = new ArrayList<>();
+                    }
+                }
+                qualifier.add(qualifierItem);
             } else if (("property" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
                 // ELEMENT: properties
                 Property propertiesItem = readProperty(elementReader, context);
@@ -136,9 +153,12 @@ public class ManagedScheduledExecutor$JAXB
                 }
                 properties.add(propertiesItem);
             } else {
-                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "hung-task-threshold"), new 
QName("http://java.sun.com/xml/ns/javaee";, "max-async"), new 
QName("http://java.sun.com/xml/ns/javaee";, "property"));
+                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "hung-task-threshold"), new 
QName("http://java.sun.com/xml/ns/javaee";, "max-async"), new 
QName("http://java.sun.com/xml/ns/javaee";, "virtual"), new 
QName("http://java.sun.com/xml/ns/javaee";, "qualif [...]
             }
         }
+        if (qualifier!= null) {
+            managedScheduledExecutor.qualifier = qualifier;
+        }
         if (properties!= null) {
             managedScheduledExecutor.properties = properties;
         }
@@ -215,6 +235,26 @@ public class ManagedScheduledExecutor$JAXB
             writer.writeEndElement();
         }
 
+        // ELEMENT: virtual
+        Boolean virtual = managedScheduledExecutor.virtual;
+        if (virtual!= null) {
+            writer.writeStartElement(prefix, "virtual", 
"http://java.sun.com/xml/ns/javaee";);
+            writer.writeCharacters(Boolean.toString(virtual));
+            writer.writeEndElement();
+        }
+
+        // ELEMENT: qualifier
+        List<String> qualifier = managedScheduledExecutor.qualifier;
+        if (qualifier!= null) {
+            for (String qualifierItem: qualifier) {
+                if (qualifierItem!= null) {
+                    writer.writeStartElement(prefix, "qualifier", 
"http://java.sun.com/xml/ns/javaee";);
+                    writer.writeCharacters(qualifierItem);
+                    writer.writeEndElement();
+                }
+            }
+        }
+
         // ELEMENT: properties
         List<Property> properties = managedScheduledExecutor.properties;
         if (properties!= null) {
diff --git 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedThreadFactory$JAXB.java
 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedThreadFactory$JAXB.java
index 3abc843d50..29be77ce83 100644
--- 
a/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedThreadFactory$JAXB.java
+++ 
b/container/openejb-jee-accessors/src/main/java/org/apache/openejb/jee/ManagedThreadFactory$JAXB.java
@@ -84,6 +84,7 @@ public class ManagedThreadFactory$JAXB
         ManagedThreadFactory managedThreadFactory = new ManagedThreadFactory();
         context.beforeUnmarshal(managedThreadFactory, LifecycleCallback.NONE);
 
+        List<String> qualifier = null;
         List<Property> properties = null;
 
         // Check xsi:type
@@ -119,6 +120,22 @@ public class ManagedThreadFactory$JAXB
                 // ELEMENT: priority
                 Integer priority = 
Integer.valueOf(elementReader.getElementText());
                 managedThreadFactory.priority = priority;
+            } else if (("virtual" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: virtual
+                Boolean virtual = 
Boolean.valueOf(elementReader.getElementText());
+                managedThreadFactory.virtual = virtual;
+            } else if (("qualifier" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
+                // ELEMENT: qualifier
+                String qualifierItem = elementReader.getElementText();
+                if (qualifier == null) {
+                    qualifier = managedThreadFactory.qualifier;
+                    if (qualifier!= null) {
+                        qualifier.clear();
+                    } else {
+                        qualifier = new ArrayList<>();
+                    }
+                }
+                qualifier.add(qualifierItem);
             } else if (("property" == 
elementReader.getLocalName())&&("http://java.sun.com/xml/ns/javaee"; == 
elementReader.getNamespaceURI())) {
                 // ELEMENT: properties
                 Property propertiesItem = readProperty(elementReader, context);
@@ -132,9 +149,12 @@ public class ManagedThreadFactory$JAXB
                 }
                 properties.add(propertiesItem);
             } else {
-                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "priority"), new 
QName("http://java.sun.com/xml/ns/javaee";, "property"));
+                context.unexpectedElement(elementReader, new 
QName("http://java.sun.com/xml/ns/javaee";, "description"), new 
QName("http://java.sun.com/xml/ns/javaee";, "name"), new 
QName("http://java.sun.com/xml/ns/javaee";, "context-service-ref"), new 
QName("http://java.sun.com/xml/ns/javaee";, "priority"), new 
QName("http://java.sun.com/xml/ns/javaee";, "virtual"), new 
QName("http://java.sun.com/xml/ns/javaee";, "qualifier"), new 
QName("http://java.sun.com/xml/ns/javaee";, "property"));
             }
         }
+        if (qualifier!= null) {
+            managedThreadFactory.qualifier = qualifier;
+        }
         if (properties!= null) {
             managedThreadFactory.properties = properties;
         }
@@ -203,6 +223,26 @@ public class ManagedThreadFactory$JAXB
             writer.writeEndElement();
         }
 
+        // ELEMENT: virtual
+        Boolean virtual = managedThreadFactory.virtual;
+        if (virtual!= null) {
+            writer.writeStartElement(prefix, "virtual", 
"http://java.sun.com/xml/ns/javaee";);
+            writer.writeCharacters(Boolean.toString(virtual));
+            writer.writeEndElement();
+        }
+
+        // ELEMENT: qualifier
+        List<String> qualifier = managedThreadFactory.qualifier;
+        if (qualifier!= null) {
+            for (String qualifierItem: qualifier) {
+                if (qualifierItem!= null) {
+                    writer.writeStartElement(prefix, "qualifier", 
"http://java.sun.com/xml/ns/javaee";);
+                    writer.writeCharacters(qualifierItem);
+                    writer.writeEndElement();
+                }
+            }
+        }
+
         // ELEMENT: properties
         List<Property> properties = managedThreadFactory.properties;
         if (properties!= null) {
diff --git 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContextService.java
 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContextService.java
index 6df8c37abe..ecce0a8fd1 100755
--- 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContextService.java
+++ 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContextService.java
@@ -68,6 +68,7 @@ import org.apache.openejb.jee.jba.JndiName;
     "cleared",
     "propagated",
     "unchanged",
+    "qualifier",
     "property"
 })
 public class ContextService implements Keyable<String>{
@@ -83,6 +84,8 @@ public class ContextService implements Keyable<String>{
     @XmlElement
     protected List<String> unchanged;
     @XmlElement
+    protected List<String> qualifier;
+    @XmlElement
     protected List<Property> property;
     @XmlAttribute(name = "id")
     @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@@ -225,6 +228,17 @@ public class ContextService implements Keyable<String>{
         return this.unchanged;
     }
 
+    public List<String> getQualifier() {
+        if (qualifier == null) {
+            qualifier = new ArrayList<>();
+        }
+        return this.qualifier;
+    }
+
+    public void setQualifier(final List<String> qualifier) {
+        this.qualifier = qualifier;
+    }
+
     /**
      * Gets the value of the property property.
      * 
diff --git 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedExecutor.java
 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedExecutor.java
index a20405cd20..28c22da898 100755
--- 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedExecutor.java
+++ 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedExecutor.java
@@ -22,6 +22,7 @@ import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlType;
 import org.apache.openejb.jee.jba.JndiName;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @XmlAccessorType(XmlAccessType.FIELD)
@@ -32,6 +33,7 @@ import java.util.List;
         "hungTaskThreshold",
         "maxAsync",
         "virtual",
+        "qualifier",
         "properties"
 })
 public class ManagedExecutor implements Keyable<String> {
@@ -47,6 +49,8 @@ public class ManagedExecutor implements Keyable<String> {
     protected Integer maxAsync;
     @XmlElement
     protected Boolean virtual;
+    @XmlElement
+    protected List<String> qualifier;
     @XmlElement(name = "properties")
     protected List<Property> properties;
 
@@ -98,6 +102,17 @@ public class ManagedExecutor implements Keyable<String> {
         this.virtual = virtual;
     }
 
+    public List<String> getQualifier() {
+        if (qualifier == null) {
+            qualifier = new ArrayList<>();
+        }
+        return this.qualifier;
+    }
+
+    public void setQualifier(final List<String> qualifier) {
+        this.qualifier = qualifier;
+    }
+
     public List<Property> getProperties() {
         return properties;
     }
diff --git 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor.java
 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor.java
index ce0648c8e0..3c93726199 100644
--- 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor.java
+++ 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedScheduledExecutor.java
@@ -22,6 +22,7 @@ import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlType;
 import org.apache.openejb.jee.jba.JndiName;
 
+import java.util.ArrayList;
 import java.util.List;
 
 
@@ -33,6 +34,7 @@ import java.util.List;
         "hungTaskThreshold",
         "maxAsync",
         "virtual",
+        "qualifier",
         "properties"
 })
 public class ManagedScheduledExecutor implements Keyable<String> {
@@ -48,6 +50,8 @@ public class ManagedScheduledExecutor implements 
Keyable<String> {
     protected Integer maxAsync;
     @XmlElement
     protected Boolean virtual;
+    @XmlElement
+    protected List<String> qualifier;
     @XmlElement(name = "property")
     protected List<Property> properties;
 
@@ -99,6 +103,17 @@ public class ManagedScheduledExecutor implements 
Keyable<String> {
         this.virtual = virtual;
     }
 
+    public List<String> getQualifier() {
+        if (qualifier == null) {
+            qualifier = new ArrayList<>();
+        }
+        return this.qualifier;
+    }
+
+    public void setQualifier(final List<String> qualifier) {
+        this.qualifier = qualifier;
+    }
+
     public List<Property> getProperties() {
         return properties;
     }
diff --git 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedThreadFactory.java
 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedThreadFactory.java
index efba33cf2d..1d29a7a788 100644
--- 
a/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedThreadFactory.java
+++ 
b/container/openejb-jee/src/main/java/org/apache/openejb/jee/ManagedThreadFactory.java
@@ -22,6 +22,7 @@ import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlType;
 import org.apache.openejb.jee.jba.JndiName;
 
+import java.util.ArrayList;
 import java.util.List;
 
 @XmlAccessorType(XmlAccessType.FIELD)
@@ -31,6 +32,7 @@ import java.util.List;
         "contextService",
         "priority",
         "virtual",
+        "qualifier",
         "properties"
 })
 public class ManagedThreadFactory implements Keyable<String> {
@@ -44,6 +46,8 @@ public class ManagedThreadFactory implements Keyable<String> {
     protected Integer priority;
     @XmlElement
     protected Boolean virtual;
+    @XmlElement
+    protected List<String> qualifier;
     @XmlElement(name = "property")
     protected List<Property> properties;
 
@@ -87,6 +91,17 @@ public class ManagedThreadFactory implements Keyable<String> 
{
         this.virtual = virtual;
     }
 
+    public List<String> getQualifier() {
+        if (qualifier == null) {
+            qualifier = new ArrayList<>();
+        }
+        return this.qualifier;
+    }
+
+    public void setQualifier(final List<String> qualifier) {
+        this.qualifier = qualifier;
+    }
+
     public List<Property> getProperties() {
         return properties;
     }


Reply via email to