Hi all,

some off list discussion on Slack with Romain resulted in uncovering XBEAN-350, 
which seems to be the root cause of this behaviour.

We can hopefully fix it, so ctor selection in this case should work just fine.

Gruß 
Richard 



Am 24. Oktober 2025 11:59:43 MESZ schrieb Richard Zowalla <[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

Reply via email to