head	1.6;
access;
symbols
	JSERV_00_09_09:1.6
	JSERV_0_9_8:1.1.1.1
	JSERV:1.1.1;
locks; strict;
comment	@# @;


1.6
date	98.01.20.08.28.47;	author ian;	state Exp;
branches;
next	1.5;

1.5
date	98.01.19.01.25.02;	author ian;	state Exp;
branches;
next	1.4;

1.4
date	98.01.19.01.21.42;	author ian;	state Exp;
branches;
next	1.3;

1.3
date	98.01.18.20.10.11;	author francis;	state Exp;
branches;
next	1.2;

1.2
date	98.01.17.23.54.51;	author francis;	state Exp;
branches;
next	1.1;

1.1
date	97.12.05.00.39.49;	author jon;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	97.12.05.00.39.49;	author jon;	state Exp;
branches;
next	;


desc
@@


1.6
log
@corrections for README mailed in by "Steve M. Martin" <smartin@@wwnet.com>
@
text
@JServ - An Apache module for using Java servlets
by Alexei Kosut <akosut@@apache.org> 
and several others <java-apache@@list.working-dogs.com>
  
Release: 0.9.8
Date: January 22, 1998

This document explains how to install and use JServ. Note that this
software is currently not fully tested or complete, and will probably not
work.

IN THIS DOCUMENT:

- Requirements
- Installing the Module
- Compiling JServ
- Configuring Apache
- Configuring Apache to use Servlets
- Example Configuration
- Accessing Servlets
- Class reloading
- Servlet and Virtual Host
- JServ and Signals
- Tracing JServ
- Running JServ Manually
- Notes

REQUIREMENTS:

* Apache 1.2.0 or later <http://www.apache.org>
* JDK 1.1 or later <http://www.javasoft.com>
* JSDK 1.0 or later <http://jserv.javasoft.com>
* JServ (this package) <http://java.apache.org>


INSTALLING THE MODULE:

Copy mod_jserv.c into your Apache src/ directory. Add the Module line 
below to your Apache Configuration file:

Module jserv_module mod_jserv.o

Run Configure to create a new Makefile, then recompile Apache.

COMPILING JSERV:

Cd to the directory where you unpack the mod_jserv distribution. Read
the first few lines of the Makefile to check that the path are ok for
your site. Then make the package. 

If you want the javadoc API, you can make doc.

CONFIGURING APACHE:

mod_jserv needs a number of configuration directives set in the Apache
configuration file before it will run. These are as follows. Note that
these must be present in the main server configuration; any of the
following directives placed in a virtual server config will be ignored:

* ServletBinary

This is the location of the java Executable. Give it the full filename to
the java binary, e.g. "ServletBinary /usr/local/jdk1.1.4/bin/java"

* ServletBinaryArgument 

This gives additional command line arguments to the java interpreter. e.g.

ServletBinaryArgument -ms8m -mx16m

To specifiy startup and maximum heap size.

* ServletClassPath

This directive adds a component to java's classpath. At least three such
directives are required: The JDK classes, the JSDK classes, and the JServ
classes. e.g.:

ServletClassPath /usr/local/jdk1.1.4/lib/classes.zip
ServletClassPath /usr/local/JSDK1.0/lib/classes.zip
ServletClassPath /usr/local/httpd/jserv/classes

Note that the servlets themselves do not have to be in these class
paths. Note however that if they are, they cannot be automatically
reloaded by JServ.  They will be added later with ServletAlias.

* ServletEnvironment

ServletEnvironment lets you pass environment variables from Apache's
environment to the Java process. Normally, only PATH and TZ are passed on
(also, a CLASSPATH which is generated by mod_servlet). For example, if you
were using JDBC with Oracle, you might need to use the following:

ServletEnvironment LD_LIBRARY_PATH ORACLE_HOME

* ServletErrorLog

This directive takes the name of a file (relative to the server root) that
will be used as a log file for the servlets. This does not log specific
errors, but simply captures anything that Java servlets print to
System.err. If this directive is not present, these messages will go to
Apache's standard error.

When ServletLog is on, stack traces from exceptions and errors thrown by
the servlet will also be logged to this file. If ServletLog is off, these
traces will not be printed anywhere.

* ServletPort

This indicates a TCP port for the Java servlet interpreter to run on. The
default is 8007 (8 for HTTP, 007 for the spy. Yes, it's silly). You might
want to change it if you'll be running more than one Apache with mod_jserv
(each needs to run on a different port), or if you already use port 8007
for something. Note that this number is never used by anything except
internally between mod_jserv and the JServ classes. It is never present in
URLs.

* ServletProperties

This directive can be present in the main server or in virtual host
section. It give the location (absolute or relative to Apache's server root) of
a JServ properties file. The default is "ServletProperties
conf/servlets.properties".  If this file is present (it silently
ignores it if cannot be found or read), it is examined for servlet
aliases, servlet init arguments, default init arguments and for a list
of servlet to launch on startup.

You can give a servlet an "alias", which you can use when
accessing the servlet (see below). To do this, use the following example:

servlet.servletname.code=Classname

Each alias use has a different instance of the servlet's class, which are
all different from the instance used if the servlet is accessed directly
by class name.

You can give that servlet init arguments by using a property like
this:

servlet.servletname.initArgs=arg1=val1,arg2=val2,...

Each name=value pair will be accessible to the servlet using the
getInitParameter() method of the ServletConfig object.

You can also use a property named servlets.default.initArgs that list
default init arguments that every servlet should get. These init
arguments will be available to servlet invoked by alias or class
name. For example :

servlets.default.initArgs=arg1=val1,arg2=val2,...

You can also use the properties file to indicate servlets which will
be initialized when JServ is started. These should be placed in a
space-delimited or comma-delimited list in the servlets.startup
property. For example:

servlets.startup=servlet1 servlet2 servlet3...

The names servlet1, etc... can be either servlet aliases or full class
names.

* ServletAuthExport

If ServletAuthExport is set to "On", then mod_jserv will put the port and
secret authentication string into the request notes, where they are
accessible by other modules. This could allow other modules, such as
mod_perl, to access Java servlets. Note that activating this is a security
risk, because it allows other modules access to the authentication data,
which allows them complete acess to the Java servlets. The default is
"ServletAuthExport Off".


CONFIGURING APACHE TO USE SERVLETS

The most important directive is ServletAlias. This can be in either the
main server or a virtual server, and identified the location (both URI and
filename) of servlet classes. It takes the following syntax:

ServletAlias <uri> <directory or filename>

It takes a URI as the first argument, and a filename as the
second. This filename can point to either a directory which contains
classes, or a zip/jar file containing classes. For example, to use the
JSDK sample servlets:

ServletAlias /servlets /usr/local/JSDK1.0/servlets

Or to use servlets that are in a zipfile:

ServletAlias /myservlets /home/bob/myservlets.zip


EXAMPLE CONFIGURATION

This is a template based on a running configuration.  Specific file paths
have been edited out since they wouldn't apply to your system.  Don't forget
to remove the []'s from the examples when you replace them - if there are
any square brackets left from this sample, you still have editing to do.

--begin example-----------------------------------------------------------
# mod_jserv: Java servlet module configuration
<IfModule mod_jserv.c>
  ServletProperties     conf/jserv.properties
  ServletPort           8007
  ServletBinary         [full path to your java executable]
  ServletClassPath      [full path to your JDK classes.zip file]
  ServletClassPath      [full path to your JSDK classes.zip file]
  ServletClassPath      [full path to your mod_jserv classes directory]
  ServletAlias          /servlets [full path to your servlets directory]
  ServletAuthExport     On
</IfModule>
--end example-------------------------------------------------------------


ACCESSING SERVLETS

When Apache starts up with the above directives, it will launch a Java
process at startup, which will be used to run the Java servlets. Each
servlet is launched only once, and is passed every request made for it (so
the servlet should be thread-safe). The servlets are kept in the processes
until Apache is killed or restarted, in which case the Java process is
also killed or restarted.

To access a servlet, simply put its class name after the URI configured by
a ServletAlias. For example, assuming you had /servlets configured as
above, and you wanted to access the SnoopServlet, you would go to
http://servername:serverport/servlets/SnoopServlet. Note that the
serverport is the port that Apache runs on, *not* the ServletPort port.
Also note that ".class" should not be present at the end of the class
name.

If your class is part of a package, the full package name should be
used. For example, to invoke a servlet in the foo.bar package you
would use a url like http://host:port/servletalias/foo.bar.Servlet.

If you wish to access a servlet by name as configured in
jserv.properties, instead of by class, you should simply provide the
name you have provided after the path specified by the ServletAlias
directive. For example, if you have given your servlet a name of
"foo", you would access the servlet with "/servlets/foo". When a
servlet is accessed by its class name, JServ looks for a file named
classname.initArgs. If that file exists, it should contain properties
to give as init arguments to the servlet. For example, to have a
servlet foo.bar.Servlet initialized with a init argument foo=bar, you
would put a file named Servlet.initArgs in the foo/bar subdirectory of
the servlet path.

CLASS RELOADING

Classes, including servlets, may be loaded from a number of
locations.  In order, the dynamic, static, and system classpaths are
searched.  Each may contain any number of directories, zip files, or
jar files.

Classes loaded from the dynamic classpath will be automatically
reloaded when the file from which they are loaded is changed.  These
files are checked as each request is processed, and if any of the
files have changed then all classes from the dynamic classpath are
discarded and reloaded.

Note that when several classloaders are in use, as is the case with
mod_jserv, the result of the expression

  com.victim.SomeClass.class

will be a different java.lang.Class object on the classloader of the
class that executed the statement.  Each of these classes will have
the same name, but different classloaders.  (TODO: JLS reference for
this behaviour.)

From the mailing list:  (TODO: Clean this up)

> From mbp@@pharos.com.au Tue Nov 11 11:40:40 1997
> Date: Mon, 10 Nov 1997 10:58:53 +1000 (EST)
> From: Martin Pool <mbp@@pharos.com.au>
> To: Java Apache Serlvet List <jsdk-apache@@latchkey.com>
> Subject: [ANNOUNCEMENT] Patch to auto-reload any class
> 
> I am happy to announce:
> 
> I have some code which automatically reloads servlet classes when any user
> classes have changed.  For example, if your servlet depends on a utility
> class or business-logic class and you edit and recompile that class, then
> the servlet engine will automatically reload that class.  This is based on
> and similar to Francis's patch 01.ClassReloadingVH.0.9.8.patch, but does
> not require you to touch the servlet class file. 
> 
> This code makes a distinction between user classes and system classes.
> User classes are candidates for reloading, and system classes are not.
> Currently, system classes are a VM-wide option -- they are loaded from the
> CLASSPATH used to start the VM -- and user classes are a per-virtual-host
> option.  More subtle distinctions, such as per-vhost system classes, could
> be added in the future.
> 
> User classes are loaded from a custom classloader.  As each request is
> handled, the classloader scans the origin files (.class, .zip, or .jar
> files) for each loaded class.  If any of them have changed, the
> classloader informs a manager object that a reload is necessary.  The
> manager discards the classloader (and implicitly all of the classes
> loaded by it.)  The manager creates a new classloader, and uses that
> classloader to load classes to service the request, including the
> servlet object and any other classes referenced by the servlet.
> 
> There is no need to determine dependency trees because all of the user
> classes are discarded when any class changes.  This behaviour is
> required -- as far as I know -- by the design of the ClassLoader
> system, because it's not possible to force classes to be discarded.
> This is actually quite a clean design, because it ensures that classes
> are always consistent with each other.
> 
> Classes are cleanly destroy()ed before unloading, and init()ed when
> they restart.  (I wouldn't bet on this, though... it'd be worth
> testing.  My java.sql.Connection objects seem to work OK in init and
> destroy.)
> 
> Subjectively, there seems to be no substantial performance loss from
> checking each class on each request.  I'd like to add an option to
> turn this behaviour on and off, but I haven't done so yet.
> 
> System classes referenced by the servlet, such as java.lang.String are
> delegated to the system classloader and so are only loaded once, when
> the VM starts.

> From mbp@@pharos.com.au Tue Nov 11 11:41:26 1997
> Date: Tue, 11 Nov 1997 08:43:59 +1000 (EST)
> From: Martin Pool <mbp@@pharos.com.au>
> To: Java Apache Serlvet List <jsdk-apache@@latchkey.com>
> Subject: Re: [ANNOUNCEMENT] Patch to auto-reload any class
> 
> On Mon, 10 Nov 1997, Francis J. Lacoste wrote:
> 
> > > I am happy to announce:
> > > 
> > > User classes are loaded from a custom classloader.  As each request is
> > > handled, the classloader scans the origin files (.class, .zip, or .jar
> > > files) for each loaded class.  If any of them have changed, the
> > > classloader informs a manager object that a reload is necessary.  The
> > > manager discards the classloader (and implicitly all of the classes
> > > loaded by it.)  The manager creates a new classloader, and uses that
> > > classloader to load classes to service the request, including the
> > > servlet object and any other classes referenced by the servlet.
> > > 
> > > [...]
> > > 
> > > Classes are cleanly destroy()ed before unloading, and init()ed when
> > > they restart.  (I wouldn't bet on this, though... it'd be worth
> > > testing.  My java.sql.Connection objects seem to work OK in init and
> > > destroy.)
> > > 
> > 
> > Are destroying every servlets, or just the one that references other
> > classes that need reloading ? You should really destroy (and maybe
> > reconstruct) *every* servlets. If not, old servlets will still
> > reference old version of the class (which is a problem with user-level
> > classes that should be shared between servlets).
> 
> Yes, my code destroys every servlet in that virtual host.  This design is,
> as far as I can tell, a forced move by the ClassLoader design simply
> because it is so hard (impossible, probably) to determine those
> dependencies. 
> 
> If one had a large number of servlets and classes in a virtual host, then
> killing and reloading them might be a bit expensive, but since this will
> only happen in development mode, not deployment I don't think it's a
> problem.  (But I'm willing to be proved wrong.)  We might want to look at
> supporting multiple classloaders per vhost in the future -- perhaps to
> give different users different isolated playgrounds.
> 
> In any case, there is very little subjective delay on reloading a
> moderately complex servlet application on my fairly humble machine buffalo
> (linux, pentium/133MHz, 96MB).  The reload time is reasonable because the
> core API is not discarded, so it doesn't have to load a hundred classes
> from java.lang.*.  (Do java -verbose someclass and you'll see what I
> mean.) 
> 
> Using classloaders means that you may have multiple java.lang.Class
> objects in your VM, with the same name and the same or different
> definitions.  They're different, and allowed to coexist, because they have
> different classloaders.  I can imagine this being confusing to people the
> first few times they encounter it. 
> 
> It's also important to make sure that your servlet's destroy() method
> fulfills its contract, because you can no longer count on the VM or
> OS-level process terminating at the same time as your servlet.  For
> example, if your servlet forked a thread, or opened a database connection
> it would have to kill them in destroy(), otherwise they'd be effectively
> orphaned with no reference to the new servlet object, or even to the new
> servlet class.
> 
> (I'll clip this mail into the README sometime.)
> 
> --
> Martin Pool, Pharos
>  
> "Success is 99% failure." -- Soichiro Honda
> 

SERVLET AND VIRTUAL HOST

Each virtual host (all that apply to virtual hosts, apply equally to
the main host, as far as JServ is concerned, the main host is just
another host) is in a different name space. This means that
getServlets() return only the servlets that are in that virtual
host. Symmetrically, getServlet( name ) will only return servlets
that are in the virtual host. Also since each host can have a separate
property file, it can define an alias with the same name but which maps
to a different class, or initialize each virtual server's set of servlets
with different arguments. 

JSERV AND SIGNALS

When you kill Apache using SIGTERM, JServ call destroy() on all its
servlets before exiting. If you restart Apache using SIGHUP, JServ
will destroy its servlets and reinit the servlet in the
servlets.startup property of the different virtual host. There is one
thing that JServ doesn't do when it is restarted like that : changes
that you made in the Apache configuration files to directive like
ServletAlias or ServletProperties won't be noticed by JServ. Also,
JServ doesn't reread the property files. (So change to servlet
aliases) won't take effect.

TRACING JSERV

Several parts of jserv can be traced to the ServletErrorLog. What is
trace is controlled via a bitmask. This bitmask is taken from the
system property jserv.tracing that can be set conviniently in a
ServletBinaryArgument directive.

Ex:

ServletBinaryArguement -Djserv.tracing=131

This will trace initialization of JServ, request servicing and servlet
manager activity. For a description of the possible flags see
JServDebug.java.
 
RUNNING JSERV MANUALLY

Normally (as assumed by the above instructions), Apache starts the
JServHandler process (JServHandler is the Java class that
acts as a servlet server) automatically when Apache starts up, and kills
it when Apache is stopped or restarted. However, you may wish to start
and stop JServHandler separately from Apache. JServ provides this
functionality if desired.

For more information, please see the manual/README file, included with
this distribution.

NOTES

This package has only been tested with a few servlets, and there are
probably some bugs. It was implemented to the JSDK API specification, and
I probably interpreted some of it slightly differently than others did,
so if there are differences in behavior between JServ and JWS, that's
probably why.

The protocol used by mod_jserv to talk to the JServ Java process is
documented in the protocol.txt file. This might be useful if someone
wanted to use the Java classes to talk to another type of server.

There are a couple points in the code where things aren't done quite
right. They are marked with "FIXME". Anyone who has any ideas on how to
fix those, please do so.
@


1.5
log
@oops... typo!  "my a configuration" should be "a configuration".
@
text
@d145 1
a145 1
You can also used a property named servlets.default.initArgs that list
d242 1
a242 1
classname.initArgs. If that file exists, it should contains properties
d406 3
a408 3
property file, it can defined alias with the same name but which maps
to different class, or init its set of servlets with different
arguments. 
d462 1
a462 1
right. There are marked with "FIXME". Anyone who has any ideas on how to
@


1.4
log
@added example configuration
@
text
@d195 1
a195 1
This is a template based on my a running configuration.  Specific file paths
@


1.3
log
@Updated todo list and change the attribution string and
release date in README.
@
text
@d19 1
d191 22
@


1.2
log
@Fixed typos and add documentation about tracing.
@
text
@d2 3
a4 2
by Alexei Kosut <akosut@@apache.org>

d6 1
a6 1
Date: December 1, 1997
@


1.1
log
@Initial revision
@
text
@d15 1
d19 4
a25 1

d43 7
d238 1
a238 1
mod_jserv, the resault of the expression
d240 1
a240 1
  com.victim.SomeClass.CLASS
d398 15
a431 4

The source is contained in five files, and compiles into seven classes.
All twelve files come with the JServ package, in the classes/apache/jserv
directory.
@


1.1.1.1
log
@JServ 0.9.8
@
text
@@
