Ctor selection behavior in TomEE/XBean for Application Resources defined via Properties

Richard Zowalla <[email protected]> Fri, 24 Oct 2025 11:59:43 +0200
Newsgroups gmane.comp.java.openejb.devel
Message-ID <[email protected]>
Hi all,

Martin W. and myself were running into a rather weird issue in unit tests with application composers (in per_jvm) mode only on Mac OSX 26.0.1 - the same tests are working fine on Linux CI (Ubuntu).

## Context

In our test context we use a @Configeration properties and the application resource definitions of TomEE [1] via a property like this:

---------
p.put(„myResourceDE", "new://Resource?class-name=my.fqdn.MyResource" +
"&constructor=locale, resourceName, useLowerCase");
p.put("myResourceDE.resourceName", "classpath:/tlm-common-stopwords_de.properties");
p.put(„myResourceDE.locale", "de");
p.put("myResourceDE.useLowerCase", "true“);
---------

Note: MyResource has multiple ctors with varying arguments, so we have signatures like (String, String, Boolean OR Locale, String, Boolean OR Locale, Properties, Boolean)
As you can see, we rely on the „constructor“ argument of the resource syntax to specify the constructor to be used for creating that resource.

## Problem

On OSX 26.0.1, we’re seeing an intermittent exception:

---------
org.apache.xbean.recipe.ConstructionException: Invalid and non-convertable constructor parameter type: name=resourceName, index=1, expected=java.util.Properties, actual=java.lang.String

at org.apache.xbean.recipe.ObjectRecipe.extractConstructorArgs(ObjectRecipe.java:597)
at org.apache.xbean.recipe.ObjectRecipe.internalCreate(ObjectRecipe.java:278)
at org.apache.xbean.recipe.AbstractRecipe.create(AbstractRecipe.java:96)
at org.apache.xbean.recipe.AbstractRecipe.create(AbstractRecipe.java:61)
at org.apache.openejb.assembler.classic.Assembler.doCreateResource(Assembler.java:3181)
at org.apache.openejb.assembler.classic.Assembler.createResource(Assembler.java:3016)
at org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:596)
at org.apache.openejb.testing.ApplicationComposers.startContainer(ApplicationComposers.java:1481)
---------

So I went ahead and did a debugging session. On OSX, the test case sometime passes and most of the time not (regardless of execution: Maven Surefire vs IDEA).
The same test passes reliably on Ubuntu.

## Findings

After some debugging, I came up in XBeans ReflectionUtil.findConstructor(…) [2]

This method relies on 

typeClass.getConstructors()
typeClass.getDeclaredConstructors()

However, according to the Javadoc [3], the order of constructors returned by these methods is not deterministic.
As a result, the sorted list (ReflectionUtil#L618f ) can differ between JVMs or OS environments.
Because TomEE doesn’t provide type arguments to the ObjectRecipe, the code simply picks the first 3-arg constructor found — leading to the exception above on OSX.

I wasn’t able to reproduce it in a standalone test case in XBeans or TomEE (since it relies on the order in which ctors are returned).

## Expectation vs. Behavior

My expectation is that, since we specify parameter names via constructor=locale,resourceName,useLowerCase,
those names should be used to select the appropriate constructor - even if the parameter types aren’t specified.

However, in XBean, parameter names are only used if parameter types are also provided.
And in TomEE, the Assembler doesn’t currently provide type arguments in Assembler#prepareRecipe(final ServiceInfo info)[4], so we end up in this situation.

## Question

How is the constructor syntax intended to work when a class provides several constructors that all have the same number of parameters (and the given parameter names aren’t used).

Should the syntax perhaps support specifying parameter types, for example:

---------
p.put("myResourceDE", "new://Resource?class-name=my.fqdn.MyResource" +
"&constructor=locale(java.lang.String),resourceName(java.lang.String),useLowerCase(java.lang.Boolean)");
---------

Any insights or background on how this constructor resolution is designed to behave would be greatly appreciated.

Thanks and Gruß
Richard




[1] https://tomee.apache.org/latest/docs/application-resources.html
[2] https://github.com/apache/geronimo-xbean/blob/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReflectionUtil.java#L583
[3] https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Class.html#getDeclaredConstructors()
[4] https://github.com/apache/tomee/blob/main/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java#L3739