On Wednesday 10 December 2003 10:26, Eric Pugh wrote: > Filippos, > > I think the patch got eaten.. Could you repost to the list and send it to > me directly?
Ok, I'm sending the patch again as an attachement this time. > Also, do you have unit tests demonstrating the functionality? Nope, I don't have... but I don't know how I can simulate a web-container enviroment with a Junit testcase .. Is there any kind of integration with junit testcases and tomcat for instance ? > That would make it easier for us to write unit tests that validate all the > services. Slavikos > > Eric > > > -----Original Message----- > > From: Filippos Slavik [mailto:[EMAIL PROTECTED] > > Sent: Tuesday, December 09, 2003 9:37 PM > > To: [EMAIL PROTECTED] > > Subject: [PATCH] workaround for EAR/WAR deployments > > > > > > 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.poo > > l.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.s > > ervices.assemblerbroker.TurbineAssemblerBrokerService > > services.PullService.classname=org.apache.turbine.services.pul > > l.TurbinePullService > > services.MimeTypeService.classname=org.apache.turbine.services > > .mimetype.TurbineMimeTypeService > > services.GlobalCacheService.classname=org.apache.turbine.servi > > ces.cache.TurbineGlobalCacheService > > services.UniqueIdService.classname=org.apache.turbine.services > > .uniqueid.TurbineUniqueIdService > > services.SecurityService.classname=gr.forthnet.backgroundftp.w > > eb.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] > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] -- #################################################################### 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..."
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
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
