0

The Problem:

Hello i'm having a problem on java EE , i have to use annotation like @Inject @Stateless etcetc, but i can't get a solution, after reading a lot of documentation and example etcetc it seems that what i 've code should work but definitly not. So the problem is that i have a custom qualifiers on an interface like this

 @Qualifier
 @Retention(RUNTIME)
 @Target({METHOD, FIELD, PARAMETER, TYPE})
 public @interface BudgetsDs {
 }

and i want inject it in another object as a member field like this

@Dependent
public class BudgetService  {

@BudgetsDs
@Inject
DataSource budgetsDS;

... some getter, setter , etcetc...

}

i've pass through this

https://docs.oracle.com/javaee/6/tutorial/doc/gjbck.html

and other kind of documentation similar to this one. I'v tried with @EJB , @Stateless but it doesn't work. I think that i'm currently missing a big thing on the annotation, so if you have good tutorials , or good advice, or explanation i want to hear them. I don't ask for a complete answer but i would like to have at least some clue. Anyone is welcome to help.

Edit: the exact error is on the line

@BudgetsDs
@Inject
DataSource budgetsDS;

budgetDS throw Unsatisfied Dependency: no bean matches the injection point

Edit2: The solution

1) I'v implemented a new class ResourceProducer As suggested by John Ament i use @Produces and @Resource(name="jdbc/myDataSource"), for each DataSource that i need.

public class ResourceProducer {

@Produces
@BudgetsDs
@Resource(name="jdbc/BudgetsDs")
public DataSource budgetsDs;

@Produces
@OtherDs
@Resource(name="jdbc/OtherDs")
public DataSource otherDs;

...  

}

2) The different custom qualifier for every connection

 // In a file 
 @Qualifier
 @Retention(RUNTIME)
 @Target({METHOD, FIELD, PARAMETER, TYPE})
 public @interface BudgetsDs {
 }

 // In a another file
 @Qualifier
 @Retention(RUNTIME)
 @Target({METHOD, FIELD, PARAMETER, TYPE})
 public @interface OtherDs {
 }

3) This way the inject works well and i can inject the different DataSource where i want, like this :

@Dependent
public class BudgetService  {

@BudgetsDs
@Inject
DataSource budgetsDS;

@OtherDs
@Inject
DataSource otherDs;
... some getter, setter , etcetc...

}

There is another solution Below, that works too.

Thanks to aribeiro and John Ament. My first question on stack overflow, and really well answered by the community

Koraxos
  • 418
  • 5
  • 13
  • Does your implementation of `DataSource` also has the `@BudgetsDs`annotation? – António Ribeiro Apr 22 '16 at 08:31
  • No i'm just using it directly in my BudgetService class, – Koraxos Apr 22 '16 at 08:34
  • In order for the container to inject the correct implementation of your `DataSource` you also need to place your qualifier in the implementation. If you notice, on the link you mentioned, the `@Informal` qualifier is placed at the beginning of the `InformalGreeting` class. Then, as you can see in https://docs.oracle.com/javaee/6/tutorial/doc/gjban.html, on the class `Printer` one is injecting greeting: `@Inject @Informal Greeting greeting;`. – António Ribeiro Apr 22 '16 at 08:39
  • So the solution would be to implement class that extends – Koraxos Apr 22 '16 at 08:51
  • No. If you don't have several implementations, then just drop the qualifier and just `@Inject` the bean. – António Ribeiro Apr 22 '16 at 09:10
  • The thing is that i will have several `DataSource`, due to the fact that i'll need access to different database. So i have to use custom qualifiers to implement my different connections, i also have a ResourceProducer class that will get the `@Resource` – Koraxos Apr 22 '16 at 09:28
  • Then yes, you'll need to extend your `DataSource` class. Take a look at the answer I've posted. – António Ribeiro Apr 22 '16 at 09:48
  • If `DataSource` is simply the JDBC datasource, what you're doing here should work. Can you include the full stack trace of the NPE you're getting? – John Ament Apr 22 '16 at 22:45

1 Answers1

1

The error you're receiving occurs due to the fact that the container does not know how to match the qualifier you've created with any implementation of any bean type.

As the documentation states:

A qualifier is an annotation that you apply to a bean

Therefore, in order to overcome the error mentioned, you need to apply the respective qualifier to each DataSource implementation:

@BudgetsDs
public class BudgetDataSource extends DataSource {
    (...)
}

@OtherDs
public class OtherDataSource extends DataSource {
    (...)
}

Then, the container will be able to needle to the right implementation when you're injecting your beans:

@Dependent
public class BudgetService  {

    @BudgetsDs
    @Inject
    DataSource budgetsDS;

    (...)
}

@Dependent
public class OtherService {

    @Inject
    @OtherDs
    DataSource otherDS;

    (...)
}

As a side note, I've noticed that you're following Java EE 6 documentation. I'd suggest you to follow the latest Java EE documentation.

António Ribeiro
  • 4,129
  • 5
  • 32
  • 49
  • Okay that's what i were thinking but i were not sure i'll try, just have to eat. I'v up-vote but i have not enough reputation to change the display score of your post – Koraxos Apr 22 '16 at 09:58
  • This answer's not correct. you can do the same with producer fields/methods. – John Ament Apr 22 '16 at 22:46
  • @JohnAment, why's the answer not correct and what's the advantage you get on having producers in this case? – António Ribeiro Apr 23 '16 at 09:40