/
README.html
912 lines (814 loc) · 56.6 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Winstone Servlet Container</title>
<meta name="description" content="Winstone is a small, fast and functional java servlet v2.4 container in a single 166kb jar file"/>
<meta name="keywords" content="servlets, servlet, servlet container, jsp, java, container, ajax, webservices, jdk, jre, winstone, small, fast, reliable, open source, gpl, gcj, jndi, xml"/>
<meta name="author" content="Rick Knowles"/>
<meta name="language" content="English"/>
<meta name="charset" content="ISO-8859-1"/>
<meta name="MSSmartTagsPreventParsing" content="TRUE"/>
<meta name="distribution" content="Global"/>
<meta name="rating" content="General"/>
<meta name="robots" content="Index, Follow"/>
<meta name="revisit-after" content="7 Days"/>
<link href="site.css" type="text/css" rel="stylesheet"></link>
</head>
<body>
<div id="header">
<h1>Winstone Servlet Container v0.9.10</h1>
<ul>
<li><a href="http://sourceforge.net/project/showfiles.php?group_id=98922">Downloads</a></li>
<li class="last"><a href="#license">License updated (CDDL)</a></li>
</ul>
</div>
<div id="body">
<p>This is a beta release of the Winstone Servlet Container. The homepage for this project is
at 'http://winstone.sourceforge.net'</p>
<p>Author: Rick Knowles (contact details below)</p>
<div id="nav">
<h2>Contents</h2>
<ul>
<li><h3>About</h3>
<ul>
<li><a href="#whatIs">What is Winstone ?</a></li>
<li><a href="#whyCalled">Why is it called Winstone ?</a></li>
<li><a href="#license">License</a></li>
<li><a href="#authorContact">Contacting the Author</a></li>
</ul>
</li>
<li><h3>Introduction</h3>
<ul>
<li><a href="#using">Using Winstone</a></li>
<li><a href="#commandLine">Command-line options</a></li>
<li><a href="#configFile">Configuration file</a></li>
<li><a href="#deployChoices">Deployment choices</a></li>
<li><a href="#caveats">Caveats</a></li>
<li><a href="#security">Security Warnings</a></li>
<li><a href="#recent">Recent Additions</a></li>
</ul>
</li>
<li><h3>Usage tips</h3>
<ul>
<li><a href="#xerces">Using Xerces as an XML parser (required for v2.4 webapps)</a></li>
<li><a href="#jasper">JSPs (aka using with Jasper)</a></li>
<li><a href="#apache">Connecting to Apache</a></li>
<li><a href="#authRealms">Using Authentication Realms</a></li>
<li><a href="#cluster">Cluster support</a></li>
<li><a href="#controlPort">Control port functions/protocol</a></li>
<li><a href="#jndi">JNDI support</a></li>
<li><a href="#https">HTTPS support</a></li>
<li><a href="#accessLog">Access logging</a></li>
<li><a href="#embedding">Embedding Winstone</a></li>
<li><a href="#sessionPersistence">Session persistence across reboots</a></li>
</ul>
</li>
</ul>
</div>
<div class="section">
<h2><a name="whatIs">What is Winstone ?</a></h2>
<p>Winstone is a servlet container that was written out of a desire to provide servlet
functionality without the bloat that full J2EE compliance introduces.</p>
<p>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. </p>
<p>Sometimes you want just a simple servlet container - without all the other junk - that just goes.
This is where Winstone is best suited.</p>
<p>The original goals in writing Winstone were:</p>
<ul>
<li>Supply fast, reliable servlet container functionality for a single webapp per server</li>
<li>Keep the size of the core distribution jar as low as possible (currently 166KB)</li>
<li>Keep configuration files to an absolute minimum, using command line options to
optionally override sensible compiled in defaults. </li>
<li>Eventually compile with GCJ to make a 3-4Meg windows exe for local development/deployment
of servlets. This has not happened yet, because of some GCJ class loading problems.</li>
<li>Optionally support JSP compilation using Apache's Jasper. (http://jakarta.apache.org)</li>
</ul>
</div>
<div class="section">
<h2><a name="whyCalled">Why is it called Winstone ?</a></h2>
<p>The short version (because the long version is way too politically incorrect) is as follows: </p>
<p>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.</p>
<p>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 ....</p>
</div>
<div class="section">
<h2><a name="license">License</a></h2>
<p>The 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).</p>
<p>As of v0.8.1, all other files are dual-licensed, under either the Lesser GNU Public
License (LGPL) as described in LICENSE-LGPL.txt, or the Common Development and Distribution
License (CDDL) as decribed in LICENSE-CDDL.txt. Until v0.8, the license used was the GNU Public
License (GPL).</p>
<p>The goal of dual-licensing is to make Winstone as attractive as possible to distributors of
commercial webapps, while ensuring everyone benefits from any improvements. The CDDL allows
free distribution with any commercial applications, while distribution with a GPL licensed
webapp is also possible under the LGPL. If you are unclear about which license applies to an
application you wish to distribute or sell, please <a href="#authorContact">contact me</a>.</p>
</div>
<div class="section">
<h2><a name="authorContact">Contacting the Author</a></h2>
<p>You 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.</p>
<p>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)</p>
</div>
<div class="section">
<h2><a name="using">Using Winstone</a></h2>
<p>If you want to build from source code, you will need to download and install Apache Maven (v1.x). 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/).</p>
<p>To build Winstone, unpack the tree:</p>
<code>tar zxf winstone-src-0.9.10.tar.gz</code>
<p>Then build it:</p>
<code>cd winstone</code><br/>
<code>maven clean jar</code>
<p>The winstone.jar file will be in the target directory after the build is complete.</p>
<p>To run it:</p>
<code>java -jar target/winstone-0.9.10.jar --webroot=<location of webroot> </code> (+ other options)
<p> - OR - </p>
<code>java -jar target/winstone-0.9.10.jar --warfile=<location of warfile></code> (+ other options)
<p> - OR - </p>
<code>java -jar target/winstone-0.9.10.jar --webappsDir=<location of webapps directory></code> (+ other options)
<p> - OR - </p>
<code>java -jar target/winstone-0.9.10.jar --hostsDir=<location of hosts directory></code> (+ other options)
</div>
<div class="section">
<h2><a name="commandLine">Command-line options:</a></h2>
<pre>
Syntax:
java -jar winstone-0.9.10.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 20
--handlerCountMaxIdle = set the max no of idle worker threads to allow. Default is 5
--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
--useSavedSessions = enables session persistence (true/false). 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)
</pre>
</div>
<div class="section">
<h2><a name="configFile">Configuration file</a></h2>
<p>You 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.</p>
<p>Winstone looks for a config file <code>winstone.properties</code> in the current directory (or in the location
specified with --config) at startup. It loads the properties in this file, overrides them with any
supplied command line properties, and then starts itself.</p>
<p>This is just intended as a handy feature for people who want to cache regular startup options, rather
than using batch files.</p>
</div>
<div class="section">
<h2><a name="deployChoices">Deployment choices</a></h2>
<p>The <b>simplest way</b> to use winstone is with a single webapp. To do this, just supply the warfile or webroot
directory as an argument:</p>
<ul>
<li><code>java -jar winstone.jar <webroot or warfile></code>, (this method auto-detects the type) or</li>
<li><code>java -jar winstone.jar --webroot=<webroot></code>, or</li>
<li><code>java -jar winstone.jar --warfile=<warfile></code></li>
</ul>
<p>If you need to support <b>multiple webapps</b>, use the <code>--webappsDir</code> switch, to which you pass a
directory that contains multiple warfiles/webroots.</p>
<ul>
<li><code>java -jar winstone.jar --webappsDir=<dir containing multiple webroots></code></li>
</ul>
<p>The directory becomes the prefix name for that webapp (so hello becomes /hello, etc). The directory named
ROOT becomes the no-prefix webapp.</p>
<p>So, for example, if you had a directory <i>/usr/local/webapps</i> which contained sub-directories ROOT
and test, if you executed <code>java -jar winstone.jar --webappsDir=/usr/local/webapps</code>, you would
find that the test folder would act as a webroot for requests prefixed with <code>/test</code>, while
other requests would go to the webapp in the ROOT folder</p>
<p>From v0.8, if you need <b>multiple hosts (sometimes called <i>name-based virtual hosting</i>)</b>, there is a
new option <code>--hostsDir</code>. This acts in a similar way to the <code>--webappsDir</code> switch,
but it defines an extra level of sub-directories, the top being a per-host directory and the second a
per-webapp directory as with <code>--webappsDir</code>.</p>
<p>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.</p>
<ul>
<li><code>java -jar winstone.jar --hostsDir=<dir containing multiple host directories></code></li>
</ul>
</div>
<div class="section">
<h2><a name="caveats">Caveats</a></h2>
<p>As a result of the design goals, there are some things Winstone doesn't do:</p>
<ul>
<li>There are currently three connectors supplied with Winstone:
<ol>
<li>An internal HTTP connector - allows plain HTTP/1.1 connections only</li>
<li>An internal HTTPS connector - allows HTTP/1.1 connections over SSL</li>
<li>An AJP13 connector - allows connection to Apache/IIS/iPlanet, etc</li>
</ol>
While there is an internal HTTPS/SSL connector included, I recommend using
Apache 2.0 with the AJP13 connector (instructions below). It has way more configuration
options than Winstone's connector does.</li>
<li>HttpSession support is cookie-based only (no URL rewriting). URL rewriting introduces a lot of
unnecessary complex request processing, and given that browser cookie support is common these
days (and no-one I know actually uses URL rewriting), I plan not to implement this.</li>
<li>The messages are all in English only. Resource bundles are used, but no translations yet.</li>
</ul>
</div>
<div class="section">
<h2><a name="security">Security Warning</a></h2>
<p>If 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.</p>
<p>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).</p>
</div>
<div class="section">
<h2><a name="recent">Recent additions</a></h2>
<p>New features in v0.9:</p>
<ul>
<li>Added <b>Servlet v2.5 spec support</b>. Please note that the annotations support mentioned
in the spec is only for J2EE compliant containers, and Winstone is deliberately only JSR154 compliant.
The adding of v2.5 support was purely driven by a requirement in the API license, so except for a bit of
syntactic sugar in the web.xml and spec clarifications, this isn't really a big deal. Also,
while the new spec mandates JDK1.5 or better, winstone should still work with a JDK1.2+ JVM.</li>
<li>Added <b>Session persistence across reboots</b>. The best thing about winstone (I find) is it's
startup time, but restarts are a pain if you have to rebuild a session in order to get to a page you're
working on. By adding --useSavedSessions to the startup args, you'll enable the feature. See
<a href="#sessionPersistence">below</a> for more.</li>
<li>A lot of <b>session and forwarding related fixes</b> - thanks to Martin Cordova and Robert Boyce for
pointing these out. These have been bugging me for some time, but having people give you reproducible
examples of error cases is often all it takes to fix a long standing problem, and these guys were
crucial in providing that.</li>
<li>A change is <b>JSP deployment requirements</b>. If you use JSPs, please see <a href="#jasper">below</a>.</li>
<li>AJP connector now apparently works with IIS. Many thanks to Cory Osborn for finding these problems and
then debugging and fixing them single-handedly.</li>
<li>Some classloading changes that should isolate classloading in webapps from each other more thoroughly.</li>
</ul>
<p>New features in v0.8:</p>
<ul>
<li>Expanded the features of the JDBC connection pool to include <b>keep-alive</b> queries
and block-and-retry behaviour when the pool has been exhausted.</li>
<li>Added filter match caching (performance improvement)</li>
<li><b>Name-based virtual hosting</b>. Using the <code>--hostsDir</code> switch, you can define a
directory that contains directories named by hostname, each of which acts like a <code>--webappsDir</code>.
See <a href="#deployChoices">above</a> for more details.</li>
<li><b>Access logging</b>. Disabled by default, but enabled with the switch
<code>--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger</code>. You can provide your
own logging implementation, but the simple access logger contains Apache Combined/Common format
logging and Resin format logging, so it should suffice for most cases. See
<a href="#accessLog">below</a> for more details.</li>
<li><b>Better embedding support</b>. You can now embed warfiles and properties file inside the
winstone jar itself, for an all-in-one application jar. See <a href="#embedding">below</a>
for more details.</li>
<li>Tested with WebDAV applications. Winstone has now been tested/debugged with Jakarta Slide and
Davenport WebDAV applications, and works correctly (previous versions had some obscure bugs
that caused WebDAV to fail)</li>
</ul>
<p>New features in v0.7:</p>
<ul>
<li>Updated build process to use Apache Maven (see <a href="http://maven.apache.org">
http://maven.apache.org</a>. Build instructions have been updated to match.</li>
<li>Source code has been reformatted - a fair bit easier to read now</li>
<li><b>Multiple webapp support has been added</b>. There's no auto-deploy features yet,
but that will come soon. Use the --webappsDir=<webapps directory> to declare
a folder that will have any directories auto-mounted and any warfiles auto-deployed.
(I originally said this was not going to be included, but changed my mind when I
realised it could be done with only 10K additional jarfile size).</li>
<li>Fixed the bugs in the exception handling and error servlet redirection, as
well as in web xml parsing, and more other places that I can possibly list here.
If you had some strange bug or incompatibility before, chances are it's been fixed
now.</li>
<li><b>Passed the Sun JSR-154 Servlet Test Compatibility Kit (TCK) tests.</b></li>
<li>I also ran the JSR-152 JSP TCK on winstone with Apache Jasper support enabled,
and while it didn't pass all tests, the tests it failed were the same ones the
Tomcat failed, so I notified the Tomcat/Jasper developers of the test failures.
Currently waiting on a response ... in any case I suspect these are actually test
errors rather than implementation errors.</li>
<li>Better support for open source JVMs. Martin Cordova has been very helpful in
testing winstone under a wider range of JVMs, as well as providing some really
good feedback on needed features. His tests included JamVM and CacaoVM, as well
as IBM's JDK. Jim Huang also reported that winstone works well under Kaffe.</li>
<li>User definable webapp class loader: This is likely to be of interest to the Aspect
Oriented Programming crowd. It allows you to write your own class loader class
(conforming to the same contructor signature as URLClassLoader), and then
to use it in place of the normal web app class loader with --preferredClassLoader.
This allows AspectWerkz style weaving classloaders to be used on webapps where it
wouldn't have been otherwise possible (eg JDKs that don't support the profiler
option, such as 1.4 and before), or anything else you can think of doing with a
custom classloader.</li>
</ul>
<p>New features in v0.6:</p>
<ul>
<li>Updated to <b>Servlet 2.4</b> specification compliance, although I haven't yet
run Sun's Test Compatibility Kit on it - I'm still waiting for that. It works
with all of the v2.4 webapps I've tried. The only caveat is that you will need
Apache Xerces in the system classpath to make it work (see below).</li>
<li>Updated to <b>JSP 2.0</b> specification compliance. This is the main cause
for the blowout in size of the larger jar file, but it does result in much
simpler set up for Jasper (see below).</li>
<li>Added a <b>command-line tool</b> for accessing control port options, such as
<b>shutdown</b> and <b>restart</b>. Restart is new to this version, and causes
a shutdown and redeploy from scratch.</li>
<li>Added a <b>lib folder</b> for additional jars. This defaults to "lib" under the
current directory, with any jar or zip files in this folder being added to the
webapp classpath.</li>
<li>Extensively tested with the <b>Apache Struts and JSTL frameworks</b>. This highlighted
a number of bugs related to internationalisation I wouldn't have found otherwise.</li>
<li>Many minor features such as <b>range downloads</b> on static resources, a <b>logfile</b>
directive for writing log messages to a file, and many MANY performance enhancements and
bugfixes. See the TODO.txt file in the source distribution for a full list.</li>
<li><b>Update: June 28, 2004</b> - Added <b>HTTPS</b> support to version v0.6.4</li>
</ul>
<p>New features in v0.5:</p>
<ul>
<li>Implemented <b>DIGEST</b> and <b>CERT</b> authentication methods. The CERT type is largely untested
(due to lack of A: access to certificates and B: knowledge of browser configuration for client
certificates) - if anyone wants to help with testing this, I'd appreciate it.</li>
<li>Implemented simple <b>clustering</b> (ie sharing of sessions between multiple Winstone instances).
See below for cluster configuration details.</li>
<li>Implemented optional <b>JNDI</b> support. This is just a memory-based Context intended for storing
lookups on <code><env-entry></code> and <code><resource-ref></code> references, but
it also includes a pooling JDBC DataSource object .... it's funny how you don't realise how important some
things are until you go without them ....</li>
<li>The control port has been modified to be more useful. See below for usage instructions.</li>
<li>The distribution jar is now available in two forms:
<ol>
<li><b>Complete version</b> (winstone.jar): This contains the complete winstone feature-set,
including AJP13 Apache connectors, Authentication/Realm support and Clustering support.</li>
<li><b>Lite version</b> (winstone-lite.jar): This is the core winstone feature-set only,
ie commonly used servlet features, as fast and reliable as possible, with unnecessary options
removed.</li>
</ol>
</li>
</ul>
<p>New features in v0.4:</p>
<ul>
<li>Implemented the <b><error-page></b> directive</li>
<li>Added object pools for request/response objects for performance reasons</li>
<li>The handler pools are now controllable via startup properties</li>
<li><b>Servlet reloading</b> is now supported (optionally - include
<code>--useServletReloading=true</code> at startup)</li>
<li>The initial <b>Authentication Model</b> is in place (see below for help). There are two base
classes that make it work: <code>AuthenticationRealm</code> and <code>AuthenticationHandler</code>.
Currently Argument-based and File-based realms (ie user/password details supplied via command-line args
or XML files) and HTTP BASIC and FORM authentication are implemented, but the others (DIGEST and
CERT authentication forms) will come soon.</li>
</ul>
<p>New features in v0.3:</p>
<ul>
<li>The request handler threads now use <b>monitors</b>, which allows them to exist beyond a single
request/response cycle. The benefit here is performance - it removes a serious bottleneck.</li>
<li><b>WAR files</b> are now supported via the --warfile attribute. If you specify a warfile in this
manner, it will be automatically extracted by the container to a temp directory, overwriting
only files that are older than the archive date.</li>
<li><b>Servlet attribute, session, and context listeners</b> (Servlet spec v2.3) are now fully supported.
The HttpSessionActivationListener class will be fully supported once the session transfer
is implemented.</li>
<li><b>Servlet Filters</b> (Servlet spec v2.3) are now fully supported.</li>
<li>There is now an <b>AJP13 connector</b>, which means Winstone will now work behind Apache/IIS/etc
using Tomcat's mod_jk. Try it out and see ... there's a section below on using the mod_jk connector.</li>
</ul>
</div>
<div class="section">
<h2><a name="xerces">Using Xerces as an XML parser (required for v2.4 webapps)</a></h2>
<p>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.</p>
<p>Anyway, to use Xerces, you'll need to download the latest Xerces-J parser from
<a href="http://xml.apache.org/xerces2-j/">here</a>, and copy xercesImpl.jar and xml-apis.jar
into a folder somewhere (name it "endorsed"). Putting them in the winstone/lib folder will not work,
because they must be in the system endorsed classpath to override the JDK internal XML parser.</p>
<p>Then add <code>-Djava.endorsed.dirs=<endorsed dir name></code> as a JVM arg to your
command line for starting winstone, eg:</p>
<pre> java -Djava.endorsed.dirs=/jdk/endorsed -jar winstone.jar --webroot=...</pre>
</div>
<div class="section">
<h2><a name="jasper">JSPs (aka using with Jasper)</a></h2>
<p>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.</p>
<p>Required steps:</p>
<ol>
<li>Add --useJasper to your startup command line, since
JSPs are disabled by default</li>
<li>
<p>Both the v1.x and v2.x versions of Jasper are supported. In order to turn on JSP compilation
in Winstone, you'll need to place the following jar files into the lib folder under the
current directory (or the folder identified by the --commonLibFolder directive).</p>
<ul>
<li><b>jasper-compiler.jar, jasper-runtime.jar, ant.jar, jsp-api.jar</b> -
Not supplied with Winstone. You can get this from the standard Tomcat binary download location.
Just download the latest Tomcat, and copy these three files into the lib folder
for Winstone. They will be in the tomcat_home/common/lib folder.</li>
<li><b>commons-logging-api.jar, commons-el.jar (Jasper 2 only)</b> -
These are required if you are using Jasper 2.0. You can get them from the
tomcat binary distribution or separately from the link below.</li>
</ul>
<p>All of these are available from the <a href="http://jakarta.apache.org/site/binindex.cgi">Jakarta download site</a></p>
</li>
<li>
<p>You'll also need <b>tools.jar</b>, and this is handled a little differently.
The ant javac compile task needs this to turn the generated .java files into
.class files at runtime. You should already have this in the <java_home>/lib folder
of your jdk.</p>
<p>There are two new startup arguments for Winstone --javaHome and --toolsJar. You
should only need to set --javaHome to make Jasper work properly. Your startup might
look like this:</p>
<pre> java -jar winstone.jar --useJasper \
--javaHome=c:\java\jdk1.4.2 \
--webroot=...</pre>
<p>Additionally, you can specify the exact location of the toolsJar file like this:</p>
<pre> java -jar winstone.jar --useJasper \
--javaHome=c:\java\jdk1.4.2 \
--toolsJar=c:\tools.jar \
--webroot=...</pre>
</li>
</ol>
<p>Newer versions of Jasper seem to use the Eclipse JDT compiler, and therefore don't require tools.jar.
You might want to try deploying the jasper related jars yourself - see if you can get it running with just
a JRE configuration. Shouldn't be difficult, just a little debugging of which jar files are necessary.</p>
<p><b>CHANGED:</b> Until v0.9.5, it wasn't necessary to add the jsp-api.jar, because winstone included it's own copy of the
JSP API classes. However, the JSP v2.1 spec mandates the use of JDK1.5 generics in the API classes, so in order
to continue supplying the API classes, Winstone would have to require JDK1.5 compilation as a minimum. Since a
large percentage of people use Winstone for it's small footprint, and PDAs running on older spec JVMs are affected by
this, it seemed more reasonable to just drop the JSP API classes and maintain the backwards compatibility.</p>
<p>I disagree with the Expert Group's penchant for trading away backwards compatibility in exchange for
spec features that are unnecessary (such as generics and XSD support). But at the end of the day, they call
the shots, so I just do what I can to minimize the downsides in practice.</p>
</div>
<div class="section">
<h2><a name="apache">Connecting to Apache</a></h2>
<p>These instructions are for beginners: if you know your way around Apache and Tomcat, you'll know what's going on here.</p>
<p>Download and install Apache for your platform (and obviously Winstone too), then follow these steps:</p>
<ol>
<li>Download mod_jk.dll/so into the apache modules directory</li>
<li>Add the following to the apache conf file (httpd.conf):
<pre>
LoadModule jk_module modules/mod_jk.dll
<Location "/<Winstone Prefix>/*">
JkMount /* ajp13
</Location>
</pre></li>
<li>Create a new file called workers.properties in the apache conf directory, with the following contents
<pre>
worker.list=ajp13
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
</pre></li>
<li>Start up Winstone, ensuring that the --ajp13Port=8009 is in the startup args. It's set to this
by default, but it's worth confirming.</li>
<li>Start up Apache and try connecting to your webapp on the apache port, with the Winstone
URL prefix. If it doesn't work, try looking at the apache error.log file for hints. If you get hex dumps, mail
them to the winstone-devel list, together with any stack traces winstone generated.</li>
</ol>
<p>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.
Additionally, Costin Manolache of the Tomcat team suggested I point out that the "jvmRoute" feature
(used for managing sticky session behaviour when clustering multiple Winstone's behind a single Apache)
is not supported. This may change in the future - we'll see how it goes.</p>
</div>
<div class="section">
<h2><a name="authRealms">Using Authentication Realms</a></h2>
<p>The 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.</p>
<ul>
<li>The web.xml part is the same for all webapps - you include the <code><security-constraint></code>
and <code><login-config></code> elements as required, eg (from the Tomcat examples web.xml):
<pre>
<security-constraint>
<display-name>Example Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/jsp/security/protected/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>tomcat</role-name>
<role-name>role1</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp/security/protected/login.jsp</form-login-page>
<form-error-page>/jsp/security/protected/error.jsp</form-error-page>
</form-login-config>
</login-config>
</pre></li>
<li>The AuthenticationRealm part is Winstone specific. Here you currently have three options:
<ol>
<li><b>ArgumentsRealm:</b> Here you simply add additional command line args for each user's password and
role list. Passwords are added with <code>--argumentsRealm.passwd.<username>=<password></code>,
and roles are added with <code>--argumentsRealm.roles.<username>=<role1>,<role2></code></li>
<li><b>FileRealm:</b> This is the same as the Tomcat <code>tomcat-users.xml</code> file.
Pass in the command line arguments <code>--realmClassName=winstone.realm.FileRealm
--fileRealm.configFile=<filename></code>, and it should work exactly the way Tomcat does by default.</li>
<li><b>Write your own:</b> You just have to extend the <code>winstone.AuthenticationRealm</code> class,
and override the appropriate methods (as the File and Arguments Realms do), and specify the class name in
<code>--realmClassName</code>.</li>
</ol>
</li>
</ul>
<p>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.</p>
</div>
<div class="section">
<h2><a name="cluster">Cluster support</a></h2>
<p>It 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.</p>
<p>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".</p>
<p>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:</p>
<pre>
java -jar winstone.jar ...< other options > ... \
--controlPort=<myControlPort> \
--useCluster \
--clusterNodes=<IP1:controlPort1>
</pre>
<p>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.</p>
<p>You would likewise set up the other instance with reciprocal options (ie changing the IPs and controlPort values
appropriately.</p>
<p>NOTE: There are some additional requirements on your web application for Clustering of sessions to be
successful.</p>
<ol>
<li>You need to include the <b><distributable/></b> element in your web.xml file. This tells Winstone that
your webapp is programmed correctly to support clustering. If this is missing, clustering will be disabled.</li>
<li>Any objects you add to the session must implement <b>java.io.Serializable</b>. This is required because
Winstone serializes the objects in the session over the controlPort to other nodes, and reconstructs the
serialized session at the destination. If you try to put a non-serializable object into the session,
Winstone will throw an exception reminding you to make all session objects serializable.</li>
</ol>
</div>
<div class="section">
<h2><a name="controlPort">Control port functions/protocol</a></h2>
<p>From 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. </p>
<p>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:</p>
<ul>
<li><b>0 (ASCII 48)</b> = shutdown</li>
<li><b>1 (ASCII 49)</b> = request search for a session</li>
<li><b>2 (ASCII 50)</b> = request list of currently connected cluster nodes</li>
<li><b>3 (ASCII 51)</b> = cluster node heartbeat</li>
<li><b>4 (ASCII 52)</b> = request reload of web application context</li>
</ul>
<p>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
<code>winstone.tools.WinstoneControl</code>. Try the following to get a usage statement:</p>
<pre> java -cp winstone.jar winstone.tools.WinstoneControl</pre>
</div>
<div class="section">
<h2><a name="jndi">JNDI support</a></h2>
<p>I 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.</p>
<p>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).</p>
<p>NOTE: JNDI support is disabled by default. It must be enabled using <code>--useJNDI=true</code></p>
<p>Configuration can be done in two ways:</p>
<ul>
<li><b><env-entry> elements</b> - This is the standard way to add simple objects, such as
sql strings or configuration integers/strings. For example:
<pre>
<env-entry>
<env-entry-name>test/hello</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>45</env-entry-value>
</env-entry>
</pre></li>
<li><b>Command line arguments</b> - This is for more complex objects that require attributes
to be created (JDBC DataSources for example). The syntax here involves adding a clause of the
kind <code>--jndi.resource.<resName>=<className></code> for each object to create,
followed by <code>--jndi.param.<resName>.<attName>=<attValue></code> for each
attribute required. For example:
<pre>
java -jar winstone.jar ...< other options > ... \
--useJNDI=true \
--jndi.resource.test=java.lang.Float \
--jndi.param.test.value=45.56
</pre></li>
</ul>
<p>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:</p>
<ol>
<li><b>url (REQUIRED)</b> - JDBC URL (<code>jdbc:mysql://db.widgets.com/db</code>)</li>
<li><b>driverClassName (REQUIRED)</b> - JDBC Driver name (eg <code>com.mysql.jdbc.Driver</code>)</li>
<li><b>username</b> - username for database authentication</li>
<li><b>password</b> - password for database authentication</li>
<li><b>maxConnections</b> - Maximum number of connections allowed in the pool. Default is 20</li>
<li><b>maxIdle</b> - Maximum number of idle connections allowed in the pool. Default is 10</li>
<li><b>startConnections</b> - The number of connections to open the pool with. Deafault is 2</li>
<li><b>keepAliveSQL</b> - The sql to execute on keep-alive (or checkBeforeGet) operations. Default is empty</li>
<li><b>checkBeforeGet</b> - If true, executes the keepAliveSQL before any connection is returned
from the pool. Default is true if the keepAliveSQL is defined</li>
<li><b>keepAlivePeriod</b> - Execute the keepAliveSQL on all unused connection every n minutes. Default is disabled</li>
<li><b>killInactivePeriod</b> - Kills excess unused connections every n minutes. Default is disabled</li>
<li><b>retryCount</b> - When the pool is maxed out, block and retry n times. Default is 1 retry</li>
<li><b>retryPeriod</b> - The period (in ms) over which the retry blocks. Default is 1000ms</li>
</ol>
<p>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:</p>
<pre>
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
</pre>
</div>
<div class="section">
<h2><a name="https">HTTPS support</a></h2>
<p>Somebody 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.</p>
<p>I recommend using a shareware tool called KeyStore Explorer, available
<a href="http://www.lazgosoftware.com/kse/index.html">here</a>. It's much easier than
all that messy CLI stuff.</p>
<p>The steps are basically as follows:</p>
<ol>
<li>Create an empty keystore of type JKS</li>
<li>Generate a key pair (Tools -> Generate Key Pair). I chose RSA 2048 bit, and used
"MD5 with RSA" for the algorithm. Set a password and remember it.</li>
<li>Generate a CSR (right click, Generate CSR).</li>
<li>Send the CSR to a Certifying Authority (CA) for processing. I used FreeSSL.com,
because it was only US$39 per year.</li>
<li>Once you get the approved certificate back, import it into the key store you
were using (Tools -> import CA reply). You should now have only a
key pair and a certificate. Save the key store, using the same password you used
before.</li>
<li>Start winstone with the following command:
<pre>java -jar winstone.jar --webroot=<webroot>
--httpsPort=443
--httpsKeyStore=<keystore file>
--httpsKeyStorePassword=<password></pre>
</li>
<li>Set your hosts file (/etc/hosts or c:/Winnt/system32/drivers/etc/hosts) to
point the name on your certificate to 127.0.0.1, then try to browse to
https://(name on certificate)/</li>
</ol>
</div>
<div class="section">
<h2><a name="accessLog">Access Logging</a></h2>
<p>From 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.</p>
<p>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:
</p>
<ul>
<li><b>--simpleAccessLogger.format</b>: Either "combined", "common", "resin" or a pattern made up of wildcards.
For example, the combined format string is:
<pre>###ip### - ###user### ###time### "###uriLine###" ###status### ###size### "###referer###" "###userAgent###"</pre>
but you can re-arrange this to be any pattern of the above wildcards with the --accessLoggerFormat
switch. Defaults to "combined"</li>
<li><b>--simpleAccessLogger.file</b>: A pattern for defining the files to log to. The default value is
<code>logs/###host###/###webapp###_access.log</code>, which splits the log files for different webapps
and hosts into directories. The wildcards <code>###host###</code> and <code>###webapp###</code> can be
moved around or even omitted. Omitting the wildcard will mean the access logs will be combined into
shared files (since the file name will be the same)</li>
</ul>
<p>For example, to enable Apache Combined style logging to separate files, use a command line like:</p>
<pre>java -jar winstone.jar --hostsDir=<vhostsDir>
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger</pre>
<p>Or to log just the date and URI for all hosts/webapps to a single file, use a command line like:</p>
<pre>java -jar winstone.jar --hostsDir=<vhostsDir>
--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
--simpleAccessLogger.format=###date###\ ###uriLine###
--simpleAccessLogger.file=/mylogs/access_log.txt</pre>
</div>
<div class="section">
<h2><a name="embedding">Embedding Winstone</a></h2>
<p>The design of Winstone has always allowed its easy embedding within another application. It's as simple
as:</p>
<pre> // 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(); </pre>
<p>From v0.8 though, there is also the ability to embed in the opposite direction: that is, to
<b>embed your warfile into the winstone JAR itself</b>. This allows an all-in-one container plus
web-application JAR file to be downloaded, and then unpacked at execution time.</p>
<p>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).</p>
<p>Now if you type: <code>"java -jar winstone.jar"</code>, your application should
automatically deploy as the ROOT web application. Try <code>http://localhost:8080/</code> to
check it out.</p>
<p>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".</p>
</div>
<div class="section">
<h2><a name="sessionPersistence">Session persistence across reboots</a></h2>
<p>From v0.9.5, if you start with --useSavedSessions as an argument, all sessions in the container will be
saved to disk after each request, and loaded on container startup. The effect is that sessions will
persist across reboots, instead of being lost (which is the default behaviour, or --useSavedSessions=false).</p>
<p>This is useful for development time, if only to prevent you from having to log in to your webapp every
time you restart the container. It does however come with a few costs / side effects to think about:</p>
<ul>
<li><b>Security:</b> The sessions are serialized to disk in the webapp temp directory (see the spec
for details) which is, by default, inside the system temp directory. If you are worried about people
being able to read these files on a shared machine, set the temp directory manually with
-Djava.io.tmpdir=<path></li>
<li><b>Speed:</b> Each time a request accesses a session, that session is re-saved to disk before the
request completes. This introduces a slight hit performance-wise, but it's after the request has released
the output stream, so there's good chance you won't notice any slow-down, except maybe under load or heavy
keep-alive usage.</li>
<li><b>Serializability:</b> You'll need to make sure anything you put in the session implements
java.io.Serializable (for obvious reasons). This follows the same rules about session contents,
as the "distributable" webapp / clustering feature, since it shares a large chunk of it's code.</li>
</ul>
<p>Please give this feature a try if you can, and let me know if you hit any problems. It is still a little
green around the edges, so any feedback or corrections will be appreciated.</p>
</div>
</div>
<div id="footer">
<ul>
<li><a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=98922&type=5" width="210" height="62" border="0" alt="SourceForge.net Logo" /></a></li>
<li class="last"><a href="http://www.java.net"><img src="http://today.java.net/images/javanet_button_170.gif" border="0" alt="Java.net Linked Project"/></a></li>
</ul>
</div>
</body>
</html>