CDI, cdi-unit. Exception trying inject interface - java-8

I test class using cdi-unit library.
Test class:
#RunWith(CdiRunner.class)
public class IAktResponseMapperTest {
#Inject
private ITestCDI testCDI;
#Test
public void testCDI(){
testCDI.testCDI();
}
}
ITestCDI interface:
public interface ITestCDI {
void testCDI();
}
TestCDI class:
#ApplicationScoped
public class TestCDI implements ITestCDI {
public void testCDI() {
System.out.println("testCDI");
}
}
So, running this test I get error:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ITestCDI with qualifiers #Default
at injection point [UnbackedAnnotatedField] #Inject private ru.nwth.pio.personal_area.accounting.mapper.IAktResponseMapperTest.testCDI
at ru.nwth.pio.personal_area.accounting.mapper.IAktResponseMapperTest.testCDI(IAktResponseMapperTest.java:0)
But if I inject TestCDI class directly instead of interface ITestCDI, it's ok. How can I make interface working? Thanks for help!

CDI-Unit does not scan all classes of your package, so does not know the TestCDI implementation of ITestCDI.
You can control CDI environment with CDI-Unit using #AdditionalClasses, #AdditionalPackages or #AdditionalClasspath annotation.
In your case, add for example #AdditionalClasses(TestCDI.class) annotation :
#RunWith(CdiRunner.class)
#AdditionalClasses(TestCDI.class)
public class IAktResponseMapperTest {
#Inject
private ITestCDI testCDI;
#Test
public void testCDI(){
testCDI.testCDI();
}
}

Related

Custom Base repository function not found

I have generic base repository defined as follows:
#NoRepositoryBean
public interface IBaseRepository<Template extends BaseModel, Id > extends
ElasticsearchRepository<Template,Id>, ICustomRepository{
}
My ICustomRepository repository interface is defined as follows:
#Repository
public interface ICustomRepository {
void someCustomFunction();
}
public class CustomRepositoryImpl implements ICustomRepository{
#Override
void someCustomFunction(){
}
}
Now when I use the baserepository as:
#Repository
public interface OrderRepository extends BaseRepository<OrderModel,Long>{
}
when I Autowired OrdeRepository in my service class it gives me compile error:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'OrderRepository ' defined in
abc.example.OrderRepository defined in
#EnableElasticsearchRepositories declared on ElkApplication:
Invocation of init method failed; nested exception is
org.springframework.data.mapping.PropertyReferenceException: No
property someCustomFunction found for type OrderModel!
Can someone please suggest whats going wrong here and how to resolve this?
Converting comment to answer
ICustomRepo
#Repository
public interface ICustomRepository {
void someCustomFunction();
}
IBaseRepository
#NoRepositoryBean
public interface IBaseRepository<Template extends BaseModel, Id > extends
ElasticsearchRepository<Template,Id>, ICustomRepository{
}
OrderRepository
#Repository
public interface OrderRepository extends IBaseRepository<OrderModel,Long>{
}
OrderRepository is a repository interface and a bean is created by a spring bean processor but this OrderRepository does not implement someCustomFunction and even spring has no idea about its implementation except it knows it has been implemented by CustomRepositoryImpl so at bootstrap/startup spring throws an error.
So instead of just having the definition of someCustomFunction we need to implement this in ICustomRepository, thanks to Java 8 we can implement the method in the interface as well
#Repository
public interface ICustomRepository {
default void someCustomFunction() {
// some code here
}
}
This code will be working fine, JDK and other proxies will work on this method as well, also we can apply AOP on someCustomFunction.
It is also possible to override this method in any repository given that's also using the default and #Override.
#Repository
public interface OrderRepository extends IBaseRepository<OrderModel,Long>{
#Override
default void someCustomFunction() {
// some code here
}
}

SpringBoot: how to inject two classes having same name

In my application, I have two classes having the same name, but of course in different packages.
Both classes need to be injected in the application; Unfortunately, I get the following error message:
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'myFeature' for bean class [org.pmesmeur.springboot.training.service.feature2.MyFeature] conflicts with existing, non-compatible bean definition of same name and class [org.pmesmeur.springboot.training.service.feature1.MyFeature]
My issue can be reproduced by the following sample:
#Component
#EnableConfigurationProperties(ServiceProperties.class)
public class MyService implements IService {
private final ServiceProperties serviceProperties;
private final IProvider provider;
private final org.pmesmeur.springboot.training.service.feature1.IMyFeature f1;
private final org.pmesmeur.springboot.training.service.feature2.IMyFeature f2;
#Autowired
public MyService(ServiceProperties serviceProperties,
IProvider provider,
org.pmesmeur.springboot.training.service.feature1.IMyFeature f1,
org.pmesmeur.springboot.training.service.feature2.IMyFeature f2) {
this.serviceProperties = serviceProperties;
this.provider = provider;
this.f1 = f1;
this.f2 = f2;
}
...
package org.pmesmeur.springboot.training.service.feature1;
public interface IMyFeature {
void print();
}
package org.pmesmeur.springboot.training.service.feature1;
import org.springframework.stereotype.Component;
#Component
public class MyFeature implements IMyFeature {
#Override
public void print() {
System.out.print("HelloWorld");
}
}
package org.pmesmeur.springboot.training.service.feature2;
public interface IMyFeature {
void print();
}
package org.pmesmeur.springboot.training.service.feature2;
import org.springframework.stereotype.Component;
#Component
public class MyFeature implements IMyFeature {
#Override
public void print() {
System.out.print("FooBar");
}
}
If I use different names for my classes MyFeature, my problem disappears!!!
I am used to work with Guice and this framework does not have this kind of problem/limitation
It seems that the spring dependencies injection framework uses only
the class-name instead of package-name + class-name in order to
select its classes.
In "real-life" I have this problem with a far-bigger project and I would strongly prefer not to have to rename my classes: can anyone help me?
One last point, I would prefer to avoid "tricks" such as using
#Qualifier(value = "ABC") when injecting my classes: in my sample,
there should be no ambiguity for finding the correct instance of
MyFeature as they do not implement the same interface
Simply re-implementing BeanNameGenerator adds a new problem for beans declared/instantiated by names
#Component("HelloWorld")
class MyComponent implements IComponent {
...
}
#Qualifier(value = "HelloWorld") IComponent component
I solved this issue by extending AnnotationBeanNameGenerator and redefining method buildDefaultBeanName()
static class BeanNameGeneratorIncludingPackageName extends AnnotationBeanNameGenerator {
public BeanNameGeneratorIncludingPackageName() {
}
#Override
public String buildDefaultBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry beanDefinitionRegistry) {
return beanDefinition.getBeanClassName();
}
}
You can assigna a value for each component e.g. #Component(value="someBean") and then inject it with #Qualifier e.g.
#Autowired
public SomeService(#Qualifier("someBean") Some s){
//....
}
Spring provides autowire by type and name. Your classname are same. By default spring considers only className not package. But you can override this behaviour by defining custom implementation of BeanNameGenerator interface in which you can generate name using both package and name. I am not providing code solution because i think you should explore more on this.
You can do something like this;
in package a
public class MyFeature implements IMyFeature {
#Override
public void print() {
System.out.print("FooBar");
}
}
in package b
public class MyFeature implements IMyFeature {
#Override
public void print() {
System.out.print("HelloWorld");
}
}
and in some config class;
#Configuration
public class Configuration {
#Bean
public a.MyFeature f1() {
return new a.MyFeature();
}
#Bean
public b.MyFeature f2() {
return new b.MyFeature();
}
}
Then you can autowire them with names f1 and f2, that are the names of their respective bean constructor methods.
You can do the similar thing with #Component("f1") &
#Component("f2")
Even though different interfaces are implemented and are in different packages, identical bean name causes this trouble, and you have to utilize some sort of custom naming to distinguish. Utilizing some custom Spring logic would be way too ugly compared to what you'd do with above solutions.

how to avoid using context.getbean in spring

There have been several arguments around not using ApplicationContext.getBean() to get a bean reference, of which most are based on logic that it violates the principles of Inversion of control.
Is there a way to get reference to prototype scoped bean without calling context.getBean() ?
Consider to use Spring Boot!
Than you can do something like this...
Runner:
#SpringBootApplication
public class Runner{
public static void main(String[] args) {
SpringApplication.run(Runner.class, args);
}
}
Some Controller:
#Controller
public class MyController {
// Spring Boot injecting beans through #Autowired annotation
#Autowired
#Qualifier("CoolFeature") // Use Qualifier annotation to mark a class, if for example
// you have more than one concreate class with differant implementations of some interface.
private CoolFeature myFeature;
public void testFeature(){
myFeature.doStuff();
}
}
Some cool feature:
#Component("CoolFeature") // To identify with Qualifier
public class CoolFeature{
#Autowired
private SomeOtherBean utilityBean;
public void doStuff(){
// use utilityBean in some way
}
}
No XML files to handle.
We can still access context for manual configurations if needed.
Suggested reading:
Spring Boot Reference
Pro Spring Boot
This type of problem can be solved using method injection, which is described in more detail here: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-method-injection
This is the most common approach to create prototype bean:
abstract class MyService {
void doSome() {
OtherService otherService = getOtherService();
}
abstract OtherService getOtherService();
}
#Configuration
class Config {
#Bean
public MyService myService() {
return new MyService() {
OtherService getOtherService() {
return otherService();
}
}
}
#Bean
#Scope("prototype")
public OtherService otherService() {
return new OtherService();
}
}

Spring can you autowire inside an abstract class?

Spring is failing to autowire my object? Is it possible to autowire an object within an abstract class. Assume all schemas are supplied in application-context.xml
Question: What annotation should be on the base and extending classes (if any) #Service #Component?
Example
abstract class SuperMan {
#Autowire
private DatabaseService databaseService;
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
Extending class
public class SuperGirl extends SuperMan {
#Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
application-context.xml
<context:component-scan base-package="com.baseLocation" />
<context:annotation-config/>
I have that kind of spring setup working
an abstract class with an autowired field
public abstract class AbstractJobRoute extends RouteBuilder {
#Autowired
private GlobalSettingsService settingsService;
and several children defined with #Component annotation.
Normally, Spring should do the autowiring, as long as your abstract class is in the base-package provided for component scan.
See this and this for further reference.
#Service and #Component are both stereotypes that creates beans of the annotated type inside the Spring container. As Spring Docs state,
This annotation serves as a specialization of #Component, allowing for
implementation classes to be autodetected through classpath scanning.
What if you need any database operation in SuperGirl you would inject it again into SuperGirl.
I think the main idea is using the same object reference in different classes.
So what about this:
//There is no annotation about Spring in the abstract part.
abstract class SuperMan {
private final DatabaseService databaseService;
public SuperMan(DatabaseService databaseService) {
this.databaseService = databaseService;
}
abstract void Fly();
protected void doSuperPowerAction(Thing thing) {
//busy code
databaseService.save(thing);
}
}
#Component
public class SuperGirl extends SuperMan {
private final DatabaseService databaseService;
#Autowired
public SuperGirl (DatabaseService databaseService) {
super(databaseService);
this.databaseService = databaseService;
}
#Override
public void Fly() {
//busy code
}
public doSomethingSuperGirlDoes() {
//busy code
doSuperPowerAction(thing)
}
In my opinion, inject once run everywhere :)
In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:
public abstract class EO {
#Autowired
protected SmsNotificationService smsNotificationService;
#Autowired
protected SendEmailService sendEmailService;
...
protected abstract void executeOperation(GenericMessage gMessage);
}
public final class OperationsExecutor {
public enum OperationsType {
ENROLL, CAMPAIGN
}
private OperationsExecutor() {
}
public static Object delegateOperation(OperationsType type, Object obj)
{
switch(type) {
case ENROLL:
if (obj == null) {
return new EnrollOperation();
}
return EnrollOperation.validateRequestParams(obj);
case CAMPAIGN:
if (obj == null) {
return new CampaignOperation();
}
return CampaignOperation.validateRequestParams(obj);
default:
throw new IllegalArgumentException("OperationsType not supported.");
}
}
}
#Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
#Override
public void executeOperation(GenericMessage genericMessage) {
LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
}
}
Initially to inject the dependencies in the abstract class I tried all stereotype annotations like #Component, #Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **#Configurable(dependencyCheck = true)** annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
I also tried these other references to find a solution:
http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
Using abstract factory with Spring framework
Spring Autowiring not working for Abstract classes
Inject spring dependency in abstract super class
Spring and Abstract class - injecting properties in abstract classes
Spring autowire dependency defined in an abstract class
Please try using **#Configurable(dependencyCheck = true)** and update this post, I might try helping you if you face any problems.

How Spring injection works for subclass

A question on how Spring injection works? If I inject same service in a class and all its sub-classes is it going to to inefficient? How does Spring's container going to store/control this?
public class baseClass {
#Autowired
private iService serviceName
}
public class extendedClassA extends baseClass {
#Autowired
private iService serviceName
}
public class extendedClassB extends extendedClassA {
#Autowired
private iService serviceName
}
Thanks..
I haven't tried but I believe it is going to cause problem.
The main problem is not due to Spring, but variable shadowing in your example. BaseClass' serviceName is shadowed by child class, that means, if you haven't done special handling, BaseClass' serviceName is going to be null.
You may want to consider doing this:
// !!!! Mind your naming convention!!!!!!
public class BaseClass {
#Autowired
private FooService fooService;
protected FooService getFooService() {
return this.fooService;
}
public setFooService(FooService fooService) { ... }
}
public class ExtendedClassA extends BaseClass {
// no need to inject fooService again, whenever it need to use that,
// simply do getFooService() and use it
}
Adrian Shum response seems fine but you need to declare too your BaseClass bean in your applicationContext file with the property "abstract=true"
<bean id="baseClass" class="BaseClass" abstract="true"/>

Resources