Repository: quarkusio/quarkus
Issue: @Produces annotated methods that are not consumed not ignored and result in failed build

**Describe the bug**
Issue described [here](https://github.com/quarkusio/quarkus/issues/2770) persists under 0.20.0.  

**Expected behavior**
When using a class with method annotated with `@Produces`, even if never "produced", expect successful build.

**Actual behavior**
Build fails with misleading error message:

```
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:0.20.0:build (default) on project injector-jira-service: 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.ArcProcessor#generateResources threw an exception: java.lang.IllegalArgumentException: Must be a Class or String, got null
[ERROR] -> [Help 1]
[ERROR]
```

**To Reproduce**
Steps to reproduce the behavior:

Simple reproducer:

```
package service;

@ApplicationScoped
public class SomeResource {
    @Inject
    SomeService someService;

    public void doSomething() {
    }
}
```

```
package service;

import client.SomeProvider;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

@ApplicationScoped
public class SomeService {
    @Inject
    @RequestScoped
    SomeProvider someProvider;

    //  as a workaround, the "produced" but unused bean can be instantiated but ignored to silence this error
    // @Inject
    // @RequestScoped
    // SomeClient someClient;

    public void doSomething() {
    }
}
```

```
package client;

import java.net.URI;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import org.eclipse.microprofile.rest.client.RestClientBuilder;

@RequestScoped
public class SomeProvider {

    @Produces
    @RequestScoped
    public SomeClient getClient() {
        return RestClientBuilder
                .newBuilder()
                .baseUri(URI.create("http://example.com"))
                .build(SomeClient.class);
    }
}
```

```
package com.cloudbees.sdm.injector.jira.client;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Consumes("application/json")
@Produces("application/json")
public interface SomeClient {

    @GET
    @Path("/rest/api/lols")
    void getLols();
}
```

Add classes to project and build with maven.

**Configuration**
N/A


**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`: 
```
$ uname -a
Darwin ip-192-168-1-137.ec2.internal 18.2.0 Darwin Kernel Version 18.2.0: Mon Nov 12 20:24:46 PST 2018; root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64
```
 - Output of `java -version`: 
```
$ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit GraalVM EE 19.1.1 (build 25.221-b11-jvmci-19.1-b01, mixed mode)
```

 - Quarkus version or git rev: 0.20.0


Changed files:
independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.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/ComponentsProviderGenerator.java

diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java
index 0bec4732f01..82e2e66e3a0 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java
@@ -217,6 +217,7 @@ void init() {
             long removalStart = System.currentTimeMillis();
             Set<BeanInfo> removable = new HashSet<>();
             Set<BeanInfo> unusedProducers = new HashSet<>();
+            Set<BeanInfo> unusedButDeclaresProducer = new HashSet<>();
             List<BeanInfo> producers = beans.stream().filter(b -> b.isProducerMethod() || b.isProducerField())
                     .collect(Collectors.toList());
             List<InjectionPointInfo> instanceInjectionPoints = injectionPoints.stream()
@@ -245,10 +246,6 @@ void init() {
                 if (declaresObserver.contains(bean)) {
                     continue test;
                 }
-                // Declares a producer - see also second pass
-                if (declaresProducer.contains(bean)) {
-                    continue test;
-                }
                 // Instance<Foo>
                 for (InjectionPointInfo injectionPoint : instanceInjectionPoints) {
                     if (Beans.hasQualifiers(bean, injectionPoint.getRequiredQualifiers()) && Beans.matchesType(bean,
@@ -256,6 +253,11 @@ void init() {
                         continue test;
                     }
                 }
+                // Declares a producer - see also second pass
+                if (declaresProducer.contains(bean)) {
+                    unusedButDeclaresProducer.add(bean);
+                    continue test;
+                }
                 if (bean.isProducerField() || bean.isProducerMethod()) {
                     // This bean is very likely an unused producer
                     unusedProducers.add(bean);
@@ -267,9 +269,10 @@ void init() {
                 Map<BeanInfo, List<BeanInfo>> declaringMap = producers.stream()
                         .collect(Collectors.groupingBy(BeanInfo::getDeclaringBean));
                 for (Entry<BeanInfo, List<BeanInfo>> entry : declaringMap.entrySet()) {
-                    if (unusedProducers.containsAll(entry.getValue())) {
+                    BeanInfo declaringBean = entry.getKey();
+                    if (unusedButDeclaresProducer.contains(declaringBean) && unusedProducers.containsAll(entry.getValue())) {
                         // All producers declared by this bean are unused
-                        removable.add(entry.getKey());
+                        removable.add(declaringBean);
                     }
                 }
             }
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ComponentsProviderGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ComponentsProviderGenerator.java
index d4984102055..a15b4289aea 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ComponentsProviderGenerator.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ComponentsProviderGenerator.java
@@ -255,6 +255,9 @@ private void addBean(MethodCreator getComponents, ResultHandle beanIdToBeanSuppl
             Map<BeanInfo, LazyValue<ResultHandle>> beanToResultSupplierHandle) {
 
         String beanType = beanToGeneratedName.get(bean);
+        if (beanType == null) {
+            throw new IllegalStateException("No bean type found for: " + bean);
+        }
 
         List<InjectionPointInfo> injectionPoints = bean.getInjections().stream().flatMap(i -> i.injectionPoints.stream())
                 .filter(ip -> !BuiltinBean.resolvesTo(ip)).collect(toList());
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 6c6886ab838..5bdf077e87a 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
@@ -8,6 +8,7 @@
 import io.quarkus.arc.ArcContainer;
 import io.quarkus.arc.test.ArcTestContainer;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import javax.annotation.PostConstruct;
 import javax.annotation.Priority;
 import javax.enterprise.context.Dependent;
@@ -27,7 +28,8 @@ public class RemoveUnusedBeansTest {
     @Rule
     public ArcTestContainer container = ArcTestContainer.builder()
             .beanClasses(HasObserver.class, Foo.class, FooAlternative.class, HasName.class, UnusedProducers.class,
-                    InjectedViaInstance.class, InjectedViaProvider.class, Excluded.class, UsedProducers.class)
+                    InjectedViaInstance.class, InjectedViaProvider.class, Excluded.class, UsedProducers.class,
+                    UnusedProducerButInjected.class, UsedViaInstanceWithUnusedProducer.class, UsesBeanViaInstance.class)
             .removeUnusedBeans(true)
             .addRemovalExclusion(b -> b.getBeanClass().toString().equals(Excluded.class.getName()))
             .build();
@@ -49,6 +51,12 @@ public void testRemoval() {
         assertTrue(foo.provider.get().isValid());
         assertEquals(1, container.beanManager().getBeans(Foo.class).size());
         assertEquals("pong", container.instance(Excluded.class).get().ping());
+        // Producer is unused but declaring bean is injected
+        assertTrue(container.instance(UnusedProducerButInjected.class).isAvailable());
+        assertFalse(container.instance(BigInteger.class).isAvailable());
+        // Producer is unused, declaring bean is only used via Instance
+        assertTrue(container.instance(UsedViaInstanceWithUnusedProducer.class).isAvailable());
+        assertFalse(container.instance(Long.class).isAvailable());
     }
 
     @Dependent
@@ -71,6 +79,9 @@ static class Foo {
         @Inject
         Provider<InjectedViaProvider> provider;
 
+        @Inject
+        UnusedProducerButInjected injected;
+
         String ping() {
             return getClass().getName();
         }
@@ -140,4 +151,28 @@ String ping() {
 
     }
 
+    @Singleton
+    static class UnusedProducerButInjected {
+
+        @Produces
+        BigInteger unusedNumber() {
+            return BigInteger.ZERO;
+        }
+
+    }
+
+    @Singleton
+    static class UsedViaInstanceWithUnusedProducer {
+
+        @Produces
+        Long unusedLong = new Long(0);
+    }
+
+    @Singleton
+    static class UsesBeanViaInstance {
+
+        @Inject
+        Instance<UsedViaInstanceWithUnusedProducer> instance;
+    }
+
 }