<document>
<header>
<product>resin</product>
<title>Symptoms</title>
<description>

<p>A list of symptoms and their possible resolution.</p>

</description>
</header>

<body>
<summary localtoc="1"/>

<section title="Resin stops responding">
<ul>

<li>There may be a thread deadlock problem, <a
href="troubleshoot|technique#thread-dump">obtain a thread dump</a>.

<li>Enable <a href="troubleshoot|technique#debug-log">full debug logging</a> and check
the last log entries for hints about what the last thing to happen was.

</ul>
</section>

<section title="Resin keeps restarting">
<ul>

<li>Enable <a href="troubleshoot|technique#debug-log">full debug logging</a> and check
the entries for an explanation of why Resin thinks it should restart.

</ul>
</section>

<section title="No line numbers in exception stack traces">

<ul>

<li>In <var/resin.conf/> specify <code>-g</code> as an option for Resin to pass to the java compiler:

<example title="-g compiler option">
&lt;java compiler='javac' compiler-args='-g'/&gt;
</example>

<li>Specify <code>-nojit</code> as a command-line option when starting Resin:

<example title="-nojit command-line options">
win&gt; bin/httpd.exe -nojit
unix&gt; bin/httpd.sh -nojit
</example>

</ul>
</section>

<section name="memory-leaks" title="java.lang.OutOfMemoryError exception, application runs out of memory">

<ul>

<li>Use JVM startup arguments to 
<a href="performance|jvm-tuning#memory">increase heap memory.</a>

<li>Obtain a <a href="troubleshoot|technique#heap-dump">heap dump</a> to
determine which objects are not getting garbage collected.

<li>Obtain a <a href="troubleshoot|technique#thread-dump">thread dump</a> and
check for unreleased threads that might be holding onto objects.

</ul>

<p>An OutOfMemoryError exception is usually an indication that heap memory is
being used up.  Often this is from application code keeping references to
objects that are no longer needed, and the garbage collector does not free
them.  A heap dump can help determine which code and which kinds of objects are
being held.</p>

<p>
If the heap dump or other monitoring tools reveal that the server and your
appliciation(s) actually are not running out of heap memory then an
OutOfMemoryError indicates that then the JVM is running out of virtual
memory, i.e. an underlying malloc() call is failing.
</p>

<p>
Often this situation is indicated by using OS tools to show memory usage, the
JVM itself indicates it has heap memory but the OS tool shows that the process
is using a very large amount of memory.  On Windows the task manager is used, on Unix <code>top</code> or <code>ps</code>.
</p>

<p>
The only non-heap allocations by the JVM (and therefore Resin and your
application) are the following:
</p>

<ul>

<li>threads and particularly the thread stack takes up virtual memory

<li>any JNI libraries might be calling malloc or mmap (or the windows
equivalent of mmap) and taking virtual memory.  This includes many database
drivers, and also some JNI code that Resin uses.

<li>for .jar/.zip files (specifically ZipFile), the JDK allocates virtual
memory.  If you have a large number of jars open, you can run into problems.
It's conceivable that a getResourceAsStream for a jar file that wasn't closed
would use up .jar memory.

</ul>

</section>

<section name="server-gets-slow" title="After a while the server starts to go very slow">
<ul>

<li>This may be a garbage collection issue.  If you have a memory leak, then an
excessive number of objects may get created, causing the garbage collector to
use up all of your CPU.  If you're running out of memory, then the JVM will
slowly halt (and continually GC) until it dies.


  <ul>

  <li>Monitor <a href="troubleshoot|technique#garbage-collection">garbage
      collection</a>.

  <li>Obtain a <a href="troubleshoot|technique#heap-dump">heap dump</a> to
      determine if objects are not getting garbage collected.
  
  <li>See <a href="performance|jvm-tuning#garbage-collection">Garbage
      Collection</a> in the JVM Tuning section for more about garbage
      collecting.

  </ul>

<li>This may be a runaway thread or a request that is tying up resources.  If a
thread does not return from a request, Resin will not be able to reuse the
thread and will have less threads to service new requests.

  <ul>
  <li>Obtain a <a href="troubleshoot|technique#thread-dump">thread dump</a> and
      check for unreleased threads that might be holding onto objects.
  </ul>
</ul>
</section> <!-- server-gets-slow -->

<section name="cpu-spike" title="CPU spikes, excessive CPU usage">
<ul>

<li>Obtain a <a href="troubleshoot|technique#thread-dump">thread dump</a> and
check for threads that are caught in tight loops.

<li>Check for <a href="#server-gets-slow">garbage collection</a> issues.

</ul>

</section> <!-- cpu-spike -->

<section title="Sessions become null, losing session">

<section title="URL rewriting">

<p>If you forget to rewrite a URL, a user who requires rewriting will lose their
session as soon as they follow that URL.</p>

<p>Resin establishes an association between a session and a user's browser by
establishing a unique id that is returned back with each new request.  This is
accomplished in one of two ways: using cookies or URL rewriting.</p>

<p>Resin first attempts to track the session of a user by sending the user's
browser a cookie containing the unique session id. </p>

<p>Sometimes Resin cannot establish a cookie, either because the user has
disabled cookies in their browser or because the browser does not support them
(as is the case with some HDML and WML browsers). If the cookie cannot be
established then something called URL rewriting is used.</p>

<p>In this case, Resin rewrites every URL that it submits to the user so that
it contains a parameter named <var>_jsessionid</var>. Then for each incoming
request the first thing it does is look for this parameter, and if it is
available it knows a session has been established and it removes the parameter
and uses it to find the users session object.</p>

<p>Rewriting requires the cooperation of the developer.  The developer must
encode every URL reference so that Resin has an opportunity to put in the
<var>_jsessionid</var> parameter.</p>


<example title="URL rewriting using JSTL">
&lt;%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %&gt;

Time to go &lt;a href="&lt;c:url value='home.jsp'/&gt;"&gt;Home&lt;/a&gt;!
</example>

<example title="URL rewriting using Java scriptlet">
&lt;%
String homeUrl = response.encodeURL("home.jsp");
%&gt;

&lt;%-- the presentation --%&gt;

Time to go &lt;a href="&lt;%= homeUrl %&gt;"&gt;Home&lt;/a&gt;!
</example>

</section>

<section title="Resin configuration for sessions">

<p>Another possiblity is that the <a config-tag='session-max'/> setting is too
low, and you are getting more users establishing sessions than you have
configured Resin for.</p>

<p>Yet another possibility is that the session is timing out, you can use the
<a config-tag="session-timeout"/> tag to configure this.</p>

<example>
&lt;web-app id='/'&gt;
  ...
  &lt;session-config&gt;
    &lt;!-- timeout after 120 minutes --&gt;
    &lt;session-timeout&gt;120&lt;/session-timeout&gt;
    &lt;!-- up to 4096 sessions at once --&gt;
    &lt;session-max&gt;4096&lt;/session-max&gt;
  &lt;/session-config&gt;
  ...
&lt;/web-app&gt;
</example>
</section>


<section title="Application reloading">

<p>Whenever a java source file, web.xml, or resin.conf changes then Resin will
restart the application.  If this happens, your current sessions will be lost
unless you have configured a persistent session store.</p>

</section>

<section title="Browser cookie limitations">

<p>Some users have reported that if their applciation uses a lot of cookies,
the browser will start to discard older cookies to make room for the new.  This
may result in the browser discarding the cookie that Resin is using to keep
track of the session.</p>

<p>If your application uses a lot of cookies, you may need to configure Resin
to always use URL rewritting by setting <a config-tag='enable-cookies'/> to
false.</p>

<example>
&lt;web-app id='/'&gt;
  ...
  &lt;session-config&gt;
    &lt;enable-cookies&gt;false&lt;/enable-cookies&gt;
    &lt;enable-url-rewriting&gt;true&lt;/enable-url-rewriting&gt;
  &lt;/session-config&gt;
  ...
&lt;/web-app&gt;
</example>

</section>

<section title='Problems with cookie domains'>

<p>You may also lose your sessions if your cookie domains are incompatible.
For example, if you have one server that uses cookie domain "hogwarts.com" and
another that uses "qa.hogwarts.com", the cookie in the browser for
"hogwarts.com" will interfere with sessions on "qa.hogwarts.com".  The solution
is to change the cookie domain "hogwarts.com" to "www.hogwarts.com".</p>

<p>You set the cookie domain in <a config-tag="session-config"/>.
(Thanks Laura for providing this)</p>

</section>

<section title='Conflicting cookie names'>

<p>If you are using Resin and another application server (such as Tomcat), you
may encounter a conflict because both of them are using the same cookie name
(usually JSESSIONID) for the session tracking cookie.</p>

<p>Resin provides <a config-tag='session-cookie'/> to let you change the name
of the cookie that Resin uses.</p>

<example title="Change the name of the cookie used for session tracking">
  &lt;server&gt;

    ...

    &lt;session-cookie&gt;RJESSESSIONID&lt;/session-cookie&gt;
</example>
</section>

</section> <!-- losing sessions -->

<section title="Specification version 1.3 of package javax.servlet, J2EE Specification, version 1.3 is not compatible with Resin">
<p>See <a href="doc|troubleshoot|technique#classpath">Clean up the classpath</a></p>
</section>

<section title="Unsupported major.minor version 48.0">

<p>
This error usually happens when a conflicting jar is found, see 
<a href="doc|troubleshoot|technique#classpath">Clean up the classpath</a>
</p>

<p>
If the classpath is completely cleaned up, as suggested in the
link, then a jar or some other component of a jdk installation
or older Resin installation is coming from somewhere else.
</p>

<p>
There may be a problem with some jar in your JAVA_HOME tree, if
you have added anything there.
There may be a conflicting jar in WEB-INF/lib/ of your webapp.
</p>

<p>
Another possibility is that you have not set JAVA_HOME, or if you
have then some component of a conflicting jdk installation (javac
for example, or the java executable itself) is getting used.
</p>

<p>
If on windows, check for stray copies of java.exe outside of
JAVA_HOME, for example in C:/WINDOWS/java.exe or anywhere else in
your PATH.
</p>

</section>
</body>

</document>


