Resin 1.1
FAQ
Reference
JavaDoc
Demo
Java Tutorial
Technical FAQ
I just get a 404 for JSP or Servlets!
Make sure you try the following: First, check your configuration with the standalone httpd. Both httpd and srun use the same configuration file, so the results should be identical. Check http://localhost/caucho-status. That will tell if mod_caucho has properly read the resin.conf. If caucho-status fails on Apache, the problem is in the mod_caucho/iis_srun installation and the Apache httpd.conf. If caucho-status fails on IIS, try http://localhost/scripts/iis_srun.dll/caucho-status directly. If this fails, IIS can't find iis_srun.dll. Check that iis_srun.dll is in c:\inetpub\scripts. Make sure that your IIS host has a mapping from /scripts to c:\inetpub\scripts and that the /scripts has execute permissions. If caucho-status shows the wrong mappings, there's something wrong with the resin.conf or the pointer to resin.conf in httpd.conf. If caucho-status shows a red servlet runner, then srun.sh hasn't properly started. If you get a "cannot connect to servlet engine", caucho-status will show red, and srun.sh hasn't started properly. If srun.sh doesn't start properly, you should look at the logs in resin1.1/log. You should start srun.sh -verbose to get more information. If you get Resin's file not found, the Apache configuration is good but the resin.conf probably points to the wrong directories. If the error message is from Resin, your app-dir is probably set wrong. Remember servlets belong in "app-dir"/WEB-INF/classes. Before you ask any questions on the list, you should be able to answer the following questions: Does httpd standalone work? What does the /caucho-status show? Is the 404 coming from your web server or from Resin? If you don't answer these questions in your mail, the mail will probably be ignored. Victor A. Salaman writes: This may sound elementary... But check for these common pitfalls: Check in your browser that it's not configured to use a proxy server.. and if it is, make it bypass local accesses or disable proxying altogether (If you are using IE, just go to Tool/Options/Connection and at the bottom you'll see the proxy stuff! Make you are running httpd.exe.... A lot of people try to use "srun.exe", and this is just a servlet runner.... Modify your resin.conf file and add this line right after "<caucho.com>" <log id="/" href="stderr:"/> After you do this, execute httpd.exe and see what pops up....
IIS - caucho-status fails
Try looking at http://localhost/scripts/iis_srun.dll/caucho-status. If this fails, IIS can't use the iis_srun.dll plugin. The problem is probably one of the following: iis_srun.dll isn't in c:\inetpub\scripts. The IIS host is missing the /scripts virtual directory. /scripts doesn't have proper execute permissions. Resin's IIS module needs the /scripts virtual directory to contain iis_srun.dll. If you create a new IIS virtual host, you must create a /scripts virtual directory that points to d:\inetpub\scripts. When the Resin ISAPI filter detects a JSP page or servlet, it rewrites the URL to /scripts/iis_srun.dll/test.jsp. IIS will then execute iis_srun.dll as an ISAPI extension. If your virtual site is missing the /scripts directory, IIS can't find the ISAPI extension.
Apache/IIS cannot contact to servlet runner
The particular error message is something like:
Cannot connect to servlet runner at localhost:6802
The servlet runner process needs to be started. In resin1.1/bin the srun executable will start the servlet runner. The srun executable will start Java and wait for connections from the web server.
File not found
The web server (IIS or Apache) and the servlet runner (srun), need to find the web pages. The resin.conf file configures srun. You need to add a 'app-dir' property, to tell srun where to look for the root directory.
<caucho.com> <http-server app-dir='d:\InetPub\wwwroot'> <servlet-mapping url-pattern='*.jsp' servlet-name='com.caucho.jsp.JspServlet'> </http-server> </caucho.com>
browser returns test.jsp source
If you're running Resin with IIS or Apache, the web server might not know how to handle *.jsp files. On Apache, the httpd.conf needs to add Resin. On IIS, the IIS configuration needs to dispatch *.jsp files to srun_iis.dll. Both may need restarting to see the changes. To test if this is the problem, stop the srun executable. If you browse http://localhost/test.jsp, you should get the 'Cannot connect to servlet runner' message.
java.net.BindException
You'll get this exception if you try to start two Resin instances using the same port. You'll need to stop the first one. On Unix, the dramatic way of stopping Resin is to kill the wrapper.pl script:
unix> ps -ef | grep wrapper.pl ferg 19441 761 0 08:33 pts/0 00:00:00 grep wrapper.pl unix> kill 19441
Where do I put my jars and classes?
First, look at the standard installation and check the HelloWorld example. The HelloWorld source is in resin1.1/doc/WEB-INF/classses. Resin will automatically compile that source when running the demo and put the class in the same directory. If you change the app-dir to /usr/local/apache/htdocs, servlets and beans will belong in /usr/local/apache/htdocs/WEB-INF/classes. Until you get your first servlets working, don't try to create your own web-apps. When you do start working with web-apps, look at the guest book examples to see where beans and servlets belong. You can also change the default location with the <classpath> directive. Application jars belong in WEB-INF/lib and standard libraries, like JDBC drivers, belong in the global classpath. In general, you should put standard libraries in the global classpath. Resin has several equivalent methods to add a jar to the classpath: Add the driver to the CLASSPATH environment variable. Start Resin with a -classpath argument including the driver. Put the jar file in resin1.1/lib. Put the classes in resin1.1/classes. Only the last two will be automatically reloaded when the class or jar changes. For the first two, you'll need to restart Resin. You can see Resin's global classpath by starting it with the -verbose option:
unix> httpd.sh -verbose
You must restart Resin to pick up the new classpath. When using the Win32 Resin, you must quit the Resin application. Just pressing the stop and start buttons will not suffice.
JSP uses the wrong JDK version
On Win32, Resin and Caucho JSP try to find Java in the following order: The command-line argument, -java_home The environment variable JAVA_HOME The registry, using JavaSoft's CurrentVersion of the JDK. Following the PATH of the java executable. To find out which Java version Caucho JSP is using, use the '-version' argument on the command line:
resin1.1> bin/httpd -version
Apache won't start on Win32
The error message might be something like:
"Syntax error on line 785 of C:\PROGRA~1\APACHE~1\APACHE/conf/httpd.conf: Cannot load c:\resin1.1\srun\win32-1.3.6\mod_caucho.dll into server:"
Usually, this is a path problem, for example, you may have used "win-1.3.6" instead of "win32-1.3.6". It will also happen if the dll is incompatible with the Apache version. Apache 1.3.6 is compatible with Apache 1.3.9. If you're using a different version, send us a message and we'll make sure you get the right compiled version.
How to get debugging information
Resin can write debugging information to standard output or to any file. To add debugging information add a log directive to the resin.conf file.
<caucho.com> <log id='/' href='stderr:'/> </caucho.com>
href can be any path. stderr: is perhaps the most useful. id can select which portions of Resin to get logging information. Here are some useful patterns:
/ | Debug everything
/caucho.com/jsp | Debug jsp
/caucho.com/jsp/java | See the JSP generated Java
/caucho.com/jsp/js | See the JSP generated Java
/caucho.com/xsl | XSL debugging
/caucho.com/tcp-server | See thread creation and deletion
/caucho.com/http | HTTP related information
Resin doesn't update changed servlets and JSP pages
Resin has a delay for testing updated servlets and JSP pages. The configuration variable for both is 'class-update-interval' in resin.conf. It's an application-level variable. The default is 15 seconds. So Resin will only check every 15 seconds for an updated page. You can set this value to 0 for development work.
<http-config class-update-interval='0'> ... </http-config>
If you want Resin to check servlets for updates every hour, your resin.conf might look like:
<http-config class-update-interval='3600'> ... </http-config>
Java JSP doesn't compile
java.lang.NoClassDefFoundError: sun/tools/javac/Main The JRE does not contain a Java compiler. You either need to get the JDK or use another compiler. To configure another compiler use:
<caucho.com> <java compiler='/usr/local/bin/jikes'/> ... </caucho.com>
Exceptions don't have line numbers
For debugging, it is crucial to get proper line numbers. Unfortunately, Java JITs (just-in-time compilers) remove the line numbers. For development we recommend you turn jit compiling off. Start the server with the JIT compiler turned off. On Unix you can use:
unix> httpd.sh -nojit
install.sh doesn't compile mod_caucho.c on Linux
This appears to be an Apache 1.3.9 bug. The loader configuration is missing from apxs (usually in /usr/local/apache/bin/apxs). For Solaris, the configuration should look like:
my $CFG_CC = gcc' my $CFG_CFLAGS_SHLIB = '-fpic -DSHARED_MODULE'; my $CFG_LD_SHLIB = 'gcc'; my $CFG_LDFLAGS_SHLIB = '-shared';
How do I get exception line numbers?
For debugging, it is crucial to get proper line numbers. Unfortunately, Java JITs (just-in-time compilers) remove the line numbers. For development we recomment you turn jit compiling off. On unix, start the server as:
unix> httpd.sh -nojit
How do I enable session url rewriting?
This is only supported in Resin 1.1.b1 and later. You can disable cookies in the resin.conf with a configuration like
<http-server> <session-config enable-cookies='false' enable-url-rewriting='true'/> </http-server>
How do I keep the generated .java files?
The generated .java files are put in <java work-dir>. By default, that's /tmp/caucho on Unix and \temp\caucho on Windows.
How do I use multiple resin.conf files?
This is especially important if you want to use a different workspace for development than deployment. Just call the `httpd` or `srun` executable with the -conf flag.
unix> httpd.sh start -conf devel.conf -verbose
d:\> httpd.exe -conf devel.conf -verbose
ClassNotFoundException for servlet or bean
First check that the class is in the right location. In the standard configuration, Java classes belong in resin/doc/WEB-INF/classes. If you're using Resin's autocompilation, the Java source file must be in the same location. If you're using the automatic compilation, check that the package in the *.java file matches its location.
Class work.test.MyBean not found
Your jsp file must import the proper packages so Java can find the bean. Also, the bean should typically be in resin/doc/WEB-INF/classes.
<%@ page import='test.*' %> <%= MyBean.printData() %>
Also, if your bean has no package, you need to import the bean by name:
<%@ page import='MyBean' %> <%= MyBean.printData() %>
Resin can't load my JDBC driver
Your JDBC driver must be in the global classpath. Both Resin's DBPool and the JDBC mechanism can only load classes in the global classpath. Since WEB-INF/lib and WEB-INF/classes use special class loaders, neither JDBC nor Resin's DBPool can find them.
My character encoding is messed up
Resin has an optimization, static-encoding, which assumes that your page is written in the same encoding as you're printing. That usually works, but some people write a page in one encoding, like Shift-JIS and print it in UTF-8. To make that work, you need to disable static-encoding.
<jsp static-encoding='false'/>
Here's an example page that would need to disable static-encoding:
<%@ page contentType='text/html; charset=Shift-JIS' %> <% response.setContentType("text/html; charset=UTF-8") %> ...
Form character encoding doesn't work
A POST request with application/x-www-form-urlencoded doesn't contain any information about the character request. So Resin needs to use a set of heuristics to decode the form. Here's the order: request.getAttribute("caucho.form.character.encoding") The response.setContentType() encoding of the page. The character-encoding tag in the resin.conf. Resin uses the default character encoding of your JVM to read form data. To set the encoding to another charset, you'll need to change the resin.conf as follows:
<http-server character-encoding='Shift_JIS'> ... </http-server>
Error 405 resource not found
Usually, this is a servlet extending HttpServlet and implementing doGet but not doPost. If you send a POST request, like a form, to a servlet that only implements doGet, you will get 405 resource not found.
Why so many processes on Linux?
On Linux, each native thread is displayed as a separate process by 'ps -auxw'. Don't worry, those processes are extremely lightweight.
How do I run Resin with a debugger?
Eric Hansen writes: A lot of people have been asking about a suitable debugging environment for resin. I have been using JPadPro with the updated version of jdb. (I found that the jdb.exe that ships with the JDKs 1.1.8 and 1.2.2 do not like all the classloading that happens in a servlet engine.) Instead, try using the JavaTM Platform Debugger Architecture (JPDA) http://www.javasoft.com/products/jpda/. Just unzip the executables, dlls, and docs files in some directory. I chose c:\jdb. My project class files are in: c:\local, my resin1.1 files are in: c:\resin1.1, and jdk1.2.2 files are in c:\jdk1.2.2. To start up the debugger issue the following command (you may need additional classfiles in the classpath, etc.):
C:\jdb\bin\jdb.exe -classpath "C:\resin1.1\lib\jdk12.jar;C:\resin1.1\lib\jsdk.jar;C:\resin1.1\lib\jsdk22.j ar;C:\resin1.1\lib\resin.jar;C:\jdk1.2.2\jre\lib\rt.jar;C:\jdk1.2.2\lib\tool s.jar;C:\local" com.caucho.server.http.HttpServer -conf c:\resin1.1\conf\resin.conf > run
You can access the webserver at: http://localhost/ or http://localhost:8080/, etc. depending on the port number you picked. You should be able to issue the usual jdb commands. Check the list of commands by doing: help or ? at the jdb> prompt. I use jdb with JPadPro (http://www.modelworks.com). It has some built-in scripts to work with jdb. It is tailored to work with the jdb that ships with the JDK, which has a slightly different response syntax from the JPDA version of jdb. Since all of JPadPro's commands are written in JavaScript, you can easily modify the commands to parse the different command/response syntax in JPDA. Or you could even modify the jdb code to have it issue similar commands, since JPDA ships with source code for jdb. However, it's probably easiest to modify the JavaScript. (Check in Tools/Java/JDK/Debugger/*, including onBreakPointHit, setBreakPoint.) I modified setBreakPoint, for example, to look like this:
function BreakpointResult(data, breakpoint) { var index = data.indexOf("Breakpoint set"); var index2 = data.indexOf("Set breakpoint request"); if ((index == -1) && (index2 == -1)) { breakpoint.active = false; gOutput.writeMessage(breakpoint.getPath(), breakpoint.getLineIndex(), "Setting breakpoint to inactive - breakpoint is not positioned on a valid line"); } }
This is because the old version of jdb issued the syntax: "Breakpoint set...", and the new one issues the command "Set breakpoint request...". You get the picture. A similar formula should bear fruit for Visual Cafe, although they have their own proprietary debugger. Hope that's useful. Eric
I've got a cryptic ServletException. How do I get the full trace?
Eric Hansen writes: #### PROBLEM: Have you ever received a cryptic Exception message like this in your error logging due to an error in a JSP page: ???
javax.servlet.ServletException at com.caucho.jsp.QPageContext.handlePageException(QPageContext.java:371) at work.ProgramOverview__jsp._jspService(ProgramOverview__jsp.java:115) at com.caucho.jsp.JavaPage.subservice(JavaPage.java, Compiled Code) at com.caucho.jsp.Page.service(Page.java, Compiled Code) at com.caucho.jsp.QServlet.service(QServlet.java, Compiled Code) at com.caucho.server.http.AbstractRequest.service(AbstractRequest.java, Compiled Code) at com.caucho.server.http.VirtualHost.service(VirtualHost.java, Compiled Code) at com.caucho.server.http.QRequestDispatcher.forward(QRequestDispatcher.java, Compiled Code) at com.caucho.server.http.QRequestDispatcher.forward(QRequestDispatcher.java, Compiled Code) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at com.caucho.server.http.AbstractRequest.service(AbstractRequest.java, Compiled Code) at com.caucho.server.http.VirtualHost.service(VirtualHost.java, Compiled Code) at com.caucho.server.http.Request.dispatch(Request.java, Compiled Code) at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java, Compiled Code) at com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java, Compiled Code) at com.caucho.server.TcpConnection.run(TcpConnection.java, Compiled Code) at java.lang.Thread.run(Thread.java:479)
### SOLUTION: You need to change your catch routine. There is a method in ServletException called getRootCause(). This allows the developer of the servlet engine/JSP engine to embed a regular Exception inside a ServletException, which gets carried along for the ride.
catch(Exception e) { logMessage(e,"",-1); if(e instanceof javax.servlet.ServletException) { Throwable et; et = ((javax.servlet.ServletException)e).getRootCause(); if(et!=null&&et instanceof Exception) { logMessage(((Exception)et),"ROOT EXCEPTION",-1); } } }
(logMessage is some logging routine you write to do logging... Could also be System.err.println...) I was finding it quite difficult to debug JSP pages because I couldn't see what the underlying Exception was, just the ServletException which gets thrown from the JSP. The above modification (or something similar) exposes it. I figure other people might have the same problem. Hope that helps, Eric
How do I configure a default servlet?
<servlet-mapping url-pattern='/' servlet-name='myServlet'/> This has a different effect from url-pattern='/*'. /* will have priority over extension mappings like *.jsp, while / has the lowest priority.
Can you recommend any JDBC drivers?
Arun Jamwal writes: I have used Weblogic's type 2 JDBC driver (formerly known as FastForward) on two big projects. Oracle's type 4 JDBC driver was crashing against a big query...and type 2 couldn't be used with M$ VM. Weblogic bundles these drivers with Tengah but you can ask them just for the JDBC drivers.... I had used Openlink's type 3 JDBC drivers too (about 2.5+ years ago) but I didn't like them much. PS: Check out these links for more info: http://www.beasys.com/products/weblogic/drivers.html http://www.javasoft.com/products/jdbc/drivers.html
How do I print an exception stack trace to the JSP out?
Mattias Nilsson writes: Here's the code I use for dumping exceptions on JSP pages
catch(Exception e) { ByteArrayOutputStream bout = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(bout)); out.println(bout.toString()); }
also very useful to include in error emails etc.
How do I get the application class loader?
Unfortunately, the Servlet API doesn't have a call to get the application's class loader. With Resin 1.1.b6, you can use
application.getAttribute("caucho.class-loader")
The application gets reloaded on each request
Other symptoms are that sessions are killed on each request. This may occur if your *.java files have a date in the future. When the *.class is compiled, it will have an date before the *.java. So Resin will think it's old and recompile on the next request. This may occur, for example, if you work on NT and use Linux as a fileserver and the two clocks aren't properly synchronized. The only solution is to synchronize the clocks for both machines.
How do I delete cookies?
Normally, you can just grab the cookie from request.getCookies(), call cookie.setMaxAge(0), and add the cookie to the Response. One thing you may need to watch out for is that the Path and Domain of the deleting cookie must match the browser's cookie. By default, Resin sends Path=/ and no domain. If you set a cookie header explicitly, you may need to call setPath(null).
response.addHeader("Set-Cookie: foo=bar");
To delete this cookie, you must call:
Cookie cookie = new Cookie("foo", "bar"); cookie.setPath(null); response.addCookie(cookie);
How do I pass JVM arguments like -ms48m?
You can pass them on the command line like: -J-ms40m. You don't need to escape -Dfoo=bar. If you're on Unix, you can also add them to srun.sh or httpd.sh in the args variable. You may need to quote the assignment:
args="-J-ms40m -Dfoo=bar"
How do I change the 'cannot connect' message?
In the resin.conf, add an error-page directive using connection for the exception type. The location must be an absolute path understandable to your web server. For example, since the web server will display this message, you can't forward to a jsp file.
<error-page exception-type='connection' location='/errorpage.html'/>
How do I set a virtual directory?
Use the <path-mapping> directive. For example, to grab images from /home/images/*, use:
<path-mapping url-pattern='/images/*' real-path='/home/images'/>
What is a web-app?
The vast majority of sites can completely ignore web-apps. If you're starting with Resin, use the default web-app and don't worry about it. You'll only want to use web-apps when you want separate projects using the same web server. For example, on an ISP site, each user might get her own web-app. She can treat the web-app as if she had control over the whole web server starting at a URL prefix like ~karen. A web-app is a generalization of a virtual host. With virtual hosts, each host pretends that it controls its own server when it really is sharing the server with other virtual hosts. A web-app extends this by creating virtual applications for a URL prefix. Each web-app gets its own sessions, servlets, beans and static pages.
Why don't my URLs work in my web-app?
Remember, the browser doesn't know about your web-apps. It treats the web server as a single URL-space. This may cause you troubles if you use a standard directory structure like putting images in '/images/*'. To see this problem, suppose you have a web-app called '/myproject'. Suppose you have a JSP page in the web-app called foo/bar.jsp. The full URL will be /myproject/foo/bar.jsp. Your image reference should look like one of the following:
<img src='../images/image1.gif'/> <img src='<%= application.getContextPath() %>/images/image1.gif'/>
Using /images/image1.gif will fail because the browser will look for http://myhost.com/images/image1.gif when you really want http://myhost.com/myproject/images/image1.gif.
How should I use XSL?
Scott Ferguson writes: Since my experience with XSLT is only with simple examples, you'll want to take it with a shaker of salt. And, of course, it really depends on the application. Some applications are a perfect fit for XSLT and others should avoid it. For what it's worth, here's my current thinking on XSLT. XSLT is a very new technology; the spec was only finished in December. There really hasn't been enough time for people to discover what works and what doesn't work. Be very careful of new technologies, especially radical new technologies. Even Java, which has turned out to be a great language, was a disaster in the 1.0.2 timeframe, and Java on the client is still less-than-optimal and applets are nightmarish. When C++ was the hot new thing, many projects jumped full into C++ implementations and created huge unmanageable disasters. Now, I'm not suggesting that you avoid XSLT entirely, just that you be careful in using it and avoid placing it at the center of your architecture. I'd suggest you limit XSLT to places where it's a clear win. Otherwise you can waste lots of time coming up with the perfect tag library or debugging an architecture that will turn out, in hindsight, to have been an anti-design pattern. Here some useful areas I've found helpful: automatic insertion of response.encodeURL in <a href> and <form action> calculating the image size from <img src> and filling in width and height some well-defined formatting primitives: <example>, <callout>, <var>, <section>. An <artist> tag is a good example. But, again, be careful of inventing the perfect tag library, stick to obvious tags, and define them only after you really need them. page formatting. It's nice to have the stylesheet create the navigation, breadcrumbs, meta tags, etc. user preferences. Call a jsp:useBean at the top of the page and use as simple as possible bean methods in the XSL. So my approach, if I were starting a project, would be to select either straight JSP or servlet->JSP templates as a basic architecture, depending on the actual project needs. I'd replace JSP with XTP, but only use a defaultcopy.xsl and a header.xsl stylesheet. So far, this use of XTP is essentially identical to JSP. Only after common idioms and formatting kruft start filling up the JSP and become error-prone would I put them into the stylesheet. With XSLT such a new technology, a waterfall-style "design before you implement" approach is likely to get you into lots of trouble with XSLT. I'd avoid putting lots of Java code in the stylesheets. Put them in beans instead. Debugging Java code that comes from stylesheets into a JSP file is hard. Really hard. Your mileage will vary. Any discussion of XSLT architecture will be theoretical until several full-sized projects succeed with XSLT and several fail.
Apache doesn't find my resin.conf
On windows, the argument to CauchoConfigFile should be enclosed in quotes. Also, since Apache treats '\' as an escape, you'll need either to use forward slashes or double the backslashes.
How do I stop the browser from caching my page?
Unfortunately, all the browsers work differently. The following seems to be a consensus on the headers to set:
response.setHeader("Cache-Control", "no-cache, post-check=0, pre-check=0"); response.setHeader("Pragma", "no-cache"); response.setHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
How do I precompile *.jsp pages?
You can run Resin on a single page from the shell:
unix> httpd.sh -e /test/myfile.jsp
That will compile the JSP. When you next start Resin, the JSP file will already be available. You can also use a link checker spider to traverse your website to hit all the pages you want to precompile.
Future |  | Reference
Copyright © 1998-2000 Caucho Technology. All rights reserved. Last modified: Tue, 28 Mar 2000 08:33:35 -0800 (PST)