使用 Flex 客户端时出现 Spring+Hibernate+Blazeds null 错误
我的问题很简单,当我从独立应用程序运行 EventService 中的方法时(通过在 main() 中使用 ClassPathXmlApplicationContext ),一切正常。
@Service
@Transactional(readOnly = true)
public class EventService {
Logger log = Logger.getLogger(EventService.class);
@Autowired private EventDao eventDao;
public List<Event> getAll() {
return eventDao.getAll();
}
public List<Event> getAllContainsResource(int resourceId) {
return eventDao.getAllWithResource(resourceId);
}
public String getName() {
return "simpleName";
}
}
当我在 tomcat(STS 上的内置服务器)上运行时,容器正确启动,但是当我将请求(通过 AMF 的 Flex 应用程序)发送到 getAll() 方法或 getAllContainsResource(int) *NullPointerException* 出现。它表明eventDao 为空。我不知道可能是什么原因,所以请帮忙。这是我的 applicationContext :
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!-- database connection -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/rapla" />
<property name="username" value="root" />
<property name="password" value="admin" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.use_sql_comments=true
</value>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<context:annotation-config />
<context:component-scan base-package="org.pwsz.dao.hibernate" />
<context:component-scan base-package="org.pwsz.services" />
<flex:message-broker />
</beans>
独立应用程序的 XML 是相同的,当然没有
<flex:message-broker />
EventDaoImpl :
@Repository
public class EventDaoImpl implements EventDao {
Logger log = Logger.getLogger(EventDaoImpl.class);
@Autowired private SessionFactory sessionFactory;
public Event getById(int id) {
return (Event) sessionFactory.getCurrentSession().get(Event.class, id);
}
public List<Event> getAll() {
return sessionFactory.getCurrentSession().createCriteria(Event.class).list();
}
public List<Event> getAllWithResource(Integer id) {
List<Event> resulu = sessionFactory.getCurrentSession()
.createCriteria(Event.class)
.createCriteria("appointments.teachers")
.add(Restrictions.eq("resourceId", id))
.list();
return resulu;
}
}
Spring-flex 连接工作正常,我可以使用 Flex 远程对象请求 getName 但发送其他两个请求会生成 null 异常。
我检查了
WebApp 中的问题(使用 spring mvc),一切正常。我发现这个问题会生成 Hibernate,当请求来自 Flex(使用 AMF 协议)时,它会为 DAO(它们是 @autowired)返回 null sessionFactory。
flex.messaging.MessageException: java.lang.NullPointerException : null
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:444)
at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1400)
at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:1005)
at flex.messaging.endpoints.AbstractEndpoint$$FastClassByCGLIB$$1a3ef066.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.flex.core.MessageInterceptionAdvice.invoke(MessageInterceptionAdvice.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$FixedChainStaticTargetInterceptor.intercept(Cglib2AopProxy.java:572)
at flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$247a330d.serviceMessage(<generated>)
at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:103)
at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)
at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:166)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)
at flex.messaging.endpoints.AMFEndpoint$$EnhancerByCGLIB$$247a330d.service(<generated>)
at org.springframework.flex.servlet.MessageBrokerHandlerAdapter.handle(MessageBrokerHandlerAdapter.java:109)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
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.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 com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:92)
at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:409)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.pwsz.services.EventService.getAll(EventService.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:418)
... 47 more
那么问题仍然没有解决,有人可以帮忙吗?提前感谢最终
我解决了我替换 blazeds services-config.xml 的问题:
<services-config>
<services>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<default-channels>
<channel ref="my-amf" />
</default-channels>
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true" />
</adapters>
<destination id="myService" channels="my-amf">
<properties>
<source>org.abc.services.EventService</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="my-amf"
class="mx.messaging.channels.AMFChannel">
<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint" />
</channel-definition>
</channels>
</services-config>
通过 org.abc.services.EventService 中的注释
@RemotingDestination(value="myService",channels={"my-amf"})
我也尝试了 appContext.xml 中的定义,它也有效:
<flex:remoting-destination destination-id="myService" ref="eventService"/>
但我仍然不明白为什么配置services-config 不起作用,主要问题是对于每个 AMF 请求,Spring 都会生成新的 eventService 对象(没有自动装配 dao),请注意,不需要 Dao 的功能可以正常工作。
我的 web.xml
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>rws</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rws</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
My problem is simple, when i run methods from my EventService from standalone app (by using ClassPathXmlApplicationContext in main() ) everything works fine.
@Service
@Transactional(readOnly = true)
public class EventService {
Logger log = Logger.getLogger(EventService.class);
@Autowired private EventDao eventDao;
public List<Event> getAll() {
return eventDao.getAll();
}
public List<Event> getAllContainsResource(int resourceId) {
return eventDao.getAllWithResource(resourceId);
}
public String getName() {
return "simpleName";
}
}
When i run on tomcat (built-in server on STS), container starts correctly but when i send request (Flex app thru AMF) to getAll() method or getAllContainsResource(int) *NullPointerException* comes up. It shows that eventDao is null. I don't know what can be the reason so please help. Here is my applicationContext :
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!-- database connection -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/rapla" />
<property name="username" value="root" />
<property name="password" value="admin" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.use_sql_comments=true
</value>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<context:annotation-config />
<context:component-scan base-package="org.pwsz.dao.hibernate" />
<context:component-scan base-package="org.pwsz.services" />
<flex:message-broker />
</beans>
XML for standalone application is same, ofcourse without
<flex:message-broker />
EventDaoImpl :
@Repository
public class EventDaoImpl implements EventDao {
Logger log = Logger.getLogger(EventDaoImpl.class);
@Autowired private SessionFactory sessionFactory;
public Event getById(int id) {
return (Event) sessionFactory.getCurrentSession().get(Event.class, id);
}
public List<Event> getAll() {
return sessionFactory.getCurrentSession().createCriteria(Event.class).list();
}
public List<Event> getAllWithResource(Integer id) {
List<Event> resulu = sessionFactory.getCurrentSession()
.createCriteria(Event.class)
.createCriteria("appointments.teachers")
.add(Restrictions.eq("resourceId", id))
.list();
return resulu;
}
}
Spring-flex connection works fine, i can request getName using Flex Remote Object but sending request for the other two generates null exception.
Regards
I checked problem in WebApp (using spring mvc) and everything works fine. I found that problem generates Hibernate which return null sessionFactory for DAOs (they are @autowired) when request comes from Flex (using AMF protocol).
flex.messaging.MessageException: java.lang.NullPointerException : null
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:444)
at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1400)
at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:1005)
at flex.messaging.endpoints.AbstractEndpoint$FastClassByCGLIB$1a3ef066.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.flex.core.MessageInterceptionAdvice.invoke(MessageInterceptionAdvice.java:66)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$FixedChainStaticTargetInterceptor.intercept(Cglib2AopProxy.java:572)
at flex.messaging.endpoints.AMFEndpoint$EnhancerByCGLIB$247a330d.serviceMessage(<generated>)
at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:103)
at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)
at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:166)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)
at flex.messaging.endpoints.AMFEndpoint$EnhancerByCGLIB$247a330d.service(<generated>)
at org.springframework.flex.servlet.MessageBrokerHandlerAdapter.handle(MessageBrokerHandlerAdapter.java:109)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
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.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 com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:92)
at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:409)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.pwsz.services.EventService.getAll(EventService.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:418)
... 47 more
So problem is still not solved, can anybody help ? thanks in advance
Finnaly i solved the problem i replaced blazeds services-config.xml :
<services-config>
<services>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<default-channels>
<channel ref="my-amf" />
</default-channels>
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true" />
</adapters>
<destination id="myService" channels="my-amf">
<properties>
<source>org.abc.services.EventService</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="my-amf"
class="mx.messaging.channels.AMFChannel">
<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint" />
</channel-definition>
</channels>
</services-config>
by annotation in org.abc.services.EventService
@RemotingDestination(value="myService",channels={"my-amf"})
i tried also definition in appContext.xml and it works too :
<flex:remoting-destination destination-id="myService" ref="eventService"/>
but i still don't get why configuration in services-config didn't work, the main problem was that for every AMF request Spring was generating new eventService object (without autowiring dao), notice that functions that don't needed Dao worked fine.
my web.xml
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>rws</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rws</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您不使用注释@RemotingDestination,或者如果您没有在appContext.xml(或Spring使用的另一个xml)中声明组件,Spring框架将无法管理您的bean(又名inhect属性等),这就是为什么DAO 对象为空。对于“经典”BlazeDS 配置文件中声明的所有组件都是如此。
If you do not use the annotation @RemotingDestination or if you don't declare the component in appContext.xml (or another xml used by Spring) the Spring framework will not be able to manage your bean (aka inhect properties etc), that's why the DAO object is null. That's true for all the components declared in the "classic" BlazeDS config files.