Opened 2 years ago

Closed 2 years ago

#2477 closed defect (fixed)

Enable .jsp support in eepsite jetty server

Reported by: Reportage Owned by:
Priority: minor Milestone: 0.9.41
Component: apps/jetty Version: 0.9.39
Keywords: jetty, tomcat, jasper, jsp Cc:
Parent Tickets: Sensitive: no


Jetty should support on-the-fly compilation of jsp files, as suggested by the comments in eepsite/etc/webdefault.xml (note that as of jetty 9.2, apache's jasper is used, not glassfish's).

The JSP page compiler and execution servlet, which is the mechanism used by Glassfish to support JSP pages. [...]

As discussed on irc, currently jsps within /docroot fail to compile, and jsps within pre-compiled .war files will also fail to run, generating an error.

For current tomcat, ecj-4.6.3.jar is additionally required.

With ecj added to i2p/lib, the following error is caused when attempting to run a jsp from within a war file:

org.apache.jasper.JasperException: java.lang.IllegalStateException: No org.apache.tomcat.InstanceManager set in ServletContext
	at org.apache.jasper.servlet.JspServletWrapper.getServlet(
	at org.apache.jasper.servlet.JspServletWrapper.service(
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(
	at org.apache.jasper.servlet.JspServlet.service(
	at javax.servlet.http.HttpServlet.service(
	at org.eclipse.jetty.servlet.ServletHolder.handle(
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(
	at org.eclipse.jetty.servlet.ServletHandler.doScope(
	at org.eclipse.jetty.server.session.SessionHandler.doScope(
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(
	at org.eclipse.jetty.server.Server.handle(
	at org.eclipse.jetty.server.HttpChannel.handle(
	at org.eclipse.jetty.server.HttpConnection.onFillable(
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(
	at org.eclipse.jetty.util.thread.QueuedThreadPool$
Caused by: java.lang.IllegalStateException: No org.apache.tomcat.InstanceManager set in ServletContext
	at org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(
	at org.apache.jasper.servlet.JspServletWrapper.getServlet(


Change History (5)

comment:1 Changed 2 years ago by zzz

See bottom of WebAppConfiguration? where we set it for the console, but moved from RouterConsoleRunner? where it had been since Jetty 7, years ago. Has to be set on the servlet context but after server is started. Not clear how to do this via config files for the eepsite. Presumably the use case is stock wars so changing web.xml is not an option.

As for the java compiler, we haven't bundled one for 10 years and don't plan to. Reported to be 2.3 MB. The best we could do is put some instructions somewhere on how to install ecj.

comment:2 Changed 2 years ago by zzz

comment:3 Changed 2 years ago by Reportage

Regarding ecj, if there's no plan to distribute it by default, perhaps the integration work can be included, so that jsp compilation support is conditionally added to jetty if ecj is detected in i2p/lib?

It might also be worth considering supplying the ecj.jar with the tomcat jars in the source, and adding a build target to build a jsp-capable installer/update. That way, default installations/updates aren't encumbered with the additional size of ecj, but for users that require jsp compilation support, deployment is trivial.

comment:4 Changed 2 years ago by zzz

Milestone: undecided0.9.41

Here's the design intent for the last 10 years, probably isn't well documented:

1) webapps (wars) NOT containing uncompiled jsp/java files should work out of the box by dropping them into the webapps/ dir. This should be the usual case for typical webapps.
2) webapps that DO contain uncompiled jsp/java/files should work as in 1), if the user first puts the ecj or other compiler jar, or a symlink, in $I2P/lib/

It appears that 1) has been broken for years due to the InstanceManager? thing. 2) is probably not documented anywhere.

I don't think anything "conditional" is required to fix 1). If 1) is fixed and ecj is present, hopefully it will just work.

2) could also be fixed by default in debian packages by adding the symlink.

So let's fix 1) and document 2) better. That should be sufficient.

comment:5 Changed 2 years ago by zzz

Resolution: fixed
Status: newclosed

Verified 1) above. A webapp such as imagegen.war can be copied into webapps/ dir, and works fine. But others may have the InstanceManager? problem, I didn't test them all.

Reproduced OP.
We aren't going to ship a java compiler.
Compiler in classpath fix (non-debian-package installs) is:

sudo apt install libecj-java
cd $I2P/lib
ln -s /usr/share/java/

Added symlinks for debian/ubuntu packages as in 2) above

Fix for OP requires both new code to workaround the issue and a change to jetty.xml (new installs only)

The fix for existing jetty.xml files is:

--- eepsite/jetty.xml
+++ eepsite/jetty.xml
@@ -235,16 +235,34 @@
     <Ref id="DeploymentManager">
       <Call id="webappprovider" name="addAppProvider">
-          <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+          <New id="WebAppProvider" class="org.eclipse.jetty.deploy.providers.WebAppProvider">
             <Set name="monitoredDirName">./eepsite/webapps</Set>
 	    <Set name="parentLoaderPriority">false</Set>
-	    <Set name="extractWars">false</Set>
+            <!-- this is required because Jetty can't handle jars inside wars,
+                 for example in php-java-bridge's JavaBridgeTemplate.war
+                 See
+                 See our ticket 2477
+              -->
+            <Set name="extractWars">true</Set>
             <Set name="defaultsDescriptor">./eepsite/etc/webdefault.xml</Set>
+    <!-- Fixup for webapps to work, see our ticket 2477
+         Note that for webapps with uncompiled jsps, you will also
+         need a java compiler in the classpath;
+         The easiest way (Debian/Ubuntu) is to put a symlink in $I2P/lib:
+         sudo apt install libecj-java
+         cd $I2P/lib
+         ln -s /usr/share/java/ecj.jar
+         stop and then start i2p (restart alone will not pick up the new jar in the classpath)
+      -->
+    <Call class="net.i2p.servlet.WebAppProviderConfiguration" name="configure">
+      <Arg><Ref refid="WebAppProvider"/></Arg>
+    </Call>
     <!-- ===================== -->
     <!-- DefaultHandler config -->
     <!-- -->

but it must be applied by hand to ~/.i2p/eepsite/jetty.xml because the paths won't match so the context diff will fail.

In 6dd227a83f9c12d8f1969e01eb4c0892ad375b76 to be 0.9.40-3

Note: See TracTickets for help on using tickets.