I wrote a servlet (attached) and it looks like it will simplify
things.
It effectively replaces WebService and WebServer (WebService
simply wraps WebServer). WebClassLoader doesn't have a dependency on
WebServ* so it can operate as normal. I ran the DynLoadingUnitTestCase
and it passes. Funnily enough it passes if it succeeds with
./build.sh -Dtest=jrmp tests-client-unit
but fails with
./build.sh -Dtest=jrmp test
I think this is how it's supposed to be called at any rate.
A couple of points:
1. I didn't implement addClassLoader - AFAIK Scott said we will use the
servlets class loader to retrieve all classes. Removing addClassLoader
doesn't appear to cause a problem.
2. The WebServ* classes should be removed.
3. run.sh/run.bat will have to be updated with
-Djava.rmi.server.codebase=http://localhost:8080/class-loader/
4. Do we need to have a jmx service for this?
I've been working on the 3.2 branch but it should work with 4.0. I have
been using my own xdoclet ant script to build it as a .war - do you want
me to use another deployment script as a template?
I'll have some time over the next couple of days to write a compliant build script and make any other changes you may want.
James
Dain Sundstrom wrote:
We have a small project open for a volunteer. In Jboss 2 and 3 we have a custom lightweight web server (port 8083) that returns java class files from the classLoader.getResouceAsStream to RMI clients (this is how remote class loading happens). I talked to Scott at JBoss Boot Camp and we think it is a good idea to replace this with a plain old Servlet for JBoss 4.0 so it can work with regular security, pooling and such. This is a fairly simple piece of code and shouldn't take longer then a day or two. If you are interested the code can be found in jboss-head/server/src/main/org/jboss/web/WebServer.java
-dain
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development
/* JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */
package org.jboss.web; import javax.servlet.ServletException; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import org.jboss.logging.Logger; import org.jboss.util.stream.Streams; /** * The HTTPClassLoader Servlet's primary purpose is to simplify dynamic class-loading in RMI. * * It can serve any file that is available, including class-files. * This is a replacement for the WebServer class in this package. * * @web.servlet * display-name="JBoss HTTPClassLoaderServlet" * load-on-startup="1" * name="HTTPClassLoaderServlet" * * @web.servlet-mapping * url-pattern="/*" * * @link org.jboss.test.jrmp.test.DynLoadingUnitTestCase * @see http://java.sun.com/j2se/1.4/docs/guide/rmi/codebase.html * * @author <a href="mailto:[EMAIL PROTECTED]">James Cooley</a> */ public class HTTPClassLoaderServlet extends HttpServlet { // Constants ----------------------------------------------------- // Attributes ---------------------------------------------------- private static Logger log = Logger.getLogger(HTTPClassLoaderServlet.class); public static final String CONTENT_TYPE = "application/binary"; public void init(ServletConfig conf) throws ServletException { super.init(conf); } /** * Called by the server (via the service method) to allow a servlet to handle a POST request. * The HTTP POST method allows the client to send data of unlimited length to the Web server * a single time and is useful when posting information such as credit card numbers. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { log.trace("post called"); doGet(request, response); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { String filePath = null; boolean traceOn = log.isTraceEnabled(); response.setContentType(CONTENT_TYPE); try { String servletRoot = request.getContextPath(); int startOfFilePath = servletRoot.length() + 1; // +1 to get the trailing "/" String rawPath = request.getRequestURI().substring(startOfFilePath); boolean usesJBossProtocol = rawPath.indexOf(']') > 0; if(usesJBossProtocol) filePath = extractClassName(rawPath); else filePath = rawPath; if (traceOn) { log.trace("servletRoot("+servletRoot+")"); log.trace("rawPath("+rawPath+")"); log.trace("filePath("+ filePath+")"); } if(filePath == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND, "Requested class name set to null!"); return; } InputStream classStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath); if(classStream != null) { long bytes = Streams.copy(classStream, response.getOutputStream()); if(log.isTraceEnabled()) log.trace("copied " + bytes + " bytes"); } } catch(IOException ioex) { // this will send back the correct HTTP error code try { response.sendError(HttpServletResponse.SC_NOT_FOUND, "Could not find " + filePath); } catch(IOException ioexOops) { log.fatal(ioexOops); } } } /** * * This is to support a JBoss proprietary class loading protocol. * We do not use the class loader key as we don't support the * addition of classloaders. The rest of this comment describes * the protocol. * * Parse the path into the class loader key and file path. * * The class loader key is a string whose format is * "ClassName[oid]", where the oid substring may contain '/' * chars. The expected form of the raw path is: * * "SomeClassName[some/object/id]/some/file/path" * * The class loader key is "SomeClassName[some/object/id]" * and the file path is "some/file/path" * * @param request a <code>HttpServletRequest</code> value * @return a <code>String</code> value - the filePath that was found * @exception IOException if an error occurs */ protected String extractClassName(String rawPath) { int endOfKey = rawPath.indexOf(']'); String filePath = rawPath.substring(endOfKey+2); String loaderKey = rawPath.substring(0, endOfKey+1); log.trace("loaderKey = "+loaderKey); log.trace("filePath = "+filePath); return filePath; } }