Using the Struts2-Rest-Plugin with Spring - spring

I'm starting to use the Struts2 Rest Plugin in our Spring application.
Let's start with our struts.xml:
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.custom.i18n.resources" value="lang/messages" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.mapper.class" value="rest" />
<package name="default">
<action name="document" class="DocumentRestaction" />
</package>
</struts>
Then in Spring, I'm doing the following (to see if the String is injected):
<bean name="DocumentRestaction" class="be.example.actions.DocumentRestaction">
<property name="injected" value="Oh Hai" />
</bean>
I do a POST request to the URL /documents and end up in the create() method, great! In debug, my injected variable is injected. But when I let the debug continue, I get following exception:
4129 [http-8080-2] ERROR org.apache.struts2.rest.RestActionInvocation - Exception processing the result.
java.lang.RuntimeException: Invalid action class configuration that references an unknown class named [DocumentRestaction]
at org.apache.struts2.convention.ConventionsServiceImpl.determineResultPath(ConventionsServiceImpl.java:100)
at org.apache.struts2.convention.ConventionUnknownHandler.determinePath(ConventionUnknownHandler.java:379)
at org.apache.struts2.convention.ConventionUnknownHandler.handleUnknownResult(ConventionUnknownHandler.java:268)
at com.opensymphony.xwork2.DefaultUnknownHandlerManager.handleUnknownResult(DefaultUnknownHandlerManager.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.createResult(DefaultActionInvocation.java:227)
at org.apache.struts2.rest.RestActionInvocation.executeResult(RestActionInvocation.java:221)
at org.apache.struts2.rest.RestActionInvocation.processResult(RestActionInvocation.java:198)
at org.apache.struts2.rest.RestActionInvocation.invoke(RestActionInvocation.java:146)
at com.opensymphony.xwork2.DefaultActionProxy.execute(DefaultActionProxy.java:147)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:679)
Caused by: java.lang.ClassNotFoundException: DocumentRestaction
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
at org.apache.struts2.util.ClassLoaderUtils.loadClass(ClassLoaderUtils.java:111)
at org.apache.struts2.convention.ConventionsServiceImpl.determineResultPath(ConventionsServiceImpl.java:98)
... 27 more
But the class has been found .. (I ended up in create), why is it saying this? And most importantly, what am I doing wrong?
I'm using Spring v3.0.5, struts2-rest-plugin v2.3.1, struts2-core v2.3.1 and struts2-spring-plugin 2.3.1

In case anyone is looking for a solution to this, this article might help.
There's an omission in the sample code given though - in your applicationContext.xml, make sure you define the "id" and "class" to be the fully qualified class name of your controller:
<bean id="com.mersoft.web.controller.TestController" class="com.mersoft.web.controller.TestController">
<constructor-arg ref="testManager" />
</bean>
Hope that helps. Oh, and to be clear, you don't have to remove the convention plugin as suggested in an earlier comment.

Related

Spring Hibernate Transaction No Session Lazy Loading

I have a problem with only one controller that has a lazy loaded entity(there is a transaction initiated and commited, see stack trace)
17:56:46,084 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl#6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
17:56:46,085 DEBUG HibernateTransactionManager:438 - Found thread-bound Session [org.hibernate.impl.SessionImpl#6b204e88] for Hibernate transaction
17:56:46,085 DEBUG HibernateTransactionManager:471 - Participating in existing transaction
Hibernate: select preference0_.id as id66_, preference0_.name as name66_, preference0_.value as value66_, preference0_.default_value as default4_66_, preference0_.updated_at as updated5_66_ from preferences preference0_ where preference0_.name='scheduleInterval'
17:56:46,086 DEBUG GooGooStatementCache:457 - cxnStmtMgr.statementSet( com.mysql.jdbc.JDBC4Connection#5ec60ee2 ).size(): 21
17:56:46,086 DEBUG GooGooStatementCache:196 - checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 1; num connections: 10; num keys: 111
17:56:46,087 DEBUG GooGooStatementCache:271 - checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 111; checked out: 0; num connections: 10; num keys: 111
17:56:46,089 FATAL app:79 - service
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.model.User_$$_javassist_76.getName(User_$$_javassist_76.java)
at com.model.json.ScheduleItemWrapper.wrap(ScheduleItemWrapper.java:55)
at com.web.controllers.ajax.Model.wrap(Model.java:127)
at com.web.controllers.ajax.Model.toJSON(Model.java:165)
at com.web.controllers.ajax.Model.getContent(Model.java:51)
at com.web.controllers.ajax.BasicAction.execute(BasicAction.java:27)
at com.web.HibernateServlet.doService(HibernateServlet.java:113)
at com.web.HibernateServlet.service(HibernateServlet.java:66)
at sun.reflect.GeneratedMethodAccessor200.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:695)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at com.levitech.web.controllers.schedule.ScheduleList$$EnhancerByCGLIB$$4a7ae33e.service(<generated>)
at com.levitech.web.RequestDispatcher.service(RequestDispatcher.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
17:56:46,090 DEBUG HibernateTransactionManager:753 - Initiating transaction commit
17:56:46,090 DEBUG HibernateTransactionManager:653 - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl#6b204e88]
17:56:46,091 DEBUG HibernateTransactionManager:735 - Closing Hibernate Session [org.hibernate.impl.SessionImpl#6b204e88] after transaction
17:56:46,091 DEBUG SessionFactoryUtils:800 - Closing Hibernate Session
The model (ScheduleItem and User) and their hibernate mappings
public class ScheduleItem {
private Integer id;
....
private User user;
}
public class User {
private Integer id;
...
private String name;
}
<class
name="ScheduleItem"
table="schedule_item"
>
<cache usage="read-write"/>
<id
name="id"
type="integer"
column="id"
>
<generator class="identity" />
</id>
<many-to-one name="user" column="user_id" lazy="proxy"></many-to-one>
</class>
<class
name="ScheduleItem"
table="schedule_item"
>
<cache usage="read-write"/>
<id
name="id"
type="integer"
column="id"
>
<generator class="identity" />
</id>
<property name="name" column="name" type="string" />
</class>
I found the culprit. OpenSessionViewFilter is using a different session or sessionfactory.
Here is my Spring config and web.xml (What am I doing wrong?):
Part of web.xml:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/app/s/*</url-pattern>
</filter-mapping>
Part of Spring Config:
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${db.driver}"/>
<property name="jdbcUrl" value="${db.url}"/>
<property name="user" value="${db.user}"/>
<property name="password" value="${db.pass}"/>
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="100" />
<property name="acquireIncrement" value="5" />
<property name="maxStatements" value="200" />
<property name="idleConnectionTestPeriod" value="120" />
<property name="maxIdleTime" value="1800" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"></property>
<property name="mappingLocations" value="classpath*:com/model/hbm/**/*.hbm.xml" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
hibernate.cache.use_query_cache=true
hibernate.cache.use_second_level_cache=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
From the log it looks like the session is still open when you get this exception. The other scenario in which you would get such an exception is if the row doesn't exist in the database.
User user = session.load(User.class, 1000); // Create a proxy
user.getName(); // This would throw lazy initialization exception if row doesn't exist
One more scenario that can lead to this is working with detached objects. If you fetched and stored the ScheduleItem as a HTTPSession variable. Retrieve it in another request and then try to access the proxy - it will result in the same exception. The session that was used to load the object has been closed. If that is the case you need to first reattach the object to the new session (merge, update or lock) before using it.
There are multiple solutions for your problem:
The easiest one is using Spring's OpenSessionInViewFilter. Just add this filter to your web.xml and configure it to filter your request.
This filter opens and closes Hibernate session in a filter, so during page rendering session will be open.
Some people believe that OpenSessionInViewFilter is against good design, and it mixes business logic into presentation tier. If you think so, fetch the referenced object in your query (for example by using join fetch in your HQLs).
You could try to:
Eagerly load the collection.
initialize the collection before leaving the collection by calling the respective getter method Hibernate.initialize(rtn.getUserRoles());
Thats basically two times the same approach depending on what works best in your setup. You are making sure to load the complete entity before leaving the session that way the entity can be detached from the old and then reatached to a new session without problems. What you are doing is initializing the proxy before leaving the session so that the collection is available for sure when you are out of a session context.

Getting "org.jasypt.exceptions.EncryptionOperationNotPossibleException" when trying to login

I'm using Jasypt 1.9.0, Spring 3.1.1.RELEASE, and Maven 3.0.3. When I enter a username and password on my login page and submit, I get the following error …
org.jasypt.exceptions.EncryptionOperationNotPossibleException
org.jasypt.digest.StandardByteDigester.matches(StandardByteDigester.java:1107)
org.jasypt.digest.StandardStringDigester.matches(StandardStringDigester.java:1052)
org.jasypt.util.password.ConfigurablePasswordEncryptor.checkPassword(ConfigurablePasswordEncryptor.java:252)
org.jasypt.spring.security3.PasswordEncoder.isPasswordValid(PasswordEncoder.java:207)
org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:64)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:149)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:194)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:184)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:155)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
Here is the Spring security I have setup
<beans:bean id="bcProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider" />
<beans:bean id="jasyptPasswordEncryptor" class="org.jasypt.util.password.ConfigurablePasswordEncryptor">
<beans:property name="algorithm">
<beans:value>SHA-256</beans:value>
</beans:property>
<beans:property name="provider">
<beans:ref bean="bcProvider" />
</beans:property>
</beans:bean>
<!-- This Spring Security-friendly PasswordEncoder implementation will -->
<!-- wrap the PasswordEncryptor instance so that it can be used from -->
<!-- the security framework. -->
<beans:bean id="passwordEncoder" class="org.jasypt.spring.security3.PasswordEncoder">
<beans:property name="passwordEncryptor">
<beans:ref bean="jasyptPasswordEncryptor" />
</beans:property>
</beans:bean>
<authentication-manager alias="authenticationManager"
id="authenticationManager">
<authentication-provider user-service-ref="sbdUserDetailsService">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
The Jasypt docs aren't very helpful and I don't know what else to check. Grateful for any help here. -
It's probably intentionally impossible to tell the cause of the error from the Jasypt library without debugging into it and finding the underlying exception. My guess would be you have an undigested password in the back end store (the most likely source of failures to compare digested passwords).

org.springframework.core.NestedIOException: Cannot find Velocity template for URL

Velocity Configuration with spring,I am missing some configuration. Please tell me why it is happening so.
Getting the below error when I hit my url.
SEVERE: Servlet.service() for servlet springDispatcher threw exception
org.springframework.core.NestedIOException: Cannot find Velocity template for URL [layout.vm]: Did you specify the correct resource loader path?; nested exception is org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'layout.vm'
at org.springframework.web.servlet.view.velocity.VelocityLayoutView.checkResource(VelocityLayoutView.java:133)
at org.springframework.web.servlet.view.UrlBasedViewResolver.loadView(UrlBasedViewResolver.java:438)
at org.springframework.web.servlet.view.AbstractCachingViewResolver.createView(AbstractCachingViewResolver.java:186)
at org.springframework.web.servlet.view.UrlBasedViewResolver.createView(UrlBasedViewResolver.java:401)
at org.springframework.web.servlet.view.AbstractCachingViewResolver.resolveViewName(AbstractCachingViewResolver.java:103)
at org.springframework.web.servlet.DispatcherServlet.resolveViewName(DispatcherServlet.java:1211)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1160)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
spring-context.xml
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/velocity/" />
</bean>
<!-- View resolvers can also be configured with ResourceBundles or XML files.
If you need different view resolving based on Locale, you have to use the
resource bundle resolver. -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".vm" />
</bean>
I'm getting the below exception when the velocityconfig is dropped.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.web.servlet.view.velocity.VelocityConfig] is defined: expected single bean but found 0
at org.springframework.beans.factory.BeanFactoryUtils.beanOfTypeIncludingAncestors(BeanFactoryUtils.java:367)
at org.springframework.web.servlet.view.velocity.VelocityView.autodetectVelocityEngine(VelocityView.java:239)
at org.springframework.web.servlet.view.velocity.VelocityView.initApplicationContext(VelocityView.java:225)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:117)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:92)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1448)
at org.springframework.beans.fact
If I am not wrong, you will be able to achieve the Velocity configuration using your viewResolver alone.
Modify your prefix to the one mentioned in your resourceLoaderPath and it should be fine (didn't test it myself)
<property name="prefix"><value>/WEB-INF/velocity/</value></property>
Also, you could drop the velocityConfig tag altogether.
you should use
(bean id="ViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver")
not
(bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver")
this bean use 'layout.vm',i also have this problem.

spring mvc and ReloadableResourceBundleMessageSource

I am trying to build a spring MVC application (basically for self trainning reasons). This application has spring MVC, tiles, spring thems and jsp (sorry for numbering all but since i am not sure what i do wrong, i just wish to number all i think may help you help me).
my spring mvc configuration seems to work, untill i try to get message property from property files through org.springframework.context.support.ReloadableResourceBundleMessageSource.
so here is my configuration
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" p:cacheSeconds="3000">
<property name="basenames">
<list>
<value>messages</value>
<value>dev</value>
<value>theme</value>
</list>
</property>
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" p:definitions="/WEB-INF/tiles-defs/tiles-defs.xml" />
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:basename="views" />
<!-- Declare the Interceptor -->
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
<bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" p:paramName="theme"/>
<!-- Declare the Resolver -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"/>
<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver"/>
<!-- Spring themes -->
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="interceptors">
<list>
<ref local="themeChangeInterceptor" />
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
tiles and theme seem to work, so in my tiles baselayout i have:
<title><tiles:insertAttribute name="title" ignore="true" /></title>
<c:set var="css"><spring:theme code="css"/></c:set>
<c:if test="${not empty css}">
<link rel="stylesheet" href="<c:url value='${css}'/>" type="text/css"/>
</c:if>
this works! html is rendered with the correct css that i have in css property located inside theme.properties file loaded from ReloadableResourceBundleMessageSource and magically existing inside tiles!
So, getting courage i go to my jsp and insert
attempt 1:
<p><spring:message code="context"/></p>
attempt 2:
<p><fmt:message key="context"/></p>
tags used:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
(is there a difference? both work? seen both over web... so i tried once the first and then the second one)
and in the messages.properties/messages_el_gr.properties files i type context=default and context=greek.
This gives me exception in the first case and in the second just the string context prefixed and postfixed with ???.
Exception i get is:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/homeAutomation] threw exception [Request processing failed; nested exception is org.apache.tiles.impl.CannotRenderException: ServletException including path '/WEB-INF/tiles/baseLayout.jsp'.] with root cause
javax.servlet.jsp.JspTagException: No message found under code 'context' for locale 'el_GR'.
at org.springframework.web.servlet.tags.MessageTag.doStartTagInternal(MessageTag.java:184)
at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
at org.apache.jsp.WEB_002dINF.jsp.friends_jsp._jspx_meth_spring_005fmessage_005f0(friends_jsp.java:104)
at org.apache.jsp.WEB_002dINF.jsp.friends_jsp._jspService(friends_jsp.java:75)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:927)
at org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:684)
at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:678)
at org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
at org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
at org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
at org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
at org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
at org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
at org.apache.jsp.WEB_002dINF.tiles.baseLayout_jsp._jspx_meth_tiles_005finsertAttribute_005f3(baseLayout_jsp.java:307)
at org.apache.jsp.WEB_002dINF.tiles.baseLayout_jsp._jspService(baseLayout_jsp.java:108)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at org.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241)
at org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222)
at org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
at ......
I consider that i do not have the messageSource inside my context, so i considered as next step of searching what is going on to do the following (found on web)
#Autowired
ReloadableResourceBundleMessageSource messageSource;
#RequestMapping("/friends.htm")
public ModelAndView getPage()
{
ModelAndView modelAndView=new ModelAndView("friends");
modelAndView.addObject(messageSource);
return modelAndView;
}
by the way, my previeus controller had that method as follows:
#RequestMapping("/friends.htm")
public String getPage()
{
return friends;
}
This again throws same exception.. messageSource is not null.. it is autowired.
if i do inside the controller:messageSource.getMessage("context", null, Locale.ENGLISH), this throws the same exception when trying to get it.. (Greek locale does not exist?? with english it will go to default locale properties file which is messages.properties, correct?)
Ah, what else can i give you... yes property files are located in the src/main/resources directory and in war inside homeAutomation.war\WEB-INF\classes\ and homeAutomation.war (why?? i thought these would exist only in homeautomation.war directory... but skip this, atleast they are there...) my poms war plugin configuration is as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources</directory>
</resource>
</webResources>
</configuration>
</plugin>
in target directory again i see the property files in both target\classes directory and target\homeAutomation.
After all these, i still do not know what i do wrong and i cannot get localized properties inside my jsp working. I hope i gave al the necessary info (sorry for the too much info..., did not know which was relevant and which not). If you need more info please ask. Have been searching for this five days now and still have no clue.
you can use <p><spring:message code="context"/></p>
but you should have context= what you want in one of the following files :
messages_el_GR.properties
dev_el_GR.properties
theme_el_GR.properties

SPRING DATA-JPA + eclipseLink2.0 failed

In my test project, Spring container can't create a bean that extends JpaRepository due to following error.
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'srSvcInfoMtrRepository': FactoryBean
threw exception on object creation; nested exception is
java.lang.NoSuchMethodError:
javax.persistence.EntityManager.getMetamodel()Ljavax/persistence/metamodel/Metamodel;
It might be the problem relevant to JPA version.
I specified certain persistenceProvider in eclipelink2.0(org.eclipse.persistence.jpa.PersistenceProvider) at persistence.xml.
do you have any idea about this problem?
Stacktrace
2012-05-14 09:11:08 ERROR Caught
exception while allowing TestExecutionListener
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener#112da40]
to prepare test instance
*> [net.tjjang.learn.spring_jpa.test.SrSvcInfoMtrTest#b6d6ab]
java.lang.IllegalStateException: Failed to load ApplicationContext at
org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at
org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'srSvcInfoMtrRepository': FactoryBean
threw exception on object creation; nested exception is
java.lang.NoSuchMethodError:
javax.persistence.EntityManager.getMetamodel()Ljavax/persistence/metamodel/Metamodel;
at
org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)
at
org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1441)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:305)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at
org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
at
org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at
org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
at
org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
at
org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
... 24 more
> Caused by: java.lang.NoSuchMethodError:
javax.persistence.EntityManager.getMetamodel()Ljavax/persistence/metamodel/Metamodel;*
at
org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:56)
at
org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145)
at
org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:83)
at
org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:66)
at
org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:146)
at
org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:120)
at
org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:39)
at
org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
JpaRepository Class()
package net.tjjang.learn.spring_jpa.repositories;
import net.tjjang.learn.spring_jpa.domain.SrSvcInfoMtr;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
#Transactional(readOnly = true)
public interface SrSvcInfoMtrRepository extends JpaRepository<SrSvcInfoMtr, String> {
Page<SrSvcInfoMtr> findBySvc_nm(String svc_nm, Pageable pageable);
}
app-context.xml(not all the contents of app-context.xml)
<!-- for data access -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="cubrid.jdbc.driver.CUBRIDDriver" p:url="jdbc:cubrid:localhost:30000:test:test::"
p:username="test" p:password="*******" p:initialSize="5" p:maxActive="10">
</bean -->
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="persistenceUnitName" value="JpaPersistenceUnit" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<jpa:repositories base-package="net.tjjang.learn.spring_jpa" />
<import resource="infrastructure.xml" />
Persistence.xml
<persistence-unit name="JpaPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>net.tjjang.learn.spring_jpa.domain.Car</class>
<class>net.tjjang.learn.spring_jpa.domain.SrSvcInfoMtr</class>
<properties>
<property name="eclipselink.logging.level" value="INFO" />
</properties>
</persistence-unit>
Libraries
\org\springframework\spring-aop\3.1.0.RELEASE\spring-aop-3.1.0.RELEASE.jar
\aopalliance\aopalliance\1.0\aopalliance-1.0.jar
\org\springframework\spring-asm\3.1.0.RELEASE\spring-asm-3.1.0.RELEASE.jar
\org\springframework\spring-core\3.1.0.RELEASE\spring-core-3.1.0.RELEASE.jar
\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar
\org\springframework\spring-orm\3.1.0.RELEASE\spring-orm-3.1.0.RELEASE.jar
\org\springframework\spring-jdbc\3.1.0.RELEASE\spring-jdbc-3.1.0.RELEASE.jar
\org\springframework\spring-tx\3.1.0.RELEASE\spring-tx-3.1.0.RELEASE.jar
\org\springframework\spring-aspects\3.1.0.RELEASE\spring-aspects-3.1.0.RELEASE.jar
\org\springframework\spring-context\3.1.0.RELEASE\spring-context-3.1.0.RELEASE.jar
\org\springframework\spring-expression\3.1.0.RELEASE\spring-expression-3.1.0.RELEASE.jar
\org\springframework\spring-context-support\3.1.0.RELEASE\spring-context-support-3.1.0.RELEASE.jar
\org\springframework\spring-beans\3.1.0.RELEASE\spring-beans-3.1.0.RELEASE.jar
\org\springframework\spring-test\3.1.0.RELEASE\spring-test-3.1.0.RELEASE.jar
\org\springframework\spring-instrument\3.1.0.RELEASE\spring-instrument-3.1.0.RELEASE.jar
\junit\junit\4.8.2\junit-4.8.2.jar
\org\slf4j\slf4j-api\1.6.0\slf4j-api-1.6.0.jar
\org\slf4j\jcl-over-slf4j\1.6.0\jcl-over-slf4j-1.6.0.jar
\org\slf4j\slf4j-log4j12\1.6.0\slf4j-log4j12-1.6.0.jar
\log4j\log4j\1.2.16\log4j-1.2.16.jar
\cubrid\cubrid-jdbc\8.4.1.2032\cubrid-jdbc-8.4.1.2032.jar
\org\eclipse\persistence\eclipselink\2.0.0\eclipselink-2.0.0.jar
\org\springframework\data\spring-data-jpa\1.0.3.RELEASE\spring-data-jpa-1.0.3.RELEASE.jar
\org\springframework\data\spring-data-commons-core\1.1.0.RELEASE\spring-data-commons-core-1.1.0.RELEASE.jar
\org\hibernate\ejb3-persistence\1.0.2.GA\ejb3-persistence-1.0.2.GA.jar
\org\aspectj\aspectjrt\1.6.8\aspectjrt-1.6.8.jar
\org\aspectj\aspectjweaver\1.6.11\aspectjweaver-1.6.11.jar
\commons-dbcp\commons-dbcp\1.2.2-p1\commons-dbcp-1.2.2-p1.jar
\commons-pool\commons-pool\1.4\commons-pool-1.4.jar
\mysql\mysql-connector-java\5.1.10\mysql-connector-java-5.1.10.jar
Spring Data JPA requires JPA 2.0. You have pulled the 1.0 version of it into your classpath (the ejb3-persistence-1.0.2.GA.jar, by whatever means). Make sure you use a recent version of EclipseLink that supports JPA 2.0. Version 2.3.2 is the current release version.

Resources