You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Peter Skala <pe...@ooom.at> on 2008/08/15 11:16:38 UTC

Tapestry 5 deployed on Tomcat - possibly a solution

Tapestry 5 documentation states, that component classes stored under
WEB-INF/classes on Tomcat will not be found during the initialization.

I did not experience this problem, neither with Tomcat 5.5.15, nor with
6.0.16.  The problem is something else: components packaged in a jar file
(custom component library module) are not found on Tomcat.

What HLS writes about this topic on his site ( see “Fighting with Tomcat”
from February 20th, 2007) might support my experience.

There is a solution to this problem. It is not very elegant, but it is
working, as far as I can judge. Please try it, if it works generally. 

The only class to be changed is ClassNameLocatorImpl.java. If the method
getResources called in findClassesWithinPath does not deliver any entry, the
other possibility will be tried, which is contained in the new method
testForJarComponents below. It scans all the URLs available to the class
loader for the searched packagePath. If found, all .class files saved on
this path are returned.

private Collection<String> findClassesWithinPath(String packagePath) throws
IOException
    {
        Collection<String> result = CollectionFactory.newList();

        Enumeration<URL> urls =
contextClassLoader.getResources(packagePath);

      boolean urlsFound = false;            // new

        while (urls.hasMoreElements())
        {
        	urlsFound = true;                 // new

            URL url = urls.nextElement();

            URL converted = converter.convert(url);

            scanURL(packagePath, result, converted);
        }

        if( urlsFound == false)              // new
        {						   
            try 					   
            {
            	testForJarComponents( packagePath, result);
            } 
            catch (IOException ex)
            {
            }
        }

        return result;
    }

And now the new method:

    /**
     * Scan all the URLs available to the class loader. In case when a URL
is a jar file, 
     * check if a searched packagePaht is contained in it. If yes, return
all classes
     * contained on the path
     *
     * @param packagePath
     * @param result - Collection reference
     * @throws java.io.IOException 
     */
 private void scanJarsForComponents( String packagePath, Collection<String>
result) 
                                                      throws IOException
 {
        
        String packageName = packagePath.replace('/', '.');
        if( URLClassLoader.class.isInstance( contextClassLoader) &&
packagePath != null)   
       {
            URL[] searchUrls =  ((URLClassLoader)
contextClassLoader).getURLs();
            
            for( int i = 0; i < searchUrls.length; i++ )  {                
            	                                                            
               if( searchUrls[ i].getFile().indexOf( ".jar") > 1)   
               {
                  JarFile jarFile = new JarFile( searchUrls[ i].getFile());
                  Enumeration<JarEntry> jarEntries = jarFile.entries();
                  
                  while( jarEntries.hasMoreElements()) 
                  {
                     String potentialComponentPathName =
jarEntries.nextElement().getName();
                     if( potentialComponentPathName.indexOf( packagePath) ==
0 )
                     {           
                        String potentialComponentName = 
                                       
potentialComponentPathName.substring( packagePath.length());
                        int classIdx = potentialComponentName.lastIndexOf(
CLASS_SUFFIX);
                        
                             // if a class is allowed to be in a subpackage,
the second test should be removed
                        if( classIdx > 0 && potentialComponentName.indexOf(
'/') == -1 )  
                       {            
                            String classNameFound =
                                               packageName +
potentialComponentName.substring(0, classIdx);
                            result.add( classNameFound);
                        }
                     }
                  }
               }
           }
      }
 }




-- 
View this message in context: http://www.nabble.com/Tapestry-5-deployed-on-Tomcat---possibly-a-solution-tp18995976p18995976.html
Sent from the Tapestry - Dev mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org