diff --git a/boms/tomee-microprofile/pom.xml b/boms/tomee-microprofile/pom.xml
index dd0682974d9..60008dd044b 100644
--- a/boms/tomee-microprofile/pom.xml
+++ b/boms/tomee-microprofile/pom.xml
@@ -919,27 +919,27 @@
org.apache.xbean
xbean-asm9-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-bundleutils
- 4.28
+ 4.30
org.apache.xbean
xbean-finder-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-naming
- 4.28
+ 4.30
org.apache.xbean
xbean-reflect
- 4.28
+ 4.30
org.bitbucket.b_c
diff --git a/boms/tomee-plume/pom.xml b/boms/tomee-plume/pom.xml
index 061c3dac906..f2de3f55281 100644
--- a/boms/tomee-plume/pom.xml
+++ b/boms/tomee-plume/pom.xml
@@ -949,27 +949,27 @@
org.apache.xbean
xbean-asm9-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-bundleutils
- 4.28
+ 4.30
org.apache.xbean
xbean-finder-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-naming
- 4.28
+ 4.30
org.apache.xbean
xbean-reflect
- 4.28
+ 4.30
org.bitbucket.b_c
diff --git a/boms/tomee-plus/pom.xml b/boms/tomee-plus/pom.xml
index 36dfe85a792..9eba851db63 100644
--- a/boms/tomee-plus/pom.xml
+++ b/boms/tomee-plus/pom.xml
@@ -959,27 +959,27 @@
org.apache.xbean
xbean-asm9-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-bundleutils
- 4.28
+ 4.30
org.apache.xbean
xbean-finder-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-naming
- 4.28
+ 4.30
org.apache.xbean
xbean-reflect
- 4.28
+ 4.30
org.bitbucket.b_c
diff --git a/boms/tomee-webprofile/pom.xml b/boms/tomee-webprofile/pom.xml
index 677f44bab1d..ce94ae2fdd1 100644
--- a/boms/tomee-webprofile/pom.xml
+++ b/boms/tomee-webprofile/pom.xml
@@ -614,27 +614,27 @@
org.apache.xbean
xbean-asm9-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-bundleutils
- 4.28
+ 4.30
org.apache.xbean
xbean-finder-shaded
- 4.28
+ 4.30
org.apache.xbean
xbean-naming
- 4.28
+ 4.30
org.apache.xbean
xbean-reflect
- 4.28
+ 4.30
org.bitbucket.b_c
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 72bf4ca06aa..f3d32135db4 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.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.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.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 static void mergeServices(final AppInfo appInfo) throws URISyntaxExceptio
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 @@ private static void unusedProperty(final String id, final String property) {
}
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 @@ private URL toUrl(final String jarPath) throws OpenEJBException {
}
}
+ 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 429a134eb2c..cde31d962fc 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 constructorArgs = new ArrayList<>();
+ public final List 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 c247580bb67..eb3567dd445 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
@@ -1922,6 +1922,7 @@ private ResourceInfo copy(final ResourceInfo a) {
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 0e0f8b6033f..1f8f0d85acb 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 @@
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 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.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 static Object toConfigDeclaration(final String id, final URI uri) throws
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 T configureService(org.apache.openejb.config.Serv
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 @@ private ServiceProvider resolveServiceProvider(final org.apache.openejb.config.S
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 @@ protected static Class extends ContainerInfo> getContainerInfoType(final Strin
return containerTypes.get(ctype);
}
- private List parseConstructorArgs(final ServiceProvider service) {
- final String constructor = service.getConstructor();
- if (constructor == null) {
+ private List parseList(final String raw) {
+ if (raw == null) {
return Collections.emptyList();
}
- return Arrays.asList(constructor.split("[ ,]+"));
+ return Arrays.asList(raw.split("[ ,]+"));
}
protected List 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 370096ef3b7..5d0b8a7ab9d 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 2f4616900d6..b4e3f37f488 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 @@ private void inherit(final ServiceProvider child, final ServiceProvider parent)
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 b2b42cafd0c..0522a7e6d7d 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 void setConstructor(final String constructor) {
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 ba7f06779ac..f65cc788c2b 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 void startElement(final String uri, final String localName, final String
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 7c92f3adb59..1b2c042298f 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 @@
* <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="provider-type" use="required" type="{http://www.openejb.org/Service/Configuration}ProviderTypes" />
* <attribute name="constructor" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * <attribute name="constructor-types" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="factory-name" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
@@ -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 void setConstructor(final String value) {
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 4cc1db8ea1f..694bc97bbe3 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 void startElement(final String uri, final String localName, final String
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 4df9ccf9393..66f70cd6d62 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 BmpEntityContainerBuilder() {
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 53d2d907a1a..dd94abac928 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 CmpEntityContainerBuilder() {
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 60ab3599c2f..5a2a93f1c34 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 DataSourceBuilder() {
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 ac5177c7064..3aa40d183d2 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 ManagedContainerBuilder() {
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 94721f98112..123e75e64d0 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 MessageDrivenContainerBuilder() {
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 d163cc0324e..538be302a0f 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 QueueBuilder() {
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 9a9d660a89b..634f7e4af4c 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 SingletonContainerBuilder() {
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 854bf79492b..fc8b0aeaf75 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 TopicBuilder() {
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 f7296c5beaf..e03dea04fc7 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 TransactionManagerBuilder() {
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 876f18b3d76..18d8ee3ce3e 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 FlushableDataSourceHandler(final CommonDataSource original, final FlushCo
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 50ef7c58ebf..1a44c9b6605 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
-
+
@@ -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">
@@ -510,8 +514,8 @@
service="SecurityService"
types="SecurityService"
class-name="org.apache.openejb.core.security.SecurityServiceImpl">
-
- DefaultUser guest
+
+ DefaultUser guest
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 232e7a92543..726e16e1a05 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 @@
+
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 0e5aa786115..e8496add81d 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 775492e1a03..a91ba38a208 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 8620ac11240..21f04e59036 100644
--- a/docs/application-resources.adoc
+++ b/docs/application-resources.adoc
@@ -290,6 +290,25 @@ specify the arguments as a comma separated list:
----
+=== 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]
+----
+
+ url http://localhost
+ username tomee
+ poolSize 20
+
+----
+
=== 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 2f5c17c5b9b..77a3c1aca2a 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]
-----
-
-----
-
-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 4ab44a1bc30..8dd8900500c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -135,7 +135,7 @@
1.2.6
2.5.1
- 4.28
+ 4.30
2.4.21
11.0.20
3.11.1
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 b61394f3ea7..51fe7083642 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.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 @@ protected ServerService initServer(final String serviceName, final Properties se
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> 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");