Repository: quarkusio/quarkus
Issue: Injecting using 'javax.inject.Provider' into JAX-RS Resource fails build

Quarkus Version: 0.11.0
Maven Version: 3.6.0
Java Version: 1.8.0_191

While using `io.quarkus:quarkus-smallrye-jwt` and performing the following:

```
@Path("v1")
@Produces(APPLICATION_JSON)
@DenyAll
public class HelloWorldResource {
	@Inject
	private Provider<JsonWebToken> jwtProvider;
```

The build fails with:
```
ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:0.11.0:build (default) on project quarkus-service-example: Failed to build a runnable JAR: Failed to build a runner jar: Failed to augment application classes: Build failure: Build failed due to errors
[ERROR] 	[error]: Build step io.quarkus.arc.deployment.ArcAnnotationProcessor#build threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.inject.Provider<org.eclipse.microprofile.jwt.JsonWebToken> and qualifiers [@Default]
[ERROR] 	- java member: acme.jaxrs.v1.HelloWorldResource#jwtProvider
[ERROR] 	- declared on CLASS bean [types=[acme.jaxrs.v1.HelloWorldResource, java.lang.Object], qualifiers=[@Default, @Any], target=acme.jaxrs.v1.HelloWorldResource]
[ERROR] -> [Help 1]
```

**Workaround**
Use `javax.enterprise.inject.Instance`.

Moved from quarkusio/quarkus-quickstarts#85.

Changed files:
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java
independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/unused/RemoveUnusedBeansTest.java
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InjectionPointInfo.java
independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java

diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
index ecba1ecd95d..23f90afdf27 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BuiltinBean.java
@@ -23,6 +23,7 @@
 import org.jboss.jandex.AnnotationInstance;
 import org.jboss.jandex.ClassInfo;
 import org.jboss.jandex.DotName;
+
 import io.quarkus.arc.BeanManagerProvider;
 import io.quarkus.arc.BeanMetadataProvider;
 import io.quarkus.arc.EventProvider;
@@ -30,7 +31,7 @@
 import io.quarkus.arc.InjectionPointProvider;
 import io.quarkus.arc.InstanceProvider;
 import io.quarkus.arc.ResourceProvider;
-import io.quarkus.arc.processor.InjectionPointInfo.InjtetionPointKind;
+import io.quarkus.arc.processor.InjectionPointInfo.InjectionPointKind;
 import io.quarkus.gizmo.ClassCreator;
 import io.quarkus.gizmo.ClassOutput;
 import io.quarkus.gizmo.FieldDescriptor;
@@ -73,7 +74,8 @@ void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionP
                     constructor.getThis(), instanceProvider);
 
         }
-    }), INJECTION_POINT(DotNames.INJECTION_POINT, new Generator() {
+    }, ip -> ip.getKind() == InjectionPointKind.CDI && (DotNames.INSTANCE.equals(ip.getRequiredType().name()) || DotNames.PROVIDER.equals(ip.getRequiredType().name()))), 
+            INJECTION_POINT(DotNames.INJECTION_POINT, new Generator() {
         @Override
         void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionPointInfo injectionPoint, ClassCreator clazzCreator,
                 MethodCreator constructor, String providerName, AnnotationLiteralProcessor annotationLiterals) {
@@ -145,7 +147,7 @@ void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionP
             constructor.writeInstanceField(FieldDescriptor.of(clazzCreator.getClassName(), providerName, InjectableReferenceProvider.class.getName()),
                     constructor.getThis(), resourceProvider);
         }
-    }, ip -> ip.getKind() == InjtetionPointKind.RESOURCE);
+    }, ip -> ip.getKind() == InjectionPointKind.RESOURCE);
 
     private final DotName rawTypeDotName;
 
@@ -154,7 +156,7 @@ void generate(ClassOutput classOutput, BeanDeployment beanDeployment, InjectionP
     private final Predicate<InjectionPointInfo> matcher;
 
     BuiltinBean(DotName rawTypeDotName, Generator generator) {
-        this(rawTypeDotName, generator, ip -> ip.getKind() == InjtetionPointKind.CDI && rawTypeDotName.equals(ip.getRequiredType().name()));
+        this(rawTypeDotName, generator, ip -> ip.getKind() == InjectionPointKind.CDI && rawTypeDotName.equals(ip.getRequiredType().name()));
     }
 
     BuiltinBean(DotName rawTypeDotName, Generator generator, Predicate<InjectionPointInfo> matcher) {
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java
index 171a9925943..c3d24e2a974 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DotNames.java
@@ -41,6 +41,7 @@
 import javax.enterprise.util.Nonbinding;
 import javax.inject.Inject;
 import javax.inject.Named;
+import javax.inject.Provider;
 import javax.inject.Qualifier;
 import javax.interceptor.AroundConstruct;
 import javax.interceptor.AroundInvoke;
@@ -66,6 +67,7 @@ public final class DotNames {
     public static final DotName POST_CONSTRUCT = create(PostConstruct.class);
     public static final DotName PRE_DESTROY = create(PreDestroy.class);
     public static final DotName INSTANCE = create(Instance.class);
+    public static final DotName PROVIDER = create(Provider.class);
     public static final DotName INJECTION_POINT = create(InjectionPoint.class);
     public static final DotName INTERCEPTOR = create(Interceptor.class);
     public static final DotName INTERCEPTOR_BINDING = create(InterceptorBinding.class);
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InjectionPointInfo.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InjectionPointInfo.java
index 06993fc2d0c..c801ae3334a 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InjectionPointInfo.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InjectionPointInfo.java
@@ -50,7 +50,7 @@ static InjectionPointInfo fromField(FieldInfo field, BeanDeployment beanDeployme
     }
 
     static InjectionPointInfo fromResourceField(FieldInfo field, BeanDeployment beanDeployment) {
-        return new InjectionPointInfo(field.type(), new HashSet<>(field.annotations()), InjtetionPointKind.RESOURCE, field, -1);
+        return new InjectionPointInfo(field.type(), new HashSet<>(field.annotations()), InjectionPointKind.RESOURCE, field, -1);
     }
 
     static List<InjectionPointInfo> fromMethod(MethodInfo method, BeanDeployment beanDeployment) {
@@ -94,7 +94,7 @@ static Set<AnnotationInstance> getParameterAnnotations(BeanDeployment beanDeploy
 
     private final AtomicReference<BeanInfo> resolvedBean;
 
-    private final InjtetionPointKind kind;
+    private final InjectionPointKind kind;
     
     private final boolean hasDefaultedQualifier;
     
@@ -103,10 +103,10 @@ static Set<AnnotationInstance> getParameterAnnotations(BeanDeployment beanDeploy
     private final int position;
 
     InjectionPointInfo(Type requiredType, Set<AnnotationInstance> requiredQualifiers, AnnotationTarget target, int position) {
-        this(requiredType, requiredQualifiers, InjtetionPointKind.CDI, target, position);
+        this(requiredType, requiredQualifiers, InjectionPointKind.CDI, target, position);
     }
 
-    InjectionPointInfo(Type requiredType, Set<AnnotationInstance> requiredQualifiers, InjtetionPointKind kind, AnnotationTarget target, int position) {
+    InjectionPointInfo(Type requiredType, Set<AnnotationInstance> requiredQualifiers, InjectionPointKind kind, AnnotationTarget target, int position) {
         this.typeAndQualifiers = new TypeAndQualifiers(requiredType,
                 requiredQualifiers.isEmpty() ? Collections.singleton(AnnotationInstance.create(DotNames.DEFAULT, null, Collections.emptyList()))
                         : requiredQualifiers);
@@ -125,7 +125,7 @@ BeanInfo getResolvedBean() {
         return resolvedBean.get();
     }
 
-    InjtetionPointKind getKind() {
+    InjectionPointKind getKind() {
         return kind;
     }
 
@@ -177,7 +177,7 @@ public String toString() {
         return "InjectionPointInfo [requiredType=" + typeAndQualifiers.type + ", requiredQualifiers=" + typeAndQualifiers.qualifiers + "]";
     }
 
-    enum InjtetionPointKind {
+    enum InjectionPointKind {
         CDI, RESOURCE
     }
 
diff --git a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
index a7fec3496bd..ab2c323299e 100644
--- a/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
+++ b/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/InstanceImpl.java
@@ -29,6 +29,7 @@
 import javax.enterprise.inject.Instance;
 import javax.enterprise.inject.UnsatisfiedResolutionException;
 import javax.enterprise.util.TypeLiteral;
+import javax.inject.Provider;
 
 /**
  *
@@ -49,7 +50,7 @@
     InstanceImpl(Type type, Set<Annotation> qualifiers, CreationalContextImpl<?> creationalContext) {
         if (type instanceof ParameterizedType) {
             ParameterizedType parameterizedType = (ParameterizedType) type;
-            if (parameterizedType.getRawType().equals(Instance.class)) {
+            if (Provider.class.isAssignableFrom(Types.getRawType(parameterizedType.getRawType()))) {
                 this.type = parameterizedType.getActualTypeArguments()[0];
             } else {
                 this.type = type;
diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/unused/RemoveUnusedBeansTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/unused/RemoveUnusedBeansTest.java
index d6969adeac5..1799aea460d 100644
--- a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/unused/RemoveUnusedBeansTest.java
+++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/unused/RemoveUnusedBeansTest.java
@@ -6,6 +6,7 @@
 
 import java.math.BigDecimal;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Priority;
 import javax.enterprise.context.Dependent;
 import javax.enterprise.event.Observes;
@@ -14,6 +15,7 @@
 import javax.enterprise.inject.Produces;
 import javax.inject.Inject;
 import javax.inject.Named;
+import javax.inject.Provider;
 import javax.inject.Singleton;
 
 import io.quarkus.arc.Arc;
@@ -26,7 +28,7 @@ public class RemoveUnusedBeansTest {
 
     @Rule
     public ArcTestContainer container = ArcTestContainer.builder()
-            .beanClasses(HasObserver.class, Foo.class, FooAlternative.class, HasName.class, UnusedProducers.class, InjectedViaInstance.class, Excluded.class, UsedProducers.class)
+            .beanClasses(HasObserver.class, Foo.class, FooAlternative.class, HasName.class, UnusedProducers.class, InjectedViaInstance.class, InjectedViaProvider.class, Excluded.class, UsedProducers.class)
             .removeUnusedBeans(true)
             .addRemovalExclusion(b -> b.getBeanClass().toString().equals(Excluded.class.getName()))
             .build();
@@ -37,12 +39,15 @@ public void testRemoval() {
         assertTrue(container.instance(HasObserver.class).isAvailable());
         assertTrue(container.instance(HasName.class).isAvailable());
         assertTrue(container.instance(InjectedViaInstance.class).isAvailable());
+        assertTrue(container.instance(InjectedViaProvider.class).isAvailable());
         assertTrue(container.instance(String.class).isAvailable());
         assertTrue(container.instance(UsedProducers.class).isAvailable());
         assertFalse(container.instance(UnusedProducers.class).isAvailable());
         assertFalse(container.instance(BigDecimal.class).isAvailable());
         // Foo is injected in HasObserver#observe()
-        assertEquals(FooAlternative.class.getName(), container.instance(Foo.class).get().ping());
+        Foo foo = container.instance(Foo.class).get();
+        assertEquals(FooAlternative.class.getName(), foo.ping());
+        assertTrue(foo.provider.get().isValid());
         assertEquals(1, container.beanManager().getBeans(Foo.class).size());
         assertEquals("pong", container.instance(Excluded.class).get().ping());
     }
@@ -63,6 +68,9 @@ static class HasName {
 
     @Dependent
     static class Foo {
+        
+        @Inject
+        Provider<InjectedViaProvider> provider;
 
         String ping() {
             return getClass().getName();
@@ -77,7 +85,7 @@ static class FooAlternative extends Foo {
 
         @Inject
         Instance<InjectedViaInstance> instance;
-        
+
         @Inject
         String foo;
 
@@ -87,6 +95,22 @@ static class FooAlternative extends Foo {
     static class InjectedViaInstance {
 
     }
+    
+    @Singleton
+    static class InjectedViaProvider {
+        
+        private boolean isValid;
+        
+        @PostConstruct
+        void init() {
+            isValid = true;
+        }
+        
+        boolean isValid() {
+            return isValid;
+        }
+
+    }
 
     @Singleton
     static class UnusedProducers {