The pain of configuring JSP in Jetty OSGi

As part of a recent project I want to run mitreid connect server embedded within the Elexis-Server Neon.3 based Jetty instance (that is version 9.3.9.v20160517).

Despite the excellent Jetty documentation on this version, I faced major trouble on getting to run this right.

My status / approach was this: First of, I want to run the plain war file provided within a WebAppContext of the Jetty container. This did not prove to be much of a problem, a simple Activator like this achieved this:

@Override
public void start(BundleContext context) throws Exception {
	WebAppContext webapp = new WebAppContext();
	Dictionary props = new Hashtable();
	props.put("war", "lib/openid-connect-server-webapp.war");
	props.put("contextPath", "/openid");
	props.put("managedServerName", "defaultJettyServer");
	context.registerService(ContextHandler.class.getName(), webapp, props);
}

But now the real trouble started – J S P !

The trouble can be broken down into three steps

  1. Configuring the JSP implementation
  2. Setting up the JSTL (Standard Tag Library)
  3. Configuring the WebAppContext to use all of this

Configuring JSP (Apache Jasper implementation)

This is pretty much straightforward, as documented in Using JSPs.
Just one thing is a little hidden – you additionally need apache aries.

Here goes a (hopefully) complete list

      id="javax.servlet.jsp.jstl"
      id="org.apache.aries.spifly.dynamic.bundle"
      id="org.apache.aries.util"
      id="org.eclipse.core.commands"
      id="org.eclipse.core.expressions"
      id="org.eclipse.core.filesystem"
      id="org.eclipse.core.resources"
      id="org.eclipse.jdt.core"
      id="org.eclipse.jetty.apache-jsp"
      id="org.eclipse.jetty.osgi.boot.jsp"
      id="org.eclipse.text"
      id="org.glassfish.web.javax.servlet.jsp.jstl"
      id="org.mortbay.jasper.apache-el"
      id="org.mortbay.jasper.apache-jsp"
      id="org.objectweb.asm"
      id="org.objectweb.asm.commons"
      id="org.objectweb.asm.tree"

Setting up the JSTL (Glassfish approach)

This is where I started to have problems. Documentation says to include org.glassfish.web:javax.servlet.jsp.jstl-1.2.2.jar which did not work out using Java 8. Eclipse complained with

I could track this down and reverted to org.glassfish.web:javax.servlet.jsp.jstl-1.5.0-b03.jar to solve this.

Configuring the WebAppContext to use all of this

At least the dependencies seemed to be satifisied by now – but did it start? No – but
a new Exception occured


2018-01-18 15:21:13,280 WARN  o.e.jetty.servlet.ServletHandler - 
org.apache.jasper.JasperException: Unable to compile class for JSP
	at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:600) ~[org.mortbay.jasper.apache-jsp_8.0.33.jar:2.3]
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:363) ~[org.mortbay.jasper.apache-jsp_8.0.33.jar:2.3]
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) ~[org.mortbay.jasper.apache-jsp_8.0.33.jar:2.3]
...
Caused by: java.lang.NullPointerException: null
	at org.apache.jasper.JspCompilationContext.getTldResourcePath(JspCompilationContext.java:551) ~[org.mortbay.jasper.apache-jsp_8.0.33.jar:2.3]
	at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:420) ~[org.mortbay.jasper.apache-jsp_8.0.33.jar:2.3]

This post left me with some
hints on what could be the problem. It breaks down to the JettyJasperInitializer#onStartup not being called and some configurations missing.

Some more searches brought me to the embedded-jetty-jsp sample project where this was initialized. (I had to use the non-jetty-annotations approach, as I also use org.eclipse.gemini.naming in the container, already providing a JNDI implementation).

I extracted the JspStarter from the mentioned project, and modified the Activator

webapp.addBean(new JspStarter(webapp.getServletContext().getContextHandler()));

and now it works – the journey continues! Hope this blog spares somebody else some trouble!