This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch 4.1.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 7fc8115cd409b2e23cd447b532b30d488722b95e Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Wed Oct 21 13:31:36 2026 +0100 CXF-8769 - Support fromString/valueOf inherited from a non-public class (#3614) (cherry picked from commit c380322d70021b707e8c0f9422cb53f975703f0b) --- .../org/apache/cxf/jaxrs/utils/InjectionUtils.java | 8 ++++- .../apache/cxf/jaxrs/resources/AbstractUserId.java | 32 ++++++++++++++++++ .../org/apache/cxf/jaxrs/resources/UserId.java | 38 ++++++++++++++++++++++ .../apache/cxf/jaxrs/utils/InjectionUtilsTest.java | 9 +++++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java index 02e9d86e22c..b61157c077a 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java @@ -27,6 +27,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; +import java.lang.reflect.InaccessibleObjectException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -657,11 +658,16 @@ public final class InjectionUtils { try { Method m = pClass.getMethod(methodName, new Class<?>[]{String.class}); if (Modifier.isStatic(m.getModifiers())) { + if (!Modifier.isPublic(m.getDeclaringClass().getModifiers())) { + // a public static method inherited from a non-public class (as generated + // by e.g. Immutables) is not accessible via reflection without this + ReflectionUtil.setAccessible(m); + } return pClass.cast(m.invoke(null, new Object[]{value})); } } catch (NoSuchMethodException ex) { // no luck: try another factory methods - } catch (IllegalAccessException ex) { + } catch (IllegalAccessException | InaccessibleObjectException | SecurityException ex) { // factory method is not accessible: try another } diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/AbstractUserId.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/AbstractUserId.java new file mode 100644 index 00000000000..9c91ff99036 --- /dev/null +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/AbstractUserId.java @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.jaxrs.resources; + +import java.util.UUID; + +/** + * Package-private base class declaring the fromString factory method, as generated by + * libraries such as Immutables, see CXF-8769 + */ +abstract class AbstractUserId { + public static UserId fromString(String id) { + return UserId.of(UUID.fromString(id)); + } +} diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/UserId.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/UserId.java new file mode 100644 index 00000000000..272a9331f29 --- /dev/null +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/resources/UserId.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.jaxrs.resources; + +import java.util.UUID; + +public final class UserId extends AbstractUserId { + private final UUID id; + + private UserId(UUID id) { + this.id = id; + } + + public static UserId of(UUID id) { + return new UserId(id); + } + + public String getId() { + return id.toString(); + } +} diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java index 7d4a6df867c..4968f7b901d 100644 --- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java +++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/InjectionUtilsTest.java @@ -46,6 +46,7 @@ import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.jaxrs.model.ParameterType; import org.apache.cxf.jaxrs.provider.ProviderFactory; import org.apache.cxf.jaxrs.provider.ServerProviderFactory; +import org.apache.cxf.jaxrs.resources.UserId; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.ExchangeImpl; import org.apache.cxf.message.Message; @@ -168,6 +169,14 @@ public class InjectionUtilsTest { assertEquals("Type is wrong", "a6f7357f-6e7e-40e5-9b4a-c455c23b10a2", helmId.getId()); } + @Test + public void testInstantiateClassWithFactoryMethodInheritedFromNonPublicClass() { + UserId userId = InjectionUtils.handleParameter("a6f7357f-6e7e-40e5-9b4a-c455c23b10a2", false, UserId.class, + UserId.class, null, + ParameterType.PATH, null); + assertEquals("Type is wrong", "a6f7357f-6e7e-40e5-9b4a-c455c23b10a2", userId.getId()); + } + @Test public void testInstantiateIntegerInQuery() { Integer integer = InjectionUtils.handleParameter("", false, Integer.class,
