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 c3872d2600 TOMEE-4570 / TOMEE-4566 - XBean 4.30 (#2417)
c3872d2600 is described below

commit c3872d2600bc97cdcf70cd7d1a80ecd000a8e668
Author: Richard Zowalla <[email protected]>
AuthorDate: Wed Jan 21 15:08:31 2026 +0100

    TOMEE-4570 / TOMEE-4566 - XBean 4.30 (#2417)
    
    * XBean 4.30-SNAPSHOT
    
    * Explicitly set the datasource ctor arg types for datasources
    
    * Explicitly set the ctor arg types for jms queue
    
    * Revert explicit declaration of constructor arg types
    
    * fix syntax
    
    * configurable constructor-types for ServiceProvider
    
    * Add missing constructor-types parsing
    
    * Implement constructor-types matching for geronimo transaction manager case
    
    * Additional change to restore previous implicit behaviour if arg types are 
NOT set
    
    * Add types for unmanaged datasource
    
    * define constructor arg types where arg name selection was used before
    
    * Don't store complex class type in ServiceInfo
    
    documented in OpenEjbConfigurationValidationTest
    
    * support constructor-types for uri definitions and xml
    
    * fix URLAsResourceTest
    
    * Update documentation
    
    * Set ctor arguments in ServiceManager
    
    * Set ctor arguments in FlushableDataSourceHandler
    
    * Remove outcommented code
    
    * Use XBEAN 4.30 release artifact
    
    ---------
    
    Co-authored-by: Markus Jung <[email protected]>
---
 boms/tomee-microprofile/pom.xml                    |  10 +-
 boms/tomee-plume/pom.xml                           |  10 +-
 boms/tomee-plus/pom.xml                            |  10 +-
 boms/tomee-webprofile/pom.xml                      |  10 +-
 .../openejb/assembler/classic/Assembler.java       |  42 +-
 .../openejb/assembler/classic/ServiceInfo.java     |   1 +
 .../java/org/apache/openejb/config/AutoConfig.java |   1 +
 .../openejb/config/ConfigurationFactory.java       |  15 +-
 .../java/org/apache/openejb/config/Service.java    |   2 +
 .../openejb/config/provider/ProviderManager.java   |   3 +
 .../apache/openejb/config/sys/AbstractService.java |  12 +
 .../org/apache/openejb/config/sys/JaxbOpenejb.java |   1 +
 .../apache/openejb/config/sys/ServiceProvider.java |  23 +
 .../apache/openejb/config/sys/StackHandler.java    |   3 +
 .../config/typed/BmpEntityContainerBuilder.java    |   1 +
 .../config/typed/CmpEntityContainerBuilder.java    |   2 +
 .../openejb/config/typed/DataSourceBuilder.java    |   2 +
 .../config/typed/ManagedContainerBuilder.java      |   1 +
 .../typed/MessageDrivenContainerBuilder.java       |   1 +
 .../apache/openejb/config/typed/QueueBuilder.java  |   1 +
 .../config/typed/SingletonContainerBuilder.java    |   1 +
 .../apache/openejb/config/typed/TopicBuilder.java  |   1 +
 .../config/typed/TransactionManagerBuilder.java    |   1 +
 .../resource/jdbc/FlushableDataSourceHandler.java  |   8 +-
 .../META-INF/org.apache.openejb/service-jar.xml    |  23 +-
 .../src/main/resources/schema/service-jar.xsd      |   1 +
 .../apache/openejb/resource/URLAsResourceTest.java |   2 +-
 docs/admin/configuration/application.adoc          |   2 +-
 docs/application-resources.adoc                    |  19 +
 docs/containers-and-resources.adoc                 | 586 ++++++++++-----------
 pom.xml                                            |   2 +-
 .../org/apache/openejb/server/ServiceManager.java  |   6 +
 32 files changed, 444 insertions(+), 359 deletions(-)

diff --git a/boms/tomee-microprofile/pom.xml b/boms/tomee-microprofile/pom.xml
index 1791bb472e..fa8ee2240d 100644
--- a/boms/tomee-microprofile/pom.xml
+++ b/boms/tomee-microprofile/pom.xml
@@ -934,27 +934,27 @@
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-asm9-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-bundleutils</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-finder-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-naming</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-reflect</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.bitbucket.b_c</groupId>
diff --git a/boms/tomee-plume/pom.xml b/boms/tomee-plume/pom.xml
index f554cd475c..9cd36f85c5 100644
--- a/boms/tomee-plume/pom.xml
+++ b/boms/tomee-plume/pom.xml
@@ -969,27 +969,27 @@
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-asm9-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-bundleutils</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-finder-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-naming</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-reflect</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.bitbucket.b_c</groupId>
diff --git a/boms/tomee-plus/pom.xml b/boms/tomee-plus/pom.xml
index 928c610d9c..3c4b2f9226 100644
--- a/boms/tomee-plus/pom.xml
+++ b/boms/tomee-plus/pom.xml
@@ -979,27 +979,27 @@
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-asm9-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-bundleutils</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-finder-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-naming</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-reflect</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.bitbucket.b_c</groupId>
diff --git a/boms/tomee-webprofile/pom.xml b/boms/tomee-webprofile/pom.xml
index ef318d33c6..e38e3c5841 100644
--- a/boms/tomee-webprofile/pom.xml
+++ b/boms/tomee-webprofile/pom.xml
@@ -629,27 +629,27 @@
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-asm9-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-bundleutils</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-finder-shaded</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-naming</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.apache.xbean</groupId>
         <artifactId>xbean-reflect</artifactId>
-        <version>4.28</version>
+        <version>4.30</version>
       </dependency>
       <dependency>
         <groupId>org.bitbucket.b_c</groupId>
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index 72bf4ca06a..f3d32135db 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -185,6 +185,7 @@ import jakarta.enterprise.inject.spi.Bean;
 import jakarta.enterprise.inject.spi.BeanManager;
 import jakarta.enterprise.inject.spi.DefinitionException;
 import jakarta.enterprise.inject.spi.DeploymentException;
+import jakarta.jms.Queue;
 import javax.management.DynamicMBean;
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanRegistrationException;
@@ -227,6 +228,7 @@ import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.Instrumentation;
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
+import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
@@ -260,6 +262,7 @@ import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
 
 import static org.apache.openejb.util.Classes.ancestors;
 
@@ -1408,6 +1411,9 @@ public class Assembler extends AssemblerTool implements 
org.apache.openejb.spi.A
                 if (si.constructorArgs != null && 
!si.constructorArgs.isEmpty()) {
                     query.put("constructor", Join.join(",", 
si.constructorArgs));
                 }
+                if (si.constructorArgTypes != null && 
!si.constructorArgTypes.isEmpty()) {
+                    query.put("constructor-types", Join.join(",", 
si.constructorArgTypes));
+                }
                 appInfo.properties.put(si.id, "new://Service?" + 
URISupport.createQueryString(query));
                 if (si.properties != null) {
                     for (final String k : si.properties.stringPropertyNames()) 
{
@@ -3737,8 +3743,19 @@ public class Assembler extends AssemblerTool implements 
org.apache.openejb.spi.A
     }
 
     public static ObjectRecipe prepareRecipe(final ServiceInfo info) {
-        final String[] constructorArgs = info.constructorArgs.toArray(new 
String[info.constructorArgs.size()]);
-        final ObjectRecipe serviceRecipe = new ObjectRecipe(info.className, 
info.factoryMethod, constructorArgs, null);
+        final String[] constructorArgs = info.constructorArgs.toArray(new 
String[0]);
+        final Class[] constructorArgTypes = info.constructorArgTypes.stream()
+                .map(it -> {
+                    try {
+                        return getClassForType(it);
+                    } catch (final ClassNotFoundException e) {
+                        throw new OpenEJBRuntimeException(e);
+                    }
+                })
+                .toArray(Class[]::new);
+
+        final ObjectRecipe serviceRecipe = new ObjectRecipe(info.className, 
info.factoryMethod,
+                constructorArgs, constructorArgTypes.length > 0 ? 
constructorArgTypes : null); //if empty, treat as not set
         serviceRecipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
         serviceRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
         serviceRecipe.allow(Option.PRIVATE_PROPERTIES);
@@ -3795,6 +3812,27 @@ public class Assembler extends AssemblerTool implements 
org.apache.openejb.spi.A
         }
     }
 
+    private static Class<?> getClassForType(String typeName) throws 
ClassNotFoundException {
+        if (typeName.endsWith("[]")) {
+            final String elementType = typeName.substring(0, typeName.length() 
- 2);
+            final Class<?> elementClass = getClassForType(elementType); // 
recursion
+            return Array.newInstance(elementClass, 0).getClass();
+        }
+
+        return switch (typeName) {
+            case "boolean" -> boolean.class;
+            case "byte"    -> byte.class;
+            case "char"    -> char.class;
+            case "short"   -> short.class;
+            case "int"     -> int.class;
+            case "long"    -> long.class;
+            case "float"   -> float.class;
+            case "double"  -> double.class;
+            case "void"    -> void.class;
+            default -> Class.forName(typeName); // regular case
+        };
+    }
+
     private static class PersistenceClassLoaderHandlerImpl implements 
PersistenceClassLoaderHandler {
         private static final AtomicBoolean logged = new AtomicBoolean(false);
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ServiceInfo.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ServiceInfo.java
index 429a134eb2..cde31d962f 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ServiceInfo.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ServiceInfo.java
@@ -35,6 +35,7 @@ public class ServiceInfo extends InfoObject {
     public String classpathAPI;
     public Properties properties;
     public final List<String> constructorArgs = new ArrayList<>();
+    public final List<String> constructorArgTypes = new ArrayList<>();
     public Properties unsetProperties; // keep it in the model to be able to 
investigate it dumping Infos
 
     /**
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
index 0946a58231..bd5f93de56 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
@@ -1902,6 +1902,7 @@ public class AutoConfig implements DynamicDeployer, 
JndiConstants {
         b.description = a.description;
         b.factoryMethod = a.factoryMethod;
         b.constructorArgs.addAll(a.constructorArgs);
+        b.constructorArgTypes.addAll(a.constructorArgTypes);
         b.originAppName = a.originAppName;
         b.types.addAll(a.types);
         b.properties = new SuperProperties();
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
index 0e0f8b6033..1f8f0d85ac 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
@@ -19,6 +19,7 @@ package org.apache.openejb.config;
 
 import org.apache.openejb.Extensions;
 import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.OpenEJBRuntimeException;
 import org.apache.openejb.Vendor;
 import org.apache.openejb.api.Proxy;
 import org.apache.openejb.api.resource.PropertiesResourceProvider;
@@ -106,6 +107,7 @@ import jakarta.ejb.embeddable.EJBContainer;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Array;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -122,6 +124,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static 
org.apache.openejb.config.DeploymentsResolver.DEPLOYMENTS_CLASSPATH_PROPERTY;
 import static org.apache.openejb.config.ServiceUtils.implies;
@@ -794,6 +797,7 @@ public class ConfigurationFactory implements 
OpenEjbConfigurationFactory {
                 service.setProvider(map.remove("provider"));
                 service.setClassName(map.remove("class-name"));
                 service.setConstructor(map.remove("constructor"));
+                
service.setConstructorArgTypes(map.remove("constructor-types"));
                 service.setFactoryName(map.remove("factory-name"));
                 
service.setPropertiesProvider(map.remove("properties-provider"));
                 service.setTemplate(map.remove("template"));
@@ -1289,7 +1293,8 @@ public class ConfigurationFactory implements 
OpenEjbConfigurationFactory {
             info.factoryMethod = provider.getFactoryName();
             info.id = service.getId();
             info.properties = props;
-            info.constructorArgs.addAll(parseConstructorArgs(provider));
+            info.constructorArgs.addAll(parseList(provider.getConstructor()));
+            
info.constructorArgTypes.addAll(parseList(provider.getConstructorTypes()));
             if (info instanceof ResourceInfo && service instanceof Resource) {
                 final ResourceInfo ri = ResourceInfo.class.cast(info);
                 final Resource resource = Resource.class.cast(service);
@@ -1458,6 +1463,7 @@ public class ConfigurationFactory implements 
OpenEjbConfigurationFactory {
             provider.getTypes().add(service.getType());
             provider.setClassName(service.getClassName());
             provider.setConstructor(service.getConstructor());
+            provider.setConstructorTypes(service.getConstructorArgTypes());
             provider.setFactoryName(service.getFactoryName());
             return provider;
         }
@@ -1598,12 +1604,11 @@ public class ConfigurationFactory implements 
OpenEjbConfigurationFactory {
         return containerTypes.get(ctype);
     }
 
-    private List<String> parseConstructorArgs(final ServiceProvider service) {
-        final String constructor = service.getConstructor();
-        if (constructor == null) {
+    private List<String> parseList(final String raw) {
+        if (raw == null) {
             return Collections.emptyList();
         }
-        return Arrays.asList(constructor.split("[ ,]+"));
+        return Arrays.asList(raw.split("[ ,]+"));
     }
 
     protected List<String> getResourceIds() {
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/Service.java 
b/container/openejb-core/src/main/java/org/apache/openejb/config/Service.java
index 370096ef3b..5d0b8a7ab9 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/Service.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/Service.java
@@ -60,6 +60,8 @@ public interface Service {
 
     String getConstructor();
 
+    String getConstructorArgTypes();
+
     String getFactoryName();
 
     void setClasspath(String classpath);
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/provider/ProviderManager.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/provider/ProviderManager.java
index 2f4616900d..b4e3f37f48 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/provider/ProviderManager.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/provider/ProviderManager.java
@@ -130,6 +130,9 @@ public class ProviderManager {
         if (n(child.getConstructor())) {
             child.setConstructor(parent.getConstructor());
         }
+        if (n(child.getConstructorTypes())) {
+            child.setConstructorTypes(parent.getConstructorTypes());
+        }
         if (n(child.getFactoryName())) {
             child.setFactoryName(parent.getFactoryName());
         }
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/AbstractService.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/AbstractService.java
index b2b42cafd0..0522a7e6d7 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/AbstractService.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/AbstractService.java
@@ -83,6 +83,9 @@ public abstract class AbstractService implements Service {
     @XmlAttribute(name = "constructor")
     protected String constructor;
 
+    @XmlAttribute(name = "constructor-types")
+    protected String constructorArgTypes;
+
     /**
      * Mutually exclusive with 'provider'
      */
@@ -231,6 +234,15 @@ public abstract class AbstractService implements Service {
         this.constructor = constructor;
     }
 
+    @Override
+    public String getConstructorArgTypes() {
+        return constructorArgTypes;
+    }
+
+    public void setConstructorArgTypes(String constructorArgTypes) {
+        this.constructorArgTypes = constructorArgTypes;
+    }
+
     public String getFactoryName() {
         return factoryName;
     }
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/JaxbOpenejb.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/JaxbOpenejb.java
index ba7f06779a..f65cc788c2 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/JaxbOpenejb.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/JaxbOpenejb.java
@@ -481,6 +481,7 @@ public abstract class JaxbOpenejb {
             provider.setService(att.getValue("", "service"));
             provider.setFactoryName(att.getValue("", "factory-name"));
             provider.setConstructor(att.getValue("", "constructor"));
+            provider.setConstructorTypes(att.getValue("", 
"constructor-types"));
             provider.setClassName(att.getValue("", "class-name"));
             provider.setParent(att.getValue("", "parent"));
             final String typesString = att.getValue("", "types");
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/ServiceProvider.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/ServiceProvider.java
index 7c92f3adb5..1b2c042298 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/ServiceProvider.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/ServiceProvider.java
@@ -46,6 +46,7 @@ import java.util.Properties;
  *       &lt;attribute name="id" use="required" 
type="{http://www.w3.org/2001/XMLSchema}string"; /&gt;
  *       &lt;attribute name="provider-type" use="required" 
type="{http://www.openejb.org/Service/Configuration}ProviderTypes"; /&gt;
  *       &lt;attribute name="constructor" 
type="{http://www.w3.org/2001/XMLSchema}string"; /&gt;
+ *       &lt;attribute name="constructor-types" 
type="{http://www.w3.org/2001/XMLSchema}string"; /&gt;
  *       &lt;attribute name="factory-name" 
type="{http://www.w3.org/2001/XMLSchema}string"; /&gt;
  *     &lt;/extension&gt;
  *   &lt;/simpleContent&gt;
@@ -64,6 +65,8 @@ public class ServiceProvider {
     protected String className;
     @XmlAttribute(name = "constructor")
     protected String constructor;
+    @XmlAttribute(name = "constructor-types")
+    protected String constructorTypes;
     @XmlAttribute
     protected String description;
     @XmlAttribute(name = "display-name")
@@ -162,6 +165,26 @@ public class ServiceProvider {
         this.constructor = value;
     }
 
+    /**
+     * Gets the value of the constructorTypes property.
+     *
+     * @return possible object is
+     * {@link String }
+     */
+    public String getConstructorTypes() {
+        return constructorTypes;
+    }
+
+    /**
+     * Sets the value of the constructorTypes property.
+     *
+     * @param value allowed object is
+     *              {@link String }
+     */
+    public void setConstructorTypes(final String value) {
+        this.constructorTypes = value;
+    }
+
     /**
      * Gets the value of the description property.
      *
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/StackHandler.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/StackHandler.java
index 4cc1db8ea1..694bc97bbe 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/sys/StackHandler.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/sys/StackHandler.java
@@ -177,6 +177,9 @@ public class StackHandler extends DefaultHandler {
             if (attributes.getValue("constructor") != null) {
                 service.setConstructor(attributes.getValue("constructor"));
             }
+            if (attributes.getValue("constructor-types") != null) {
+                
service.setConstructorArgTypes(attributes.getValue("constructor-types"));
+            }
             if (attributes.getValue("factory-name") != null) {
                 service.setFactoryName(attributes.getValue("factory-name"));
             }
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/BmpEntityContainerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/BmpEntityContainerBuilder.java
index 4df9ccf939..66f70cd6d6 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/BmpEntityContainerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/BmpEntityContainerBuilder.java
@@ -39,6 +39,7 @@ public class BmpEntityContainerBuilder extends Container {
         setId("BmpEntityContainer");
 
         setConstructor("id, securityService, poolSize");
+        setConstructorArgTypes("java.lang.Object, 
org.apache.openejb.spi.SecurityService, int");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/CmpEntityContainerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/CmpEntityContainerBuilder.java
index 53d2d907a1..dd94abac92 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/CmpEntityContainerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/CmpEntityContainerBuilder.java
@@ -39,6 +39,8 @@ public class CmpEntityContainerBuilder extends Container {
         setId("CmpEntityContainer");
 
         setConstructor("id, transactionManager, securityService, 
cmpEngineFactory");
+        setConstructorArgTypes("java.lang.Object, 
jakarta.transaction.TransactionManager, org.apache.openejb.spi.SecurityService, 
java.lang.String");
+
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/DataSourceBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/DataSourceBuilder.java
index 60ab3599c2..5a2a93f1c3 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/DataSourceBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/DataSourceBuilder.java
@@ -99,6 +99,8 @@ public class DataSourceBuilder extends Resource {
         setId("DataSource");
 
         setConstructor("serviceId, jtaManaged, jdbcDriver, definition, 
maxWaitTime, timeBetweenEvictionRuns, minEvictableIdleTime, 
OpenEJBResourceClasspath");
+        
setConstructorArgTypes("java.lang.String,boolean,java.lang.Class,java.lang.String,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,boolean");
+
 
         setFactoryName("create");
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/ManagedContainerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/ManagedContainerBuilder.java
index ac5177c706..3aa40d183d 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/ManagedContainerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/ManagedContainerBuilder.java
@@ -36,6 +36,7 @@ public class ManagedContainerBuilder extends Container {
         setId("ManagedContainer");
 
         setConstructor("id, securityService");
+        setConstructorArgTypes("java.lang.Object, 
org.apache.openejb.spi.SecurityService");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/MessageDrivenContainerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/MessageDrivenContainerBuilder.java
index 94721f9811..123e75e64d 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/MessageDrivenContainerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/MessageDrivenContainerBuilder.java
@@ -45,6 +45,7 @@ public class MessageDrivenContainerBuilder extends Container {
         setId("MessageDrivenContainer");
 
         setConstructor("id, securityService, resourceAdapter, 
messageListenerInterface, activationSpecClass, instanceLimit, 
failOnUnknownActivationSpec");
+        setConstructorArgTypes("java.lang.Object, 
org.apache.openejb.spi.SecurityService, jakarta.resource.spi.ResourceAdapter, 
java.lang.Class, java.langClass, int, boolean");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/QueueBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/QueueBuilder.java
index d163cc0324..538be302a0 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/QueueBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/QueueBuilder.java
@@ -39,6 +39,7 @@ public class QueueBuilder extends Resource {
         setId("Queue");
 
         setConstructor("destination");
+        setConstructorArgTypes("java.lang.String");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/SingletonContainerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/SingletonContainerBuilder.java
index 9a9d660a89..634f7e4af4 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/SingletonContainerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/SingletonContainerBuilder.java
@@ -44,6 +44,7 @@ public class SingletonContainerBuilder extends Container {
         setId("SingletonContainer");
 
         setConstructor("id, securityService");
+        setConstructorArgTypes("java.lang.Object, 
org.apache.openejb.spi.SecurityService");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TopicBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TopicBuilder.java
index 854bf79492..fc8b0aeaf7 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TopicBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TopicBuilder.java
@@ -39,6 +39,7 @@ public class TopicBuilder extends Resource {
         setId("Topic");
 
         setConstructor("destination");
+        setConstructorArgTypes("java.lang.String");
 
     }
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TransactionManagerBuilder.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TransactionManagerBuilder.java
index f7296c5bea..e03dea04fc 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TransactionManagerBuilder.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/config/typed/TransactionManagerBuilder.java
@@ -71,6 +71,7 @@ public class TransactionManagerBuilder extends 
TransactionManager {
         setId("TransactionManager");
 
         setConstructor("defaultTransactionTimeoutSeconds, 
defaultTransactionTimeout, txRecovery, tmId, bufferClassName, bufferSizeKb, 
checksumEnabled, adler32Checksum, flushSleepTimeMilliseconds, flushSleepTime, 
logFileDir, logFileExt, logFileName, maxBlocksPerFile, maxBuffers, maxLogFiles, 
minBuffers, threadsWaitingForceThreshold");
+        setConstructorArgTypes("java.lang.Integer, 
org.apache.openejb.util.Duration, boolean, byte[], java.lang.String, int, 
boolean, boolean, java.lang.Integer, org.apache.openejb.util.Duration, 
java.lang.String, java.lang.String, java.lang.String, int, int, int, int, int");
 
         setFactoryName("create");
 
diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
index 876f18b3d7..18d8ee3ce3 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
@@ -16,6 +16,7 @@
  */
 package org.apache.openejb.resource.jdbc;
 
+import org.apache.openejb.util.Duration;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.xbean.recipe.ObjectRecipe;
@@ -38,6 +39,10 @@ public class FlushableDataSourceHandler implements 
DelegatableHandler {
     public static final String[] FACTORY_ARGS = new String[]{
         "ServiceId", "JtaManaged", "JdbcDriver", "Definition", "MaxWaitTime", 
"TimeBetweenEvictionRuns", "MinEvictableIdleTime", "OpenEJBResourceClasspath"
     };
+    public static final Class[] FACTORY_ARG_TYPES = new Class[]{
+            String.class, boolean.class, Class.class, String.class,
+            Duration.class, Duration.class, Duration.class,
+            boolean.class};
 
     private final FlushConfig config;
     private final ReadWriteLock lock = new ReentrantReadWriteLock();
@@ -53,7 +58,8 @@ public class FlushableDataSourceHandler implements 
DelegatableHandler {
     private void createANewDelegate() {
         final CommonDataSource old = delegate.get();
         try {
-            final ObjectRecipe recipe = new 
ObjectRecipe(DataSourceFactory.class.getName(), "create", FACTORY_ARGS);
+            final ObjectRecipe recipe = new 
ObjectRecipe(DataSourceFactory.class.getName(), "create",
+                    FACTORY_ARGS, FACTORY_ARG_TYPES);
             recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
             recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
             recipe.allow(Option.NAMED_PARAMETERS);
diff --git 
a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
 
b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
index 50ef7c58eb..1a44c9b660 100644
--- 
a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
+++ 
b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
@@ -46,6 +46,7 @@
                    service="Container"
                    types="CMP_ENTITY"
                    constructor="id, transactionManager, securityService, 
CmpEngineFactory"
+                   constructor-types="java.lang.Object, 
jakarta.transaction.TransactionManager, org.apache.openejb.spi.SecurityService, 
java.lang.String"
                    class-name="org.apache.openejb.core.cmp.CmpContainer">
 
     CmpEngineFactory org.apache.openejb.core.cmp.jpa.JpaCmpEngineFactory
@@ -61,6 +62,7 @@
           service="Container"
           types="BMP_ENTITY"
           constructor="id, securityService, PoolSize"
+          constructor-types="java.lang.Object, 
org.apache.openejb.spi.SecurityService, int"
           class-name="org.apache.openejb.core.entity.EntityContainer">
 
     # Specifies the size of the bean pools for this
@@ -125,7 +127,7 @@
     # side of the pool reaches its `MaxAge`, it is also immediately
     # replaced.  Replacement is done in a background queue using the
     # number of threads specified by `CallbackThreads`.
-    
+
     MinSize = 0
 
     # StrictPooling tells the container what to do when the pool
@@ -345,6 +347,7 @@
           service="Container"
           types="SINGLETON"
           constructor="id, securityService"
+          constructor-types="java.lang.Object, 
org.apache.openejb.spi.SecurityService"
           class-name="org.apache.openejb.core.singleton.SingletonContainer">
 
     # Specifies the maximum time an invocation could wait for the
@@ -362,7 +365,7 @@
     # annotation is used.
 
     AccessTimeout = 30 seconds
-    
+
   </ServiceProvider>
 
 
@@ -428,10 +431,10 @@
     # override this setting for the bean where the annotation is used.
 
     TimeOut 20
-    
-    # Specifies the frequency (in seconds) at which the bean cache is checked 
for 
+
+    # Specifies the frequency (in seconds) at which the bean cache is checked 
for
     # idle beans.
-    
+
     Frequency 60
 
     # Specifies the size of the bean pools for this
@@ -456,6 +459,7 @@
           service="Container"
           types="MANAGED"
           constructor="id, securityService"
+          constructor-types="java.lang.Object, 
org.apache.openejb.spi.SecurityService"
           class-name="org.apache.openejb.core.managed.ManagedContainer">
 
   </ServiceProvider>
@@ -510,8 +514,8 @@
           service="SecurityService"
           types="SecurityService"
           class-name="org.apache.openejb.core.security.SecurityServiceImpl">
-  
-    DefaultUser guest         
+
+    DefaultUser guest
   </ServiceProvider>
 
   <ServiceProvider
@@ -531,6 +535,7 @@
             types="TransactionManager"
             factory-name="create"
             constructor="defaultTransactionTimeoutSeconds, 
defaultTransactionTimeout, TxRecovery, tmId, bufferClassName, bufferSizeKb, 
checksumEnabled, adler32Checksum, flushSleepTimeMilliseconds, flushSleepTime, 
logFileDir, logFileExt, logFileName, maxBlocksPerFile, maxBuffers, maxLogFiles, 
minBuffers, threadsWaitingForceThreshold"
+            constructor-types="java.lang.Integer, 
org.apache.openejb.util.Duration, boolean, byte[], java.lang.String, int, 
boolean, boolean, java.lang.Integer, org.apache.openejb.util.Duration, 
java.lang.String, java.lang.String, java.lang.String, int, int, int, int, int"
             
class-name="org.apache.openejb.resource.GeronimoTransactionManagerFactory">
       defaultTransactionTimeout 10 minutes
 
@@ -585,6 +590,7 @@
           types="javax.sql.DataSource, DataSource"
           factory-name="create"
           constructor="ServiceId, JtaManaged, JdbcDriver, Definition, 
MaxWaitTime, TimeBetweenEvictionRuns, MinEvictableIdleTime, 
OpenEJBResourceClasspath"
+          
constructor-types="java.lang.String,boolean,java.lang.Class,java.lang.String,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,boolean"
           class-name="org.apache.openejb.resource.jdbc.DataSourceFactory">
     # Determines wether or not this data source should be JTA managed
     # or user managed.  If set to 'true' it will automatically be enrolled
@@ -626,6 +632,7 @@
           types="javax.sql.DataSource, DataSource"
           factory-name="create"
           constructor="ServiceId, JtaManaged, JdbcDriver, Definition, 
MaxWaitTime, TimeBetweenEvictionRuns, MinEvictableIdleTime, 
OpenEJBResourceClasspath"
+          
constructor-types="java.lang.String,boolean,java.lang.Class,java.lang.String,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,org.apache.openejb.util.Duration,boolean"
           class-name="org.apache.openejb.resource.jdbc.DataSourceFactory">
     JtaManaged = false
 
@@ -706,6 +713,7 @@
           service="Resource"
           types="jakarta.jms.Queue, Queue, jakarta.jms.Destination"
           constructor="destination"
+          constructor-types="java.lang.String"
           class-name="org.apache.activemq.command.ActiveMQQueue">
 
     # Specifies the name of the queue
@@ -718,6 +726,7 @@
           service="Resource"
           types="jakarta.jms.Topic, Topic, jakarta.jms.Destination"
           constructor="destination"
+          constructor-types="java.lang.String"
           class-name="org.apache.activemq.command.ActiveMQTopic">
 
     # Specifies the name of the topic
diff --git a/container/openejb-core/src/main/resources/schema/service-jar.xsd 
b/container/openejb-core/src/main/resources/schema/service-jar.xsd
index 232e7a9254..726e16e1a0 100644
--- a/container/openejb-core/src/main/resources/schema/service-jar.xsd
+++ b/container/openejb-core/src/main/resources/schema/service-jar.xsd
@@ -46,6 +46,7 @@
           <xsd:attribute name="description" type="xsd:string" use="optional"/>
           <xsd:attribute name="class-name" type="ClassName"/>
           <xsd:attribute name="constructor" type="xsd:string" use="optional"/>
+          <xsd:attribute name="constructor-types" type="xsd:string" 
use="optional"/>
           <xsd:attribute name="factory-name" type="xsd:string" use="optional"/>
         </xsd:extension>
       </xsd:simpleContent>
diff --git 
a/container/openejb-core/src/test/java/org/apache/openejb/resource/URLAsResourceTest.java
 
b/container/openejb-core/src/test/java/org/apache/openejb/resource/URLAsResourceTest.java
index 0e5aa78611..e8496add81 100644
--- 
a/container/openejb-core/src/test/java/org/apache/openejb/resource/URLAsResourceTest.java
+++ 
b/container/openejb-core/src/test/java/org/apache/openejb/resource/URLAsResourceTest.java
@@ -39,7 +39,7 @@ public class URLAsResourceTest {
     @Configuration
     public Properties config() {
         return new PropertiesBuilder()
-            .p("url", 
"new://Resource?class-name=java.net.URL&constructor=value")
+            .p("url", 
"new://Resource?class-name=java.net.URL&constructor=value&constructor-types=java.lang.String")
             .p("url.value", "http://tomee.apache.org";)
             .build();
     }
diff --git a/docs/admin/configuration/application.adoc 
b/docs/admin/configuration/application.adoc
index 775492e1a0..a91ba38a20 100644
--- a/docs/admin/configuration/application.adoc
+++ b/docs/admin/configuration/application.adoc
@@ -87,7 +87,7 @@ to use a MySQL database on OpenShift you can do:
 
 `resources.xml` supports `Resource`, `Service` and `Container`.
 
-=== `resources.xml` mecanism
+=== `resources.xml` mechanism
 
 `resources.xml` resources are still available globally like any `tomee.xml` 
resource.
 
diff --git a/docs/application-resources.adoc b/docs/application-resources.adoc
index 8620ac1124..21f04e5903 100644
--- a/docs/application-resources.adoc
+++ b/docs/application-resources.adoc
@@ -290,6 +290,25 @@ specify the arguments as a comma separated list:
 </Resource>
 ----
 
+=== constructor-types
+
+When no types are explicitly defined, the underlying mechanism relies on 
implicit matching to bind
+the declared properties to the constructor parameter names.
+
+Because of this, it can be useful to explicitly define the constructor 
argument types to ensure that
+the correct constructor or factory method is selected for the configured 
resource.
+
+You can specify the types as shown below:
+
+[source,xml]
+----
+<Resource id="config" class-name="org.superbiz.Configuration" constructor="id, 
poolSize" constructor-types="java.lang.String,int">
+    url http://localhost
+    username tomee
+    poolSize 20
+</Resource>
+----
+
 === factory-name method
 
 In some circumstances, it may be desirable to add some additional logic
diff --git a/docs/containers-and-resources.adoc 
b/docs/containers-and-resources.adoc
index 2f5c17c5b9..77a3c1aca2 100644
--- a/docs/containers-and-resources.adoc
+++ b/docs/containers-and-resources.adoc
@@ -4,461 +4,405 @@
 :jbake-type: page
 :jbake-status: published
 
+== Containers
 
-[source,xml]
-----
-          <p><a name="ContainersandResources-containers"></a></p>
-----
-
-CMP_ENTITY
+=== CMP_ENTITY
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Container?type=CMP_ENTITY
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-CmpEngineFactory
-
-Default value is org.apache.openejb.core.cmp.jpa.JpaCmpEngineFactory.
-
-TransactionManager
-
-Declarable in tomee.xml via
-
-Supports the following properties
+Supports the following properties:
 
-Property Name
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-Description
+| CmpEngineFactory
+| Default value is `org.apache.openejb.core.cmp.jpa.JpaCmpEngineFactory`.
 
-defaultTransactionTimeoutSeconds
+| TransactionManager
+| Transaction manager used by the container.
+|===
 
-Default value is 10 minutes.
+---
 
-BMP_ENTITY
+=== BMP_ENTITY
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Container?type=BMP_ENTITY
+----
 
-Supports the following properties
-
-Property Name
+Supports the following properties:
 
-Description
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-PoolSize
+| PoolSize
+| Specifies the size of the bean pools for this BMP entity container.
+Default value is `10`.
+|===
 
-Specifies the size of the bean pools for this bmp entity container.
-Default value is 10.
+---
 
-STATELESS
+=== STATELESS
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Container?type=STATELESS
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-TimeOut
+Supports the following properties:
 
-Specifies the time to wait between invocations. This value is measured
-in milliseconds. A value of 5 would result in a time-out of 5
-milliseconds between invocations. A value of zero would mean no timeout.
-Default value is 0.
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-PoolSize
+| TimeOut
+| Specifies the time to wait between invocations, in milliseconds.
+A value of `0` means no timeout.
+Default value is `0`.
 
-Specifies the size of the bean pools for this stateless SessionBean
-container. Default value is 10.
+| PoolSize
+| Specifies the size of the bean pools for this stateless SessionBean 
container.
+Default value is `10`.
 
-StrictPooling
+| StrictPooling
+| Controls behavior when the pool reaches its maximum size.
+If `true`, requests wait for instances to become available and the pool never 
grows beyond `PoolSize`.
+If `false`, temporary instances are created for one invocation and then 
discarded.
+Default value is `true`.
+|===
 
-StrictPooling tells the container what to do when the pool reaches it's
-maximum size and there are incoming requests that need instances. With
-strict pooling, requests will have to wait for instances to become
-available. The pool size will never grow beyond the the set PoolSize
-value. Without strict pooling, the container will create temporary
-instances to meet demand. The instances will last for just one method
-invocation and then are removed. Default value is true.
+---
 
-STATEFUL
+=== STATEFUL
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Container?type=STATEFUL
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-Passivator
-
-The passivator is responsible for writing beans to disk at passivation
-time. Different passivators can be used by setting this property to the
-fully qualified class name of the PassivationStrategy implementation.
-The passivator is not responsible for invoking any callbacks or other
-processing, its only responsibly is to write the bean state to disk.
-Known implementations: org.apache.openejb.core.stateful.RAFPassivater
-org.apache.openejb.core.stateful.SimplePassivater Default value is
-org.apache.openejb.core.stateful.SimplePassivater.
+Supports the following properties:
 
-TimeOut
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-Specifies the time to wait between invocations. This value is measured
-in minutes. A value of 5 would result in a time-out of 5 minutes between
-invocations. A value of zero would mean no timeout. Default value is 20.
+| Passivator
+| Responsible for writing beans to disk during passivation.
+Known implementations:
+`org.apache.openejb.core.stateful.RAFPassivater`
+`org.apache.openejb.core.stateful.SimplePassivater`
+Default value is `org.apache.openejb.core.stateful.SimplePassivater`.
 
-PoolSize
+| TimeOut
+| Specifies the time to wait between invocations, in minutes.
+A value of `0` means no timeout.
+Default value is `20`.
 
-Specifies the size of the bean pools for this stateful SessionBean
-container. Default value is 1000.
+| PoolSize
+| Specifies the size of the bean pools for this stateful SessionBean container.
+Default value is `1000`.
 
-BulkPassivate
+| BulkPassivate
+| Number of instances to passivate at one time during bulk passivation.
+Default value is `100`.
+|===
 
-Property name that specifies the number of instances to passivate at one
-time when doing bulk passivation. Default value is 100.
+---
 
-MESSAGE
+=== MESSAGE
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Container?type=MESSAGE
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-ResourceAdapter
-
-The resource adapter delivers messages to the container Default value is
-Default JMS Resource Adapter.
+Supports the following properties:
 
-MessageListenerInterface
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-Specifies the message listener interface handled by this container
-Default value is jakarta.jms.MessageListener.
+| ResourceAdapter
+| Resource adapter that delivers messages to the container.
+Default value is *Default JMS Resource Adapter*.
 
-ActivationSpecClass
+| MessageListenerInterface
+| Message listener interface handled by this container.
+Default value is `jakarta.jms.MessageListener`.
 
-Specifies the activation spec class Default value is
-org.apache.activemq.ra.ActiveMQActivationSpec.
+| ActivationSpecClass
+| Activation specification class.
+Default value is `org.apache.activemq.ra.ActiveMQActivationSpec`.
 
-InstanceLimit
+| InstanceLimit
+| Maximum number of bean instances allowed per MDB deployment.
+Default value is `10`.
+|===
 
-Specifies the maximum number of bean instances that are allowed to exist
-for each MDB deployment. Default value is 10.
+---
 
-Resources
+== Resources
 
-javax.sql.DataSource
+=== javax.sql.DataSource
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=javax.sql.DataSource
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-JtaManaged
-
-Determines wether or not this data source should be JTA managed or user
-managed.  If set to 'true' it will automatically be enrolled in any
-ongoing transactions.  Calling begin/commit/rollback or setAutoCommit on
-the datasource or connection will not be allowed.  If you need to
-perform these functions yourself, set JtaManaged to 'false' In terms of
-JPA persistence.xml: "JtaManaged=true" can be used as a
-'jta-data-source' "JtaManaged=false" can be used as a
-'non-jta-data-source' Default value is true.
-
-JdbcDriver
-
-Driver class name Default value is org.hsqldb.jdbcDriver.
-
-JdbcUrl
-
-Url for creating connections Default value is
-jdbc:hsqldb:file:data/hsqldb/hsqldb.
-
-UserName
-
-Default user name Default value is sa.
-
-Password
-
-Default password
-
-ConnectionProperties
-
-The connection properties that will be sent to the JDBC driver when
-establishing new connections Format of the string must be
-[propertyName=property;]* NOTE - The "user" and "password" properties
-will be passed explicitly, so they do not need to be included here.
-
-DefaultAutoCommit
-
-The default auto-commit state of new connections Default value is true.
-
-DefaultReadOnly
-
-The default read-only state of new connections If not set then the
-setReadOnly method will not be called. (Some drivers don't support read
-only mode, ex: Informix)
-
-DefaultTransactionIsolation
-
-The default TransactionIsolation state of new connections If not set
-then the setTransactionIsolation method will not be called. The allowed
-values for this property are:     NONE     READ_COMMITTED    
-READ_UNCOMMITTED     REPEATABLE_READ     SERIALIZABLE Note: Most JDBC
-drivers do not support all isolation levels
-
-InitialSize
-
-The initial number of connections that are created when the pool is
-started Default value is 0.
-
-MaxActive
-
-The maximum number of active connections that can be allocated from this
-pool at the same time, or a negative number for no limit. Default value
-is 20.
+Supports the following properties:
 
-MaxIdle
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-The maximum number of connections that can remain idle in the pool,
-without extra ones being released, or a negative number for no limit.
-Default value is 20.
+| JtaManaged
+| Determines whether the datasource is JTA managed.
+Default value is `true`.
 
-MinIdle
+| JdbcDriver
+| JDBC driver class name.
+Default value is `org.hsqldb.jdbcDriver`.
 
-The minimum number of connections that can remain idle in the pool,
-without extra ones being created, or zero to create none. Default value
-is 0.
+| JdbcUrl
+| JDBC URL for creating connections.
+Default value is `jdbc:hsqldb:file:data/hsqldb/hsqldb`.
 
-MaxWait
+| UserName
+| Default username.
+Default value is `sa`.
 
-The maximum number of milliseconds that the pool will wait (when there
-are no available connections) for a connection to be returned before
-throwing an exception, or -1 to wait indefinitely. Default value is -1.
+| Password
+| Default password.
 
-ValidationQuery
+| ConnectionProperties
+| Properties passed to the JDBC driver when creating connections.
+Format: `[propertyName=property;]*`
+`user` and `password` are passed explicitly.
 
-The SQL query that will be used to validate connections from this pool
-before returning them to the caller. If specified, this query MUST be an
-SQL SELECT statement that returns at least one row.
+| DefaultAutoCommit
+| Default auto-commit state of new connections.
+Default value is `true`.
 
-TestOnBorrow
+| DefaultReadOnly
+| Default read-only state of new connections.
+If not set, `setReadOnly` is not called.
 
-If true connections will be validated before being borrowed from the
-pool. If the validation fails, the connection is destroyed, and a new
-conection will be retrieved from the pool (and validated). NOTE - for a
-true value to have any effect, the ValidationQuery parameter must be
-set. Default value is true.
+| DefaultTransactionIsolation
+| Default transaction isolation level.
+Allowed values: `NONE`, `READ_COMMITTED`, `READ_UNCOMMITTED`, 
`REPEATABLE_READ`, `SERIALIZABLE`.
 
-TestOnReturn
+| InitialSize
+| Initial number of connections created when the pool starts.
+Default value is `0`.
 
-If true connections will be validated before being returned to the
-pool.  If the validation fails, the connection is destroyed instead of
-being returned to the pool. NOTE - for a true value to have any effect,
-the ValidationQuery parameter must be set. Default value is false.
+| MaxActive
+| Maximum number of active connections.
+Default value is `20`.
 
-TestWhileIdle
+| MaxIdle
+| Maximum number of idle connections.
+Default value is `20`.
 
-If true connections will be validated by the idle connection evictor (if
-any). If the validation fails, the connection is destroyed and removed
-from the pool NOTE - for a true value to have any effect, the
-timeBetweenEvictionRunsMillis property must be a positive number and the
-ValidationQuery parameter must be set. Default value is false.
+| MinIdle
+| Minimum number of idle connections.
+Default value is `0`.
 
-TimeBetweenEvictionRunsMillis
+| MaxWait
+| Maximum wait time (ms) for a connection before throwing an exception.
+Default value is `-1`.
 
-The number of milliseconds to sleep between runs of the idle connection
-evictor thread. When set to a negative number, no idle connection
-evictor thread will be run. Default value is -1.
+| ValidationQuery
+| SQL query used to validate connections.
 
-NumTestsPerEvictionRun
+| TestOnBorrow
+| Validate connections before borrowing.
+Default value is `true`.
 
-The number of connectionss to examine during each run of the idle
-connection evictor thread (if any). Default value is 3.
+| TestOnReturn
+| Validate connections before returning to the pool.
+Default value is `false`.
 
-MinEvictableIdleTimeMillis
+| TestWhileIdle
+| Validate connections during idle eviction runs.
+Default value is `false`.
 
-The minimum amount of time a connection may sit idle in the pool before
-it is eligable for eviction by the idle connection evictor (if any).
-Default value is 1800000.
+| TimeBetweenEvictionRunsMillis
+| Time between idle eviction runs (ms).
+Default value is `-1`.
 
-PoolPreparedStatements
+| NumTestsPerEvictionRun
+| Number of connections tested per eviction run.
+Default value is `3`.
 
-If true, a statement pool is created for each Connection and
-PreparedStatements created by one of the following methods are
-pooled:    public PreparedStatement prepareStatement(String
-sql);    public PreparedStatement prepareStatement(String
-sql,            int resultSetType,            int resultSetConcurrency)
-Default value is false.
+| MinEvictableIdleTimeMillis
+| Minimum idle time before eviction.
+Default value is `1800000`.
 
-MaxOpenPreparedStatements
+| PoolPreparedStatements
+| Enables pooling of prepared statements.
+Default value is `false`.
 
-The maximum number of open statements that can be allocated from the
-statement pool at the same time, or zero for no limit. NOTE - Some
-drivers have limits on the number of open statements, so make sure there
-are some resources left for the other (non-prepared) statements. Default
-value is 0.
+| MaxOpenPreparedStatements
+| Maximum open prepared statements.
+Default value is `0`.
 
-AccessToUnderlyingConnectionAllowed
+| AccessToUnderlyingConnectionAllowed
+| Allows access to the raw JDBC connection.
+Default value is `false`.
+|===
 
-If true the raw physical connection to the database can be accessed
-using the following construct:     Connection conn =
-ds.getConnection();     Connection rawConn = ((DelegatingConnection)
-conn).getInnermostDelegate();     ...     conn.close() Default is false,
-because misbehaving programs can do harmfull things to the raw
-connection shuch as closing the raw connection or continuing to use the
-raw connection after it has been assigned to another logical
-connection.  Be carefull and only use when you need direct access to
-driver specific extentions. NOTE: Do NOT close the underlying
-connection, only the original logical connection wrapper. Default value
-is false.
+---
 
-ActiveMQResourceAdapter
+=== ActiveMQResourceAdapter
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=ActiveMQResourceAdapter
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-BrokerXmlConfig
+Supports the following properties:
 
-Broker configuration Default value is
-broker:(tcp://localhost:61616)?useJmx=false.
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-ServerUrl
+| BrokerXmlConfig
+| Broker configuration.
+Default value is `broker:(tcp://localhost:61616)?useJmx=false`.
 
-Broker address Default value is vm://localhost?async=true.
+| ServerUrl
+| Broker address.
+Default value is `vm://localhost?async=true`.
 
-DataSource
+| DataSource
+| Datasource for message persistence.
+Default value is *Default Unmanaged JDBC Database*.
+|===
 
-DataSource for persistence messages Default value is Default Unmanaged
-JDBC Database.
+---
 
-jakarta.jms.ConnectionFactory
+=== jakarta.jms.ConnectionFactory
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=jakarta.jms.ConnectionFactory
+----
 
-Supports the following properties
-
-Property Name
-
-Description
-
-ResourceAdapter
-
-Default value is Default JMS Resource Adapter.
-
-TransactionSupport
-
-Specifies if the connection is enrolled in global transaction allowed
-values: xa, local or none Default value is xa.
+Supports the following properties:
 
-PoolMaxSize
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-Maximum number of physical connection to the ActiveMQ broker Default
-value is 10.
+| ResourceAdapter
+| Default value is *Default JMS Resource Adapter*.
 
-PoolMinSize
+| TransactionSupport
+| Transaction support type: `xa`, `local`, or `none`.
+Default value is `xa`.
 
-Minimum number of physical connection to the ActiveMQ broker Default
-value is 0.
+| PoolMaxSize
+| Maximum number of physical connections.
+Default value is `10`.
 
-ConnectionMaxWaitMilliseconds
+| PoolMinSize
+| Minimum number of physical connections.
+Default value is `0`.
 
-Maximum amount of time to wait for a connection Default value is 5000.
+| ConnectionMaxWaitMilliseconds
+| Maximum time to wait for a connection.
+Default value is `5000`.
 
-ConnectionMaxIdleMinutes
+| ConnectionMaxIdleMinutes
+| Maximum idle time before reclaiming a connection.
+Default value is `15`.
+|===
 
-Maximum amount of time a connection can be idle before being reclaimed
-Default value is 15.
+---
 
-jakarta.jms.Queue
+=== jakarta.jms.Queue
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=jakarta.jms.Queue
+----
 
-Supports the following properties
-
-Property Name
+Supports the following properties:
 
-Description
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-destination
+| destination
+| Name of the queue.
+|===
 
-Specifies the name of the queue
+---
 
-jakarta.jms.Topic
+=== jakarta.jms.Topic
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=jakarta.jms.Topic
+----
 
-Supports the following properties
-
-Property Name
+Supports the following properties:
 
-Description
+[cols="1,3",options="header"]
+|===
+| Property Name | Description
 
-destination
+| destination
+| Name of the topic.
+|===
 
-Specifies the name of the topic
+---
 
-jakarta.mail.Session
+=== jakarta.mail.Session
 
-Declarable in tomee.xml via
+Declarable in `tomee.xml` via
 
-Declarable in properties via
+Declarable in properties via:
 
+----
 Foo = new://Resource?type=jakarta.mail.Session
+----
 
 No properties.
diff --git a/pom.xml b/pom.xml
index d9f6b9413e..dc1098eac2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -142,7 +142,7 @@
     <version.shrinkwrap.shrinkwrap>1.2.6</version.shrinkwrap.shrinkwrap>
 
     <version.tomee-quartz-shade>2.5.1</version.tomee-quartz-shade>
-    <version.xbean>4.28</version.xbean>
+    <version.xbean>4.30</version.xbean>
     <version.groovy>2.4.21</version.groovy>
     <version.jetty>11.0.20</version.jetty>
     <version.ehcache>3.11.1</version.ehcache>
diff --git 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceManager.java
 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceManager.java
index b61394f3ea..51fe708364 100644
--- 
a/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceManager.java
+++ 
b/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceManager.java
@@ -42,6 +42,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Locale;
+import java.util.stream.Collectors;
 
 import static 
org.apache.openejb.util.PropertyPlaceHolderHelper.holdsWithUpdate;
 
@@ -146,6 +147,11 @@ public abstract class ServiceManager {
                             serviceClass, "createServerService", null, null, 
serviceProperties.stringPropertyNames(), 
Collections.singleton(Option.NAMED_PARAMETERS));
                     if (factory != null) {
                         
recipe.setConstructorArgNames(factory.getParameterNames()); // can throw an 
exception so call it before next line
+                        final List<Class<?>> argTypes = 
factory.getParameterTypes().stream()
+                                    .filter(t -> t instanceof Class<?>)
+                                    .map(t -> (Class<?>) t)
+                                    .collect(Collectors.toList());
+                        recipe.setConstructorArgTypes(argTypes);
                         recipe.setFactoryMethod("createServerService");
                     } else if (ReflectionUtil.findStaticFactory(serviceClass, 
"createServerService", null, null) != null) { // old behavior, remove when sure 
previous check is ok
                         recipe.setFactoryMethod("createServerService");

Reply via email to