Still receiving BeanDefinitionOverrideException after setting overriding to true - spring-test

When building my project, i am receiving errors for my test. I googled a little and found that everyone is talking about how spring requires setting the bean definition overriding to true. My properties has already set the bean overriding to true but still i am receiving this error. Does anyone know what am i missing?
Controller Test
#WebMvcTest(controllers = PermitController.class)
public class PermitControllerTest extends CrudControllerTest<Permit, PermitRepository> {
#TestConfiguration
static class Configuration {
#Bean
public PermitController permitController() {
return new PermitController();
}
}
#Autowired
private PermitController permitController;
#MockBean
private PermitRepository permitRepository;
#MockBean
private AccountRepository accountRepository;
#MockBean
private PocRepository pocRepository;
#MockBean
private DateslotRepository dateslotRepository;
#MockBean
private TimeslotRepository timeslotRepository;
#MockBean
private CoordinateRepository coordinateRepository;
// TODO: test invalid fields
/**
* Setup before unit tests are run.
*/
#Before
public void before() {
permitController.setRepository(permitRepository);
super.init(permitRepository);
super.setUrl(WebConfig.PERMIT + "/");
super.setEntities(TestEntities.getPermit(null), TestEntities.getPermit(TestEntities.ID1));
}
}
Error from test
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'permitController' defined in com.example.permitservice.controller.PermitControllerTest$Configuration: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=permitControllerTest.Configuration; factoryMethodName=permitController; initMethodName=null; destroyMethodName=(inferred); defined in com.example.permitservice.controller.PermitControllerTest$Configuration] for bean 'permitController': There is already [Generic bean: class [com.example.permitservice.controller.PermitController]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\workspace\gitpermitmanager\permitMgrService\build\classes\java\main\com\example\permitservice\controller\PermitController.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:274)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:691)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 50 more
Properties:
spring.profiles.active = development
spring.main.allow-bean-definition-overriding = true

Related

JoinFaces #Configurable does not inject services

I am migrating an old JSF application to newer versions.
I have the problem with the lazyDataModel of Primefaces
#Configurable
public class PerfilSeleccionLazyDataModel extends LazyDataModel<Perfil> {
#Autowired
private transient PerfilService perfilService;
Now these classes do not inject services and are null
My new project is with Spring Boot, JoinFaces 4 and Spring 5.
Can someone tell me what new strategy I should use or if I should add some extra confirmation, so that my services are injected well?
I am using JoinFaces and here is what my LazyDatatable looks like. Use JSF ViewScoped on the bean and use normal Inject to inject the bean you want.
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#ViewScoped
public class PerfilDatatable extends LazyDataModel<Perfil> {
#Inject
private transient PerfilService perfilService;
JoinFaces config:
joinfaces:
jsf:
project-stage: Development
state-saving-method: server
facelets-refresh-period: -1
facelets-skip-comments: true
interpret-empty-string-submitted-values-as-null: true
datetimeconverter-default-timezone-is-system-timezone: true
primefaces:
theme: babylon-bluegrey-accent
font-awesome: true
transform-metadata: true
move-scripts-to-bottom: true
submit: partial
omnifaces:
combined-resource-handler-cache-ttl: 3628800
combined-resource-handler-disabled: true
myfaces:
support-managed-beans: false
early-flush-enabled: true
check-id-production-mode: false
I faced the similar issue while using Spring-Boot-2.5.4 and JoinFaces_4.5.4. My solution is to pass the dependency from outside.
public class LazyProductsDataModel extends LazyDataModel<Product> {
private static final long serialVersionUID = 1L;
private transient ProductRepository productRepository;
public LazyProductsDataModel(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
and then in you can initialize it like this:
#Named
#ViewScoped
public class ProductListView {
#Autowired
private ProductRepository productRepository;
private LazyProductsDataModel lazyProductsDataModel;
#PostConstruct
private void init() {
lazyProductsDataModel = new LazyProductsDataModel(productRepository);
}
}

How to send push via o:socket from EJB to Client?

I need help for the cooperation between #EJB and #CDI
Hi all,
I would like to have the following scenario:
1) In my app a Notification is created (in database)
2) Afterwards a Push Notification should be send to the specific client
3) In Client it will update a specific #form from my page...
Here is my code:
#Stateless
public class NotificationCreationSendServiceBean implements NotificationCreationSendService {
#Inject
private BeanManager beanManager;
public void createNotification {
// createNotificationInDatabase();
.....
PushEvent event = new PushEvent("Test");
beanManager.fireEvent(event);
}
}
My JSF Bean:
import static org.omnifaces.util.Messages.addGlobalError;
import static org.omnifaces.util.Messages.addGlobalInfo;
#Named
#ViewScoped
public class NotificationSocket implements Serializable {
#Inject
private LoginBean loginBean;
#Inject
#Push(channel = "notificationChannel")
private PushContext push;
/**
* Push Notification
*
* #param recipientUser
*/
public void pushUser(#Observes PushEvent event) {
Set<Future<Void>> sent = push.send(event.getMessage(), loginBean.getCurrentEmployee().getId());
if (sent.isEmpty()) {
addGlobalError("This user does not exist!");
} else {
addGlobalInfo("Sent to {0} sockets", sent.size());
}
}
}
In here JSF page:
<o:socket channel="notificationChannel"
user="#{loginBean.currentEmployee.id}" scope="view">
<f:ajax event="someEvent" listener="#{bean.pushed}" render=":notificationLink" />
</o:socket>
My question is now:
How is my #EJB container recognized with Socket is the right one? Where do I define the channel name in #EJB?
Can anybody help me, please.
How to send push via o:socket from EJB to Client?
This title is strange as your question already shows the code which does exactly that right.
How is my #EJB container recognized with Socket is the right one? Where do I define the channel name in #EJB?
This specific question is really strange in the current context. I can only assume that you actually have multiple #Observes PushEvent methods and that you actually wanted to target only a specific method which is associated with a specific #Push channel. Only in that context this question would make somewhat sense.
Well, in order to achieve that, there are several ways.
Pass it as an argument/property of the PushEvent class:
beanManager.fireEvent(new PushEvent("notificationChannel", "Test"));
And then just check for that in your observer method:
if ("notificationChannel".equals(event.getChannelName())) {
// ...
}
Feel free to use enums instead.
Or, create a specific class for every specific event:
beanManager.fireEvent(new NotificationEvent("Test"));
And then just make sure you observe it in only one method:
public void pushUser(#Observes NotificationEvent event) {
// ...
}
Or, create a #Qualifier for the PushEvent:
#Qualifier
#Retention(RUNTIME)
#Target({ FIELD, PARAMETER })
public #interface Notification {}
Which you #Inject via Event<T>:
#Inject #Notification
private Event<PushEvent> pushEvent;
public void createNotification {
pushEvent.fire(new PushEvent("Test"));
}
And then just make sure you observe it in only one method:
public void pushUser(#Observes #Notification PushEvent event) {
// ...
}

Managed property - Unable to set property

I'm trying to use ManagedProperty:
From here
#ManagedBean(name = "SelectionBean")
#SessionScoped
public class TableSelectionBean implements Serializable {
private String selectionMode = "single";
private Collection<Object> selection;
private List<MonitoringData> monitoringData;
private List<MonitoringData> selectionMonitoringData;
to here:
#ManagedBean(name="ActionBean")
#SessionScoped
public class MonitoringActionBean implements Serializable {
private ThreadPoolExecutor executor;
#ManagedProperty(value="{SelectionBean.selectionMonitoringData}")
private List<MonitoringData> selectedMonitoring;
and i got the following error message:
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property selectedMonitoring for managed bean ActionBean
...
Caused by: java.lang.IllegalArgumentException: Cannot convert {SelectionBean.selectionMonitoringData} of type class java.lang.String to interface java.util.List
Any idea why it is not working?
It seems you're forgetting the hashtag:
#ManagedProperty(value="{SelectionBean.selectionMonitoringData}")
Should be:
#ManagedProperty(value="#{SelectionBean.selectionMonitoringData}")

Cant access property of managed bean from another managed bean

I want to access the property of a #SessionScoped bean in another bean using #ManagedProperty. In short, I want to access the name property of firstBean in secondBean.
#ManagedBean
#SessionScoped
public class FirstBean implements Serializable{
private String name;
//...other attributes
//...constructor
public String getSelectedModel() {
return selectedModel;
}
public void setSelectedModel(String selectedModel) {
this.selectedModel = selectedModel;
}
//other getters&setters
}
And second bean:
#ManagedBean
#SessionScoped
public class SecondBean implements Serializable{
#ManagedProperty(value="#{firstBean}")
private FirstBean firstBean
public SecondBean() {
System.out.println(firstBean.getName());
}
public IndexBean getFirstBean() {
return firstBean;
}
public void setFirstBean(FirstBean firstBean) {
this.firstBean = firstBean;
}
When I run this, I always get NullPointerException on System.out.println(firstBean.getName()); in the constructor of second bean, which seems to mean that I need to create a new instance of firstBean.
But strangely, when I commented out this line, I can do something like this with no errors, which means that firstBean is actually a property of secondBean.
<h:outputText value="#{secondBean.firstBean.name}" />
What's the problem here?
It's not possible to access an injected dependency in the constructor. You're basically expecting that Java is able to do something like this:
SecondBean secondBean; // Declare.
secondBean.firstBean = new FirstBean(); // Inject.
secondBean = new SecondBean(); // Construct.
It's absolutely not possible to set an instance variable if the instance is not constructed yet. Instead, it works as follows:
SecondBean secondBean; // Declare.
secondBean = new SecondBean(); // Construct.
secondBean.firstBean = new FirstBean(); // Inject.
Then, in order to perform business actions based on injected dependencies, use a method annotated with #PostConstruct. It will be invoked by the dependency injection manager directly after construction and dependency injection.
So, just replace
public SecondBean() {
System.out.println(firstBean.getName());
}
by
#PostConstruct
public void init() { // Note: method name is fully to your choice.
System.out.println(firstBean.getName());
}

NullPointerException while trying to access #Inject bean in constructor

I've a session scoped bean:
#Named
#SessionScoped
public class SessionBean implements Serializable {
private String someProperty;
public String getSomeProperty() {
return someProperty;
}
}
I'd like to inject this in a request scoped bean and initialize with it:
#Named
#RequestScoped
public class RequestBean {
#Inject
private SessionBean sessionBean;
public RequestBean() {
System.out.println(sessionBean.getProperty());
}
}
However, it throws the following exception:
java.lang.NullPointerException
at com.example.RequestBean.<init>(RequestBean.java:42)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.jboss.weld.introspector.jlr.WeldConstructorImpl.newInstance(WeldConstructorImpl.java:206)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:117)
at org.jboss.weld.bean.ManagedBean.createInstance(ManagedBean.java:336)
at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:200)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:292)
...
How is this caused and how can I solve it?
You're expecting that the injected dependency is available before the bean is constructed. You're expecting that it works like this:
RequestBean requestBean;
requestBean.sessionBean = sessionBean; // Injection.
requestBean = new RequestBean(); // Constructor invoked.
This is however not true and technically impossible. The dependencies are injected after construction.
RequestBean requestBean;
requestBean = new RequestBean(); // Constructor invoked.
requestBean.sessionBean = sessionBean; // Injection.
You should be using a #PostConstruct method instead if you intend to perform business logic based on injected dependencies directly after bean's construction.
Remove the constructor and add this method:
#PostConstruct
public void init() {
System.out.println(sessionBean.getSomeProperty());
}
BalusC's reply is correct, but is does reflect the assignment phase of a object creation, that did not run at this time. But anyway the CDI bean should be accessible if you grep it programatically via:
javax.enterprise.inject.spi.CDI.current().select(SessionBean.class).get()

Resources