tomcat 8中java.awt.Rectangle的NoClassDefFoundError

时间:2015-01-22 12:43:15

标签: java tomcat archlinux tomcat8

我正在将一个小型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)下的文件系统中。在tomcat参数中,-tp没有显式引用HIt,恕我直言,它应该已经在类路径中。如果我明确地添加它,它什么都不会改变:

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的部署。

所以问题是:如何获取java.awt功能以在tomcat中生成图像?

由于我花了几个小时在这上面并且似乎没有向前发展,所以我决定将其从更有经验的人的头上反弹。非常感谢任何帮助。


编辑(2015.01.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

2 个答案:

答案 0 :(得分:2)

我认为您应该首先尝试将无头选项设置为false。

-Djava.awt.headless=false

您应该做的第二件事是将DISPLAY环境变量指向有效位置。没有它,awt将无法工作,甚至背景图像生成。

DISPLAY=localhost:0.0 or DISPLAY=:0.0

您可能必须执行xhost +命令,但不一定。希望您的Linux安装已正确安装和配置虚拟显示器。

检查你正在使用的JRE(以及因此CLASSPATH)是否具有awt类的第三件事。

是的......没有必要将JRE系统jar文件显式添加到类路径中......默认情况下应该选择它们。但是你应该查看那些jar文件并验证是否包含了awt包。

希望这有帮助。

答案 1 :(得分:0)

有趣的是,在用OpenJDK8替换OpenJDK7并从/etc/systemd/system/multi-user.target.wants/tomcat8.service中删除所有更改后问题得到了解决。似乎tomcat 8和OpenJDK7之间存在某种不兼容性。现在异常现在神奇地消失了。我可以通过返回OpenJDK7来重现它,但是我无法找到,究竟是什么导致了这一点。我正在将问题标记为已解决,但仍然可以获得有关此特殊行为的任何输入。

亲切的问候。