1 问题
今天启动 Tomcat 后,登录页验证码不见了。在 localhost.xxx.log 发现以下错误:
org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [StickyCaptcha] in context with path [/web2] threw exception [Servlet execution threw an exception] with root cause java.awt.AWTError: Can't connect to X11 window server using 'localhost:11.0' as the value of the DISPLAY variable. at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:65) at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:115) at java.security.AccessController.doPrivileged(Native Method) at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:74) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at java.awt.GraphicsEnvironment.createGE(GraphicsEnvironment.java:103) at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82) at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1181) at nl.captcha.text.renderer.DefaultWordRenderer.render(DefaultWordRenderer.java:65) at nl.captcha.Captcha$Builder.addText(Captcha.java:145) at com.ncc.core.CustomCaptchaServlet.doGet(Unknown Source) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at com.ncc.services.water.util.XssFilter.doFilter(Unknown Source) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492) at com.radiadesign.catalina.session.RedisSessionHandlerValve.invoke(RedisSessionHandlerValve.java:26) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1152) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1539) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1495) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)复制代码
2 分析
因为验证码是通过 AWT 实现的, 而 AWT 会调用操作系统本地窗口资源来绘图, windows 可以很好地支持;但在 linux 下,如果没有进到 X window , 就无法使用 AWT 绘图。
3 解决
在 tomcat bin 内的 startup.sh,第一行添加:
export CATALINA_OPTS="-Djava.awt.headless=true"复制代码
在操作系统可能缺少显示设备、键盘或鼠标这些外设的情况下可以开启该模式。
好啦,验证码是不是已经出来啦O(∩_∩)O~