# JettyPlus://

## What it is and how to run it

The purpose of this project is to enrich Jetty by selectively incorporating useful J2EE and non-J2EE features. The result is JettyPlus, an environment offering additional facilities to core web and servlet services, but which does not entail a full-blown application server (such as JettyJBoss and JettyJOnAS).

The feature set currently contains:

- Java Transaction API (JTA) and Resource references, eg DataSources Updated
- Java Naming and Directory Interface API (JNDI)
- Log4J
- Java Authentication and Authorization Service (JAAS)
- Java Mail New

To use JettyPlus, you must:

- Configure the `org.mortbay.jetty.plus.Server` class in your xml configuration file rather than the standard `org.mortbay.jetty.Server` class, eg:
  `

        <Configure class="org.mortbay.jetty.plus.Server">

  `
- Reference this class on the runline:
  `

         java -Djetty.server=org.mortbay.jetty.plus.Server -Dlog4j.configuration=log4j.xml -jar start.jar config.xml

  ` If you prefer, instead of specifying the class on the runline, you can edit the `start.config` file inside `start.jar` and change the line: `

                   # The main class to run
                   org.mortbay.jetty.Server.class

                   to

                   org.mortbay.jetty.plus.Server.class

  `

JettyPlus consists of `org.mortbay.jetty.plus.jar`, ancillary file `org.mortbay.jetty.plus.resource.jar`, and optionally `org.mortbay.jaas.jar` as well as a number of libraries found in `extra/ext`. If you use the convenient start.jar method of running Jetty (highly recommended), all necessary jar files will automatically be placed on the JVM classpath for you. Otherwise, you will need to place the following on the Java classpath in addition to the usual Jetty jars:

- org.mortbay.jetty.plus.jar
- org.mortbay.jetty.plus.resource.jar
- org.mortbay.jetty.jaas.jar (if you want to use JAAS)
- activation.jar
- mail.jar
- carol.jar
- commons-cli.jar
- commons-logging.jar
- hsqldb.jar (only for running the demo webapps)
- jonas_timer.jar
- jotm.jar
- jotm_iiop_stubs.jar
- jotm_jrmp_stubs.jar
- jta-spec1_0_1.jar
- jts1_0.jar
- log4j.jar
- objectweb-datasource.jar
- ow_util_log_file.jar
- ow_util_log_wrp_log4j.jar
- p6spy.jar
- xapool.jar

The `extra/plus/README.TXT` file in the source distribution contains more information on the JettyPlus package, including instructions on how to run the JettyPlus demonstration webapps.

## Features

### Transactions and DataSources

Thanks to the integration of the JOTM and XAPool packages from ObjectWeb, it is now possible to easily incorporate distributed transactional semantics in your servlets and JSPs using `javax.transaction.UserTransaction` objects.

For example: code to obtain, start and commit a UserTransaction is as follows: ``

        try
        {
          UserTransaction usertransaction =
                          (UserTransaction)context.lookup("java:comp/UserTransaction");
          //do some stuff
          usertransaction.begin();
          //access some resources and make changes
          usertransaction.commit();
        }
        catch (Exception e)
        {
          usertransaction.rollback();
        }

JettyPlus also provides support for `javax.sql.DataSource` and `javax.sql.XADataSource` objects referenced in web.xml `<resource-ref>` and `<resource-env-ref>` elements. To use DataSources in your webapp, you need to:

- Step 1: reference the DataSource in your `web.xml` descriptor. Eg. `

        <resource-env-ref>
          <description>
            DB Connection
          </description>
          <resource-env-ref-name>
            jdbc/myDB
          </resource-env-ref-name>
          <resource-env-ref-type>
            javax.sql.DataSource
          </resource-env-ref-type>
        </resource-env-ref>

  `
- Step 2: set up the DataSource in your JettyPlus xml configuration file. Note that this is configured along with the transaction service Eg: `

        <Call name="addService">
          <Arg>
            <New class="org.mortbay.jetty.plus.JotmService">
              <Set name="Name">TransactionMgr</Set>
               <!-- set up a pooled DataSource -->
               <Call name="addPooledDataSource">
                   <Arg>jdbc/myDB</Arg>
                   <!-- set up the datasource -->
                   <Arg>

                     <!-- Uncomment one of the following types of XADataSource        -->
                     <!-- according to your type of database:                         -->
                     <!-- New class="org.enhydra.jdbc.sybase.SybaseXADataSource"      -->
                     <!-- New class="org.enhydra.jdbc.informix.InformixXADataSource"  -->
                     <!-- New class="org.enhydra.jdbc.oracle.OracleXADataSource"      -->

                     <New class="org.enhydra.jdbc.standard.StandardXADataSource">
                       <Set name="DriverName">org.hsqldb.jdbcDriver</Set>
                       <Set name="Url">jdbc:hsqldb:extra/etc/tmtest</Set>
                       <Set name="User">sa</Set>
                       <Set name="Password"></Set>

                       <!-- Uncomment to setup isolation level as required            -->

                       <!--
                       <Set name="TransactionIsolation"><Get class="java.sql.Connection" name="TRANSACTION_SERIALIZABLE"/></Set>
                       -->
                     </New>
                   </Arg>
                   <!-- set up a pool for the datasource -->
                   <Arg>
                     <New class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
                       <Arg type="Integer">4</Arg>          <!-- initial size of pool -->
                       <Set name="MinSize">4</Set>
                       <Set name="MaxSize">15</Set>
                       <!-- Uncomment to setup other pool params as required          -->
                       <!--
                       <Set name="SleepTime">10</Set>
                       <Set name="LifeTime">10</Set>
                       <Set name="DeadLockMaxWait">10</Set>
                       <Set name="DeadLockRetryWait">10</Set>
                       <Set name="LoginTimeout">10</Set>
                       <Set name="Debug" type="boolean">true</Set>
                       -->
                     </New>
                   </Arg>
              </Call>

              Note: if your JDBC driver does connection pooling for you, then instead of
              configuring both a StandardXADataSource and a StandardXAPoolDataSource,
              you can just configure the StandardXADataSource instead:

              <!-- set up a DataSource where the driver does the pooling                 -->
              <Call name="addDataSource">
                   <Arg>jdbc/otherDB</Arg>    <!-- client lookup jndi name of datasource  -->
                   <Arg>
                     <New class="org.enhydra.jdbc.standard.StandardXADataSource">
                       <Set name="DriverName">com.mysql.jdbc.Driver</Set>
                       <Set name="Url">jdbc:mysql://localhost:3306/oln </Set>
                       <Set name="User"></Set>
                       <Set name="Password"></Set>
                     </New>
                   </Arg>
              </Call>

           </New>
         </Arg>
        </Call>

  `
- Step 3: access it in your code. Eg: `

        DataSource datasource =
        (DataSource)context.lookup("java:comp/env/jdbc/myDB");
        Connection connection = datasource.getConnection();

  `

### Mail Service

A mail service is provided with JettyPlus. This means that you can send email programmatically from servlets, JSPs etc.

To use the mail service, you need to:

- Step 1: reference the Mail Service in your `web.xml` descriptor as a resource. Eg. `

        <resource-env-ref>
          <description>
            Mail Service
          </description>
          <resource-env-ref-name>
            mail/Session <!-- must be same as JNDI name in xml config file (see step 2) -->
          </resource-env-ref-name>
          <resource-env-ref-type>
            javax.mail.Session
          </resource-env-ref-type>
        </resource-env-ref>

  `
- Step 2: set up the Mail Service in your JettyPlus xml configuration file. Eg: `

        <Call name="addService">
          <Arg>
            <New class="org.mortbay.jetty.plus.MailService">
              <Set name="Name">MailService</Set>
              <Set name="JNDI">mail/Session</Set>
              <!-- set up the id of the smtp user                 -->
              <Set name="User">XXX</Set>
              <!-- set up the password of the smtp user           -->
              <Set name="Password">XXX</Set>
               <!-- set up the hostname/ip addr of the smtp server -->
              <Put name="mail.smtp.host">XXX</Put>
               <!-- setup any javax.mail.smtp provider variables   -->
              <Put name="mail.pop3.user">zzz</Put>
              <Put name="mail.pop3.host">vvv</Put>
              <Put name="mail.from">me@me</Put>
              <Put name="mail.debug">false</Put>
            </New>
          </Arg>
        </Call>

  `
- Step 3: access it in your code. Eg: `

        javax.mail.Session session =
        (javax.mail.Session)context.lookup("java:comp/env/mail/Session");
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("me@me.com"));
        msg.addRecipient(new InternetAddress("you@you.com"));
        msg.setContent("Hi");
        Transport.send(msg);

  `

### JNDI

JettyPlus supports JNDI, including ENC lookups of <env-entry> tags in the web.xml descriptor. All you need to do to effect JNDI env lookups in your code is to:

- Step 1: enter some env entries in your webapp web.xml file, eg: `

        <env-entry>
          <env-entry-name>
             someEnv
          </env-entry-name>
          <env-entry-value>
             A long time ago in a galaxy far far away
          </env-entry-value>
          <env-entry-type>
             java.lang.String
          </env-entry-type>
        </env-entry>

  `
- Step 2: obtain a javax.naming.InitialContext object and call the lookup method, eg: `

       InitialContext context = new InitialContext();
       String starwars = (String)context.lookup("java:comp/env/someEnv");

  `

New: JettyPlus JNDI service is now lenient on leading and trailing `"/"` elements of JNDI names. This avoids a lot of errors caused by mis-typings. For example, the following are all now equivalent:

> `

>     java:comp/env/mything (strictly the correct form according to the spec)
>     java:/comp/env/mything
>     java:/comp/env/mything/

> `

### Log4J

The JettyPlus package provides a Jetty `org.mortbay.util.LogSink` to enable Jetty log messages to appear in Log4J style logs. The `org.mortbay.jetty.plus.resource.jar` file contains a `log4j.xml` configuration file which may be modified as needed.

To use Log4J:

- Step 1: configure the LogSink in your Jetty xml configuration file, eg: `

        <Call name="instance" class="org.mortbay.util.Log">
          <Call name="disableLog"/>
          <Call name="add">
            <Arg>
              <New class="org.mortbay.util.log4j.Log4jSink">
                <Call name="start"/>
              </New>
            </Arg>
          </Call>
        </Call>

  `
- Step 2: enable it on the command line: `

        java -Dlog4j.configuration=log4j.xml -jar start.jar config.xml

  `

### JAAS

JAAS provides a pluggable framework for authenticating and authorising users. JettyPlus JAAS integrates this with the declarative security model of the Java Servlet Specification.

The Jetty JAAS classes are <emph>not</emph> included in the main JettyPlus jar (`org.mortbay.jetty.plus.jar`). Instead, it is built as `org.mortbay.jaas.jar` to enable it to be used either with standard Jetty, or with JettyPlus.

As JAAS is a pluggable framework, the Jetty JAAS integration aims to dictate as little as possible whilst providing a sufficiently flexible infrastructure to allow users to drop in their own custom LoginModules. An example LoginModule (`org.mortbay.jaas.spi.JDBCLoginModule`), interacting with a database to store user names, passwords and roles, is included with the release to illustrate what to implement.

Some important classes are:

#### org.mortbay.jaas.JAASUserRealm

This bridges Jetty's realm concept to JAAS. This class must be configured as the realm for your webapp.

#### org.mortbay.jaas.JAASPrincipal

Implements the java.security.Principal interface. This class is used by the sample JDBCLoginModule, but the Jetty JAAS infrastructure is Principal agnostic, meaning you can use your own implementation of this class for your LoginModules if you wish.

#### org.mortbay.jaas.JAASRole

This is a Principal that represents a role possessed by a user.

#### org.mortbay.jaas.JAASGroup

An implementation of the java.security.acl.Group interface. It is used only by the sample JDBCLoginModule to group all roles possessed by a user under a single Principal called "roles".

#### org.mortbay.jaas.spi.JDBCLoginModule

An implementation of a LoginModule that uses a database to store user names, passwords and roles. All database-related information is configurable, including:

- the names and columns of the user table and role table
- the database connection driver, URL, username and password.

To use JAAS:

- Step 1: Configure the realm for your webapp context in the Jetty xml configuration file: `

          <Call name="addWebApplication">
          <Arg>/jaas/*</Arg>
          <Arg><SystemProperty name="jetty.home"/>/extra/plus/demo/webapps/jaas</Arg>

          <Set name="Realm">
              <New class="org.mortbay.jaas.JAASUserRealm">
                <Set name="Name">Test JAAS Realm</Set>
                <Set name="LoginModuleName">jdbc</Set>
                <Set name="RoleCheckPolicy">
                  <New class="org.mortbay.jaas.StrictRoleCheckPolicy"/>
                </Set>
                <Set name="CallbackHandler">
                  <New class="org.mortbay.jaas.callback.DefaultCallbackHandler"/>
                </Set>
              </New>
          </Set>
        </Call>

  ` Note that it is only actually necessary to specify the `RoleCheckPolicy` or `CallbackHandler` if you have provided custom implementations of them.
- Step 2: Configure some security constraints and a login method in your `web.xml` file, eg: `

        <security-constraint>
          <web-resource-collection>
            <web-resource-name>JAAS Role</web-resource-name>
            <url-pattern>/doit/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
            <role-name>roleA</role-name>
          </auth-constraint>
        </security-constraint>

        <login-config>
          <auth-method>BASIC</auth-method>
          <realm-name>Jetty Demo Realm</realm-name>
        </login-config>

  `
- Step 3: Create a login module configuration file. This one is from the Jetty JAAS demo (in `extra/etc/login.conf`): `

            // sample login config file for the Jetty JDBCLoginModule
            // if you change the database and need to specify a password, set the property dbPassword
            jdbc {
            org.mortbay.jaas.spi.JDBCLoginModule required
            debug="true"
            dbUrl="jdbc:hsqldb:."
            dbUserName="sa"
            dbDriver="org.hsqldb.jdbcDriver"
            userTable="myusers"
            userField="myuser"
            credentialField="mypassword"
            userRoleTable="myuserroles"
            userRoleUserField="myuser"
            userRoleRoleField="myrole";
            };

  ` Note that the name of the module ("jdbc") must be the same as that specified as the `LoginModuleName` in the Jetty xml config file in Step 1.
- Step 4: Specify the location of the login configuration file on the Jetty run line by setting the `java.security.auth.login.config` property: `

          -Djava.security.auth.login.config=mylogin.conf

  `

The above describes how to use the Jetty JAAS integration to authenticate web users and authorize them against webapp security constraints. It can also be used for authorization with a Java security manager and permission policy file. For information on how to accomplish this, build and run the JAAS demo in `extra/plus` as instructed in the README.TXT file in the source distribution.