I'm sending my patch for Turbine based web-apps that are being deployed as a WAR/EAR modules.
This is a workaround and not a complete solution of the issue, since there is a need for a major refactoring in turbine's services which assumes that there is always an "applicationRoot" available. The hack here is based on the fact that fortunately all services (or most of them) and the turbine's main servlet initialization access resources through the turbine's static getRealPath(String) method which returns an absolute path of the resource. The proposed new behaviour is: There are two new methods. [1] java.io.InputStream getResourceAsStream(String) which returns an InputStream, obtained from the servlet's context, to the specified resource. [2] java.io.File getTempFileFromResource(String) which retrieves an InputStream, using the above method, and writes all resource's content to a temporary created file somewhere in the platforms temp directory (File.createTempFile(Stirng, String) is used). Turbine's static method getRealPath(String) is altered as: 1) first an attempt is made to retrieve the requested resource from the servlet's context and if successfull the absolute path of the temporary file is returned to the caller 2) if step (1) is not succesfull then the old behaviour is used instead (which should only happen if we're running junit tests AFAIK) patch against TURBINE_2_3 version. I have succesfully compiled turbine with the patch applied and deployed an WAR turbine based app contained within an EAR module. Certainly this is just a workaround and not all services will run correctly. In my case, the following services were enabled during tests: services.FactoryService.classname=org.apache.turbine.services.factory.TurbineFactoryService services.PoolService.classname=org.apache.turbine.services.pool.TurbinePoolService services.RunDataService.classname=org.apache.turbine.services.rundata.TurbineRunDataService services.ServletService.classname=org.apache.turbine.services.servlet.TurbineServletService services.AssemblerBrokerService.classname=org.apache.turbine.services.assemblerbroker.TurbineAssemblerBrokerService services.PullService.classname=org.apache.turbine.services.pull.TurbinePullService services.MimeTypeService.classname=org.apache.turbine.services.mimetype.TurbineMimeTypeService services.GlobalCacheService.classname=org.apache.turbine.services.cache.TurbineGlobalCacheService services.UniqueIdService.classname=org.apache.turbine.services.uniqueid.TurbineUniqueIdService services.SecurityService.classname=gr.forthnet.backgroundftp.web.turbine.services.security.BackgroundFTPSecurityService services.TemplateService.classname=org.apache.turbine.services.template.TurbineTemplateService services.VelocityService.classname=org.apache.turbine.services.velocity.TurbineVelocityService And I had no problems at all. If the patch will be accepted I would like to continue and refactor some services which currently requires an "applicationRoot" available. Best Regards Filippos Slavik Index: Turbine.java =================================================================== RCS file: /home/cvspublic/jakarta-turbine-2/src/java/org/apache/turbine/ Turbine.java,v retrieving revision 1.45 diff -u -r1.45 Turbine.java --- Turbine.java 2 Jul 2003 16:52:24 -0000 1.45 +++ Turbine.java 9 Dec 2003 21:14:20 -0000 @@ -54,10 +54,15 @@ * <http://www.apache.org/>. */ +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Properties; import javax.servlet.ServletConfig; @@ -135,6 +140,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> * @author <a href="mailto:[EMAIL PROTECTED]">Quinton McCombs</a> * @author <a href="mailto:[EMAIL PROTECTED]">Eric Pugh</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Filippos Slavik</a> * @version $Id: Turbine.java,v 1.45 2003/07/02 16:52:24 henning Exp $ */ public class Turbine @@ -263,6 +269,9 @@ private void configure(ServletConfig config, ServletContext context) throws Exception { + // Set the Servlet's context right away. + setTurbineServletContext(context); + // // Set up Commons Logging to use the Log4J Logging // @@ -284,6 +293,14 @@ if (applicationRoot == null || applicationRoot.equals(WEB_CONTEXT)) { applicationRoot = webappRoot; + if(applicationRoot==null) { + // if we're running within a servlet container enviroment + // the applicationRoot attribute will have a null value, since + // the applicationRoot can be a WAR or EAR file. Just set here + // a dummy value to avoid NullPointerExceptions with jakarta's + // common configuration framework + applicationRoot="foo"; + } // log.info("got empty or 'webContext' Application root. Application root now: " + applicationRoot); } @@ -390,7 +407,7 @@ setTurbineServletConfig(config); - setTurbineServletContext(context); + getServiceManager().setApplicationRoot(applicationRoot); @@ -459,6 +476,60 @@ } /** + * Returns the resource located at the named path as an <code>InputStream</code> object. + * + * @param resource_path a <code>String</code> specifying the path to the resource + * @return the <code>InputStream</code> returned, or <code>null</code> if no resource exists at the specified path. + */ + public static InputStream getResourceAsStream(String resource_path) { + return getTurbineServletContext().getResourceAsStream(resource_path); + } + + /** + * Returns a File instance of a given resource. This method is supplied here + * as a workaround for all turbine specific code which tries to access web-app + * resources directly with absolute paths (getRealPath()). + * + * The tweak here is that the resource is retrieved from an <code>InputStream</code> + * acquired from the servlet's context and it is written to a temporary file. + * + * @param resource_path a <code>String</code> specifying the path to the resource + * @return An <code>File</code> instance pointing to the temp file or <code>null</code> + * if the resource couldn't be found. + */ + public static File getTempFileFromResource(String resource_path) { + InputStream in = null; + OutputStream out = null; + try { + File f_out = File.createTempFile("turbine_temp_resource", ".tmp"); + f_out.deleteOnExit(); + in = new BufferedInputStream(getResourceAsStream(resource_path)); + out = new BufferedOutputStream(new FileOutputStream(f_out)); + int b; + while((b=in.read())!=-1) + out.write(b); + return f_out; + } catch (Exception ex) { + return null; + } finally { + if(in!=null) { + try { + in.close(); + in = null; + } catch(Exception ex) { + } + } + if(out!=null) { + try { + out.flush(); + out.close(); + out = null; + } catch(Exception ex) { + } + } + } + } + /** * Finds the specified servlet configuration/initialization * parameter, looking first for a servlet-specific parameter, then * for a global parameter, and using the provided default if not @@ -1120,13 +1191,19 @@ */ public static String getRealPath(String path) { - if (path.startsWith("/")) - { - path = path.substring(1); + // try to retrieve the requested resource + // using the getTempFileFromResource(String). + File resource_file = getTempFileFromResource(path); + if(resource_file==null || !resource_file.exists()) { + // oops! Resource is not available which means that + // either we are not currently running within a servlet + // container enviroment or we were unable to retrieve + // the resource via getResourceAsStream() for some reason. + // Fallback to Turbine's default behaviour; + resource_file = new File(getApplicationRoot(), path.startsWith("/") ? path.substring(1) : path); } - - return new File(getApplicationRoot(), path).getAbsolutePath(); - } + return resource_file.getAbsolutePath(); + } /** * Return an instance of the currently configured Service Manager -- #################################################################### Filippos Slavik FORTHnet R&D, Heraklion, Greece e-mail : [EMAIL PROTECTED] phone : (+30) 2811 391230 Key ID: 0xF4B5B375 Filippos Slavik(search pgp.mit.edu) Key FingerPrint: 81D4 25D0 01EB 9DCA 62E4 B694 20E7 31FB F4B5 B375 #################################################################### "The software said 'runs on Win95 or better,' so I installed it on Linux..." --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
