我正在将一个小型 Java servlet 部署到 tomcat 8。它绘制图像并将其保存到硬盘驱动器。它使用 java.awt.Rectangle、java.awt.Image 和 java.awt.Graphics2D 类。相关代码如下。
int WIDTH = 200;
int HEIGHT = 250;
Rectangle drawArea = new Rectangle(WIDTH, HEIGHT);
Image image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
//...
//use the dimensions of the drawArea to draw something on the gw
//...
在Eclipse开发过程中它运行得很好。
但是,当我使用 maven 打包它并将其部署到具有作为服务运行的标准 tomcat 8 的外部服务器时,它提示无法找到 java.awt.Rectangle 类。
服务器运行 OpenJDK (1.7.0_71) 和 tomcat 8(使用 -Djava.awt.headless=true
运行)。列出tomcat进程(ps -fp
)的结果如下:
jsvc.exec -Dcatalina.home=/usr/share/tomcat8 -Dcatalina.base=/usr/share/tomcat8 -Djava.io.tmpdir=/var/tmp/tomcat8/temp -Djava.awt.headless=true -cp /usr/share/java/commons-daemon.jar:/usr/share/java/eclipse-ecj.jar:/usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar -user tomcat8 -java-home /usr/lib/jvm/default-runtime -pidfile /var/run/tomcat8.pid -errfile SYSLOG -outfile SYSLOG org.apache.catalina.startup.Bootstrap
包含 java.awt.Rectangle 的 rt.jar 可在标准 OpenJDK lib 目录下的文件系统中找到 (/usr/lib/jvm/default-runtime/lib/rt.jar
)。 HIt 没有在 tomcat 参数中被 -cp 显式引用,恕我直言,它应该已经在类路径中了。如果我明确添加它,它不会改变任何内容:
jsvc.exec -Dcatalina.home=/usr/share/tomcat8 -Dcatalina.base=/usr/share/tomcat8 -Djava.io.tmpdir=/var/tmp/tomcat8/temp -Dderby.system.home=/var/lib/derby -Djava.awt.headless=true -cp /usr/share/java/commons-daemon.jar:/usr/share/java/eclipse-ecj.jar:/usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar:/usr/lib/jvm/default-runtime/lib/rt.jar -user tomcat8 -java-home /usr/lib/jvm/default-runtime -pidfile /var/run/tomcat8.pid -errfile SYSLOG -outfile SYSLOG org.apache.catalina.startup.Bootstrap
服务器是在本地开发机器上运行最新的 Arch Linux 的 VM,以便我轻松测试 servlet 的部署。
所以问题是:如何获得在 tomcat 中生成图像的 java.awt 功能?
由于我在这个问题上花了好几个小时,而且似乎没有进展,所以我决定向更有经验的人提出这个问题。非常感谢任何帮助。
编辑(2015年1月22日,根据@Moonwalker的回答添加信息)
基本上,我所做的测试是编辑 /etc/systemd/system/multi-user.target.wants/tomcat8.service
然后调用
systemctl daemon-reload
# and
systemctl restart tomcat8
我通过改变以下内容进行了 4 种编辑组合:
DISPLAY=localhost:0.0
or
DISPLAY=:0.0
和
-Djava.awt.headless=true
or
-Djava.awt.headless=false
所有组合都会导致:
threw an unexpected exception: java.lang.NoClassDefFoundError: Could not initialize class java.awt.Rectangle
rt.jar 确实有 java.awt.Rectangle 类。
编辑(2015.01.23,按照@prunge的建议添加了完整的堆栈跟踪)
Jan 22, 2015 9:49:07 AM org.apache.catalina.core.ApplicationContext log
SEVERE: Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract void com.mytest.imagegeom.GeometryService.doGeom(java.lang.String) throws java.lang.IllegalArgumentException' threw an unexpected exception: java.lang.NoClassDefFoundError: Could not initialize class java.awt.Rectangle
at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:415)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:605)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:333)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:303)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373)
at com.gooJan 22 09:49:07 test-host-deploygle.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(Abst
Jan 22 09:49:07 test-host-deploy jsvc.exec[8963]: ractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportV
Jan 22 09:49:07 test-host-deploy jsvc.exec[8963]: alve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.jav
Jan 22 09:49:07 test-host-deploy jsvc.exec[8963]: a:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class java.awt.Rectangle
at com.mytest.com.mytest.imagegeom.GeometryServiceImpl.createPNG(GeometryServiceImpl.java:488)
at com.mytest.com.mytest.imagegeom.GeometryServiceImpl.convertStringToTree(GeometryServiceImpl.java:479)
at com.mytest.com.mytest.imagegeom.GeometryServiceImpl.doGeom(GeometryServiceImpl.java:265)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:587)
... 28 more
最佳答案
我认为您应该尝试的第一件事是将 headless 选项设置为 false。
-Djava.awt.headless=false
您应该做的第二件事是将 DISPLAY 环境变量指向有效位置。没有它,awt 将无法工作,甚至无法生成背景图像。
DISPLAY=localhost:0.0 or DISPLAY=:0.0
您可能必须执行 xhost + 命令但不一定。希望您的 Linux 安装已正确安装和配置虚拟显示器。
第三件事是检查您正在使用的 JRE(以及相应的 CLASSPATH)中是否有 awt 类。
是的...没有必要将 JRE 系统 jar 文件显式添加到类路径中...默认情况下应该选择它们。但您应该查看这些 jar 文件并验证是否包含 awt 包。
希望这有帮助。
关于java - tomcat 8 中 java.awt.Rectangle 的 NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28089107/