1

Trying to inject bean in a class which has field with @Any annotation. But getting error as -

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.enterprise.inject.Instance' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject(), @javax.enterprise.inject.Any()}

   @Named
@Singleton
public class ProcessorFactoryImpl implements ProcessorFactory {

    @Inject @Any
    private Instance<Processor> processorList;
}

Interface is

public interface Processor {
some method
}

And implementing class is :

@Named
@Singleton
@Default
public class ProcessorImpl implements Processor {
}

For now, I have only one implementation so did not create qualifiers.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
javaq
  • 131
  • 1
  • 9
  • 1
    How is this CDI related? If you use Spring for injection, there is nothing CDI related and certainly not java-ee? – Kukeltje Apr 18 '18 at 15:49
  • related?: https://stackoverflow.com/questions/36203489/spring-differences-between-named-and-component – Kukeltje Apr 23 '18 at 21:15

2 Answers2

2

You are mixing Spring DI and CDI which are not made to work together.

Choose one of them but not both.

If you choose CDI

@Named
@ApplicationScoped
public class ProcessorFactoryImpl implements ProcessorFactory
{  
    @Inject
    private Processor processor;
}

and

@Dependent
@Default
public class ProcessorImpl implements Processor {
  // etc ...
}

In this case, the processor attribute is not a List ! You should think about what you expect. If you want a List<Processor>, you will have to use a CDI Producer instead.

If you choose Spring DI

@Component
public class ProcessorFactoryImpl implements ProcessorFactory
{
    @Inject // or @Autowired
    private Processor processor;
}

and

@Scope("prototype")
public class ProcessorImpl implements Processor 
{
  // etc ...
}

Mixing Spring and CDI

As written in the comments below, Spring can use @Inject and @Named as theses annotations are part of JSR-330.

The trouble is that too much framework mixing and using @Inject on an Instance<T>field cannot be achieved like that with Spring as it is a CDI feature.

To use the same feature, use @Provider from Spring.

Example :

CDI

@Inject
private Instance<MyClass> lazyInstance;

usage :

MyClasse instance = lazyInstance.get();

Spring

@Inject // or @Autowired
private Provider<MyClass> lazyInstance;

usage (same as CDI):

 MyClasse instance = lazyInstance.get();
fxrobin
  • 590
  • 3
  • 9
  • Sure? Reading https://stackoverflow.com/questions/10189531/both-component-and-named-for-the-same-bean-class and https://stackoverflow.com/questions/18540696/named-annotation-in-spring-mvc it seems spring recognizes CDI annotations as well and sort of acts as a CDI container. – Kukeltje Apr 23 '18 at 21:07
  • Yes you are right : Spring can use `@Inject`, `@Named` , but `Instance` is a pure CDI functionnality. That's why I said that "mixing" frameworks is the issue. The `Instance` class does not belong to JSR-330 neither Spring. – fxrobin Apr 24 '18 at 07:52
  • Ok, clear (I'm not a Spring user) Please add this to the answer, makes it more clear. Maybe also reference the other links I posted. But effectively, https://stackoverflow.com/questions/22875680/using-inject-instanceblah-in-spring and some other 'duplicates' are already in stackoverflow? Including the answer below by @CassioMazzochiMolin which would better have been a comment to try some of the duplicates... Cheers – Kukeltje Apr 24 '18 at 08:21
1

Have you tried List instead of Instance?

@Autowired
private List<Processor> processorList;
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • tried with List but still getting similar error - Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject(), @javax.enterprise.inject.Any()} – javaq Apr 18 '18 at 15:34
  • @javaq You may not need `@Any`. And you also could try `@Autowired` instead on `@Inject`. – cassiomolin Apr 18 '18 at 15:35