Application scoped managed bean not initializing - cdi

I have an application scoped managed bean which I am trying to inject into a session filter to filter rules based on the map provided from application scoped bean .
The Application scoped beans purpose was to load application configuration from the database into the Map which can be accessed during the scope of the application.
#Named
#ApplicationScoped
public class ApplicationConfig implements Serializable {
private Map<String,String> accessRule;
private static final long serialVersionUID = -7984677603595580195L;
#PostConstruct
public void init() throws SQLException, Exception {
System.out.println("ApplicationContainer INIT");
accessRule.put("A", "A");
}
public Map<String,String> getAccessRule() {
return accessRule;
}
public void setAccessRule(Map<String,String> accessRule) {
this.accessRule = accessRule;
}
}
I have tried #PostConstruct and also tried using the constructor too but the bean is not being called.This how the Named bean is being injected
#WebFilter(urlPatterns = { "/*" })
public class ApplicationFilter implements Filter {
private static final String FACES_RESOURCES = "javax.faces.resource";
private static final Logger log = Logger.getLogger(ApplicationFilter.class.getName());
private boolean disableFilter;
private String errorPage;
private String indexPage;
#Inject
public ApplicationConfig applicationConfig;
private List<String> ignoredResources = new ArrayList<>();
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
System.out.println(applicationConfig.getAccessRule());
arg2.doFilter(arg0, arg1);
}
#Override
public void init(FilterConfig arg0) throws ServletException {
}
}
I have used #Named / #Inject and still doesn't work. I want to use a application scoped bean that takes details from DB and used it in a WebFilter. Kindly help

Related

Why is my Primefaces.current() returning null

So, I have this page:
#Named("ManagementPage")
#ViewScoped
#Getter
#Setter
#Join(path = "/{appScope}/admin/management",
to = "/pages/scoped/managementOverview.xhtml")
#Page(
group = "kitchen",
icon = "mdi mdi-comment-text",
key = "management",
navigation = Page.Navigation.ADMIN_SCOPED,
outcome = "/pages/scoped/managementOverview.xhtml",
auth = #PageAuth(value = "MANAGER_ACCESS", scoped = true))
public class ManagementPage implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private ManagementModel model;
#PostConstruct
public void init() {
this.model.init();
}
}
It's ViewScoped. And the model for it is:
#Log4j
#Dependent
#Getter
#Setter
public class ManagementModel implements Serializable {
...
}
I want, whenever I receive an event, to refresh some UI on the frontend (I'm using JSF). For that, I've created this dispatcher:
#ApplicationScoped
public class OrderEventDispatcher {
private static final List<ManagementModel> subscriptions = new ArrayList<>();
public static void addSubscriber(ManagementModel subscriber) {
subscriptions.add(subscriber);
}
public static void removeSubscriber(ManagementModel subscriber) {
subscriptions.remove(subscriber);
}
public void observerOrderCreated(#Observes FrontendEvent frontendEvent) {
if(frontendEvent instanceof ContentItemCreatedEvent){
if(!"order".equals(((ContentItemCreatedEvent) frontendEvent).getTypeKey())){
return;
}
}
if(frontendEvent instanceof ContentItemChangedEvent){
if(!"order".equals(((ContentItemChangedEvent) frontendEvent).getTypeKey())){
return;
}
}
subscriptions.forEach(ManagementModel::orderInit);
}
}
(I have implemented a proper equals for this in my model)
For my dispatcher to work, I'm subcribing with my model to it (the methods are inside the model)
#PostConstruct
public void init() {
id = totalIds++;
OrderEventDispatcher.addSubscriber(this);
...
And then i unsubscribe before I destroy the model:
#PreDestroy
public void preDestroy() {
OrderEventDispatcher.removeSubscriber(this);
}
And finally, the methods I call from my dispatcher:
public void orderInit() {
loadMergedOrders();
initializeDonut();
PrimeFaces.current().executeScript("orderInit()");
}
I'm doing all this in order to refresh my page (even when multiple instance of the same page are open) in reaction to an event (some item is created/deleted/modified, of that the FrontendEvent takes care). Now the issue is that my PrimeFaces.current() is always returning null, I've added a breakpoint in the init() method and I tried using PrimeFaces.current() and it worked then, but then when I went through the Dispatcher and into the orderInit() with the debugger I've seen that PrimeFaces.current() now returns null. Does anyone have any idea what I'm doing wrong? If not how to fix this then maybe a different approach to solving this. Thanks for your time!

How to inject beans with AspectJ and CDI

I've coded this aspect:
#Aspect
public class LoggingCacheAspect {
#Pointcut("call * javax.cache.integration.CacheLoader.load(*)")
void cacheLoadCalls() {};
#Before("cacheLoadCalls")
public void beforeCacheCalls() {}
}
Also, I'm using CDI, and I'm looking forward to figure out how to inject a bean into this aspect.
I guess that adding #Inject annotation will not be enought.
Is it possible?
How could I get it?
You need to use an interceptor instead of the aspect
Here is an example:
#InterceptorBinding
#Target({TYPE, METHOD })
#Retention(RUNTIME)
public #interface CacheLog{
}
#Interceptor
#CacheLog
public class CacheLogInterceptor implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private YourBean yourBean;
#AroundInvoke
public Object cacheLogMethodCall(InvocationContext ctx) throws Exception {
//#Before
yourBean.method();
...
return ctx.proceed();
}
}
#CacheLog
public void cacheLoadCalls() {
...
...
}

Calling a method in application-scoped bean from quartz job

I have an application scoped bean
#ManagedBean(name = "myController")
#ApplicationScoped
public class MyController implements Serializable{
...
public void allOn(){...}
And i want to call the allOn() method from a quartz-job
import org.quartz.Job;
public class CronJobAllOn implements Job{
#Override
public void execute(..){
//call allOn();}
}
I tried to pass the FacesContext to the Job-Class via the JobDataMap
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("facesContext", FacesContext.getCurrentInstance());
JobDetail job = newJob(CronJobAllOn.class)
.usingJobData(jobDataMap)
.withIdentity("job1", "group1")
.build();
But it only throws an IllegalStateException when i try to call it in the CronJobAllOn Class
public void execute(JobExecutionContext context) throws JobExecutionException {
FacesContext fc= (FacesContext) context.getMergedJobDataMap().get("facesContext");
MyController test = (MyController)fc.getExternalContext().getApplicationMap().get("MyController");
test.allOn();}
How can i call the allOn() method in MyController from a quartz-job?
I got the solution for my Problem, the short comment from BalusC put me on the right path.
I switched to TomEE, to get CDI.
To use the CDI-Bean injection in my jobs, i had to create my own JobFactory Class:
public class CdiJobFactory implements JobFactory {
#Inject
#Any
private Instance<Job> jobs;
#Override
public Job newJob(TriggerFiredBundle triggerFiredBundle, Scheduler scheduler) throws SchedulerException {
final JobDetail jobDetail = triggerFiredBundle.getJobDetail();
final Class<? extends Job> jobClass = jobDetail.getJobClass();
for (Job job : jobs) {
if (job.getClass().isAssignableFrom(jobClass)) {
return job;
}
}
throw new RuntimeException("Cannot create a Job of type " + jobClass);
}
create the Factory
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.setJobFactory(cdiJobFactory);
after that i was able to inject myController:
public class CronJobAllOn implements Job{
#Inject
private MyController mc;
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
mc.allOn();
}

GlassFish ManagedBeanCreationException and NullPointerException

I have written an EJB and a dynamic web project Eclipse on GlassFish server. I used DAO , Facade and JPA. Normally I am calling a method from my service it is giving these errors ;
kitapOduncVerme.xhtml]com.sun.faces.mgbean.ManagedBeanCreationException
PWC1406: Servlet.service() for servlet Faces Servlet threw exceptionjava.lang.NullPointerException
at com.mesutemre.kitapislemleri.KitapOduncVermeBean.initList(KitapOduncVermeBean.java:47)
at com.mesutemre.kitapislemleri.KitapOduncVermeBean.initialize(KitapOduncVermeBean.java:43)
My codes are below;
#ManagedBean(name = "oduncKitapVerBean")
#ViewScoped
public class KitapOduncVermeBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<Kitaplar> entityList = new ArrayList<Kitaplar>();
private Kitaplar selectedEntity;
private Kitaplar entity;
private String kullaniciadi;
private KitaplarFacade service;
public KitapOduncVermeBean() {
entity = new Kitaplar();
selectedEntity = new Kitaplar();
}
#PostConstruct
public void initialize(){
HttpSession session = Util.getSession();
kullaniciadi = Util.getUserName();
initList();
}
private void initList(){
entityList = service.findAllKitaplar();
}
DaoImpl
#SuppressWarnings("unchecked")
public List<Kitaplar> findAllKitaplar(){
return em.createNamedQuery("tumkitaplarigetir").getResultList();
}
Dao
#Stateless
#LocalBean
public class KitaplarDAO extends KitaplarDaoImpl<Kitaplar> implements Serializable{
private static final long serialVersionUID = 1L;
#Override
public List<Kitaplar> findAllKitaplar() {
return super.findAllKitaplar();
}
FacadeImpl
#Stateless
#LocalBean
public class KitaplarFacadeImpl implements KitaplarFacade,Serializable {
private static final long serialVersionUID = 1L;
#EJB
KitaplarDAO kitapDao;
#Override
public List<Kitaplar> findAllKitaplar() {
return kitapDao.findAllKitaplar();
}
}
Facade
#Local
public interface KitaplarFacade {
public abstract List<Kitaplar> findAllKitaplar();
}
I can't see any problem in this codes? But Why am I getting that errors?
ManagedBeanCrearionException is simply wrapping and rethrowing the NullPointerException, that is very easy to debug: you have a null variable at the exact line that appears in the stack trace.
In KitapOduncVermeBean class, you are declaring service property, but you are not initializing it, therefore it's null when invoked in initList() method. Since it's an EJB, annotate it as such and the EJB container will instantiate it automatically:
#EJB
private KitaplarFacade service;
Unrelated to the concrete problem, your code is too complicated: with EJB 3.x, in most web applications, you don't need EJBs to implement or expose interfaces.

Java EE 6: How to inject ServletContext into managed bean

(Java EE 6 with Glassfish 3.1)
I have a property file that I want to process only once at start up time, so I did this
public class Config implements ServletContextListener{
private static final String CONFIG_FILE_PATH = "C:\\dev\\harry\\core.cfg";
private static final String CONFIG_ATTRIBUTE_NAME = "config";
private long startupTime;
private ConfigRecord config;
#Override
public void contextInitialized(ServletContextEvent sce) {
this.startupTime = System.currentTimeMillis() / 1000;
this.config = new ConfigRecord(CONFIG_FILE_PATH); //Parse the property file
sce.getServletContext().setAttribute(CONFIG_ATTRIBUTE_NAME, this);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
//Nothing to do here
}
public ConfigRecord getConfig() {
return config;
}
public long getStartupTime() {
return startupTime;
}
}
and in web.xml, i register it as follow
<listener>
<listener-class>com.wf.docsys.core.servlet.Config</listener-class>
</listener>
Now how do I access the ConfigRecord config from the managed bean. I try this
#ManagedBean
#RequestScoped
public class DisplayInbound {
#EJB
private CoreMainEJBLocal coreMainEJBLocal;
#javax.ws.rs.core.Context
private ServletContext servletContext;
public void test(){
Config config = (Config) servletContext.getAttribute("config")
ConfigRecord configRecord = config.getConfig();
}
}
I dont think it work. Got NullPointerException.
That #Context annotation is only applicable in a JAX-RS controller, not in a JSF managed bean. You have to use #ManagedProperty instead. The ServletContext is available by ExternalContext#getContext(). The FacesContext itself is available by #{facesContext}.
#ManagedProperty(value="#{facesContext.externalContext.context}")
private ServletContext context;
Or because you stored the listener as a servletcontext attribute, which is basically the same as the JSF application scope, you could also just set it as managed property by its attribute name:
#ManagedProperty(value="#{config}")
private Config config;
But since you're on JSF 2.0, I'd suggest to use an #ApplicationScoped #ManagedBean instead which is eagerly constructed. With #PostConstruct and #PreDestroy in such a bean you have similar hooks on webapp's startup and shutdown as in a ServletContextListener.
#ManagedBean(eager=true)
#ApplicationScoped
public void Config {
#PostConstruct
public void applicationInitialized() {
// ...
}
#PreDestroy
public void applicationDestroyed() {
// ...
}
}
You can inject it in another beans the usual #ManagedProperty way and access it in the views the usual EL way.

Resources