DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13479>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13479 Cocoon fails to compile sitemap and XSP in JBoss 3.0.3 with embedded Tomcat 4.1.12 and 4.0.5 Summary: Cocoon fails to compile sitemap and XSP in JBoss 3.0.3 with embedded Tomcat 4.1.12 and 4.0.5 Product: Cocoon 2 Version: 2.0.3 Platform: All OS/Version: Other Status: NEW Severity: Major Priority: Other Component: core AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] Coocon 2.0.3 fails to compile the sitemap and all XSPs with java compiler problems. It appear thar any stuff in /WEB-INF/lib and /WEB-INF/classes is not visibile for the java compiler (tried with pizza and javac). The reason is that an embedded tomcat does not make an absolute pathname visible for /WEB-INF/lib and hands out resource URL like jndi:/<context hostname>/<webapp name>/WEB-INF/lib if the web application is deployed as a WAR (either standalone of within an EAR, doesn't matter) The patch below scans for such resource URLs and copies the contents from /WEB-INF/lib and /WEB-INF/classes via JNDI lookups into a private work directory. *** src/java/org/apache/cocoon/servlet/CocoonServlet.java.orig Wed Oct 9 23:41:10 2002 --- src/java/org/apache/cocoon/servlet/CocoonServlet.java Wed Oct 9 23:41:09 2002 *************** *** 81,86 **** --- 81,91 ---- import org.apache.log.Priority; import org.apache.log.output.ServletOutputLogTarget; + import javax.naming.Binding; + import javax.naming.NameClassPair; + import javax.naming.NamingEnumeration; + import javax.naming.NamingException; + import javax.naming.directory.DirContext; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; *************** *** 92,102 **** --- 97,110 ---- import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; + import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.StringWriter; import java.io.PrintWriter; import java.lang.reflect.Constructor; + import java.net.MalformedURLException; import java.net.URL; + import java.net.URLConnection; import java.util.Arrays; import java.util.HashMap; import java.util.StringTokenizer; *************** *** 522,568 **** try { libDirURL = this.servletContext.getResource("/WEB-INF/lib"); } catch (java.net.MalformedURLException me) { if (log.isWarnEnabled()) { this.log.warn("Unable to add WEB-INF/lib to the classpath", me); } } ! ! if (libDirURL != null && libDirURL.toExternalForm().startsWith("file:")) { ! root = new File(libDirURL.toExternalForm().substring("file:".length())); ! } if (classDirURL != null) { ! buildClassPath.append(classDirURL.toExternalForm()); ! ! addClassLoaderURL(classDirURL); } } ! // Unable to find lib directory. Going the hard way. if (root == null) { root = extractLibraries(); } ! if (root != null && root.isDirectory()) { File[] libraries = root.listFiles(); Arrays.sort(libraries); for (int i = 0; i < libraries.length; i++) { String fullName = IOUtils.getFullFilename(libraries[i]); buildClassPath.append(File.pathSeparatorChar).append(fullName); ! addClassLoaderDirectory(fullName); } } ! buildClassPath.append(File.pathSeparatorChar) ! .append(System.getProperty("java.class.path")); ! buildClassPath.append(File.pathSeparatorChar) ! .append(getExtraClassPath()); return buildClassPath.toString(); } ! private File extractLibraries() { try { URL manifestURL = this.servletContext.getResource("/META-INF/MANIFEST.MF"); --- 530,619 ---- try { libDirURL = this.servletContext.getResource("/WEB-INF/lib"); + this.log.debug("/WEB-INF/lib resource URL is " + +libDirURL.toString()); } catch (java.net.MalformedURLException me) { if (log.isWarnEnabled()) { this.log.warn("Unable to add WEB-INF/lib to the classpath", me); } } ! ! if (libDirURL != null) { ! if(libDirURL.toExternalForm().startsWith("file:")) { ! root = new File(libDirURL.toExternalForm().substring("file:".length())); ! } else if(libDirURL.toExternalForm().startsWith("jndi:")) { ! this.log.debug("having jndi: pseudo-URL"); ! ! try { ! URLConnection con = libDirURL.openConnection(); ! Object content = con.getContent(); ! ! this.log.debug("jndi-url points to object of class " + content.getClass().getName()); ! if(content instanceof DirContext) { ! root = extractJNDILibraries((DirContext)content); ! } ! } catch(Exception e) { ! this.log.debug("exception examinig " + libDirURL.toExternalForm(), e); ! } ! } ! } if (classDirURL != null) { ! if(classDirURL.toExternalForm().startsWith("file:")) { ! String path = classDirURL.toExternalForm().substring("file:".length()); ! ! buildClassPath.append(path); ! addClassLoaderDirectory(path); ! } else if(classDirURL.toExternalForm().startsWith("jndi:")) { ! this.log.debug("having jndi: pseudo-URL"); ! ! try { ! URLConnection con = libDirURL.openConnection(); ! Object content = con.getContent(); ! ! this.log.debug("jndi-url points to object of class " + content.getClass().getName()); ! if(content instanceof DirContext) { ! String path = extractJNDIClasses((DirContext)content); ! ! if(path != null) { ! buildClassPath.append(path); ! addClassLoaderDirectory(path); ! } ! } ! } catch(Exception e) { ! this.log.debug("exception examinig " + libDirURL.toExternalForm(), e); ! } ! } else { ! buildClassPath.append(classDirURL.toExternalForm()); ! ! addClassLoaderURL(classDirURL); ! } } } ! // Unable to find lib directory. Going the hard way. if (root == null) { root = extractLibraries(); } ! if (root != null && root.isDirectory()) { File[] libraries = root.listFiles(); Arrays.sort(libraries); for (int i = 0; i < libraries.length; i++) { String fullName = IOUtils.getFullFilename(libraries[i]); buildClassPath.append(File.pathSeparatorChar).append(fullName); ! addClassLoaderDirectory(fullName); } } ! buildClassPath.append(File.pathSeparatorChar) ! .append(System.getProperty("java.class.path")); ! buildClassPath.append(File.pathSeparatorChar) ! .append(getExtraClassPath()); return buildClassPath.toString(); } ! private File extractLibraries() { try { URL manifestURL = this.servletContext.getResource("/META-INF/MANIFEST.MF"); *************** *** 631,637 **** if (os != null) os.close(); } } ! if (lastModified != -1) { lib.setLastModified(lastModified); } --- 682,688 ---- if (os != null) os.close(); } } ! if (lastModified != -1) { lib.setLastModified(lastModified); } *************** *** 644,649 **** --- 695,844 ---- } } + /** + * extract all libraries from a jndi://something DirContext. Tomcat hands out +some URLs like jndi:/localhost/.../WEB-INF/lib + * if asked for a resourece URL to /WEB-INF/lib. + * + */ + private File extractJNDILibraries(DirContext libDirContext) { + File root = new File(this.workDir, "lib"); + + root.mkdirs(); + + File[] oldLibs = root.listFiles(); + for (int i=0; i<oldLibs.length; i++) { + String oldLib = oldLibs[i].getName(); + this.log.debug("Removing old library " + oldLibs[i]); + oldLibs[i].delete(); + } + + try { + NamingEnumeration libEnum = libDirContext.listBindings(""); + byte[] buffer = new byte[65536]; + + while(root != null && libEnum.hasMoreElements()) { + Binding binding = (Binding)libEnum.nextElement(); + + this.log.debug("bound library on " + binding.getName()); + + File lib = new File(root, binding.getName()); + InputStream is = +this.servletContext.getResourceAsStream("/WEB-INF/lib/" + binding.getName()); + + if (is == null) { + this.log.warn("Skipping " + binding.getName()); + } else { + this.log.debug("Extracting " + binding.getName()); + + if(!copy(is, lib)) { + this.log.fatalError("failed to copy " + binding.getName()); + + if(lib.exists()) { + if(!lib.delete()) { + this.log.fatalError("failed to remove left-over " + binding.getName()); + + root = null; + } + } + } + } + } + } catch(NamingException ne) { + this.log.fatalError("cant enumerate JNDI bound jars", ne); + + root = null; + } + + return root; + } + + /** + * extract all classes from a jndi://something DirContext. Tomcat hands out some URLs like jndi:/localhost/.../WEB-INF/classes + * if asked for a resourece URL to /WEB-INF/classes. + * + */ + private String extractJNDIClasses(DirContext libClassesContext) { + File root = new File(this.workDir, "classes"); + + root.mkdirs(); + extractJNDIContextClasses(libClassesContext, "classes", root); + + return (root != null ? root.getAbsolutePath() : null); + } + + private void extractJNDIContextClasses(DirContext curCtx, String prefix, File curDir) { + try { + NamingEnumeration enum = curCtx.list(""); + + while (enum.hasMoreElements()) { + NameClassPair ncPair = (NameClassPair) enum.nextElement(); + String name = ncPair.getName(); + Object object = curCtx.lookup(name); + File currentFile = new File(curDir, name); + + if(object instanceof DirContext) { + currentFile.mkdir(); + extractJNDIContextClasses((DirContext)object, prefix + "/" + name, currentFile); + } else { + InputStream is = +this.servletContext.getResourceAsStream("/WEB-INF/" + prefix + "/" + name); + + if (is == null) { + this.log.warn("Skipping " + name); + } else { + this.log.debug("Extracting " + name); + + if(!copy(is, currentFile)) { + this.log.fatalError("failed to copy " + prefix + "/" + +name); + + if(currentFile.exists()) { + if(!currentFile.delete()) + this.log.fatalError("failed to remove left-over " ++ prefix + "/" + name); + } + } + } + } + } + } catch(NamingException ne) { + this.log.fatalError("cant enumerate JNDI bound classes", ne); + } + } + + /** + * Copy a file from an input stream to an output stream. + */ + private boolean copy(InputStream is, File of) { + try { + FileOutputStream os = new FileOutputStream(of); + + return copy(is, os); + } catch(FileNotFoundException e) { + this.log.debug("cant open " + of.getAbsolutePath() + " for output", e); + + return false; + } + } + + /** + * Copy a file from an input stream to an output stream. + */ + private boolean copy(InputStream is, OutputStream os) { + + try { + byte[] buf = new byte[16384]; + while (true) { + int len = is.read(buf); + if (len < 0) + break; + os.write(buf, 0, len); + } + is.close(); + os.close(); + } catch (IOException e) { + return false; + } + + return true; + + } /** * Retreives the "extra-classpath" attribute, that needs to be --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]