Saturday, September 13, 2008

Tapestry 5 with Run Jetty Run

I'm currently going through the Tapestry 5 tutorial and am quite impressed. However, the tutorial is a bit out of date and recommends using the Jetty Launcher Eclipse plug-in to launch Jetty and to only use Jetty 5 as Jetty Launcher does not support Jetty 6.

I could not get Jetty Launcher to work at all under Eclipse 3.4 (Ganymede) on Ubuntu Linux. The Jetty Launcher page notes that it is no longer being maintained and recommends trying Run Jetty Run.

After installing Run Jetty Run, everything seemed to be copacetic with class changes being loaded live without a server restart. That is, everything was OK until beaneditform component was added. At that point, the app bombed with:

Error obtaining injected value for field org.apache.tapestry5.corelib.components.Form.logger: java.lang.ClassNotFoundException: org.slf4j.Logger

Some googling led me to: Tapestry5HowToSetupEclipseRunJettyRun.

I could not really follow the directions about adding -Dorg.mortbay.jetty.webapp.parentLoaderPriority=true to the VM arguments for the launch configuration.

Finally I was able to get this to work by adding -Dorg.mortbay.jetty.webapp.parentLoaderPriority=true to the default JRE's VM arguments.

Go to Window -> Preferences -> Installed JREs. Select the default JRE and click the Edit button. Paste -Dorg.mortbay.jetty.webapp.parentLoaderPriority=true into the Default VM Arguments field and click the Finish button.

Thursday, May 08, 2008

Code Syntax Highlighting



Here is a plug-in that formats code (Java, xml, etc) within html in a very nice way.
http://code.google.com/p/syntaxhighlighter/

This looks great. I'll be adding this functionality ASAP to handle code snippets.

Wednesday, May 07, 2008

Injecting a Spring Bean into a Servlet

I've done some searching on the web for how to cleanly inject a spring-managed bean into a servlet. There are a number of ways, but I believe this is the cleanest.

Assuming you have a bean, limaBean, that you want to inject into a servlet, here is the applicationContext.xml:

<bean id="limaBean" class="com.example.LimaBeanImpl">

<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="limaBeanInServletContext">
<ref bean="limaBean">
</ref>
</entry></map>
</property>
</bean>

The ServletContextAttributeExporter takes an existing managed bean, 'limaBean', and injects it into the ServletContext under the name 'limaBeanInServletContext'.

The servlet accesses this bean like:

public class DocumentViewerServlet extends HttpServlet
{

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
LimaBean limaBean = getLimaBean();
limaBean.doSomething();

...
}

private DocumentService getLimaBean()
{
ServletContext servletContext = this.getServletContext();

return (LimaBean) servletContext
.getAttribute("limaBeanInServletContext");
}
}

At runtime, Spring will inject the bean and everything works.

The reason you wanted to inject the bean in the first place, though, was so that you could easily write a test that injects the bean.

Set the attribute on org.springframework.mock.web.MockServletConfig and pass that into the servlets init(ServletConfig) method.

public class VegetableServletTest extends TestCase
{
private VegetableServlet servlet = null;
private LimaBean fakeLimaBean = null;

protected void setUp() throws Exception
{
super.setUp();

servlet = new VegetableServlet();
fakeLimaBean = new FakeLimaBean();

MockServletConfig config = new MockServletConfig();
config.getServletContext().setAttribute("limaBeanInServletContext",
fakeLimaBean);

servlet.init(config);
}

}