大家好我又来问问题了。。。
事情是这样的。
现在的项目使用了Hessian。
在Commander 项目中调用 Spider 项目中的一个service
这个Service中使用了线程池。
然而问题来了。当在Spider项目中自己调用自己的Service的时候,一切正常。
但是通过Hessian调用Spider的Service的时候,线程池却是空指针的。
代码如下:
这是Spider(被调用)项目中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 业务类 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<bean id="impl" class="com.whr.Service.Impl.WorkServiceImpl" />
<!-- 远程服务 -->
<bean name="/workService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="impl" />
<property name="serviceInterface">
<value>
com.whr.Service.WorkService
</value>
</property>
</bean>
</beans>
这是Spider(被调用)项目中的Service 实现:
package com.whr.Service.Impl;
import java.sql.Date;
import java.util.List;
import javax.annotation.Resource;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.whr.Dao.WorkDao;
import com.whr.Entity.Work;
import com.whr.Service.WorkService;
import com.whr.Spiders.Spider_ZhiLian;
@Service("workService")
public class WorkServiceImpl implements WorkService {
@Autowired
private WorkDao workDao;
@Resource(name = "taskExecutor_Spider")
private TaskExecutor taskExecutor;// 线程池
@Autowired
private Spider_ZhiLian spider_ZhiLian;
public List<Work> getAllWork() {
return workDao.getAllWork();
}
public void saveWork()
{
System.out.println("Commander 调用 Spider");
TaskExecutor teExecutor = this.taskExecutor;
teExecutor.execute(new Spider_ZhiLian(workDao));
}
public void updateWork(Work work)
{
workDao.updateWork(work);
}
public void deleteWork(Work work)
{
workDao.deleteWork(work);
}
}
结果:
Commander 调用 Spider
2016-04-13 10:15:49 [org.springframework.remoting.support.RemoteInvocationTraceInterceptor]-[WARN] Processing of HessianServiceExporter remote call resulted in fatal exception: com.whr.Service.WorkService.saveWork
java.lang.NullPointerException
at com.whr.Service.Impl.WorkServiceImpl.saveWork(WorkServiceImpl.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
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:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:78)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at $Proxy38.saveWork(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:306)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:221)
at org.springframework.remoting.caucho.HessianExporter.doInvoke(HessianExporter.java:223)
at org.springframework.remoting.caucho.HessianExporter.invoke(HessianExporter.java:138)
at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:66)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Commander调用的过程(部分):
public class UserController {
@Autowired
private UserService userService;
@Autowired
private WorkService workService;
@Autowired
private HessianService testHessianService;
private static Logger logger = Logger.getLogger(UserController.class);
@RequestMapping("/test")
public ModelAndView getStudent(HttpServletRequest request,HttpServletResponse response,ModelMap modelMap) throws MalformedURLException
{
/*HessianModel model = testHessianService.getHessianModel("uid", "pwd");
logger.info("username: " + model.getUsername());*/
testHessianService.saveWork();
List<User> list = userService.getAllUser();
modelMap.put("students", list);
logger.info("Log4测试");
return new ModelAndView("test", modelMap);
}
调用方的Spring配置:
<bean id="testHessianService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/Spider/hessian/workService"/>
<property name="serviceInterface" value="com.whr.Hessian.HessianService"/>
</bean>
调用方的Hessian接口:
package com.whr.Hessian;
public interface HessianService {
public String sayHello(String username);
public void saveWork();
public HessianModel getHessianModel(String username, String password);
}
以上。
问题简述就是一个在本项目中可以调用的Service经过Hessian调用后线程池缺空指针了。但是明确可以调用到的。
求大神解答。谢谢!
刚才尝试了一下不使用线程池,通过Hessian调用服务然后在服务中直接操作Dao层,也是不好使的,一样的空指针。
但是在服务端自己调用服务端的Service却好使。
貌似Hessian调用的时候所有的注入都失效了。。。
首先,非常感謝 @Kavlez 給予的幫助,提示了我查找是不是註解配置的問題。
這個問題查了查資料分析了一下,雖然解決了但是原理不甚清楚。還望高手指點。以下是修改後的Hessian-servlet.xml
還有一個細節就是在Service上要如下書寫:
寫成這樣就不行:
但是在其他的地方又兩種都可以。這也是一個不是很理解的地方。
至於修改的點,在於加入了 設定。
因為之後又試驗了各種註解方式註入的bean均不可用,就表示是註解注入方式出現了問題。
查了一些資料看到有人加入了這個配置,試驗了一下可以。
然後根據提示加入了其他的配置,最終的結果就是如上了。
以上。
再次感謝給予幫助的夥伴。
我無法確定我的方法是否奏效,但題主不妨一試:
WorkServiceImpl中的
@Service("workService")
改为@Service
服務端的設定改為:
@Service預設是產生bean的id為預設類別名稱首字母小寫,也就是workServiceImpl,但你ref的是workService所以必須寫@Service("workService")來指定產生bean的id