diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java new file mode 100644 index 0000000000000..4ebf0abe4de45 --- /dev/null +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java @@ -0,0 +1,50 @@ +package io.quarkus.arc.test.unproxyable; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.test.unproxyable.some.Resource; +import io.quarkus.test.QuarkusUnitTest; + +// This test aims to test the https://github.com/quarkusio/quarkus/issues/22815 in Quarkus integration +// There is a duplicate test for ArC standalone: io.quarkus.arc.test.clientproxy.constructor.ProducerReturnTypePackagePrivateNoArgsConstructorTest +public class ProducerReturnTypePackagePrivateNoArgsConstructorTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot(root -> root + .addClasses(ProducerReturnTypePackagePrivateNoArgsConstructorTest.class, ResourceProducer.class, + Resource.class)); + + @Inject + Instance instance; + + @Test + public void testProducer() throws IOException { + assertTrue(instance.isResolvable()); + assertEquals(5, instance.get().ping()); + } + + @Singleton + static class ResourceProducer { + + @ApplicationScoped + @Produces + Resource resource() { + return Resource.from(5); + } + + } + +} diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/some/Resource.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/some/Resource.java new file mode 100644 index 0000000000000..de4455f18f6a8 --- /dev/null +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/unproxyable/some/Resource.java @@ -0,0 +1,20 @@ +package io.quarkus.arc.test.unproxyable.some; + +public abstract class Resource { + + Resource() { + } + + public static Resource from(int ping) { + return new Resource() { + + @Override + public int ping() { + return ping; + } + }; + } + + public abstract int ping(); + +} diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java index 8c34ecf0969d6..786837e2c0b61 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java @@ -895,7 +895,7 @@ private List findBeans(Collection beanDefiningAnnotations, Li // non-inherited stuff: for (MethodInfo method : beanClass.methods()) { - if (Methods.isSynthetic(method)) { + if (method.isSynthetic()) { continue; } if (annotationStore.getAnnotations(method).isEmpty()) { @@ -922,7 +922,7 @@ private List findBeans(Collection beanDefiningAnnotations, Li while (aClass != null) { for (MethodInfo method : aClass.methods()) { Methods.MethodKey methodDescriptor = new Methods.MethodKey(method); - if (Methods.isSynthetic(method) || Methods.isOverriden(methodDescriptor, methods)) { + if (method.isSynthetic() || Methods.isOverriden(methodDescriptor, methods)) { continue; } methods.add(methodDescriptor); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java index 678eb0f701820..8c012e64800a6 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanGenerator.java @@ -1793,7 +1793,7 @@ protected void implementIsSuppressed(BeanInfo bean, ClassCreator beanCreator) { private String getProxyTypeName(BeanInfo bean, String baseName) { StringBuilder proxyTypeName = new StringBuilder(); - proxyTypeName.append(bean.getTargetPackageName()); + proxyTypeName.append(bean.getClientProxyPackageName()); if (proxyTypeName.length() > 0) { proxyTypeName.append("."); } diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanInfo.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanInfo.java index 86f245aace871..026d3f18f78a4 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanInfo.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanInfo.java @@ -492,6 +492,22 @@ public String getTargetPackageName() { return packageName; } + public String getClientProxyPackageName() { + if (isProducerField() || isProducerMethod()) { + AnnotationTarget target = getTarget().get(); + DotName typeName = target.kind() == Kind.FIELD ? target.asField().type().name() + : target.asMethod().returnType().name(); + String packageName = DotNames.packageName(typeName); + if (packageName.startsWith("java.")) { + // It is not possible to place a class in a JDK package + packageName = AbstractGenerator.DEFAULT_PACKAGE; + } + return packageName; + } else { + return getTargetPackageName(); + } + } + void validate(List errors, List validators, Consumer bytecodeTransformerConsumer, Set classesReceivingNoArgsCtor) { Beans.validateBean(this, errors, validators, bytecodeTransformerConsumer, classesReceivingNoArgsCtor); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ClientProxyGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ClientProxyGenerator.java index 62a7320b42ba6..36e2309d0f9d9 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ClientProxyGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ClientProxyGenerator.java @@ -84,7 +84,7 @@ Collection generate(BeanInfo bean, String beanClassName, ProviderType providerType = new ProviderType(bean.getProviderType()); ClassInfo providerClass = getClassByName(bean.getDeployment().getBeanArchiveIndex(), providerType.name()); String baseName = getBaseName(bean, beanClassName); - String targetPackage = bean.getTargetPackageName(); + String targetPackage = bean.getClientProxyPackageName(); String generatedName = generatedNameFromTarget(targetPackage, baseName, CLIENT_PROXY_SUFFIX); if (existingClasses.contains(generatedName)) { return Collections.emptyList(); diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java index dc7b71450cff7..82317e337438b 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Methods.java @@ -42,10 +42,9 @@ final class Methods { public static final String INIT = ""; // static initializer public static final String CLINIT = ""; - // copied from java.lang.reflect.Modifier.SYNTHETIC - static final int SYNTHETIC = 0x00001000; // copied from java.lang.reflect.Modifier.BRIDGE static final int BRIDGE = 0x00000040; + public static final String TO_STRING = "toString"; private static final List IGNORED_METHODS = initIgnoredMethods(); @@ -60,10 +59,6 @@ private static List initIgnoredMethods() { private Methods() { } - static boolean isSynthetic(MethodInfo method) { - return (method.flags() & SYNTHETIC) != 0; - } - static boolean isBridge(MethodInfo method) { return (method.flags() & BRIDGE) != 0; } diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java new file mode 100644 index 0000000000000..8fa51503cc28e --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/ProducerReturnTypePackagePrivateNoArgsConstructorTest.java @@ -0,0 +1,44 @@ +package io.quarkus.arc.test.clientproxy.constructor; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.ClientProxy; +import io.quarkus.arc.test.ArcTestContainer; +import io.quarkus.arc.test.clientproxy.constructor.some.Resource; +import java.io.IOException; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Singleton; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +// This test aims to test the https://github.com/quarkusio/quarkus/issues/22815 in ArC standalone +// There is a duplicate test for Quarkus integration: io.quarkus.arc.test.unproxyable.ProducerReturnTypePackagePrivateNoArgsConstructorTest +public class ProducerReturnTypePackagePrivateNoArgsConstructorTest { + + @RegisterExtension + public ArcTestContainer container = new ArcTestContainer(ResourceProducer.class); + + @Test + public void testProducer() throws IOException { + Resource res = Arc.container().instance(Resource.class).get(); + assertNotNull(res); + assertTrue(res instanceof ClientProxy); + assertEquals(5, res.ping()); + } + + @Singleton + static class ResourceProducer { + + @ApplicationScoped + @Produces + Resource resource() { + return Resource.from(5); + } + + } + +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/some/Resource.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/some/Resource.java new file mode 100644 index 0000000000000..e45ce99529978 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/clientproxy/constructor/some/Resource.java @@ -0,0 +1,20 @@ +package io.quarkus.arc.test.clientproxy.constructor.some; + +public abstract class Resource { + + Resource() { + } + + public static Resource from(int ping) { + return new Resource() { + + @Override + public int ping() { + return ping; + } + }; + } + + public abstract int ping(); + +}