This is not a good implementation, simply searching the web.xml file for a string containing "<distributable/>" is not good enough. It'll find the tag even if commented out and and won't find the tag "<distributable />" (space before closing, perfectly valid). I'm surprised this got past you Jacques.
Regards Scott On 1/05/2012, at 1:31 AM, Jacques Le Roux wrote: > Pierre, > > I did not test, but I believe it's only used in a clustered environment and > should have any impacts in other cases. > It makes only a webapp distributable. Before we added this, all were > distributable by default, which could annoying in certain circumstances. > So adding it in web.xml files should not changes from previous behaviour. > Which makes me believe it's safe... (see commit for more) > > Jacque > > From: "Pierre Smits" <pierre.sm...@gmail.com> >> Jacques, >> >> If I have this tag in the web.xml, but the change is tested in an >> unclustered environment what do you thing the result would be? Is it of no >> effect, would it fail? >> >> Regards, >> >> Pierre >> >> 2012/4/30 Jacques Le Roux <jacques.le.r...@les7arts.com> >> >>> Hi Sam, >>> >>> Yes: http://tomcat.apache.org/**tomcat-6.0-doc/cluster-howto.** >>> html#Cluster_Basics<http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html#Cluster_Basics> >>> http://wiki.metawerx.net/Wiki.**jsp?page=web.xml.Distributable<http://wiki.metawerx.net/Wiki.jsp?page=web.xml.Distributable> >>> >>> Also consider >>> <property name="apps-cross-context" value="true"/> >>> <property name="apps-context-reloadable" value="true"/> >>> (false by default) >>> >>> If you use sticky sessions all above is not an issue... >>> >>> Maybe we should ask a comment in *-containers.xml BTW... Feel free to >>> provide one ;o) >>> >>> Jacques >>> >>> >>> Sam Hamilton wrote: >>> >>>> Hi Jacques, >>>> >>>> Quick question - does this setting mean that now if you uncomment >>>> framework/config/ofbiz-**containers.xml cluster settings it wont >>>> cluster and that you should also add a <distributable/> tag to all the >>>> web.xml files? >>>> >>>> Thanks >>>> Sam >>>> >>>> >>>> On 14 Apr 2012, at 15:30, jler...@apache.org wrote: >>>> >>>> Author: jleroux >>>>> Date: Sat Apr 14 07:30:30 2012 >>>>> New Revision: 1326064 >>>>> >>>>> URL: >>>>> http://svn.apache.org/viewvc?**rev=1326064&view=rev<http://svn.apache.org/viewvc?rev=1326064&view=rev> >>>>> Log: >>>>> Adapted by hand from Lon F. Binder "CatalinaContainer Doesn't Respect >>>>> <distributable/> Node for web.xml files." >>>>> https://issues.apache.org/**jira/browse/OFBIZ-4242<https://issues.apache.org/jira/browse/OFBIZ-4242> >>>>> >>>>> Per the servlet specification, the web.xml file should allow an optional >>>>> <distributable/> node to indicate that the application >>>>> is clusterable. Currently, OFBiz does not respect this setting and >>>>> assumes all applications should be distributed if any cluster >>>>> configuration is provided in the ofbiz-containers.xml file. As a result, >>>>> if, for example, the DeltaManager is enable, all >>>>> applications attempt to cluster and communicate via DeltaManager. >>>>> >>>>> The expected and proper functionality is to check the individual >>>>> application's web.xml file for the <distributable/> node and >>>>> only use the DeltaManager if found; otherwise the StandardManager should >>>>> be used for sessions. >>>>> >>>>> jleroux: replaced some tabs, reformatted, added a comment about >>>>> <distributable/> in the *-containers.file >>>>> >>>>> Modified: >>>>> ofbiz/trunk/framework/base/**src/org/ofbiz/base/util/**FileUtil.java >>>>> ofbiz/trunk/framework/**catalina/src/org/ofbiz/**catalina/container/** >>>>> CatalinaContainer.java >>>>> >>>>> Modified: ofbiz/trunk/framework/base/**src/org/ofbiz/base/util/** >>>>> FileUtil.java >>>>> URL: >>>>> http://svn.apache.org/viewvc/**ofbiz/trunk/framework/base/** >>>>> src/org/ofbiz/base/util/**FileUtil.java?rev=1326064&r1=** >>>>> 1326063&r2=1326064&view=diff<http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/FileUtil.java?rev=1326064&r1=1326063&r2=1326064&view=diff> >>>>> ==============================**==============================**================== >>>>> --- >>>>> ofbiz/trunk/framework/base/**src/org/ofbiz/base/util/**FileUtil.java >>>>> (original) +++ >>>>> ofbiz/trunk/framework/base/**src/org/ofbiz/base/util/**FileUtil.java >>>>> Sat Apr 14 07:30:30 2012 @@ -29,6 +29,7 @@ import >>>>> java.io.FileWriter; >>>>> import java.io.FilenameFilter; >>>>> import java.io.IOException; >>>>> import java.io.OutputStream; >>>>> +import java.io.Reader; >>>>> import java.io.Writer; >>>>> import java.net.**MalformedURLException; >>>>> import java.util.List; >>>>> @@ -67,7 +68,7 @@ public class FileUtil { >>>>> >>>>> /** >>>>> * Converts a file path to one that is compatible with the host >>>>> operating system. >>>>> - * >>>>> + * >>>>> * @param path The file path to convert. >>>>> * @return The converted file path. >>>>> */ >>>>> @@ -341,4 +342,57 @@ public class FileUtil { >>>>> return false; >>>>> } >>>>> } >>>>> + >>>>> + /** >>>>> + * >>>>> + * >>>>> + * Search for the specified <code>searchString</code> in the given >>>>> + * {@link Reader}. >>>>> + * >>>>> + * @param reader A Reader in which the String will be searched. >>>>> + * @param searchString The String to search for >>>>> + * @return <code>TRUE</code> if the <code>searchString</code> is >>>>> found; >>>>> + * <code>FALSE</code> otherwise. >>>>> + * @throws IOException >>>>> + */ >>>>> + public static boolean containsString(Reader reader, final String >>>>> searchString) throws IOException { >>>>> + char[] buffer = new char[1024]; >>>>> + int numCharsRead; >>>>> + int count = 0; >>>>> + while((numCharsRead = reader.read(buffer)) > 0) { >>>>> + for (int c = 0; c < numCharsRead; ++c) { >>>>> + if (buffer[c] == searchString.charAt(count)) count++; >>>>> + else count = 0; >>>>> + if (count == searchString.length()) return true; >>>>> + } >>>>> + } >>>>> + return false; >>>>> + } >>>>> + >>>>> + /** >>>>> + * >>>>> + * >>>>> + * Search for the specified <code>searchString</code> in the given >>>>> + * filename. If the specified file doesn't exist, <code>FALSE</code> >>>>> + * returns. >>>>> + * >>>>> + * @param fileName A full path to a file in which the String will be >>>>> searched. >>>>> + * @param searchString The String to search for >>>>> + * @return <code>TRUE</code> if the <code>searchString</code> is >>>>> found; >>>>> + * <code>FALSE</code> otherwise. >>>>> + * @throws IOException >>>>> + */ >>>>> + public static boolean containsString(final String fileName, final >>>>> String searchString) throws IOException { >>>>> + File inFile = new File(fileName); >>>>> + if (inFile.exists()) { >>>>> + BufferedReader in = new BufferedReader(new >>>>> FileReader(inFile)); >>>>> + try { >>>>> + return containsString(in, searchString); >>>>> + } finally { >>>>> + if (in != null)in.close(); >>>>> + } >>>>> + } else { >>>>> + return false; >>>>> + } >>>>> + } >>>>> } >>>>> >>>>> Modified: ofbiz/trunk/framework/**catalina/src/org/ofbiz/** >>>>> catalina/container/**CatalinaContainer.java >>>>> URL: >>>>> http://svn.apache.org/viewvc/**ofbiz/trunk/framework/** >>>>> catalina/src/org/ofbiz/**catalina/container/** >>>>> CatalinaContainer.java?rev=**1326064&r1=1326063&r2=1326064&**view=diff<http://svn.apache.org/viewvc/ofbiz/trunk/framework/catalina/src/org/ofbiz/catalina/container/CatalinaContainer.java?rev=1326064&r1=1326063&r2=1326064&view=diff> >>>>> ==============================**==============================**================== >>>>> --- >>>>> ofbiz/trunk/framework/**catalina/src/org/ofbiz/**catalina/container/**CatalinaContainer.java >>>>> (original) +++ >>>>> ofbiz/trunk/framework/**catalina/src/org/ofbiz/**catalina/container/**CatalinaContainer.java >>>>> Sat Apr 14 07:30:30 2012 @@ -75,9 +75,10 >>>>> @@ import org.ofbiz.base.concurrent.**Executi >>>>> import org.ofbiz.base.container.**ClassLoaderContainer; >>>>> import org.ofbiz.base.container.**Container; >>>>> import org.ofbiz.base.container.**ContainerConfig; >>>>> -import org.ofbiz.base.container.**ContainerException; >>>>> import org.ofbiz.base.container.**ContainerConfig.Container.**Property; >>>>> +import org.ofbiz.base.container.**ContainerException; >>>>> import org.ofbiz.base.util.Debug; >>>>> +import org.ofbiz.base.util.FileUtil; >>>>> import org.ofbiz.base.util.SSLUtil; >>>>> import org.ofbiz.base.util.UtilURL; >>>>> import org.ofbiz.base.util.**UtilValidate; >>>>> @@ -537,7 +538,7 @@ public class CatalinaContainer implement >>>>> } catch (Exception e) { >>>>> Debug.logError(e, "Couldn't create connector.", module); >>>>> } >>>>> - >>>>> + >>>>> try { >>>>> for (ContainerConfig.Container.**Property prop: >>>>> connectorProp.properties.**values()) { >>>>> connector.setProperty(prop.**name <http://prop.name>, >>>>> prop.value); >>>>> @@ -583,7 +584,7 @@ public class CatalinaContainer implement >>>>> engine.addChild(host); >>>>> } >>>>> } >>>>> - >>>>> + >>>>> if (host instanceof StandardHost) { >>>>> // set the catalina's work directory to the host >>>>> StandardHost standardHost = (StandardHost) host; >>>>> @@ -618,11 +619,24 @@ public class CatalinaContainer implement >>>>> mount = mount.substring(0, mount.length() - 2); >>>>> } >>>>> >>>>> + >>>>> + final String webXmlFilePath = new StringBuilder().append(** >>>>> location) >>>>> + .append(File.separatorChar).**append("WEB-INF") >>>>> + .append(File.separatorChar).**append("web.xml").toString(); >>>>> + boolean appIsDistributable = false; >>>>> + try { >>>>> + appIsDistributable = >>>>> FileUtil.containsString(**webXmlFilePath, >>>>> "<distributable/>"); >>>>> + } catch (IOException e) { >>>>> + Debug.logWarning(String.**format("Failed to read web.xml >>>>> [%s].", webXmlFilePath), module); >>>>> + appIsDistributable = false; >>>>> + } >>>>> + final boolean contextIsDistributable = distribute && >>>>> appIsDistributable; >>>>> + >>>>> // configure persistent sessions >>>>> Property clusterProp = clusterConfig.get(engine.**getName()); >>>>> >>>>> Manager sessionMgr = null; >>>>> - if (clusterProp != null) { >>>>> + if (clusterProp != null && contextIsDistributable) { >>>>> String mgrClassName = >>>>> ContainerConfig.**getPropertyValue(clusterProp, >>>>> "manager-class", >>>>> "org.apache.catalina.ha.**session.DeltaManager"); try { >>>>> sessionMgr = (Manager)Class.forName(** >>>>> mgrClassName).newInstance(); >>>>> @@ -639,16 +653,16 @@ public class CatalinaContainer implement >>>>> context.setDocBase(location); >>>>> context.setPath(mount); >>>>> context.addLifecycleListener(**new ContextConfig()); >>>>> - >>>>> + >>>>> JarScanner jarScanner = context.getJarScanner(); >>>>> if (jarScanner instanceof StandardJarScanner) { >>>>> StandardJarScanner standardJarScanner = (StandardJarScanner) >>>>> jarScanner; >>>>> standardJarScanner.**setScanClassPath(false); >>>>> } >>>>> - >>>>> + >>>>> Engine egn = (Engine) context.getParent().getParent(**); >>>>> egn.setService(tomcat.**getService()); >>>>> - >>>>> + >>>>> Debug.logInfo("host[" + host + "].addChild(" + context + ")", >>>>> module); >>>>> //context.setDeployOnStartup(**false); >>>>> //context.**setBackgroundProcessorDelay(5)**; >>>>> @@ -664,7 +678,9 @@ public class CatalinaContainer implement >>>>> context.setAllowLinking(true); >>>>> >>>>> context.setReloadable(**contextReloadable); >>>>> - context.setDistributable(**distribute); >>>>> + >>>>> + context.setDistributable(**contextIsDistributable); >>>>> + >>>>> context.setCrossContext(**crossContext); >>>>> context.setPrivileged(appInfo.**privileged); >>>>> context.setManager(sessionMgr)**; >>>>> >>>>