|
This is a beta release of the Winstone Servlet Container. The homepage for this project is at 'http://winstone.sourceforge.net' Author: Rick Knowles (contact details below) ContentsAbout:Introduction:
Usage tips:
What is Winstone ?Winstone is a servlet container that was written out of a desire to provide servlet functionality without the bloat that full J2EE compliance introduces. It is not intended to be a completely fully functional J2EE style servlet container (by this I mean supporting extraneous APIs unrelated to Servlets, such as JNDI, JavaMail, EJBs, etc) - this is left to Tomcat, Jetty, Resin, JRun, Weblogic et al. Sometimes you want just a simple servlet container - without all the other junk - that just goes. This is where Winstone is best suited. The original goals in writing Winstone were:
Why is it called Winstone ?The short version (because the long version is way too politically incorrect) is as follows: Winstone is the name of a rather large Jamaican man a friend of mine met one night, while he was out clubbing in the Roppongi area of Tokyo. He (my friend) was a little liquored up at the time, and when Winstone suggested they head to "this really cool club" he knew, he didn't think anything was wrong. It wasn't until Winstone led him down a dark stairwell and dropped his trousers that my friend clued in and ran like hell. It was too good a story to let die, so I named this project Winstone so that said friend will continue to be reminded of it. Heheheh .... LicenseThe Web-App DTD files (everything in the src/javax/servlet/resources and src/javax/servlet/jsp/resources folders) are covered by the licenses described at the top of each file (usually as licensed by Sun Microsystems). All other files are covered by the GNU Public License, as described in LICENSE.txt. Contacting the AuthorYou can contact me through the Winstone development list at sourceforge (winstone-devel AT lists DOT sourceforge DOT net). If you have any general comments or questions about Winstone please mail me on that list - I'll try to start a faq soon. I'm open to help from anyone who's willing to help me meet the above goals for Winstone. Just mail me at the list (winstone-devel AT lists DOT sourceforge DOT net) Using WinstoneIf you want to build from source code, you will need to download and install Apache Maven. The following instructions assume you have already installed Maven and have the maven shell script in your path (to get Maven, see http://maven.apache.org/). To build Winstone, unpack the tree: tar zxf winstone-src-0.8.tar.gz
Then build it: cd winstonemaven clean jar
The winstone.jar file will be in the target directory after the build is complete. To run it: java -jar target/winstone-0.8.jar --webroot=<location of webroot> (+ other options)
- OR - java -jar target/winstone-0.8.jar --warfile=<location of warfile> (+ other options)
- OR - java -jar target/winstone-0.8.jar --webappsDir=<location of webapps directory> (+ other options)
- OR - java -jar target/winstone-0.8.jar --hostsDir=<location of hosts directory> (+ other options)
Command-line options:
Syntax:
java -jar winstone-0.8.jar [--option=value] [--option=value] etc
Required options: either --webroot OR --warfile OR --webappsDir OR --hostsDir
--webroot = set document root folder.
--warfile = set location of warfile to extract from.
--webappsDir = set directory for multiple webapps to be deployed from
--hostsDir = set directory for name-based virtual hosts to be deployed from
Other options:
--javaHome = Override the JAVA_HOME variable
--toolsJar = The location of tools.jar (default is JAVA_HOME/lib/tools.jar)
--config = load configuration properties from here(if supplied).
--prefix = add this prefix to all URLs. (eg http://host/prefix/etc).
--commonLibFolder = folder for additional jar files. Default is ./lib
--logfile = redirect winstone log messages to this file
--logThrowingLineNo = show the line no that logged the message (slow). Default is false
--logThrowingThread = show the thread that logged the message. Default is false
--debug = set the level of debug msgs (1-9). Default is 5 (INFO level)
--httpPort = set the http listening port. -1 to disable, Default is 8080
--httpListenAddress = set the http listening address. Default is all interfaces
--httpDoHostnameLookups = enable host name lookups on http connections. Default is false
--httpsPort = set the https listening port. -1 to disable, Default is disabled
--httpsListenAddress = set the https listening address. Default is all interfaces
--httpsDoHostnameLookups = enable host name lookups on https connections. Default is false
--httpsKeyStore = the location of the SSL KeyStore file. Default is ./winstone.ks
--httpsKeyStorePassword = the password for the SSL KeyStore file. Default is null
--httpsKeyManagerType = the SSL KeyManagerFactory type (eg SunX509, IbmX509). Default is SunX509
--ajp13Port = set the ajp13 listening port. -1 to disable, Default is 8009
--ajp13ListenAddress = set the ajp13 listening address. Default is all interfaces
--controlPort = set the shutdown/control port. -1 to disable, Default disabled
--handlerCountStartup = set the no of worker threads to spawn at startup. Default is 5
--handlerCountMax = set the max no of worker threads to allow. Default is 300
--handlerCountMaxIdle = set the max no of idle worker threads to allow. Default is 50
--directoryListings = enable directory lists (true/false). Default is true
--useJasper = enable jasper JSP handling (true/false). Default is false
--useServletReloading = enable servlet reloading (true/false). Default is false
--preferredClassLoader = override the preferred webapp class loader.
--useInvoker = enable the servlet invoker (true/false). Default is true
--invokerPrefix = set the invoker prefix. Default is /servlet/
--simulateModUniqueId = simulate the apache mod_unique_id function. Default is false
--usage / --help = show this message
Cluster options:
--useCluster = enable cluster support (true/false). Default is false
--clusterClassName = Set the cluster class to use. Defaults to SimpleCluster class
--clusterNodes = a comma separated list of node addresses (IP:ControlPort,IP:ControlPort,etc)
JNDI options:
--useJNDI = enable JNDI support (true/false). Default is false
--containerJndiClassName = Set the container wide JNDI manager class to use. Defaults to ContainerJNDIManager
--webappJndiClassName = Set the web-app JNDI manager class to use. Defaults to WebAppJNDIManager
--jndi.resource.<name> = set the class to be used for the resource marked <name>
--jndi.param.<name>.<att> = set an attribute <att> for the resource marked <name>
Security options:
--realmClassName = Set the realm class to use for user authentication. Defaults to ArgumentsRealm class
--argumentsRealm.passwd.<user> = Password for user <user>. (for ArgumentsRealm)
--argumentsRealm.roles.<user> = Roles for user <user> (comma-separated) (for ArgumentsRealm)
--fileRealm.configFile = File containing users/passwds/roles. Only valid for the FileRealm realm class
Access logging:
--accessLoggerClassName = Set the access logger class to use for user authentication. Defaults to disabled
--simpleAccessLogger.format = The log format to use. Supports combined/common/resin/custom (SimpleAccessLogger only)
--simpleAccessLogger.file = The location pattern for the log file(SimpleAccessLogger only)
Configuration fileYou don't really need a config file, but sometimes it's handy to be able to use the same settings each time without running through the command history. Winstone looks for a config file This is just intended as a handy feature for people who want to cache regular startup options, rather than using batch files. Deployment choicesThe simplest way to use winstone is with a single webapp. To do this, just supply the warfile or webroot directory as an argument:
If you need to support multiple webapps, use the
The directory becomes the prefix name for that webapp (so hello becomes /hello, etc). The directory named ROOT becomes the no-prefix webapp. So, for example, if you had a directory /usr/local/webapps which contained sub-directories ROOT
and test, if you executed From v0.8, if you need multiple hosts (sometimes called name-based virtual hosting), there is a
new option The directory name becomes the host name: that is, a directory named "www.blah.com" will only serve requests with the host header www.blah.com, unless it is the default host. If a directory named "default" is found, it becomes the default host. If no default directory is found, the first directory in the list (alphabetically) becomes the default host.
CaveatsAs a result of the design goals, there are some things Winstone doesn't do
Security WarningIf you enable the controlPort, be aware that there is no password protection at all on this port. Anyone who can get access to this port can stop or restart the server. I plan to add some simple authentication to this at some point, but I'll wait until someone asks for it. The controlPort is disabled by default. If you choose not to enable it, the only way to shut Winstone down is to kill the process (either by Ctrl-C or kill command). Recent additionsNew features in v0.8:
New features in v0.7:
New features in v0.6:
New features in v0.5:
New features in v0.4:
New features in v0.3:
Using Xerces as an XML parser (required for v2.4 webapps)As part of the upgrade in the servlet specification, the v2.4 incarnation of the web.xml file is validated using XML Schema Documents (XSD) as opposed to Document Type Definitions (DTD). While I still have no idea why such a change was necessary - especially given that DTD validation seems to be more than enough in this case - I did implement it. Perhaps the people on the specification committee might want to give a thought to container size next time round, as this one change multiplies the size of the distribution by five. Anyway, to use Xerces, you'll need to download the latest Xerces-J parser from here, and copy xercesImpl.jar and xml-apis.jar into the jre/lib/ext folder of your JDK. Putting them in the winstone/lib folder will not work, because they must be in the system classpath to override the JDK internal XML parser. Alternatively you can add these two files to your startup classpath, but you will have to manually specify the Winstone startup class: java -cp winstone.jar;xercesImpl.jar;xml-apis.jar winstone.Launcher --webroot=... JSPs (aka using with Jasper)Winstone supports JSPs using Apache's Jasper JSP compiler. Thanks to a rather clever design by the Jasper team, this was much less work than I expected - well done Jasper guys. Required steps:
Connecting to ApacheThese instructions are for beginners: if you know your way around Apache and Tomcat, you'll know what's going on here. Download and install Apache for your platform (and obviously Winstone too), then follow these steps:
Please note this is not an optimal configuration for production uses. This is provided purely for those who need some help to get started. Read the mod_jk documentation with Tomcat for more detailed info. Using Authentication RealmsThe process here is almost identical to that of Tomcat (I know this because I used the Tomcat examples webapp to develop against). There are two components - the web.xml component and selecting/configuring an AuthenticationRealm class.
This component is left intentionally fairly simple, and relatively extracted. I'm planning to break the realm and authentication stuff into an optional jar later, since not many webapps I've seen use it. Cluster supportIt should be pointed out in the beginning that the Cluster support currently implemented in Winstone is actually just session sharing. If a request comes to a node in the cluster that doesn't recognise the session ID supplied, that node simply asks the others "Do you know this session ?". If one does know it, it transfers the session to the requesting node, and the requesting node carries on as if it had always had the session in the first place. If a specific node in the cluster goes offline, so do all the sessions that it was holding. There is no active "push" of sessions to other nodes, so as far as resilience to failure goes, this cluster is fairly weak. The clustering provided here is meant to allow a dumb load balancer to redirect requests randomly across a cluster of Winstone instances without requiring it to be "session sticky". That said, the configuration is fairly simple. The only information you need is the IP address and control port of at least one other active node in the cluster. Once you have that, add the following options to the command line startup:
java -jar winstone.jar ...< other options > ... \
--controlPort=<myControlPort> \
--useCluster \
--clusterNodes=<IP1:controlPort1>
where IP1 is the IP address of the other node in the cluster, and myControlPort and controlPort1 are the port numbers to use for the control ports of this instance and the other node respectively. Note that it is necessary to actively set the controlPort on this instance, since it is disabled by default. You would likewise set up the other instance with reciprocal options (ie changing the IPs and controlPort values appropriately. NOTE: There are some additional requirements on your web application for Clustering of sessions to be successful.
Control port functions/protocolFrom v0.5, the behaviour of the control port changes slightly. Due to increased usage of the control port by the clustering function, a rudimentary protocol has been added. The protocol is very simple. The first byte sent to the server is a flag indicating what type of request is being issued. Beyond that the protocol varies for each request type, but the request type flag options are listed below:
Obviously, unless you're planning to write your own cluster extensions, the only two you will be interested
in are the shutdown and reload options. Luckily there is a wrapper class for accessing these functions, named
java -cp winstone.jar winstone.tools.WinstoneControl JNDI supportI know that in the introduction I said that Winstone was only going to support the core servlet APIs, but I've since discovered that most people use just a little more than the core servlet API offers. For example, some people use just a JNDI JavaMail session to send administrator error mails, while others want to offer a simple servlet over SSL (and hence need Apache), still others use just a JNDI DataSource to keep a reference to the connection pool. For this reason I've included a really basic optional JNDI service within Winstone. For the moment, it supports simple operations (such as bind, lookup, rebind, etc) and allows you to store references to environment variables (drawn from the env-entry elements in web.xml and/or command line arguments). NOTE: JNDI support is disabled by default. It must be enabled using Configuration can be done in two ways:
Additionally, it includes a JDBC DataSource object which can be used as a wrapper around normal JDBC drivers. This is fairly simple for now, but it meets the requirements I mentioned above. Options are as follows:
For example to create a DataSource object at the JNDI location java:/comp/env/jdbc/connPool, use the following command line (or config file) options:
java -jar winstone.jar ...< other options > ... \
--useJNDI=true \
--jndi.resource.jdbc/connPool=javax.sql.DataSource \
--jndi.param.jdbc/connPool.url=jdbc:mysql://db.widgets.com/db \
--jndi.param.jdbc/connPool.driverClassName=com.mysql.jdbc.Driver \
--jndi.param.jdbc/connPool.username=foo \
--jndi.param.jdbc/connPool.password=bar
HTTPS supportSomebody asked me to add HTTPS support, using the JDK 1.4 SSL socket classes, and so I decided to give it a try. It was a lot easier than expected - the API was really nice to use. Unfortunately the hard work seems to be in the configuration, rather than the programming. I recommend using a shareware tool called KeyStore Explorer, available here. It's much easier than all that messy CLI stuff. The steps are basically as follows:
Access LoggingFrom v0.8, there's an option to allow access logging. It's disabled by default, but can be enabled by defining a logging implementation class, with --accessLoggerClassName. The class defined must be an implementation of the interface winstone.AccessLogger, and is defined container wide, but instantiated once per webapp. The supplied logger is called winstone.accesslog.SimpleAccessLogger. It supports Apache style combined/common format logs, as well as Resin format (which is actually just Apache common style plus a user agent). Configuration options are:
For example, to enable Apache Combined style logging to separate files, use a command line like: java -jar winstone.jar --hostsDir=<vhostsDir>
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
Or to log just the date and URI for all hosts/webapps to a single file, use a command line like: java -jar winstone.jar --hostsDir=<vhostsDir>
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
--simpleAccessLogger.format=###date###\ ###uriLine###
--simpleAccessLogger.file=/mylogs/access_log.txt
Embedding WinstoneThe design of Winstone has always allowed its easy embedding within another application. It's as simple as: // at startup
Map args = new HashMap();
args.put("webroot", "<my webroot dir>"); // or any other command line args, eg port
Launcher.initLogger(args);
Launcher winstone = new Launcher(args); // spawns threads, so your application doesn't block
... (your application code)
// before shutdown
winstone.shutdown();
From v0.8 though, there is also the ability to embed in the opposite direction: that is, to embed your warfile into the winstone JAR itself. This allows an all-in-one container plus web-application JAR file to be downloaded, and then unpacked at execution time. To use this, simply unpack the winstone JAR, and place your WAR file inside the unpacked folder at the top level (with the same parent as the folder named "winstone"). Then rename your WAR file to "embedded.war", and repack the jar as before (make sure to preserve the META-INF and manifest). Now if you type: If you need to add any default command-line arguments (eg ports or prefixes), you can embed a properties file in exactly the same way, except that the file must be named "embedded.properties". |