Hi,

About 2 years ago (closer to 3) I started a sandbox experiment with the goal
of  refactoring tomcat to a smaller
and easier to embed variant. I think it's time to see what can be
contributed back to tomcat main branch, what can be
released, and what needs to be retired or moved out.

The code is organized in several relatively independent components, some of
them low-risk, some controversial -
I will start a separate thread with a proposal to merge back the first
component, then decide what to do with the
others based on the feedback I get here.


1. General tomcat-util and coyote improvements.

This should be the easy part I hope  - sandbox/tomcat-lite/tomcat-coyote
contains the code, just small additions to make it easier to code with
coyote. The only 'major' and backward-incompatible change is in RequestInfo,
replacing ObjectName with Object, it requires 2 casts in nio/apr ( JMX is
not available on some embedded platforms ).
There are few additions - Appendable, CharSequence in CharChunk/ByteChunk,
few small fixes, etc. There is also a new ObjectManager
that can be used to abstract JMX and/or better integrate with frameworks (
osgi, guice, other dep-injection ).

2. Examples and extensions for coyote for 'standalone' use.

As we know, coyote implements the HTTP protocol, catalina implements the
servlet spec. There are cases where you may
just want a small http server embedded in your app ( but not full servlets),
or maybe you want to load-test/optimize coyote itself.
There are several Adapters - including a conversion of the dav servlet
(default servlet) from tomcat, mapping, startup code, examples.

I don't know if we want to support 'standalone coyote' - but having the
adapters in the main branch ( marked as
example/unsupported ) shouldn't hurt anyone, and may help people working on
coyote. It works quite well as a server on
very small devices ( like a storage server or phone, with jamvm or on the
android emulator )


3. A new connector and http client

This will probably be controversial :-), but there are no deps between the
rest of tomcat-lite and the new connector - all works
just fine with the apr/nio connectors. It is not intended as a replacement,
but as a low-end ( or high-end) alternative.

The reasons I wrote it:
- wanted to see if the apr/nio code could be merged ( lots is duplicated ).
I think SelectorThread is a good abstraction and can hide the
details of apr/nio.
- was quite unhappy with http client - wanted a non-blocking http client,
and simpler.
- nio/apr connectors were a bit too big for embedded
- I wanted to write a fast proxy servlet - but  comet didn't support enough
non-blocking behavior (detached operation, both
input and output blocking). And of course - the http client for proxy needed
to be non-blocking. See the ProxyAdapter as example.

Again, I don't think adding it to the main branch would hurt ( not enabling
it by default, marking it as 'in progress', etc) - but
I can move it to sourceforge or leave it in sandbox until it's more
appealing. It is missing SSL ( I'm working on it ) and many
of the config flags ( easy to add back ).

The code is actually based on the existing connectors - I started with the
code in apr connector, then abstracting all that was
apr or nio specific in SelectorThread ( SelectorThreadApr is not submitted,
but at some point worked and shouldn't be hard to fix),
then refactored http parsing code to be fully non-blocking ( nio has this I
think ), and added support for client-mode as well.

The client should be faster and simpler than apache http-client, and
currently uses coyote APIs ( Request, etc ) - it is
quite convenient if you want to just proxy a request to a different server.
Of course, it is quite tomcat-specific, but if there is
interest it should be used without a server.

4. Few filters and servlet code that can be used with any server - and some
tomcat-independent interfaces to better integrate them

Refactored from Catalina Valves - the idea was that Filters can be used
instead of Valves and be more generic (
Valves were developed before or at same time with Filter standardization ).
The benefit is that code could be reused
in other engines - like next point, tomcat-lite :-)
The filters provide same services as the original valves - but with no deps
on catalina.

This can be used if for example you want to have the same auth code on
different servlet engines. I'll send more
explanations when I get to this - IMO it would be great for the servlet
world if tomcat moves away from Valves for
 some extensions, when they can be done with filters ( and very light
additional container
 interfaces that could be ported easily to other engines )

5. Tomcat-lite - the servlet engine impl

Again, this started with catalina code, I replaced Valves with Filters,
removed most of the layers ( listeners, etc ) and
kept only the core code. Another major change is removal of all 'sandbox'
support - 10 years ago sandbox was important,
today we have virtualization and improvements in multi-process java.
Removing the sandbox - and the facade objects that
were needed to support proper isolation in sandbox - greatly reduces the
size and simplifies the code ( and reduces memory
footprint ). Full tomcat-lite ( including coyote, servlet.jar - no jsp ) is
about 700K, coyote-standalone is ~400K, core code is in a single package and
uses the plain filters/servlets for most features ( auth, etc ).

The watchdog is passing - I didn't try the official TCK. BTW - there is also
a port of watchdog to junit ( and testNG ) to make it
easier to run in an IDE. There is some JSP support - but not passing
watchdog.

If you read this far - I don't want to start a flame war,  but I appreciate
all feedback :-). My current goal is to
'graduate' the first 2 components, the others can stay longer in sandbox or
be moved out - but since they rely on
the first 2 I would have to clone a lot of tomcat code. I think 4 would also
be nice for tomcat, allowing people
to extend tomcat by using easier interfaces ( and have the extensions easily
ported ). I don't mind too much if 3 and 5
are not accepted at this point, I'll move them out or try again later :-)

I think moving forward, for tomcat-7 and beyond - it would be worth
reconsidering some of the 10-year-old decisions, and
tomcat-lite can be a good example on how things can be done differently:
- Valves/LifecycleListeners versus plain Filters and listeners
- configuration and better integration with frameworks (
JMX/dep-injection/etc)
- sanbox support
- layers and complexity


Costin

Reply via email to