每个Java应用容器都要包含tomcat_部署一个不依赖tomcat容器的应用
一個task項目,應用里邊都是一些定時任務。我和新入職的高開商定程序部署不依賴于tomcat。
計劃趕不上變化,任務開發(fā)完成還沒等上線呢,哥們要離職了。工作交接時大概說了一下上線怎么部署。
結果呢,當我在linux測試服務器上部署時,可費了一些周折。之前都是把應用部署到tomcat下面的。那位高開說過,不依賴tomcat容器的部署方式已經(jīng)不是新概念了。漫長的解決過程中,有同事建議我放棄,沿用tomcat吧。我覺得有必要堅持下來,最終也堅持下來了。
一.先介紹一下項目
工程如下圖。assembly/bin下有一個emax-paycenter-task.sh文件,主要是通過nohup命令來運行LauncherMain。高開說了,部署時將該shell文件放到應用的根目錄下,通過執(zhí)行它來啟動程序。
emax-paycenter-task.sh文件里是如下命令,start用的是nohup命令:
LauncherMain.java里是一個main方法,用來初始化環(huán)境:
importch.qos.logback.classic.LoggerContext;importch.qos.logback.classic.joran.JoranConfigurator;importorg.slf4j.ILoggerFactory;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.core.io.ClassPathResource;importorg.springframework.web.context.support.XmlWebApplicationContext;importjava.net.URL;importjava.util.concurrent.Semaphore;/*** Description 啟動方法
* Date 2018/2/8 上午10:01*/
public classLauncherMain {private static Logger logger= LoggerFactory.getLogger(LauncherMain.class);public static void main(String[] args) throwsException {
logger.info("init @Prop");
Semaphore sp= new Semaphore(0);
XmlWebApplicationContext xmlWeb= newXmlWebApplicationContext();
xmlWeb.setConfigLocation("classpath*:*spring/spring-applicationContext.xml");
String logbackCfg= "logback.xml";
URL logURL= newClassPathResource(logbackCfg).getURL();
ILoggerFactory loggerFactory=LoggerFactory.getILoggerFactory();
LoggerContext loggerContext=(LoggerContext) loggerFactory;
JoranConfigurator configurator= newJoranConfigurator();
configurator.setContext(loggerContext);
configurator.doConfigure(logURL);
xmlWeb.refresh();
xmlWeb.start();
sp.acquire();
}
}
項目中涉及到的定時任務采用Spring的@Scheduled來實現(xiàn):
@Componentpublic classAgentPayTask {
@AutowiredprivateLimitConfigDataHolder limitConfigDataHolder;
@AutowiredprivateAgentPayTaskService agentPayTaskService;private static Logger logger = LoggerFactory.getLogger(AgentPayTask.class);
@Scheduled(cron="0/5 * * * * ?")public voidprocess() {
System.out.println("AgentPayTask111");
logger.info("AgentPayTask");
Map LimiterMap =limitConfigDataHolder.getAgentPayLimiter();
agentPayTaskService.distributeTask(LimiterMap);
}
}
二.linux部署
我在本地直接運行LauncherMain#main方法,程序是沒問題的,里面的定時任務都可以正常跑。
將maven打包后的emax-paycenter-task-1.0.0-SNAPSHOT-assembly.tar.gz解壓部署到測試服務器上。最終執(zhí)行命令
./emax-paycenter-task.sh start &
查看生成的nohup.out文件,發(fā)現(xiàn)總是找不到class?com.emax.paycenter.LauncherMain。
后來咨詢運維,發(fā)現(xiàn)是沒有給目錄分配權限所致。
技能嫻熟的運維又幫忙把emax-paycenter-task.sh里的命令修正了一下。最終如下:
再次按照上面命令啟動程序,查看日志文件發(fā)現(xiàn)只有如下一條日志:
2018-03-21 15:11:45.381 [main] INFO [com.emax.paycenter.LauncherMain] - init @Prop
多次測試發(fā)現(xiàn),程序執(zhí)行到sp.acquire();這條語句時,就不動了;我在這條語句后加打印日志結果也沒打印出來;定時任務也沒執(zhí)行。
了解了一下Semaphore信號量,把permits改成0或1或其他數(shù)字,都不行。
。。。。。一個小時。。。。
。。。。。兩個小時。。。。
找同事幫助,無果。
。。。。。若干小時。。。。
靈感咋現(xiàn)!我將懷疑的焦點放到了spring context的設置這里,是不是壓根都沒有設置成功呢?
xmlWeb.setConfigLocation("classpath*:*spring/spring-applicationContext.xml");
莫非是各jar包里有同名的配置文件? 將路徑參數(shù)"classpath*:*spring/spring-applicationContext.xml"改成"classpath:spring/spring-applicationContext.xml"后,查看nohup.out發(fā)現(xiàn)出現(xiàn)了新的問題:
[root@localhost emax-paycenter-task]# tail -f nohup.out
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:531)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:295)
... 11 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade]
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:997)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:867)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:779)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:503)
... 13 more
同時,logback日志文件里也發(fā)現(xiàn)類似問題:spring context初始化時出現(xiàn)了異常。項目中一個類“AgentPayTaskQueryServiceImpl”通過@Autowired依賴注入了另一個type為“IPayCenterFacade”的bean,而在spring context里找不到這個類型為“IPayCenterFacade”的bean(NoSuchBeanDefinitionException),從而導致spring context創(chuàng)建bean “agentPayTaskQueryServiceImpl”失敗(BeanCreationException異常)。
[root@localhost emax-paycenter-task]# tail -n200 -f logback-task/task_info.log
2018-03-21 16:16:37.174 [main] INFO [com.emax.paycenter.LauncherMain] - init @Prop
2018-03-21 16:16:39.397 [main] WARN [org.springframework.web.context.support.XmlWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentPayTaskQueryServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emax.paycenter.api.service.IPayCenterFacade com.emax.paycenter.service.impl.AgentPayTaskQueryServiceImpl.payCenterFacade; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934) ~[spring-context-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) ~[spring-context-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at com.emax.paycenter.LauncherMain.main(LauncherMain.java:38) [emax-paycenter-task-1.0.0-SNAPSHOT.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emax.paycenter.api.service.IPayCenterFacade com.emax.paycenter.service.impl.AgentPayTaskQueryServiceImpl.payCenterFacade; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:531) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:295) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
... 11 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emax.paycenter.api.service.IPayCenterFacade] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:997) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:867) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:779) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:503) ~[spring-beans-3.2.13.RELEASE.jar:3.2.13.RELEASE]
... 13 common frames omitted
View Code
IPayCenterFacade定義在dubbo配置文件里。因此,將spring applicationContext里對dubbo配置文件的import由
改成
就可以了。
總結
以上是生活随笔為你收集整理的每个Java应用容器都要包含tomcat_部署一个不依赖tomcat容器的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java的部署目录在哪里_Java:To
- 下一篇: java文件复制速度_java中文件复制