I have some constants like APPVERSION, APPNAME and APPREV that I want to display on every page on my Struts 2 app.
With these requirements I thought that it would be great to put that info intro servletContext and to load this when the app is deployed.
I have created a listener that implements ServletContextListener:
public class ApplicationInitListenerImpl extends GenericVsService implements ApplicationInitListener,ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext sc = sce.getServletContext();
sc.setAttribute("appVer",xxx.utils.VConstants.APPVER);
sc.setAttribute("appName",xxx.utils.VConstants.APPNAME);
sc.setAttribute("appRev",xxx.utils.VConstants.APPREV);
}
}
and then I have added in my web.xml the listener:
<listener>
<listener-class>xxx.listeners.ApplicationInitListenerImpl</listener-class>
</listener>
In my Tiles template I have added:
<s:property value="#application.appName"/> - <s:property value="#application.appVer"/>
But I get nothing here.
If I retrieve the servletContext from a Struts 2 Action I can read the correct values, so the values are set ok.
What am I doing wrong?
You can use
<s:property value="#attr.appName"/> - <s:property value="#attr.appVer"/>
Or
${appName} - ${appVer}
Related
I am nea to EJB3 and JSF. I am facing issue with bean injection and getting NullPointerException.
I have twi different modules - EJB & WEB
EJB Module has below class:
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class TestFacadeBean implements TestFacade {
.........
....
}
#Local
public interface TestFacade {
........
}
I am using this bean in my WEB module as below:
public class UserBean {
#EJB
private TestFacade testFacade;
public void useBean(){
testFacade.use();//this throws NullPointerException
}
}
UserBean is configured in faces-config.xml
<managed-bean>
<description>User Bean</description>
<managed-bean-name>userBean</managed-bean-name>
<managed-bean-class>com.test.managed.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
I tries to check value for bean testFacade and found it is null. Bean is not getting set.
Every time I try to inject a session-scoped bean into my view-scoped beans, I get a NullPointerException when calling said bean. This problem is directly related to auto -instantiate a session bean?
Here is what I tried so far:
faces-config.xml
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>com.example.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>viewBean</managed-bean-name>
<managed-bean-class>com.example.ViewBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<property-class>com.example.SessionBean</property-class>
<value>#{sessionMBean}</value>
</managed-property>
</managed-bean>
SessionBean.java:
package com.example;
public class SessionBean {
public SessionBean() {
System.out.println("Session is instantiated.");
}
public void sayHello() {
System.out.println("Hello from session");
}
}
ViewBean.java:
package com.example;
public class ViewBean {
private SessionBean sessionBean;
private String text = "Look at me!";
public ViewBean() {
System.out.println("View bean is instantiated.");
sessionBean.sayHello();
}
public SessionBean getSessionBean() {
return sessionBean;
}
public void setSessionBean(SessionBean sessionBean) {
this.sessionBean = sessionBean;
}
public String getText() {
return text;
}
}
and the relevant content of index.xhtml:
<f:view>
<h:outputText value="#{viewBean.text}"/>
</f:view>
And this is what I get:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.example.ViewBean.
...
Caused by: java.lang.NullPointerException
at com.example.ViewBean.(ViewBean.java:12)
This runs (or rather doesn't run) on weblogic-10.3.6 with the shipped jsf-2-0.war deployed as a library.
What am I doing wrong here? I'm hoping this is not a container bug...
You cannot access the #SessionScoped bean in the #ViewScoped constructor. The #SessionScoped bean will be set AFTER the constructor of the #ViewScoped bean has been called.
Use the #PostConstruct annotation in some kind of init method to access the #SessionScoped bean.
public ViewBean() {
System.out.println("Constructor viewbean");
}
#PostConstruct
public void init() {
sessionBean.sayHello();
}
Further Links:
Why use #PostConstruct?
Spring Injection - access to the injected object within a constructor
I have a problem. I wanna create a Job but not when application is started.
I wanna invoke method from pingServcie but is null.
This is my code:
Job class
class MyJob implements Job {
def pingService
#Override
void execute(JobExecutionContext context) throws JobExecutionException {
pingService.checkPing()
}
}
I read somewhere that I need bean with my Service class, because Spring Autowire doesn't work in this case, so I create it (I never work with bean so I don't if this is correct).
I create resources.xml instead of resources.groovy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="pingService" class="inzynierka.PingService" />
</beans>
But this doesn't work.
Finally, I did something like this.
class MyJob implements Job {
def PingService pingService
#Override
void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
pingService = dataMap.getWrappedMap().get("pingService")
pingService.checkPing()
}
}
I passing params in different class like this
job.getJobDataMap().put("pingService", pingService)
and it works.
Interception with CDI works perfectly in #Named , but doesn't in #ManagedBean:
Logable.java
#InterceptorBinding
#Retention(RUNTIME)
#Target({TYPE, METHOD})
public #interface Logable {
}
LoggingInterceptor.java
#Logable
#Interceptor
public class LoggingInterceptor {
#AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
//log smth. with ctx.
}
}
WorkingBean.java
#Named
#Logable
public class WorkingBean implements Serializable {
//works : methods will be logged
}
beans.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>LoggingInterceptor</class>
</interceptors>
</beans>
ViewScopedBean.java
#Logable
#ManagedBean
public class ViewScopedBean implements Serializable {
//doesn't work
}
I'm aware, that this kind of Interceptor is meant to work with WebBeans (and EJB),
but i'm searching for solution for both worlds (described + JSF) with same Interceptor concept
I need #ViewScoped #ManagedBean, thats why i cant get rid of #ManagedBean in favour of pure WebBeans
System:
Mojarra 2.1.7
Primefaces 3.2
As far as I understand, there isn't one. JSF doesn't have anything supporting interception.
JSF does not support the CDI interception like you have posted per se. A CDI interceptor will work for lifecycle methods like #PostConstruct
#Inherited
#InterceptorBinding
#Retention(RUNTIME)
#Target({TYPE})
public #interface TypeLogger {
#Nonbinding
public LoggingLevel logLevel() default LoggingLevel.INFO;
}
Here is how it would be used since it only binds to the #Target({TYPE})
#ManagedBean
#ViewScoped
#TypeLogger
public class Index implements Serializable {
private static final long serialVersionUID = 3336392241545517919L;
#PostConstruct
private void init() {
setup();
}
}
The first "nonpostback" request to viewBean, someValue property in sessionBean is null.
Now, in a postback request, I am setting a user input to someValue. The problem is that someValue is always null in any "nonpostback" request.
Here is my code:
#ManagedBean
#ViewScoped
public class ViewBean implements Serializable {
#ManagedProperty(value = "#{sessionBean}")
private SessionBean sessionBean;
private String inputText;
#PostConstruct
public void init() {
if (sessionBean.getSomeValue() != null) // ALWAYS NULL
doSomething(sessionBean.getSomeValue());
}
private void doSomething(String s) {}
public void action(final ActionEvent ae) {
sessionBean.setSomeValue(getInputText());
doSomething(getInputText());
}
GETTERS/SETTERS
}
#ManagedBean
#SessionScoped
public class SessionBean implements Serializable {
private String someValue;
GETTER/SETTER
}
I feel I am doing something wrong. I am using Mojarra 2.1.2
Any advice is appreciated. Thank you.
UPDATE:
Using evaluateExpressionGet on both methods (init and action) works fine:
FacesContext context = FacesContext.getCurrentInstance();
SessionBean sessionBean = context.getApplication().evaluateExpressionGet(context,
"#{sessionBean}", SessionBean.class);
This is a known issue:
SessionScoped bean inside a ViewScoped bean is resolved as different bean depending on the expression used
I just changed the state saving method in my web.xml:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
I use GAE (Google App Engine) and need to set javax.faces.STATE_SAVING_METHOD to client. This problem can have workaround. After the action, just call refreshSession() with new value force the session object persist
protected void refreshSession(){
saveSession(CeaConst.SESSION_ATTR_NAME_LAST_REFRESH_TIME, new java.util.Date());
}