Answers |
How do I make hits on
'http://www.myserver.com/' go to a servlet? |
|
There are various approaches to this. Several involve
'mod_rewrite', so check out the docs for that if the following does not suite you. Another
possibility is to use JServSSI in conjunction with the DirectoryIndex directive (in
srm.conf, or a local '.htaccess' file)
DirectoryIndex index.jhtml
index.jhtml:
<SERVLET CODE="com.myserver.www.HomepageServlet">
Error! Page not parsed.
</SERVLET>
|
When will next
release of Apache JServ be ready? |
|
As of today there were exactly 39.342 unidentified bugs.
Identified bugs have mostly been fixed, though. Since then 9.34 bugs have been fixed.
Assuming that there are at least 10 unidentified bugs for every identified one, that
leaves us with 39.342 - 9.32 + 10 * 9.34 = 123.402 unidentified bugs. If we follow this to
its logical conclusion we will have an infinite number of unidentified bugs before the
number of bugs can start to diminish, at which point the program will be bug-free. Since
this is a computer program infinity = 3.4028e+38 if you don't insist on double-precision.
At the current rate of bug discovery we should expect to achieve this point in 3.37e+27
years. I guess we'd better plan on passing this thing on to our children.... -
paraphrased from the 'fvwm2' man page. ;)
In short, we don't know, but if you'd like to see it happen faster, you're welcome to
join the development group. |
When I try to startup Apache
JServ I get an error message starting with "java.lang.NoClassDefFoundError:
javax/servlet/...". What's wrong? |
|
You need to have the JavaSoft Java Servlet Development
Kit 2.0 installed and jsdk.jar visible in your classpath when Apache JServ starts. These
classes are the definitions of the Servlet API and you need to download them directly from
the servlets web site. |
Why do I get
'Connection from host/address refused due to authentication failure'? |
|
One common cause for this is people attempting to
connect to Apache JServ with their web browser. Apache JServ is not an
HTTP server. You cannot connect directly to it with a web browser by adding the Apache
JServ port number to the URL. You must configure a web server to relay requests for
servlets to the Apache JServ engine. At present, the only supported web server is Apache,
but the protocol used between the web server and Apache JServ is well-defined, so adding
support for other web servers is possible. Another common cause is people not
configuring their security environment properly. For security reasons, connection
authentication is enabled by default. Then, in order to correctly perform the connection
authentication, both the module and the servlet engine must share a common secret key that
must be exactly the same. Another issue is the IP address filtering that
is performed automatically by Apache JServ to avoid risks of denial of service attacks.
You must enable at least one host to be able to communicate with Apache
JServ. |
Where can I find
examples of session management? |
|
JavaSoft have written a write paper on how they designed
the JDC. This can be found at http://developer.java.sun.com/developer/technicalArticles/#jdc.
|
What methods/packages exist to
enhance the presentation of my servlet site? |
|
Simple servlets will contain something like:
PrintWriter out = req.getWriter();
out.println("<HTML>");
...
out.println("</HTML>");
For larger servlets, where presentation is important, this is not ideal for many
reasons. For example, if a web designer was tasked with designing the look and feel of the
site, they may not be comfortable editing and compiling Java servlet programs. There are
two mainstream solutions to this problem:
Page Compilation is when servlets are compiled and run on-the-fly by the web server
from Java code embedded in the web page. JSP is described at http://java.sun.com/products/jsp/index.html.
GnuJSP is a free implementation of the JSP standard. You might want to check it out at http://www.nmg.nl/~vinny/gnujsp/. Another
implementation called GSP, can be found at http://www.bitmechanic.com/projects/gsp/.
Template System, is when you base your page layout in an HTML template. A few Java
Apache members have created a template package, which has not yet been packaged and
released. It can be checked out using anonymous CVS from the same repository as Apache
JServ as the module 'jserv_utils'. See the CVS instructions on the Java Apache Project web site for more information on
this. |
How do I create
different work areas for several developers? |
|
Using servlet zones, you can map a different directory
and set of servlet repositories and class paths for each user, e.g.,
www.urlstuff.com/bob/<bob-servlets>
www.urlstuff.com/alice/<alice-servlets>
etc.
The different developers will share a single jserv.properties file, which is
actually pretty convenient since this contains stuff that typically doesn't need to vary.
Each servlet zone gets its own configuration file.
You could also setup separate virtual hosts, in which case each developer would have an
even more separate environment in which to run cgi, servlets, etc. it's really easy to
setup virtual hosts, and it's how I do my own work even as the sole user of my machine.
The different virtual hosts would still need to share the jserv.properties file.
For more information on servlet zones and how to mount them on different network
environments, go here. |
Why do I get class
not found errors for servlet classes in javax.* when compiling Apache JServ even
though my classpath is correct? |
|
Some java compilers can't handle compressed jar files.
The solution is to decompress the jar file: jar xf jsdk.jar
jar cf0 jsdk-uncompressed.jar javax sun
(that's a zero after "cf", not the letter "O") then update your
makefiles to point to the uncompressed jar |
When my servlet
gets following URL http://www.server.com/servlets/cal?name=foo+bar+&calsystem=foobar&cal=foo@bar
and I try to make sense of it in servlet's doGet(req,res) method with HttpUtils.parseQueryString() ,
I get {calsystem=[Ljava.lang.String;@1dce128e,
cal=[Ljava.lang.String;@1dce127c,name=[Ljava.lang.String;@1dce12a8} - the key values
look just fine, but the value fields seems to have something wrong. What is it? |
|
As you can see from the parseQueryString source
(below), the value of each hashtable entry is an array of one or more strings. If you do
this:
Hashtable params = HttpUtils.parseQueryString(req.getQueryString());
String name = ((String[]) (params.get("name")))[0];
you should attain your heart's desire. The javadoc for this function is wrong, in that
it implies that arrays will only be used if a parameter is repeated. In my opinion, it's
better to always return String[]s and have then be length 1 in some cases, rather than
make people check every time whether they got an array or a single object. The string
"[Ljava.lang.String;@1dce128" means "an array of Strings", which
should provide a hint as to what is going wrong. |
What do I put in my
Apache Configuration file for the module line? |
|
|
Apache JServ 0.9.x |
Apache JServ 1.0.x |
Apache 1.2.x |
Module jserv_module mod_jserv.o |
Module jserv_module modules/jserv/mod_jserv.o |
Apache 1.3.x |
AddModule jserv_module mod_jserv.o |
AddModule jserv_module modules/jserv/mod_jserv.o |
Note: If you're using Apache 1.3 and you use APACI, you can do this simply by adding a
"--add-module=modules/jserv/mod_jserv.o" option to your command line invocation
of 'configure'. And if you build Apache JServ as a DSO, you don't need to recompile
Apache. |
I have a directory
within my servlets directory and things break when I try to use http://www.server.com/servlets/test/TestServlet,
but when I put TestServlet directly in the servlets directory and remove the
"test" from the URL, things work just fine. Is this a bug? |
|
No, this is not a bug but a wanted feature. This problem
derives from the way Java structures classes into subdirectories per package name. People
suffer similar problems writing non-servlet code. (we have a love-hate relationship with
this approach: it's clean, but it creates deep directory trees.) Java would expect a file
called $DIR/test/SimpleServlet to have the fully-qualified classname
test.SimpleServlet . It looks in the 'test' subdirectory of each directory in the
classpath for files in the 'test' package.
The module currently converts a request for test/SimpleServlet into a request for the
class test.SimpleServlet. It finds the class file, but gets confused because the file
actually contains a definition of the file 'SimpleServlet'. In short: make sure the
package name declared in the class matches the directory structure where the class file is
located.
To fix this particular problem: declare the servlet using a proper package name:
org.dummy.test.SimpleServlet, compile it into
$ROOT/servlets/org/dummy/test/SimpleServlet.class, and make your ServletPath
$ROOT/servlets. Add an alias or servlet.simple.code property to generate a shorter URL if
you like. (Thanks to Martin Pool) |
Where can I get more
information on servlets (JSDK, specification, sample code, case studies, tutorials,
examples)? |
|
JavaSoft servlet web site is
the best place since it has updated link to almost all servlet resources worldwide. |
Why servlet API
classes were removed from JDK 1.2beta3 on? |
|
To allow faster update cycles. |
Why do I get lots
of errors when I try to build Apache JServ? |
|
Try to update to a recent version of GNU Make. |
I see a lot of CPU usage
even though I'm not running any servlets. Can I change this? |
|
This is caused by a problem due to the combination of
green threads scheduling and asynchronous garbage collecting. If you are using a platform
that have a native thread implementation JVM (like Solaris 2.6 for example), you should
consider upgrading. If you are stuck with a green thread implementation then you may try
to turn off asynchronous garbage collection by adding a
wrapper.bin.parameters=-noasyncgc
directive to your jserv.properties file. This lower considerably the CPU usage
(0% when idle). On the other hand, when memory is low, the garbage collector runs
synchronously and decreases performance. (Thanks to Francis J. Lacoste) |
I have Solaris
and all the Java classes have compiled correctly, but a "make install" fails
miserably. What's wrong? |
|
Make sure your path is using /usr/ucb/install |
Why my classes are
not reloaded even if autoreloading is enabled? |
|
Probably because Apache JServ finds them in your classpath
and any class found in the classpath is considered a system class and cannot be reloaded. |
Why Apache JServ log file
gets so big? |
|
You may want to disable some log channels in your jserv.properties
to avoid request and response tracing which are usually very wordy. |
Why do I keep getting
UnsatisfiedLinkError? (or) Why won't my servlets using native code run? |
|
Servlets using native libraries must be put in the
classpath, otherwise you will get a java.lang.UnsatisfiedLinkError because in JDK1.1 a
class with native methods can't be loaded by custom class loaders (servlet class loader). |
Can I use different
UIDs/GIDs for different servlets or virtual hosts? |
|
Yes, you can! The complete separation
between the web server and the server engine allows you to connect multiple servlet
engines to the same web server. If these servlet engines are started in standalone mode
using the wrapper with different UID/GID, you end up having multiple secured servlet
environments. Of course, this requires a different JVM for each secured servlet
environment. For this reason, future releases will include a servlet sandbox to guarantee
a comfortable security level without requiring multiple JVMs. |
Which one is the right
name: JServ, mod_jserv or Apache-JServ or Apache JServ? |
|
Apache JServ is the right name. Please,
avoid the use of other denominations because "JServ" is a registered trademark
we don't own and "mod_jserv" is somehow misleading since it should be used to
refer only to the Apache module used to communicate with Apache JServ. |
Why the JSDK is not
redistributed with Apache JServ even if the license says it is freely redistributable? |
|
We know this sucks but there are some claims in Sun's
license that simply don't fit with our open source model because we may get sued for
problems found in their code even if we didn't touch it. To avoid eventual legal problems
we decided not to ship it. |
So, why didn't you
implement your own servlet API classes following the spec? |
|
Well, we thought about it but we decided to stick with
JavaSoft's to avoid platform incompatibility. |
How can I use
simple load-balancing for my servlets? |
|
This can be done with optional mod_rewrite module, a a
rule-based rewriting engine to rewrite requested URLs on the fly. The idea is to rewrite
incoming URL with different Servlet mount points in order to be able to distribute
requests on different Apache JServ's. In the following sample, a random load-balancing
is performed on 3 servlet engines (but mod_rewrite can make more for you).
- Enable the
mod_rewrite module in the server build Configuration file making
sure that mod_jserv stands before the mod_rewrite's line, as module's as
module's execution order is dependant of the (reverse) order in this file.
AddModule modules/jserv/mod_jserv.o
../..
AddModule modules/standard/mod_rewrite.o
For win32 systems, you just need to uncomment the mod_rewrite directive up on top of
httpd.conf
LoadModule rewrite_module modules/ApacheModuleRewrite.dll
- Rebuild apache (not needed for win32 systems).
- Configure Apache to start Apache JServ manually (in httpd.conf)
ApJServManual on
- Configure Apache to distribute servlet execution over different servlet engines
depending on URL
ApJServMount /servlet1 ajpv11://host1:port/zone
ApJServMount /servlet2 ajpv11://host2:port/zone
ApJServMount /servlet3 ajpv11://host3:port/zone
ApJServMount /defservlet ajpv11://host1:port/zone
- Create the load-balancing config file (/usr/local/apache/conf/load_balancer.txt)
jserv servlet1|servlet2|servlet3
- Configure Apache to enable URL rewriting
RewriteEngine on
RewriteLog "/usr/local/apache/logs/rewrite.log"
RewriteLogLevel 9
RewriteMap mountservlet rnd:/usr/local/apache/conf/load_balancer.txt
RewriteRule /servlets/(.*)$ /${mountservlet:jserv|defservlet}/$1 [PT]
Note: this load balancing method works only for stateless servlets. If sessions are
created by the servlet, there is the chance that requests on the same session are handled
by different servlet engines which, by now, have no way of sharing sessions between them.
A complete load balancing schema will be implemented in future versions of Apache JServ
and won't use external programs/modules but they will be handled internally. (Thanks to
Jean-luc Rochat) |
How can I
use tricky load-balancing/fail-over/manageability for my servlets? |
|
Use the previous sample, and create a "watchdog
program", that is able to delete an entry in the load_balancer.txt file. |
After Apache JServ is
installed, I can't get servlets to run. I get this error message: "Received empty
servlet name" or "Status: 400 Bad Request Servlet-Error" or
hangs for a long time. What's wrong? |
|
Two common mistakes may generate such behavior:
- you are trying to connect directly to the port Apache JServ is listening on (usually
8007). Eg. the following is usually wrong:
http://host:8007/servlets/HelloWorldServlet
This is doesn't work because Apache JServ is not an HTTP server, but an AJP server (see
Apache JServ Protocol for more information) and does
not understand HTTP requests on that port. You should request servlet directly to your web
server using the HTTP port for your virtual host (usually the default HTTP port 80), in
this case
http://host/servlets/HelloWorldServlet
- if the above doesn't apply or doesn't correct the problem, make sure authentication
settings (enabled/disabled) are matched on the two sides. In fact, if the two sides don't
match, this generates AJP fault states and bad-request type errors.
|
I want to enable
connection authentication. How do I generate the needed secret keys? |
|
You don't need any special tool but just a little
fantasy. A secret key could be any file (even an image could do the job) with any length
that should be really hard to guess and protected from untrusted access. The
authentication procedure needs to compute an MD5 hash for that file and it's complexity
(time of execution) is linear with the length of the secret key file. For this reason, as
long as the size of the secret key is not known, even a few dozen bytes would do the job
perfectly without security hazards and will reduce the authentication overhead. Note that
both the module and the servlet engine must use exactly the same secret key (binary copy). |
How do I create an
image with a servlet, for example, a graph out of a list of values? |
|
Servlets allow you to specify the content type of the
response. This ability let you generate dynamic images simply mapping the <img> tag
with the proper servlet URL. To do this, you need to generate an off-screen image object
and send it encoded in your favorite image format. Free GIF image encoders are not
available due to patent restrictions, while JDK 1.2 contains a JPG image encoder (and few
others like PNG may be added in the future). To create an off-screen image you could
follow these guidelines:
Frame f = new Frame();
f.addNotify() // <-- this creates a "frame peer", which makes it all work
Image img = f.createImage();
doMyPaintImage(img.getGraphics());
(etc.)
Note that it apparently needs to be a Frame since Canvas doesn't seem to work. It
probably just calls for the toplevel window component to do the job. (Thanks to Bjorn
Sandberg). |
When I call
HttpUtils.parsePostData() all the POST data is eaten by Apache Jserv. Is this a bug? |
|
A servlet engine is only supposed to read (and thus eat)
the POST data by calling parsePostData() when parsePostData() would actually be able to
handle it, i.e. the content-type is "application/x-www-urlencoded". If the
content-type is something else, like "multipart/form-data" (or
"text/html" when a HTML document is PUT from Netscape Composer), the POST data
should be left to the servlet itself to handle. (Thanks for Vincent Partington) |
How come I don't get any log
messages even if I enabled tracing and all trace channels? |
|
In the latest releases, the directive trace was
replaced with log, along with all other instances of trace in the jserv.properties
configuration file. You should change any directives that contains "trace." with
"log." |
Note: if you have a question that
should be listed here (even if you don't have the answer) or have a better answer for one
of these questions, let us know it on the mailing lists. Every possible help is greatly
appreciated. Thanks in advance. |