diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Alpha.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Alpha.java new file mode 100644 index 000000000..17405a9cd --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Alpha.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class Alpha { + public String value() { + return "alpha"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Bravo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Bravo.java new file mode 100644 index 000000000..508e1c3ba --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/Bravo.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class Bravo { + public String value() { + return "bravo"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsExtension.java new file mode 100644 index 000000000..493c41bb6 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsExtension.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(Alpha.class, new Annotation[0]) + .withInjectionPoint(Bravo.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class) + .disposeWith(SyntheticPojoDisposer.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsTest.java new file mode 100644 index 000000000..c9ec01445 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticInjectionsTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ca", note = "withInjectionPoint(Class) registers injection points") + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cb", note = "no qualifier passed, @Default is assumed") + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cd", note = "SyntheticInjections used in creator") + public void testCreatorReceivesInjections() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + SyntheticPojo pojo = handle.get(); + assertEquals(pojo.alphaValue, "alpha"); + assertEquals(pojo.bravoValue, "bravo"); + handle.destroy(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ce", note = "SyntheticInjections used in disposer") + public void testDisposerReceivesInjections() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + handle.get(); + SyntheticPojoDisposer.disposed.set(false); + SyntheticPojoDisposer.bravoValueInDisposer = null; + handle.destroy(); + assertTrue(SyntheticPojoDisposer.disposed.get()); + assertEquals(SyntheticPojoDisposer.bravoValueInDisposer, "bravo"); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojo.java new file mode 100644 index 000000000..8db75a998 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojo.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +public class SyntheticPojo { + public final String alphaValue; + public final String bravoValue; + + public SyntheticPojo(String alphaValue, String bravoValue) { + this.alphaValue = alphaValue; + this.bravoValue = bravoValue; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoCreator.java new file mode 100644 index 000000000..a80335e77 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoCreator.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + Alpha alpha = injections.get(Alpha.class); + Bravo bravo = injections.get(Bravo.class); + return new SyntheticPojo(alpha.value(), bravo.value()); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoDisposer.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoDisposer.java new file mode 100644 index 000000000..787c92a9c --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjections/SyntheticPojoDisposer.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjections; + +import java.util.concurrent.atomic.AtomicBoolean; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanDisposer; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoDisposer implements SyntheticBeanDisposer { + static final AtomicBoolean disposed = new AtomicBoolean(false); + static String bravoValueInDisposer = null; + + @Override + public void dispose(SyntheticPojo instance, SyntheticInjections injections, Parameters params) { + Bravo bravo = injections.get(Bravo.class); + bravoValueInDisposer = bravo.value(); + disposed.set(true); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/AnnotationInfoExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/AnnotationInfoExtension.java new file mode 100644 index 000000000..50aba0887 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/AnnotationInfoExtension.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.AnnotationBuilder; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class AnnotationInfoExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(Widget.class, new Annotation[0]) + .withInjectionPoint(Widget.class, AnnotationBuilder.of(Nice.class).build()) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Nice.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Nice.java new file mode 100644 index 000000000..b55b2a0d8 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Nice.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) +public @interface Nice { + final class Literal extends AnnotationLiteral implements Nice { + public static final Literal INSTANCE = new Literal(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/NiceWidget.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/NiceWidget.java new file mode 100644 index 000000000..168237e20 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/NiceWidget.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import jakarta.enterprise.context.Dependent; + +@Nice +@Dependent +public class NiceWidget implements Widget { + @Override + public String name() { + return "nice"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/PlainWidget.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/PlainWidget.java new file mode 100644 index 000000000..6f8be0321 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/PlainWidget.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class PlainWidget implements Widget { + @Override + public String name() { + return "plain"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticInjectionsAnnotationInfoTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticInjectionsAnnotationInfoTest.java new file mode 100644 index 000000000..b6cfb1907 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticInjectionsAnnotationInfoTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import static org.testng.Assert.assertEquals; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsAnnotationInfoTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsAnnotationInfoTest.class) + .withBuildCompatibleExtension(AnnotationInfoExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ca", note = "withInjectionPoint(Class, AnnotationInfo...) overload") + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cl", note = "AnnotationInfo qualifier distinguishes beans") + public void testAnnotationInfoQualifier() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + SyntheticPojo pojo = handle.get(); + assertEquals(pojo.plainName, "plain"); + assertEquals(pojo.niceName, "nice"); + handle.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojo.java new file mode 100644 index 000000000..a1ae8579d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojo.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +public class SyntheticPojo { + public final String plainName; + public final String niceName; + + public SyntheticPojo(String plainName, String niceName) { + this.plainName = plainName; + this.niceName = niceName; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojoCreator.java new file mode 100644 index 000000000..eaae861d2 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/SyntheticPojoCreator.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + Widget plain = injections.get(Widget.class); + Widget nice = injections.get(Widget.class, Nice.Literal.INSTANCE); + return new SyntheticPojo(plain.name(), nice.name()); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Widget.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Widget.java new file mode 100644 index 000000000..c7dae2773 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsAnnotationInfo/Widget.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsAnnotationInfo; + +public interface Widget { + String name(); +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentExtension.java new file mode 100644 index 000000000..4d703d98a --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentExtension.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsDependentExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(TrackedBean.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class) + .disposeWith(SyntheticPojoDisposer.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentTest.java new file mode 100644 index 000000000..a0c58a5ff --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticInjectionsDependentTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import static org.testng.Assert.assertEquals; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsDependentTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsDependentTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsDependentExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ch", note = "@Dependent beans from SyntheticInjections destroyed with synthetic bean") + public void testDependentBeanLifecycle() { + TrackedBean.reset(); + SyntheticPojo.reset(); + + Instance lookup = getCurrentBeanContainer().createInstance(); + + assertEquals(TrackedBean.createdCount.get(), 0); + assertEquals(TrackedBean.destroyedCount.get(), 0); + + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + handle.get(); + + // TrackedBean was obtained during creation + assertEquals(TrackedBean.createdCount.get(), 1); + assertEquals(TrackedBean.destroyedCount.get(), 0); + + handle.destroy(); + + // After synthetic bean destruction: + // - TrackedBean created in creator should be destroyed + // - TrackedBean created in disposer is also destroyed (disposer dependents + // are destroyed when disposal completes) + assertEquals(TrackedBean.createdCount.get(), 2); + assertEquals(TrackedBean.destroyedCount.get(), 2); + assertEquals(SyntheticPojo.destroyedCount.get(), 1); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojo.java new file mode 100644 index 000000000..85334ac0a --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojo.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import java.util.concurrent.atomic.AtomicInteger; + +public class SyntheticPojo { + static final AtomicInteger createdCount = new AtomicInteger(0); + static final AtomicInteger destroyedCount = new AtomicInteger(0); + + static void reset() { + createdCount.set(0); + destroyedCount.set(0); + } + + public SyntheticPojo() { + createdCount.incrementAndGet(); + } + + public void destroy() { + destroyedCount.incrementAndGet(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoCreator.java new file mode 100644 index 000000000..e1e9f4cdb --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoCreator.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + TrackedBean tracked = injections.get(TrackedBean.class); + tracked.ping(); + return new SyntheticPojo(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoDisposer.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoDisposer.java new file mode 100644 index 000000000..0378f4c08 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/SyntheticPojoDisposer.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanDisposer; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoDisposer implements SyntheticBeanDisposer { + @Override + public void dispose(SyntheticPojo instance, SyntheticInjections injections, Parameters params) { + TrackedBean tracked = injections.get(TrackedBean.class); + tracked.ping(); + instance.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/TrackedBean.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/TrackedBean.java new file mode 100644 index 000000000..e2447ae0f --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsDependent/TrackedBean.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsDependent; + +import java.util.concurrent.atomic.AtomicInteger; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.Dependent; + +@Dependent +public class TrackedBean { + static final AtomicInteger createdCount = new AtomicInteger(0); + static final AtomicInteger destroyedCount = new AtomicInteger(0); + + static void reset() { + createdCount.set(0); + destroyedCount.set(0); + } + + @PostConstruct + void postConstruct() { + createdCount.incrementAndGet(); + } + + @PreDestroy + void preDestroy() { + destroyedCount.incrementAndGet(); + } + + public String ping() { + return "tracked"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/MyQualifier.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/MyQualifier.java new file mode 100644 index 000000000..bb1d6d480 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/MyQualifier.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.enterprise.util.Nonbinding; +import jakarta.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) +public @interface MyQualifier { + String binding(); + + @Nonbinding + String nonBinding(); + + final class Literal extends AnnotationLiteral implements MyQualifier { + private final String binding; + private final String nonBinding; + + public Literal(String binding, String nonBinding) { + this.binding = binding; + this.nonBinding = nonBinding; + } + + @Override + public String binding() { + return binding; + } + + @Override + public String nonBinding() { + return nonBinding; + } + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/PojoConsumer.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/PojoConsumer.java new file mode 100644 index 000000000..a83acb7c4 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/PojoConsumer.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; + +@Dependent +public class PojoConsumer { + @Inject + @MyQualifier(binding = "alpha", nonBinding = "bravo") + SyntheticPojo pojo; +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointExtension.java new file mode 100644 index 000000000..c08809265 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointExtension.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; +import jakarta.enterprise.inject.spi.InjectionPoint; + +public class SyntheticInjectionsInjectionPointExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .qualifier(new MyQualifier.Literal("alpha", "")) + .withInjectionPoint(InjectionPoint.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class) + .disposeWith(SyntheticPojoDisposer.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointTest.java new file mode 100644 index 000000000..87bd4c451 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticInjectionsInjectionPointTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsInjectionPointTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsInjectionPointTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsInjectionPointExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ci", note = "@Dependent synthetic bean can obtain InjectionPoint from SyntheticInjections") + public void testInjectionPointLookup() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(PojoConsumer.class).getHandle(); + PojoConsumer consumer = handle.get(); + assertNotNull(consumer.pojo); + assertNotNull(consumer.pojo.injectionPoint); + assertEquals(consumer.pojo.injectionPoint.getType(), SyntheticPojo.class); + + MyQualifier qualifier = null; + for (Annotation a : consumer.pojo.injectionPoint.getQualifiers()) { + if (a instanceof MyQualifier) { + qualifier = (MyQualifier) a; + } + } + assertNotNull(qualifier); + assertEquals(qualifier.binding(), "alpha"); + assertEquals(qualifier.nonBinding(), "bravo"); + + assertNotNull(consumer.pojo.injectionPoint.getBean()); + assertEquals(consumer.pojo.injectionPoint.getBean().getBeanClass(), PojoConsumer.class); + assertFalse(consumer.pojo.injectionPoint.isDelegate()); + assertFalse(consumer.pojo.injectionPoint.isTransient()); + assertNotNull(consumer.pojo.injectionPoint.getMember()); + assertNotNull(consumer.pojo.injectionPoint.getAnnotated()); + handle.destroy(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ci", note = "InjectionPoint lookup in disposer via SyntheticInjections is invalid") + public void testDisposerInjectionPointLookupIsInvalid() { + Instance lookup = getCurrentBeanContainer().createInstance(); + + SyntheticPojoDisposer.lookedUp = null; + + Instance.Handle handle = lookup.select(PojoConsumer.class).getHandle(); + handle.get(); + + handle.destroy(); + + assertNull(SyntheticPojoDisposer.lookedUp); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojo.java new file mode 100644 index 000000000..01124896e --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojo.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import jakarta.enterprise.inject.spi.InjectionPoint; + +public class SyntheticPojo { + public final InjectionPoint injectionPoint; + + public SyntheticPojo(InjectionPoint injectionPoint) { + this.injectionPoint = injectionPoint; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoCreator.java new file mode 100644 index 000000000..4db497e00 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoCreator.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; +import jakarta.enterprise.inject.spi.InjectionPoint; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + InjectionPoint ip = injections.get(InjectionPoint.class); + return new SyntheticPojo(ip); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoDisposer.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoDisposer.java new file mode 100644 index 000000000..30655b79a --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPoint/SyntheticPojoDisposer.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPoint; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanDisposer; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; +import jakarta.enterprise.inject.spi.InjectionPoint; + +public class SyntheticPojoDisposer implements SyntheticBeanDisposer { + static InjectionPoint lookedUp = null; + + @Override + public void dispose(SyntheticPojo instance, SyntheticInjections injections, Parameters params) { + try { + lookedUp = injections.get(InjectionPoint.class); + } catch (Exception ignored) { + // The spec says looking up InjectionPoint in a disposer is "invalid". + // The container may throw any exception. + } + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/MyService.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/MyService.java new file mode 100644 index 000000000..7efbe768e --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/MyService.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPointIndirect; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.spi.InjectionPoint; +import jakarta.inject.Inject; + +@Dependent +public class MyService { + @Inject + InjectionPoint injectionPoint; +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointExtension.java new file mode 100644 index 000000000..09187dfe7 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointExtension.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPointIndirect; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsIndirectInjectionPointExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(MyService.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointTest.java new file mode 100644 index 000000000..31db92db8 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticInjectionsIndirectInjectionPointTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPointIndirect; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +import jakarta.enterprise.inject.Default; +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsIndirectInjectionPointTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsIndirectInjectionPointTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsIndirectInjectionPointExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ci", note = "InjectionPoint metadata is available for a dependent bean injected into a synthetic bean") + public void testIndirectInjectionPoint() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + SyntheticPojo pojo = handle.get(); + + assertNotNull(pojo.serviceInjectionPoint); + assertEquals(pojo.serviceInjectionPoint.getType(), MyService.class); + assertTrue(pojo.serviceInjectionPoint.getQualifiers().contains(Default.Literal.INSTANCE)); + assertNotNull(pojo.serviceInjectionPoint.getBean()); + assertEquals(pojo.serviceInjectionPoint.getBean().getBeanClass(), SyntheticPojo.class); + assertFalse(pojo.serviceInjectionPoint.isDelegate()); + assertFalse(pojo.serviceInjectionPoint.isTransient()); + assertNull(pojo.serviceInjectionPoint.getAnnotated()); + assertNull(pojo.serviceInjectionPoint.getMember()); + + handle.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojo.java new file mode 100644 index 000000000..a48a9c0dc --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojo.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPointIndirect; + +import jakarta.enterprise.inject.spi.InjectionPoint; + +public class SyntheticPojo { + public final InjectionPoint serviceInjectionPoint; + + public SyntheticPojo(InjectionPoint serviceInjectionPoint) { + this.serviceInjectionPoint = serviceInjectionPoint; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojoCreator.java new file mode 100644 index 000000000..32f52d1d6 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsInjectionPointIndirect/SyntheticPojoCreator.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsInjectionPointIndirect; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + MyService service = injections.get(MyService.class); + return new SyntheticPojo(service.injectionPoint); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/DefaultService.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/DefaultService.java new file mode 100644 index 000000000..c8e9c516f --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/DefaultService.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class DefaultService implements MyService { + @Override + public String id() { + return "default"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/MyService.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/MyService.java new file mode 100644 index 000000000..61ff68220 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/MyService.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +public interface MyService { + String id(); +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/Special.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/Special.java new file mode 100644 index 000000000..3d11826f1 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/Special.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.inject.Qualifier; + +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) +public @interface Special { + final class Literal extends AnnotationLiteral implements Special { + public static final Literal INSTANCE = new Literal(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SpecialService.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SpecialService.java new file mode 100644 index 000000000..03a2aa21e --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SpecialService.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import jakarta.enterprise.context.Dependent; + +@Special +@Dependent +public class SpecialService implements MyService { + @Override + public String id() { + return "special"; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierExtension.java new file mode 100644 index 000000000..a7ebec5b0 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierExtension.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsQualifierExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(MyService.class, new Annotation[0]) + .withInjectionPoint(MyService.class, Special.Literal.INSTANCE) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierTest.java new file mode 100644 index 000000000..593cc1921 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticInjectionsQualifierTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import static org.testng.Assert.assertEquals; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsQualifierTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsQualifierTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsQualifierExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cl", note = "qualifier distinguishes beans in SyntheticInjections.get()") + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cb", note = "no qualifier = @Default assumed") + public void testQualifiedInjections() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + SyntheticPojo pojo = handle.get(); + assertEquals(pojo.defaultId, "default"); + assertEquals(pojo.specialId, "special"); + handle.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojo.java new file mode 100644 index 000000000..d5da28184 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojo.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +public class SyntheticPojo { + public final String defaultId; + public final String specialId; + + public SyntheticPojo(String defaultId, String specialId) { + this.defaultId = defaultId; + this.specialId = specialId; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojoCreator.java new file mode 100644 index 000000000..c3cec2dd5 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsQualifier/SyntheticPojoCreator.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsQualifier; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + MyService defaultSvc = injections.get(MyService.class); + MyService specialSvc = injections.get(MyService.class, Special.Literal.INSTANCE); + return new SyntheticPojo(defaultSvc.id(), specialSvc.id()); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/Converter.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/Converter.java new file mode 100644 index 000000000..f4d0ef1fe --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/Converter.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +public interface Converter { + String convert(T input); +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/StringConverter.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/StringConverter.java new file mode 100644 index 000000000..111a23072 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/StringConverter.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class StringConverter implements Converter { + @Override + public String convert(String input) { + return input.toUpperCase(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralExtension.java new file mode 100644 index 000000000..ff088197d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralExtension.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; +import jakarta.enterprise.inject.build.compatible.spi.Types; +import jakarta.enterprise.lang.model.types.Type; + +public class SyntheticInjectionsTypeLiteralExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn, Types types) { + // Build Converter as a lang model Type + Type converterOfString = types.parameterized(Converter.class, String.class); + + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(converterOfString, new Annotation[0]) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralTest.java new file mode 100644 index 000000000..f151567f8 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticInjectionsTypeLiteralTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +import static org.testng.Assert.assertEquals; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsTypeLiteralTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsTypeLiteralTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsTypeLiteralExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cg", note = "TypeLiteral used to look up parameterized type") + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "ca", note = "withInjectionPoint(Type) registers parameterized type") + public void testTypeLiteralInjection() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + SyntheticPojo pojo = handle.get(); + assertEquals(pojo.convertedValue, "HELLO"); + handle.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojo.java new file mode 100644 index 000000000..c93e31c50 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojo.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +public class SyntheticPojo { + public final String convertedValue; + + public SyntheticPojo(String convertedValue) { + this.convertedValue = convertedValue; + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojoCreator.java new file mode 100644 index 000000000..9ed1e5a7d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsTypeLiteral/SyntheticPojoCreator.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsTypeLiteral; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; +import jakarta.enterprise.util.TypeLiteral; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + Converter converter = injections.get(new TypeLiteral>() { + }); + return new SyntheticPojo(converter.convert("hello")); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/RegisteredBean.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/RegisteredBean.java new file mode 100644 index 000000000..6ea8b3f97 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/RegisteredBean.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class RegisteredBean { +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredExtension.java new file mode 100644 index 000000000..b1281fb35 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredExtension.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsUnregisteredExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(RegisteredBean.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredTest.java new file mode 100644 index 000000000..379091a9d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticInjectionsUnregisteredTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +import static org.testng.Assert.assertTrue; + +import jakarta.enterprise.inject.Instance; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsUnregisteredTest extends AbstractTest { + @Deployment + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsUnregisteredTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsUnregisteredExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cf", note = "SyntheticInjections.get() throws IllegalArgumentException for unregistered type") + public void testUnregisteredLookupThrows() { + Instance lookup = getCurrentBeanContainer().createInstance(); + Instance.Handle handle = lookup.select(SyntheticPojo.class).getHandle(); + handle.get(); + assertTrue(SyntheticPojoCreator.illegalArgumentThrown, + "Expected IllegalArgumentException when looking up unregistered bean"); + handle.destroy(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojo.java new file mode 100644 index 000000000..39af2e244 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojo.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +public class SyntheticPojo { +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojoCreator.java new file mode 100644 index 000000000..f38f58f5a --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/SyntheticPojoCreator.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + static boolean illegalArgumentThrown = false; + + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + // This should work — RegisteredBean was registered + injections.get(RegisteredBean.class); + + // This should throw IllegalArgumentException — UnregisteredBean was NOT registered + try { + injections.get(UnregisteredBean.class); + } catch (IllegalArgumentException e) { + illegalArgumentThrown = true; + } + + return new SyntheticPojo(); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/UnregisteredBean.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/UnregisteredBean.java new file mode 100644 index 000000000..b95093afc --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsUnregistered/UnregisteredBean.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsUnregistered; + +import jakarta.enterprise.context.Dependent; + +@Dependent +public class UnregisteredBean { +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/NonExistentBean.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/NonExistentBean.java new file mode 100644 index 000000000..057fced58 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/NonExistentBean.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsValidation; + +import jakarta.enterprise.inject.Vetoed; + +@Vetoed +public class NonExistentBean { +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationExtension.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationExtension.java new file mode 100644 index 000000000..de487351d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationExtension.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsValidation; + +import java.lang.annotation.Annotation; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension; +import jakarta.enterprise.inject.build.compatible.spi.Synthesis; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticComponents; + +public class SyntheticInjectionsValidationExtension implements BuildCompatibleExtension { + @Synthesis + public void synthesize(SyntheticComponents syn) { + syn.addBean(SyntheticPojo.class) + .type(SyntheticPojo.class) + .scope(Dependent.class) + .withInjectionPoint(NonExistentBean.class, new Annotation[0]) + .createWith(SyntheticPojoCreator.class); + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationTest.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationTest.java new file mode 100644 index 000000000..bce436415 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticInjectionsValidationTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsValidation; + +import jakarta.enterprise.inject.spi.DeploymentException; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.ShouldThrowException; +import org.jboss.cdi.tck.AbstractTest; +import org.jboss.cdi.tck.cdi.Sections; +import org.jboss.cdi.tck.shrinkwrap.WebArchiveBuilder; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.test.audit.annotations.SpecAssertion; +import org.jboss.test.audit.annotations.SpecVersion; +import org.testng.annotations.Test; + +@SpecVersion(spec = "cdi", version = "5.0") +public class SyntheticInjectionsValidationTest extends AbstractTest { + @Deployment + @ShouldThrowException(DeploymentException.class) + public static WebArchive createTestArchive() { + return new WebArchiveBuilder() + .withTestClassPackage(SyntheticInjectionsValidationTest.class) + .withBuildCompatibleExtension(SyntheticInjectionsValidationExtension.class) + .build(); + } + + @Test + @SpecAssertion(section = Sections.SYNTHESIS_PHASE, id = "cc", note = "Unresolvable injection point causes deployment problem") + public void trigger() { + } +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojo.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojo.java new file mode 100644 index 000000000..b8eb5441d --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojo.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsValidation; + +public class SyntheticPojo { +} diff --git a/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojoCreator.java b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojoCreator.java new file mode 100644 index 000000000..e2cacc3b5 --- /dev/null +++ b/impl/src/main/java/org/jboss/cdi/tck/tests/build/compatible/extensions/syntheticBeanInjectionsValidation/SyntheticPojoCreator.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * Apache Software License 2.0 which is available at: + * https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.jboss.cdi.tck.tests.build.compatible.extensions.syntheticBeanInjectionsValidation; + +import jakarta.enterprise.inject.build.compatible.spi.Parameters; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticBeanCreator; +import jakarta.enterprise.inject.build.compatible.spi.SyntheticInjections; + +public class SyntheticPojoCreator implements SyntheticBeanCreator { + @Override + public SyntheticPojo create(SyntheticInjections injections, Parameters params) { + return new SyntheticPojo(); + } +} diff --git a/impl/src/main/resources/tck-audit-cdi.xml b/impl/src/main/resources/tck-audit-cdi.xml index 10c814288..4e67f651c 100644 --- a/impl/src/main/resources/tck-audit-cdi.xml +++ b/impl/src/main/resources/tck-audit-cdi.xml @@ -6601,6 +6601,36 @@ Test that synthesis observers are notified of fired events + + A synthetic bean may declare injection points using |withInjectionPoint()|. These injection points are validated by the container at deployment time. + + + If no qualifier is passed to |withInjectionPoint()|, |@Default| is assumed. + + + A registered injection point for which no matching bean exists is treated as a deployment problem. + + + The synthetic bean creation function may accept a |SyntheticInjections| parameter to obtain injectable references for registered injection points. + + + The synthetic bean destruction function may accept a |SyntheticInjections| parameter to obtain injectable references for registered injection points. + + + |SyntheticInjections.get()| throws |IllegalArgumentException| if the type/qualifiers combination was not registered with |withInjectionPoint()|. + + + |SyntheticInjections.get()| may use |TypeLiteral| to look up parameterized bean types. + + + All |@Dependent| bean instances created by |SyntheticInjections| are destroyed when the corresponding synthetic bean instance is destroyed. + + + For a |@Dependent| synthetic bean, the |InjectionPoint| to which it is injected may be obtained from the |SyntheticInjections| parameter, if previously registered. + + + |SyntheticInjections.get()| with a qualifier retrieves the bean matching both type and qualifier. +