#Inject gives null Object [duplicate] - jsf

This question already has answers here:
NullPointerException while trying to access #Inject bean in constructor
(2 answers)
Closed 5 years ago.
I have these two classes and want to use the method of MyData to insert data in MyBean.
#Named
#RequestScoped
public class MyBean implements Serializable {
#Inject
private MyData myData;
public MyBean() {
// NullPointerException, because myData is null
this.dataList = myData.method();
}
...
}
#Singleton
class MyData {
method(){
...
}
}
MyData on the other Hand injects a controller class myHandler:
#Singleton
public class myHandler {...}
I keep getting error messages, that myData.method() is null and have no idea about it. Maybe I haven't fully understood what CDI injection means?
Edit:
These are the fully qualified annotations.
import javax.ejb.Singleton;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
Edit2: The container used is a wildfly 11. Since I use Maven too, there is not much I could do wrong with my project structure because I have to follow the Maven rules.
As I mentioned before, the server works fine for crud operations on my database, where I used CDI and JSF before. I just added MyBean and MyData to my project.
I tried #Startup, results have not changed.
Edit3: I don't think it's a duplicate because I tried to use #DependsOn() annotation and still get null back. The NullException doesn't come from the bean but from JavaScript, where I want to insert a String with JSF later being processed to a chart. The stacktrace says, that this function passes null value to the member variable in the contructor of the bean.

Have you used EJB Singleton by mistake? javax.ejb.Singleton is not recognised by CDI and so it will not be picked up.
For CDI, use either javax.inject.Singleton or #ApplicationScoped.

Related

Rename WELD request parameter "cid" [duplicate]

This question already has answers here:
Get rid of org.jboss.weld.context.NonexistentConversationException, when a query-string parameter named cid is appended to the URL
(3 answers)
Closed 3 years ago.
I have a project with "Omnifaces 3.3" and "weld.servlet.shaded 3.0.5.Final".
I need to use a request parameter named "cid" in my application, but using it produces the next exception in Weld:
javax.servlet.ServletException: WELD-000321: No conversation found to restore for id 12312312
javax.faces.webapp.FacesServlet.service(FacesServlet.java:683)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
es.ine.sgtic.web.filter.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:38)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
I'm trying to rename the parameter that uses Weld internally using the next context-param, but it doesn't work, it keeps using "cid":
servletContext.setInitParameter("WELD_CONTEXT_ID_KEY", "weldCid")
I'm using JSF 2.3 with Spring, so my beans are managed by Spring with the annotation #Component. I've seen other solutions where they Inject #Inject private HttpConversationContext conversationContext; in an application bean, but it isn't available, and Spring doesn't find any implementation of that interface if I try to inject it in a bean.
How can I rename that parameter or get rid of it. I only use WELD in my project because Omnifaces requires it, but I don't really use anything from it.
Thanks.
After many tests, the only thing that worked was the next listener.
#WebListener
public class MyServletContextListener implements ServletContextListener {
#Inject
private HttpConversationContext conversationContext;
#Override
public void contextInitialized(ServletContextEvent sce) {
this.hideConversationScope();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
// Not used
}
private void hideConversationScope() {
this.conversationContext.setParameterName(UUID.randomUUID().toString());
}
}
Here the object "conversationContext" was properly initialized and the renamed worked.

Using LocalDate in Serialized JSF Managed Bean

I'm currently working on an Java EE application with Java 8. And, I have a SessionScoped managed bean as below. Since LocalDate is value based, SONAR check throws me an error saying, "Value based should not be serialized"
#SessionScoped
#ManagedBean
public class MyBean implements Serializable {
private LocalDate startDate;
/*getters and setters */
}
How to handle this situation. Is it fine to make the variable transient? Is there any impact, if I make it transient? Or I can ignore this SONAR error?
Any help would be appreciated. Thank you in advance!

RESTEasy, CDI, embedded Jetty, bean validation is ignored

I've a Groovy project where I use RESTEasy with Weld and deploy to embedded Jetty. What I can't seem to get working is bean validation. RESTEasy documentation says that adding resteasy-validator-provider-11 along with hibernate validator dependencies (hibernate-validator, hibernate-validator-cdi, javax.el-api, javax.el) is enough. But the bean validation is simply ignored by RESTEasy. I curiously also get the following message in the logs:
plugins.validation.ValidatorContextResolver - Unable to find CDI supporting ValidatorFactory. Using default ValidatorFactory
Based on the suggestions on [this][1] post, I tried registering Hibernate InjectingConstraintValidatorFactory in META-INF/validation.xml but it depends on a BeanManager being injected and blows up at runtime.
The code can be found here https://github.com/abhijitsarkar/groovy/tree/master/movie-manager/movie-manager-web
A log gist is here: https://gist.github.com/anonymous/8947319
I've tried everything under the sun without any success. Pls help.
To do this without EE, I believe you'll need to fork the existing InjectingConstraintValidatorFactory but instead of using injection of the bean manager, use the CDI 1.1 class CDI to get a reference to the bean manager, e.g. CDI.current().getBeanManager(). http://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/spi/CDI.html
You do need to be on CDI 1.1 to do this (so Weld 2+, 2.1.1 is current I believe). Here's an example impl, based on: https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main/java/org/hibernate/validator/internal/cdi/InjectingConstraintValidatorFactory.java
public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
// TODO look for something with better performance (HF)
private final Map<Object, DestructibleBeanInstance<?>> constraintValidatorMap =
Collections.synchronizedMap( new IdentityHashMap<Object, DestructibleBeanInstance<?>>() );
private final BeanManager beanManager;
public InjectingConstraintValidatorFactory() {
this.beanManager = CDI.current().getBeanManager();
Contracts.assertNotNull( this.beanManager, "The BeanManager cannot be null" );
}
#Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
DestructibleBeanInstance<T> destructibleBeanInstance = new DestructibleBeanInstance<T>( beanManager, key );
constraintValidatorMap.put( destructibleBeanInstance.getInstance(), destructibleBeanInstance );
return destructibleBeanInstance.getInstance();
}
#Override
public void releaseInstance(ConstraintValidator<?, ?> instance) {
DestructibleBeanInstance<?> destructibleBeanInstance = constraintValidatorMap.remove( instance );
destructibleBeanInstance.destroy();
}
}
I finally fixed this. Turns out, a validation.xml is not really required, resteasy-cdi module does a fine job of registering the BeanManager. What I was missing and not clearly documented anywhere, is that if an annotation is placed on a method, the validation engine just "decides" what should be validated. I placed a #NotNull on a method and it was validating the return type, not the parameters. One can use validationAppliesTo element in some cases but #NotNull doesn't have it. When I moved it from the method to the parameter, it started working.
Now I ran across what I believe is a Weld bug but I'll post that question separately.

Non-lazy instantiation of CDI SessionScoped beans

CDI newbie question. Simple test scenario: JSF + CDI SessionScoped beans.
I need an elegant way to instantiate a known set of session scoped CDI beans without mentioning them on a JSF page or calling their methods from other beans. As a test case - a simple logging bean, which simply logs start and end time of an http session.
Sure, I could create an empty JSF component, place it inside of a site-wide template and make it trigger dummy methods of the required session beans, but it's kinda ugly from my pov.
Another option I see, is to choose a single session bean (which gets initialized 100% either by EL in JSF or by references from other beans), and use its #PostConstruct method to trigger other session beans - the solution a little less uglier than the previous one.
Looks like I'm missing something here, I'd appreciate any other ideas.
While accepting the Karl's answer and being thankful to Luiggi for his hint, I also post my solution which is based on HttpSessionListener but does not require messing with BeanProvider or BeanManager whatsoever.
#WebListener
public class SessionListener implements HttpSessionListener {
#Inject
Event<SessionStartEvent> startEvent;
#Inject
Event<SessionEndEvent> endEvent;
#Override
public void sessionCreated(HttpSessionEvent se) {
SessionStartEvent e = new SessionStartEvent();
startEvent.fire(e);
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
SessionEndEvent e = new SessionEndEvent();
endEvent.fire(e);
}
}
To my surprise, the code above instantiates all the beans which methods are observing these events:
#Named
#SessionScoped
public class SessionLogger implements Serializable {
#PostConstruct
public void init() {
// is called first
}
public void start(#Observes SessionStartEvent event) {
// is called second
}
}
Yes, HttpSessionListener would do it. Simply inject the beans and invoke them.
If you container does not support injection in a HttpSessionListener you could have a look at deltaspike core and BeanProvider
http://deltaspike.apache.org/core.html

CDI: How to put an existing object into application scope (without writing CDI extension)?

I have an object which I initialized manually (legacy code).
I'd like to put this object to the application context to make it available through CDI.
How do I do that without writing a CDI extension?
Using a producer. Make a bean that #Produces instances of your class.
Do you need something like that?
#ApplicationScoped
public class ApplicationScopedClass {
#Produces
public static ApplicationScopedClass makeAnInstance() {
return new ApplicationScopedClass();
}
}

Resources