<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="jboss">
  <title>JBoss AS Crash Course</title>

  <para>The JBoss Application Server (AS7) is the foundation upon which
  TorqueBox is built. You can go a long way with TorqueBox without knowing
  anything about the administration of JBoss AS, but for advanced
  applications, it's worth knowing something about how AS is configured and
  extended. Feel free to skip this section if you're just getting started with
  TorqueBox, and use it as a reference later.</para>

  <para>For more detailed documentation, please read the <ulink
  url="https://docs.jboss.org/author/display/AS7/Documentation">official
  AS7 docs</ulink>.</para>

  <section id="configuring-jboss">
    <title>Configuring</title>

    <para>JBoss AS7 has extensive changes since the previous releases,
    the most visible being folder structure and runtime modes:
    <emphasis role="bold">domain</emphasis> and <emphasis
    role="bold">standalone.</emphasis></para>

    <para>In AS7, all server configuration is kept in two folders for
    each runtime mode: <filename>standalone</filename> and
    <filename>domain</filename>. Administrative tasks are simplified
    from previous releases because all configuration is in one folder
    and, in standalone mode, in a single file.</para>

    <para><mediaobject>
        <imageobject>
          <imagedata align="center" fileref="images/jboss-server.png"
                     format="PNG" />
        </imageobject>
      </mediaobject></para>

    <para>TorqueBox uses standalone mode by default but can be run in
    domain mode as well.</para>

    <para>JBoss AS 7 uses a modular architecture - libraries
    common to all server configurations are kept under the
    <filename>modules/</filename> directory. Configuration files are
    stored inside <filename>standalone/configuration/</filename> and
    <filename>domain/configuration/</filename> folders.</para>

    <para>Both standalone and domain modes have a common folder
    structure, including the following directories:
    <filename>configuration/</filename>, <filename>deployments/</filename>
    and <filename>lib/</filename>. In general, it isn't a good idea to
    remove anything from these directories that you didn't put there
    yourself.</para>

    <para><mediaobject>
        <imageobject>
          <imagedata align="center" fileref="images/jboss-standalone-mode.png"
                     format="PNG" />
        </imageobject>
      </mediaobject></para>

    <para>Some additional directories are created automatically at runtime,
    as needed: <filename>tmp/</filename>, <filename>data/</filename>, and
    <filename>log/</filename>. Though not typically necessary, you may safely
    delete these when the server is not running to clear its persistent
    state.</para>
  </section>

  <section id="running-jboss">
    <title>Running</title>

    <para>The <filename>$JBOSS_HOME/bin/</filename> directory contains the
    main JBoss entry point, <filename>standalone.sh</filename> (or
    <filename>standalone.bat</filename>), along with its config file,
    <filename>standalone.conf</filename>. Running the JBoss server is simple:

    <screen> <prompt>$</prompt> <command>$JBOSS_HOME/bin/standalone.sh</command> </screen>

    Use the <option>--server-config</option> option to specify a
    different configuration. For example, to put JBoss in "clustered"
    mode:

    <screen> <prompt>$</prompt> <command>$JBOSS_HOME/bin/standalone.sh --server-config=standalone-ha.xml</command></screen>

    You may set Java system properties using the <option>-D</option>
    option. Pass <option>-h</option> for a list of all the available
    options.</para>

    <para>Permanent runtime configuration of JBoss should go in
    <filename>bin/standalone.conf</filename>. For example, your application
    may require more memory (RAM) than the default allocated. Edit
    <filename>standalone.conf</filename> to increase the value of
    <option>-Xmx</option> to something reasonable.</para>

    <para>Though <xref linkend="capistrano-support" /> doesn't strictly
    require it, in production you may prefer to control JBoss via a Unix "init
    script", examples of which may be found in <filename>bin/</filename>. Feel
    free to tweak one for your particular OS.</para>

    <para>We also provide support for managing TorqueBox via 
    <ulink url="http://upstart.ubuntu.com/">upstart</ulink>. See <xref linkend="rake-server-control"/> 
    for more details.</para>
  </section>

  <section id="deploying-to-jboss">
    <title>Deploying</title>

    <para>Each runtime mode has a <literal>deployments/</literal>
    subdirectory, the contents of which determine the applications and
    services JBoss runs. These apps and services are represented as archives 
    or text files called "deployment descriptors". 
    TorqueBox provides Rake tasks and a <command>torquebox</command> 
    to aid the deployment process. For more
    details, see <xref linkend="deployment" /> and <xref
    linkend="deployment-descriptors" />.</para>
  </section>

  <section id="jboss-logging">
    <title>Logging</title>

    <para>Here we'll focus on the default JBoss configuration and how
    to expose the JBoss logging system to your Ruby applications, if
    so desired.</para>

    <para>JBoss provides a very sophisticated logging system that
    nobody completely understands. It's possible to configure
    hierarchical, categorized log message routing, complex file
    rotation, syslog integration, SMTP notifications, SNMP traps, JMS,
    JMX and much more. Obviously, most of that is far beyond the scope
    of this document.</para>

    <para>All JBoss log messages, just like Ruby ones, have an
    associated <emphasis>level</emphasis>, e.g. DEBUG, INFO,
    WARN, ERROR, or FATAL. These levels are ordered by increasing
    severity, e.g. FATAL is higher than ERROR, which is higher than
    WARN, etc. Unlike messages from a Ruby Logger, each JBoss log
    message also has a <emphasis>category</emphasis>. Logging
    configuration rules determine where messages are logged according
    to their category and level. These rules are contained in the
    <emphasis>logging</emphasis> subsystem element of
    <filename>standalone/configuration/standalone.xml</filename>. By
    default, you will see INFO (and higher, i.e. more severe) messages
    on the console (the shell where you start TorqueBox) and written
    persistently to
    <filename>standalone/log/server.log</filename>.</para>

    <para>Anything written to <constant>stdout</constant> or
    <constant>stderr</constant> is interpreted as an INFO log message
    and will therefore also be displayed on the console and written to
    <filename>standalone/log/server.log</filename>.</para>

    <section id="torquebox-logger">
      <title>TorqueBox::Logger</title>

      <para>Of course, standard Ruby Loggers work fine inside of
      TorqueBox, and you'll find your Rails log files exactly where
      you expect them to be (unless your app is archived, in which
      case they'll reside beneath
      <filename>standalone/log/</filename>). But some users,
      especially those already familiar with Java logging, may prefer
      for some Ruby log messages to be passed to JBoss. This is easily
      achieved using the <classname>TorqueBox::Logger</classname>. For
      example, you may configure your Rails app like so:

      <screen><code>config.logger = TorqueBox::Logger.new</code></screen>

      This results in all Rails-generated log messages being passed to
      JBoss, hence written to
      <filename>standalone/log/server.log</filename> in the default
      configuration. The category for these messages will be the
      application's name. You can override this by passing the
      category name in the constructor:

      <screen><code>TorqueBox::Logger.new( "Billing" )</code></screen>

      You may pass any type of object to the constructor as long as it
      responds to <code>:to_s</code>. A common convention is to use a
      class name as a category in Java applications. You can do the
      same with Ruby:

      <screen><code>@logger = TorqueBox::Logger.new( self.class )</code></screen>

      If the class is defined in a module, its name will be something
      like <classname>YourModule::YourClass</classname>. The logger
      will replace the double-colons (::) with a period (.), yielding
      <classname>YourModule.YourClass</classname> as the category.
      This is because categories are hierarchical and delimited by a
      period, enabling you to define rules for all classes in the same
      module, for example.</para>

      <para>It's important to understand that, although the
      <classname>TorqueBox::Logger</classname> does honor the Ruby
      Logger interface, setting its <code>:level</code> attribute will
      have no effect. The only configuration it honors is JBoss', e.g.
      the logging subsystem element in
      <filename>standalone/configuration/standalone.xml</filename></para>

    </section>
    <section id="torquebox-logging-config">
      <title>JBoss Logging Configuration</title>

      <para>
        The default AS 7.1 configuration is shown below. It includes
        two handlers (one for the CONSOLE and one for the FILE), some
        loggers and a root logger. When a message is logged, here's
        what happens:
      </para>

      <orderedlist>
        <listitem>
          <para>
            The message's category is compared to any defined
            <code>&lt;logger&gt;</code> elements. If a match is found,
            the message's level must be greater than or equal to that
            of the <code>&lt;logger&gt;</code>, else it's discarded.
          </para>
        </listitem>
        <listitem>
          <para>
            If no matching <code>&lt;logger&gt;</code> is found, the
            message's level must be greater than or equal to the level
            of the <code>&lt;root-logger&gt;</code>, else it's
            discarded.
          </para>
        </listitem>
        <listitem>
          <para>
            If it hasn't been discarded, the message is passed to all
            handlers associated with its <code>&lt;logger&gt;</code>,
            including those in the <code>&lt;root-logger&gt;</code>.
            Set <code>use-parent-handlers="false"</code> in the
            <code>&lt;logger&gt;</code> to override this behavior.
          </para>
        </listitem>
        <listitem>
          <para>
            If the handler has no <code>&lt;level&gt;</code> threshold
            defined, as is the case for the FILE handler below, the
            message is logged.
          </para>
        </listitem>
        <listitem>
          <para>
            If the handler has a <code>&lt;level&gt;</code> threshold
            defined, as is the case for the CONSOLE handler below, the
            message's level must be greater than or equal to that
            threshold to be logged.
          </para>
        </listitem>
      </orderedlist>

      <example>
        <title>Logging Config from <filename>standalone/configuration/standalone.xml</filename></title>

        <programlisting>
          &lt;subsystem xmlns='urn:jboss:domain:logging:1.1'&gt;
              &lt;console-handler name='CONSOLE'&gt;
                  &lt;level name='INFO'/&gt;
                  &lt;formatter&gt;
                      &lt;pattern-formatter pattern='%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n'/&gt;
                  &lt;/formatter&gt;
              &lt;/console-handler&gt;
              &lt;periodic-rotating-file-handler name='FILE'&gt;
                  &lt;formatter&gt;
                      &lt;pattern-formatter pattern='%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n'/&gt;
                  &lt;/formatter&gt;
                  &lt;file relative-to='jboss.server.log.dir' path='server.log'/&gt;
                  &lt;suffix value='.yyyy-MM-dd'/&gt;
                  &lt;append value='true'/&gt;
              &lt;/periodic-rotating-file-handler&gt;
              &lt;logger category='com.arjuna'&gt;
                  &lt;level name='WARN'/&gt;
              &lt;/logger&gt;
              &lt;logger category='org.apache.tomcat.util.modeler'&gt;
                  &lt;level name='WARN'/&gt;
              &lt;/logger&gt;
              &lt;logger category='sun.rmi'&gt;
                  &lt;level name='WARN'/&gt;
              &lt;/logger&gt;
              &lt;logger category='jacorb'&gt;
                  &lt;level name='WARN'/&gt;
              &lt;/logger&gt;
              &lt;logger category='jacorb.config'&gt;
                  &lt;level name='ERROR'/&gt;
              &lt;/logger&gt;
              &lt;root-logger&gt;
                  &lt;level name='INFO'/&gt;
                  &lt;handlers&gt;
                      &lt;handler name='CONSOLE'/&gt;
                      &lt;handler name='FILE'/&gt;
                  &lt;/handlers&gt;
              &lt;/root-logger&gt;
              &lt;logger category='org.jboss.jca.adapters.jdbc.extensions.mysql'&gt;
                  &lt;level name='ERROR'/&gt;
              &lt;/logger&gt;
          &lt;/subsystem&gt;
        </programlisting>

      </example>
      
      <para>
        One thing to note about the default logging configuration is
        that DEBUG messages won't show up anywhere. So, for example,
        the following log message will be discarded:
      </para>

      <programlisting>
        @logger = TorqueBox::Logger.new( YourModule::YourClass )
        @logger.debug("Will code for food")
      </programlisting>
      
      <para>
        This is because the "YourModule.YourClass" category matches no
        logger and its level (DEBUG) is lower than the default level
        for the root logger (INFO). One solution is to lower the
        default level for the root logger to DEBUG, but that results
        in DEBUG messages for every other category that doesn't match
        any of the loggers, potentially a lot of messages. A better
        solution is to define a <code>&lt;logger&gt;</code>
        specifically for the category:
      </para>

      <programlisting>
        &lt;logger category='YourModule.YourClass'&gt;
          &lt;level name='DEBUG'/&gt;
        &lt;/logger&gt;
      </programlisting>

      <para>
        This will result in log messages written to the FILE handler,
        but not the CONSOLE, since its threshold level is still set at
        INFO.
      </para>

      <para>
        For many applications, it's usually better to take advantage
        of the hierarchical nature of categories and refer only to the
        module name so that any logger associated with any class
        within that module will match:
      </para>

      <programlisting>
        &lt;logger category='YourModule'&gt;
          &lt;level name='DEBUG'/&gt;
        &lt;/logger&gt;
      </programlisting>

      <para>
        For more information, see the <ulink
        url="https://docs.jboss.org/author/display/AS71/Logging+Configuration">official
        JBoss logging documentation</ulink>.
      </para>

    </section>
  </section>
</chapter>
