I really do not know what's the cause of the problem. I created a website with hibenate and JSF and later decided to integrate Spring framework as well, but eventually faced a problem.
My managed bean "loginbean" was working perfectly. It also recognizes the method within a JSF page, but when I run the application I see an "error excusion" message.
My bean:
#ManagedBean(name="loginBean")
#SessionScoped
public class LoginBean {
private String username;
private String password;
private int activeindex;
public String Dirige(int a){
setActiveindex(a);
if (a == 0){
return "/Menu.jsf";
}else{
if (a == 1) {
return "/pagess/pagesFabricant/Fabricant.jsf";
}else{
if (a == 2) {
return "/pagess/pagesComposant/Composant.jsf";
}else{
if(a == 3){
return "/pagess/pagesDeq/DEQ.jsf";
}
}
}
}
return null;
}
}
I added SpringBeanFacesELResolver in faces-config.xml:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application> on faces.config.xml
and I also included the relevant listeners in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
My view:
<p:tabMenu activeIndex="#{loginBean.activeindex}">
<p:menuitem value="Home" icon="ui-icon-star" action="#{loginBean.Dirige(0)}" />
<p:menuitem value="Fabricants" icon="ui-icon-wrench" action="#{loginBean.Dirige(1)}" />
<p:menuitem value="Composants" icon="ui-icon-search" action="#{loginBean.Dirige(2)}"/>
<p:menuitem value="Dossier d'equivalence" icon="ui-icon-document" action="#{loginBean.Dirige(3)}"/>
</p:tabMenu>
And finally this is the error I've got:
Grave: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:92)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
the problem is that I start the application in another tomcat server .. it works well it accepts bean method with parameters
Thx all for your cooperation
Related
I need to Autowire a service class annotated with #Service annotation in my session listener class as I need to perform some DB operation on session destroyed method. I am not able to autowire the service class as I have added the listener in my web.xml and it is no longer spring managed. I have tried several options(workarounds) like getting a bean from application context via servlet context but I am not getting any beans in that way.
Following are my classes:-
MyService:
#Service
#Transactional
public class FxTransactionService{
//some autowirings
public void performDBoperation(Long id)
{
//business logic
}
}
Session Listener:
public class SessionHandler implements HttpSessionListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
private MyService myService;
#Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("Session created");
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(arg0.getSession()
.getServletContext());
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
//This gives me empty list
}
#Override
public void sessionDestroyed(HttpSessionEvent arg0) {
Long id = (Long) arg0.getSession().getAttribute("Id");
myService.performDBoperation(id);
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.abc.controller.SessionHandler</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<filter>
<filter-name>preAuthHeaderAdditionFilter</filter-name>
<filter-class>com.abc.filter.PreAuthHeaderAdditionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>preAuthHeaderAdditionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- <filter> <filter-name>openEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter> <filter-mapping> <filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern> </filter-mapping> -->
</web-app>
First install the Spring listener ContextLoaderListener.
In your own listener you can access the context using WebApplicationContextUtils.
It is not autowiring though, you have to fetch the required bean/service yourself.
I am using JSF2 with Spring3 JDBC template. I have added the following content to the web.xml file
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
I have added the following code into faces-config.xml
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
DAO code is the following
#Repository
public class XXXDAOImpl implements ZZZDAO{
#Autowired
private JdbcTemplate jdbcTemplate
------------------
}
public void methodname(object){
jdbcTemplate.update(sqlquery,arguments);
}
I have added the following code in application context xml file.
The managed bean is
#ManagedBean(name = "aaaBean")
#RequestScoped
public class CustomerBean{
-----
}
I am using Spring 3.0 jar files and javax.faces-2.2.8 jar file.
The intention is to get customer details from a JSF view page and store it in a table.
Upon execution of the code a null pointer exception is thrown from DAO where jdbc template's update method is invoked. Help is apprciated.
I'm trying to integrate Vaadin with Spring. In my main Vaadin application class I have:
public class MyVaadinApplication extends UI {
#Inject
private PrivatePersonBo privatePersonBo;
#Override
public void init(VaadinRequest request) {
Layout layout = new FormLayout();
layout.setCaption("New Private Person");
setContent(layout);
ApplicationContext appContext = new ClassPathXmlApplicationContext("resources/spring/Context.xml");
appContext.getBean(MyVaadinApplication.class);
PrivatePersonBo privatePersonBo = (PrivatePersonBo) appContext.getBean("privatePersonBo");
PrivatePerson existingEmployee = privatePersonBo.findByName("TestUserName");
}
}
If I get bean from context directly I recieve bean, however If I comment line which recieves bean from appContext then #Inject annotation doesn't work and I get NullPointerException. My deployment descriptor is below:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:resources/spring/Context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>VaadinApplicationServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>pl.adamsalata.MyVaadinApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>VaadinApplicationServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Any suggestions please?
You can integrate Vaadin 7 with Spring in two simple steps:
1) Create a UIProvider that lookup UIs in spring context:
public class SpringUIProvider extends DefaultUIProvider {
#Override
public UI createInstance(UICreateEvent event) {
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(VaadinServlet.getCurrent().getServletContext());
return ctx.getBean(event.getUIClass());
}
}
2) Declare the UIProvider in web.xml:
<context-param>
<param-name>UIProvider</param-name>
<param-value>org.example.SpringUIProvider</param-value>
</context-param>
And remember to use prototype scope for UI classes.
If you want to integrate Vaadin with Spring then use #Configurable feature. Then all instantiated objects (even if you create them using new MyObject() code) will be integrated with Spring context. You can find more details about such setup in Spring documentation: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-using-aspectj
I can see that the FilterDispatcher is called (by debugger), but it doesn't seem to find the service to call. I've got trouble grasping how RestEasy actually maps between resources defined in Spring and RestEasy.
Main story: Getting http://my.local.no:8087/rest/typeaheads/h only renders 404
web.xml:
...
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>restFilterDispatcher</filter-name>
<filter-class>org.jboss.resteasy.plugins.server.servlet.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>restFilterDispatcher</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
...
resteasy resource is set up by bean:
#Configuration
#ComponentScan(basePackageClasses = TypeaheadsRestService.class)
public class SpringConfig {
}
TypeaheadsRestService.java:
#Resource
#Path("/typeaheads")
public class TypeaheadsRestService {
#GET
#Path("/{search}")
#Produces(MediaType.APPLICATION_JSON)
public List<NameUrl> get(#PathParam("search") String search) {
...
}
}
The RestEasy SpringContextLoaderListener seem to be the missing part. I created a stripped down problem from RestEasy example and used it. For my somewhat more complex application however it would not work. That is probably because it overrides the deprecated createContextLoader-method. In Spring 3 ContextLoaderListener is an instance of ContextLoader. So I reimplemented it like this:
public class MyContextLoaderListener extends ContextLoaderListener {
private SpringContextLoaderSupport springContextLoaderSupport = new SpringContextLoaderSupport();
#Override
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
super.customizeContext(servletContext, applicationContext);
this.springContextLoaderSupport.customizeContext(servletContext, applicationContext);
}
}
I originally tried to do the customizeContext(...) in a bean initialisation. That worked in RestEasy 2.2.1.GA, but not in 2.3.4.FINAL.
I get this error with a gwt (using requestfactory) and spring
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.calibra.server.service.AccountService] is defined: expected single bean but found 0:
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:271)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
at org.calibra.server.SpringServiceLocator.getInstance(SpringServiceLocator.java:24)
at com.google.web.bindery.requestfactory.server.LocatorServiceLayer.createServiceInstance(LocatorServiceLayer.java:56)
My service locator
public class SpringServiceLocator implements ServiceLocator {
#Override
public Object getInstance(Class<?> clazz) {
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(
RequestFactoryServlet.getThreadLocalServletContext());
return context.getBean(clazz);
}
}
My spring service
#Service
public class AccountServiceImpl implements AccountService{
#Override
public void addNewAccount(Account account) {
...
}
#Override
public List<Account> loadAllAccounts() {
...
}
}
Gwt requestContext, reference my spring service
#Service(value=AccountService.class, locator=SpringServiceLocator.class)
public interface AccountRequest extends RequestContext {
Request<Void> addNewAccount(AccountProxy account);
Request<List<AccountProxy>> loadAllAccounts();
}
my web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>gwtRequest</servlet-name>
<servlet-class>com.google.web.bindery.requestfactory.server.RequestFactoryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gwtRequest</servlet-name>
<url-pattern>/gwtRequest</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>welcomeGWT.html</welcome-file>
</welcome-file-list>
I don't understand how i can have 0 AccountService beans ?
i tried to add in the dispatcher-servlet
<bean id="accountService" class="org.calibra.server.service.AccountServiceImpl"/>
I got the same result
Any idea?
edit: if somebody have a full complete example, that could be useful.
I think using the ContextLoaderListener alone is not enough as you don't seem to have the DispatcherServlet in use (have you?).
The following lines work for me:
<filter>
<filter-name>springRequestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springRequestContextFilter</filter-name>
<url-pattern>/gwtRequest</url-pattern>
</filter-mapping>
I've seen this question in a couple of other places. You should try explicity defining the AccountServiceImpl as a bean in your applicationContext.xml (not the dispatch-servlet.xml) first and see if you still get the error, if you don't then you know it's that you're missing the component-scan in your application context xml which is what I think is the case.
hope this helps