0 Replies Latest reply on Apr 22, 2003 10:39 AM by jonlee

    Working with embedded Jetty

    jonlee

      This is a quick guide to working with web applications in an integrated Jetty-JBoss 3.2.0 environment. It gives the basic information for operating Jetty and outlines the differences when Jetty is embedded in JBoss. For more Jetty configuration details, refer to Jetty documentation. We start with the standard JBoss-Jetty installation and modify only the bits relevant to this discussion.

      Shared libraries, servlets and JSP execution

      The core Jetty service resides in a subdirectory under the deploy directory for your server instance. Usually this subdirectory is called jbossweb.sar. Here you will find the Jetty jar libraries and the Jasper JSP compiler. You can place any shared libraries that only your web applications will use in this directory. The benefit of an integrated environment is that libraries your EJBs and web applications both use can be placed in the JBoss instance's lib directory. So place your custom libraries appropriately.

      The webdefault.xml file in this subdirectory controls invocation of servlets and compilation of java server pages (JSPs) by the Jetty application server. I'll cover some of the things to consider in the configuration.

      Jetty uses the Jasper JSP compiler and this is controlled by the following xml fragment:

      <servlet-name>jsp</servlet-name>
      <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
      <load-on-startup>0</load-on-startup>


      These defaults are not the best for a production setting. Generally, you would have more available JSP compiler servlets by default. Tomcat usually has a minimum of 3 at startup. Normally, in a Unix environment you would substitute in the Jikes Java compiler instead of using the JDK supplied Java compiler. The Sun 1.4.1 compiler had a memory leak that affected the JVM that invoked it, according to Jasper technical notes. This can be an issue if you have many JSPs installed in your Jetty container. Also, the Jikes compiler is much faster than the Sun 1.4.1 compiler so I would recommend this anyway. Finally, create a non-development JSP compiler in which the compiler does not check for changes in the JSP on every access - which is acceptable in a stable production environment. The result is shown below.


      <servlet-name>jsp</servlet-name>
      <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
      <init-param>
      <param-name>development</param-name>
      <param-value>false</param-value>
      </init-param>
      <init-param>
      <param-name>jspCompilerPlugin</param-name>
      <param-value>org.apache.jasper.compiler.JikesJavaCompiler</param-value>
      </init-param>
      <init-param>
      <param-name>compiler</param-name>
      <param-value>jikes</param-value>
      </init-param>
      <init-param>
      <param-name>javaEncoding</param-name>
      <param-value>iso-8859-1</param-value>
      </init-param>
      <load-on-startup>3</load-on-startup>


      Depending on your settings, you may need to check your classpath configuration for Jikes. For more information on Jasper 2 and its configuration, read the Jasper 2 JSP Engine HowTo at the Tomcat project.

      From a security standpoint, you may want to disable the invoker servlet as this may allow the return of the unprocessed source of a JSP, or a static resource which might otherwise be protected by a security constraint. The following fragment is that which you should disable by commenting out.

      <servlet-mapping>
      <servlet-name>invoker</servlet-name>
      <url-pattern>/servlet/*</url-pattern>
      </servlet-mapping>

      More information on this security issue is covered at http://www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg33723.html//www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg33723.html. I would imagine that Jetty replicates Tomcat's operation rather faithfully and is therefore subject to the same vulnerability.

      Handling web requests

      Having completed that, let us turn to the Jetty listeners that accept web requests. The configuration file, jboss-service.xml is contained below the embedded Jetty directory in META-INF. I'll cover the basics of setting up a stand-alone service - that is, one that doesn't use the AJP to connect to a front-end web server.

      The standard port listener at 8080 only needs the addition of a request redirector when your web application requires access to a resource to be secure - tagged in your web application's web.xml by <security-constraint>. That is a little beyond the scope of this humble document to explain but essentially a request for a particular JSP or servlet in the web application that is marked by a security constraint will redirect the request to a secure port - i.e. https usually. In Jetty, you add a confidential port to the 8080 listener to redirect the request to 8443 or any other port of your choosing. Essentially, Jetty will rewrite the URL for a request to a protected resource so that it points to the https port. The following fragment shows the configuration we describe.





      5
      100
      30000
      5000
      8443




      Now, you need to create the secure listener (https) to catch the redirected requests to protected resources. This secure listener will require a certificate for the https encryption. Follow the Jetty instructions for creating a Java keystore which contains the certificate. Following my Tomcat familiarity, I use passwords of 'changeit' for the keystore protection. I normally place the certificate in the conf directory for the JBoss server instance and call the certificate keystore tomcat-cert.key. The listener configuration reflecting this information is shown below.




      8443
      5
      100
      30000
      2000
      /conf/tomcat-cert.key
      changeit
      changeit




      The standard JBoss-Jetty configuration includes an AJP13 listener at port 8009. You might wish to disable this in a production environment. And that completes the configuration of Jetty for full web application operation.

      Deployment

      JBoss controls the deployment of the web applications. Place your web application WARS or EARS into the deploy directory of your JBoss server instance and your applications will be automagically deployed and made operational. You can also manually place unpacked web applications into the deploy directory as long as the web application directory structures match the requirements for a proper web application and the directory has an extension such as .war or .ear and so on. Please familiarise yourself with WAR and EAR requirements to understand this.

      Security

      One last word - there are certain security issues associated with a real-world production deployment. I detail these quickly and in little depth as this is not the main aim of this document.

      Usually, you would not start JBoss and Jetty in a Unix system as a privileged account as this might allow an attacker to exploit a JVM weakness as root. Running JBoss as a non-privileged account, this will mean that you cannot bind Jetty to the standard http ports (port 80 and port 443). Linux port mapping allows port rediection to overcome this, but you would need to address this issue in a manner compliant to the native operating system.

      The JBoss install exposes the JMX management console on the web server. The JMX console allows access to resource information on JBoss as well as control of resources running on JBoss including the ability to shut it down. Currently there are no security measures implemented in the application. You can disable the console by removing jmx-console.war from the deploy directory.

      JBoss also has control and access ports that will need protection from hostile attack. Port blocking on vulnerable interfaces need to be considered. Again this is beyond the scope of this document to cover but be aware that an integrated JBoss-Jetty installation can potentially expose JBoss to hostile environments through the same physical interface that serves web content.