Make @Singleton to be singleton with CDI integration

Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
index 9e35966..214f3c1 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
@@ -41,6 +41,7 @@
 
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.inject.Singleton;
 import javax.ws.rs.core.Application;
 
 import javax.annotation.ManagedBean;
@@ -223,6 +224,9 @@
         if (priority > ContractProvider.NO_PRIORITY) {
             builder.ranked(priority);
         }
+        if (clazz.isAnnotationPresent(Singleton.class) && beanScopeAnnotation == null) {
+            builder.in(Singleton.class);
+        }
 
         injectionManager.register(builder);
 
diff --git a/tests/integration/cdi-integration/cdi-singleton/pom.xml b/tests/integration/cdi-integration/cdi-singleton/pom.xml
new file mode 100644
index 0000000..83b16d7
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>cdi-integration-project</artifactId>
+        <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
+        <version>2.35-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>cdi-sigleton</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>jakarta.ws.rs</groupId>
+            <artifactId>jakarta.ws.rs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.annotation</groupId>
+            <artifactId>jakarta.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.enterprise</groupId>
+            <artifactId>jakarta.enterprise.cdi-api</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.ext.cdi</groupId>
+            <artifactId>jersey-cdi1x</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.weld.se</groupId>
+            <artifactId>weld-se-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-bundle</artifactId>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.ext.cdi</groupId>
+            <artifactId>jersey-weld2-se</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.enterprise</groupId>
+                    <artifactId>cdi-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.jboss.weld.se</groupId>
+                    <artifactId>weld-se-core</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java
new file mode 100644
index 0000000..2f95a80
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonResource.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.cdi.singleton;
+
+import javax.inject.Singleton;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+@Path("/")
+@Singleton
+public class SingletonResource {
+    @GET
+    public String get() {
+        SingletonTestApp.SINGLETON_RESOURCES[1] = this;
+        return SingletonResource.class.getSimpleName();
+    }
+}
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java
new file mode 100644
index 0000000..59aa774
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestApp.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.cdi.singleton;
+
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SingletonTestApp extends Application {
+
+    static final SingletonResource[] SINGLETON_RESOURCES = new SingletonResource[3];
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        final Set<Class<?>> classes = new HashSet<>();
+        classes.add(SingletonResource.class);
+        classes.add(SingletonTestContainerRequestFilter.class);
+        classes.add(SingletonTestContainerResponseFilter.class);
+        return classes;
+    }
+}
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java
new file mode 100644
index 0000000..34a1f2c
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerRequestFilter.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.cdi.singleton;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Context;
+import java.io.IOException;
+
+public class SingletonTestContainerRequestFilter implements ContainerRequestFilter {
+    @Context
+    SingletonResource resource;
+
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        SingletonTestApp.SINGLETON_RESOURCES[0] = resource;
+    }
+}
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java
new file mode 100644
index 0000000..6e853d3
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTestContainerResponseFilter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.cdi.singleton;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Context;
+import java.io.IOException;
+
+public class SingletonTestContainerResponseFilter implements ContainerResponseFilter {
+    @Context
+    SingletonResource resource;
+    @Override
+    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+        SingletonTestApp.SINGLETON_RESOURCES[2] = resource;
+    }
+}
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/main/resources/META-INF/beans.xml b/tests/integration/cdi-integration/cdi-singleton/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..8a282c5
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+		http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
+       bean-discovery-mode="annotated">
+</beans>
\ No newline at end of file
diff --git a/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java b/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java
new file mode 100644
index 0000000..eb5e9c6
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-singleton/src/test/java/org/glassfish/jersey/tests/cdi/singleton/SingletonTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.cdi.singleton;
+
+import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
+import org.jboss.weld.environment.se.Weld;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+
+public class SingletonTest extends JerseyTest {
+    private Weld weld;
+
+    @Before
+    public void setup() {
+        Assume.assumeTrue(Hk2InjectionManagerFactory.isImmediateStrategy());
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        if (Hk2InjectionManagerFactory.isImmediateStrategy()) {
+            if (!ExternalTestContainerFactory.class.isAssignableFrom(getTestContainerFactory().getClass())) {
+                weld = new Weld();
+                weld.initialize();
+            }
+            super.setUp();
+        }
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        weld.shutdown();
+        super.tearDown();
+    }
+
+    @Override
+    protected Application configure() {
+        return new SingletonTestApp();
+    }
+
+    @Test
+    public void testSingleton() {
+        try (Response response = target().request().get()) {
+            String entity = response.readEntity(String.class);
+            Assert.assertEquals(SingletonResource.class.getSimpleName(), entity);
+
+            final SingletonResource actualResource = SingletonTestApp.SINGLETON_RESOURCES[1];
+            Assert.assertEquals(actualResource, SingletonTestApp.SINGLETON_RESOURCES[0]);
+            Assert.assertEquals(actualResource, SingletonTestApp.SINGLETON_RESOURCES[2]);
+        }
+    }
+}