I don’t talk about my day job much. For those outside of the Java Geeky circles, it’s pretty dull stuff. But today has been particularly active, so I thought I’d share some of the bits I learned while teaching myself the wonders of Struts. This can best be summed up by the following revelations…
1) When changing a struts.xml file, within an Eclipse WTP environment, being serviced by Tomcat, WTP does not click that the Tomcat server needs to be restarted. The ‘Dynamic’ part of WTP does not take effect, and no matter how many times you save what you’re working on, it won’t go live in the server until you actually restart Tomcat.
2) Despite all the awesome advances in Eclipse in the last few years, there’s twitches that still drive me absolutely gonzo. One is that the ‘smart insert mode’ (which helpfully closes XML tags and closes quotes and parentheses for you) cannot be turned off globally. You can do it on a per-editor basis, but not globally, so I’m always forgetting to turn it off when I open a new editor. Another is XML syntax validator is still quite twitchy, and occasionally will flag incomplete tags or non-well-formed XML when the file is just fine. A close and re-open fixes it, but ugh.
3) Last, but not least – that which almost got me up on the roof with a high powered rifle. I give you a quiz as my example. One of these two struts.xml configurations apparently tickles a bug in Struts2 and will cause an internal server error and stacktrace with a Null Pointer Exception. The other will not. Can you figure out which is which?
<action name="/*"> <interceptor-ref name="mystack" /> <result name="success">/WEB-INF/jsp/{1}.jsp</result> <result name="login">/WEB-INF/jsp/index.jsp</result> </action>
<action name="*"> <interceptor-ref name="mystack" /> <result name="success">/WEB-INF/jsp/{1}.jsp</result> <result name="login">/WEB-INF/jsp/index.jsp</result> </action>
Just for fun, here’s the actual stack trace:
1.
INFO: Server startup in 954 ms
2.
Jun 17, 2008 7:41:14 PM org.apache.catalina.core.StandardWrapperValve invoke
3.
SEVERE: Servlet.service() for servlet default threw exception
4.
java.lang.NullPointerException
5.
at com.opensymphony.xwork2.config.impl.ActionConfigMatcher.convertActionConfig(ActionConfigMatcher.java:168)
6.
at com.opensymphony.xwork2.config.impl.ActionConfigMatcher.match(ActionConfigMatcher.java:144)
7.
at com.opensymphony.xwork2.config.impl.DefaultConfiguration$RuntimeConfigurationImpl.getActionConfig(DefaultConfiguration.java:316)
8.
at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:169)
9.
at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:41)
10.
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:494)
11.
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
12.
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
13.
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
14.
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
15.
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
16.
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
17.
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
18.
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
19.
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
20.
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
21.
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
22.
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
23.
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
24.
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
25.
at java.lang.Thread.run(Thread.java:619)
How the hell am I supposed to debug that?
I finally did, after a good 2 hours of hair-ripping, gnashing of teeth, and spewing my venom upon the #struts IRC support channel.