【发布时间】:2020-02-07 07:09:58
【问题描述】:
情况: 我有一个本地环境,我将 Web 应用程序部署到 vanilla tomcat 服务器。应用程序按预期运行。我部署到 Azure 并在部署期间获得 NPE。 Azure tomcat 服务器也应该是 vanilla 的。
问题 问题是为什么我会在一个环境中获得一个 NPE,阻止应用程序运行,而在不同的环境中获得相同的 NPE,而这两个环境假设是相同的?我会从哪里开始寻找?
或者换一种说法: “为什么 container.addServlet("dispatcher", new DispatcherServlet(ctx)) 在生产中返回 null '如果此 ServletContext 已经包含给定 servletName 的完整 ServletRegistration'?当它不在我的本地/开发环境中执行时。
Java 新手,azure 新手,以及陷入困境的时髦人士。 将 eclipse 与 azure 工具包插件一起使用。
Web 应用程序在本地 tomcat 服务器上运行得很好。与部署在 azure 上的 mysql db 对话就好了。
我尝试部署到 azure。它说它发布正确,但我收到 404 错误。无法弄清楚如何让日志记录在 azure 上正常工作,但能够让流正常工作。在复制流并花费大量时间格式化输出之后,这是部署时出现的唯一错误:
07-Feb-2020 05:57:32.426 SEVERE [main] org.apache.catalina.startup.HostConfig.deployDirectory Error deploying web application directory [D:\home\site\wwwroot\webapps\hds]java.lang.IllegalStateException: Error starting child
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:716)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1133)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1868)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1045)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1577)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:424)
at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:367)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:934)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1382)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1372)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:907)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:933)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:637)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/hds]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713)... 37 moreCaused by: java.lang.NullPointerException
at hds.configs.ApplicationInitializer.onStartup(ApplicationInitializer.java:21)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5120)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)... 38 more
有趣的部分似乎是:
at hds.configs.ApplicationInitializer.onStartup(ApplicationInitializer.java:21)
这是“违规”代码:
public class ApplicationInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebMvcConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
//servlet.setLoadOnStartup(1);
servlet.setLoadOnStartup(-1);
servlet.addMapping("/");
}
}
代码的第 21 行是: ''' servlet.setLoadOnStartup(-1); '''
如果您需要 WebMvcConfig.class:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "hds.controllers,hds.daos,hds.services,hds.configs")
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
@Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
}
我不知道为什么会产生这个错误。就像我之前所说的,我对 java 和 azure 非常陌生,并且完全公开这是大学顶点项目的一部分。创建一个网站而不是一个 cms 并将其绑定到数据库是额外的。
如果有人能告诉我如何让日志在 azure 上运行,那将会很有帮助。我继续并获得了一个存储帐户并打开了日志,但我不知道如何访问它们。
我尝试使用 azure 支持,虽然这位先生很好,但他显然超出了他的能力范围。
就像我说的那样在本地运行就好了,配置几乎是样板(我认为基于我的研究)。
【问题讨论】:
-
如果真的是空指针问题,问题不会出现在本地部署中吗?请打开我的问题备份。
-
所以您的应用在本地 Tomcat 上运行良好,但在 Azure Tomcat 上出现 NPE 失败?
-
确保您在本地使用 exact 与 azure 上相同的 Java 和 Tomcat 版本。也不要设置
ServletContext,因为DispatcherServlet会处理这个问题。最后添加一个日志配置以启用跟踪/调试日志记录以查看发生了什么。 -
@Deinum 不太确定如何在不这样设置的情况下创建 servlet。我发现的每个示例都使用该方法。我打开了Insights,添加了log4j,maven依赖将两者连接起来。我都没有经验,但会阅读并尝试将一些东西放在一起。
-
我们成功了。我最终阅读了这个部署示例:howtodoinjava.com/spring5/webmvc/spring5-mvc-hibernate5-example 并使用了他们的 AppInitializer 类,它似乎已经发布并且可以运行。现在我只需要研究为什么这个类有效而另一个没有。
标签: spring azure maven azure-web-app-service