-
1. Re: Facelets scanning for .taglib.xml is broken in trunk
ccrouch Feb 4, 2008 8:09 PM (in response to pmuir)Ok stupid question: How does this problem manifest itself?
I'm not seeing anything obvious (e.g. web app not displaying, exceptions in the log) yet we're using facelets? I am seeing this though which looks kind of odd (taglibs getting loaded twice):14:10:59,828 ERROR [STDERR] Feb 4, 2008 2:10:59 PM com.sun.facelets.compiler.TagLibraryConfig loadImplicit INFO: Added Library from: vfsfile:/C:/usr/apps/jboss/jboss-5.0.0.r69477/server/default/deploy/embedded-console.war/WEB-INF/lib/jboss-seam-ui-2.0.1.GA.jar/META-INF/s.taglib.xml 14:10:59,828 ERROR [STDERR] Feb 4, 2008 2:10:59 PM com.sun.facelets.compiler.TagLibraryConfig loadImplicit INFO: Added Library from: jar:file:/C:/usr/apps/jboss/jboss-5.0.0.r69477/server/default/tmp/deploy/embedded-console51602-exp.war/WEB-INF/lib/jboss-seam-ui-2.0.1.GA.jar!/META-INF/s.taglib.xml 14:11:01,750 ERROR [STDERR] Feb 4, 2008 2:11:01 PM com.sun.facelets.compiler.TagLibraryConfig loadImplicit INFO: Added Library from: vfsfile:/C:/usr/apps/jboss/jboss-5.0.0.r69477/server/default/deploy/embedded-console.war/WEB-INF/lib/jsf-facelets-1.1.14.jar/META-INF/jsf-core.taglib.xml 14:11:01,859 ERROR [STDERR] Feb 4, 2008 2:11:01 PM com.sun.facelets.compiler.TagLibraryConfig loadImplicit INFO: Added Library from: jar:file:/C:/usr/apps/jboss/jboss-5.0.0.r69477/server/default/tmp/deploy/embedded-console51602-exp.war/WEB-INF/lib/jsf-facelets-1.1.14.jar!/META-INF/jsf-core.taglib.xml
Thanks -
2. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 4, 2008 8:30 PM (in response to pmuir)"charles.crouch@jboss.com" wrote:
Ok stupid question: How does this problem manifest itself?02:22:38,609 ERROR [STDERR] 5.2.2008 2:22:38 com.sun.facelets.compiler.Compiler initialize SEVERE: Missing Built-in Tag Libraries! Make sure they are included within the META-INF directory of Facelets' Jar
I get this when hitting my browser.
What's your environment? -
3. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 5, 2008 11:00 AM (in response to pmuir)Just tested this on r69523 (pre Scott's war CL changes) and it works.
-
4. Re: Facelets scanning for .taglib.xml is broken in trunk
ccrouch Feb 5, 2008 11:06 AM (in response to pmuir)You beat me to it :-) I'm running r69477 and not seeing this.
-
5. Re: Facelets scanning for .taglib.xml is broken in trunk
ccrouch Feb 5, 2008 1:07 PM (in response to pmuir)do we have a jira for this yet?
-
6. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 5, 2008 1:53 PM (in response to pmuir)"charles.crouch@jboss.com" wrote:
do we have a jira for this yet?
No.
Can you create one?
Perhaps as a subtask of Scott's war CL change (if it exists).
And assign it to Scott, since he's currently the suspect. :-) -
7. Re: Facelets scanning for .taglib.xml is broken in trunk
ccrouch Feb 5, 2008 1:58 PM (in response to pmuir)I have no idea which jira the war CL changes went into, so I created a new one
http://jira.jboss.com/jira/browse/JBAS-5211 -
8. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 6, 2008 4:17 PM (in response to pmuir)The current version of Facelets used in our Seam Booking example is 1.1.14:
- https://facelets.dev.java.net/servlets/ProjectDocumentList?folderID=3635&expandFolder=3635&folderID=0
I think it all starts from FaceletViewHandler.buildView().
Calling DefaultFaceletFactory.getFacelet.
This call another getFacelet method, which calls createFacelet.
Which invokes compiler.compile(url, alias), that does initialize().
Compiler.initialize invokes TagLibraryConfig.loadImplicit, which does the actual search Classpath.search(cl, "META-INF/", ".taglib.xml").
The cl variable is context classloader.
ClassPath class:public final class Classpath { /** * */ public Classpath() { super(); } public static URL[] search(String prefix, String suffix) throws IOException { return search(Thread.currentThread().getContextClassLoader(), prefix, suffix); } public static URL[] search(ClassLoader cl, String prefix, String suffix) throws IOException { Enumeration[] e = new Enumeration[] { cl.getResources(prefix), cl.getResources(prefix + "MANIFEST.MF") }; Set all = new LinkedHashSet(); URL url; URLConnection conn; JarFile jarFile; for (int i = 0, s = e.length; i < s; ++i) { while (e.hasMoreElements()) { url = (URL) e.nextElement(); conn = url.openConnection(); conn.setUseCaches(false); conn.setDefaultUseCaches(false); if (conn instanceof JarURLConnection) { jarFile = ((JarURLConnection) conn).getJarFile(); } else { jarFile = getAlternativeJarFile(url); } if (jarFile != null) { searchJar(cl, all, jarFile, prefix, suffix); } else { searchDir(all, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix); } } } URL[] urlArray = (URL[]) all.toArray(new URL[all.size()]); return urlArray; } private static void searchDir(Set result, File file, String suffix) throws IOException { if (file.exists() && file.isDirectory()) { File[] fc = file.listFiles(); String path; URL src; for (int i = 0; i < fc.length; i++) { path = fc.getAbsolutePath(); if (fc.isDirectory()) { searchDir(result, fc, suffix); } else if (path.endsWith(suffix)) { // result.add(new URL("file:/" + path)); result.add(fc.toURL()); } } } } /** For URLs to JARs that do not use JarURLConnection - allowed by * the servlet spec - attempt to produce a JarFile object all the same. * Known servlet engines that function like this include Weblogic * and OC4J. * This is not a full solution, since an unpacked WAR or EAR will not * have JAR "files" as such. */ private static JarFile getAlternativeJarFile(URL url) throws IOException { String urlFile = url.getFile(); // Trim off any suffix - which is prefixed by "!/" on Weblogic int separatorIndex = urlFile.indexOf("!/"); // OK, didn't find that. Try the less safe "!", used on OC4J if (separatorIndex == -1) { separatorIndex = urlFile.indexOf('!'); } if (separatorIndex != -1) { String jarFileUrl = urlFile.substring(0, separatorIndex); // And trim off any "file:" prefix. if (jarFileUrl.startsWith("file:")) { jarFileUrl = jarFileUrl.substring("file:".length()); } return new JarFile(jarFileUrl); } return null; } private static void searchJar(ClassLoader cl, Set result, JarFile file, String prefix, String suffix) throws IOException { Enumeration e = file.entries(); JarEntry entry; String name; while (e.hasMoreElements()) { try { entry = (JarEntry) e.nextElement(); } catch (Throwable t) { continue; } name = entry.getName(); if (name.startsWith(prefix) && name.endsWith(suffix)) { Enumeration e2 = cl.getResources(name); while (e2.hasMoreElements()) { result.add(e2.nextElement()); } } } } }
-
9. Re: Facelets scanning for .taglib.xml is broken in trunk
starksm64 Feb 6, 2008 4:44 PM (in response to pmuir)getAlternativeJarFile is broken for vfs urls. It all comes down to no ability to navigate a URL and no ClassLoader.getResources with a regex pattern, so they have to try to guess what type of URL it is. There needs to be a better servlet api to access resources inside of a war for code like this to work in general.
Is there any point that the tag lib urls can be overriden? -
10. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 6, 2008 5:03 PM (in response to pmuir)"scott.stark@jboss.org" wrote:
getAlternativeJarFile is broken for vfs urls. It all comes down to no ability to navigate a URL and no ClassLoader.getResources with a regex pattern, so they have to try to guess what type of URL it is.
But why this worked before, with VFS and the new CL both already being used.
Why it stopped with your war CL changes?"scott.stark@jboss.org" wrote:
There needs to be a better servlet api to access resources inside of a war for code like this to work in general.
Couldn't agree more.
But we are constantly seeing this problem, so it won't go away soon. :-("scott.stark@jboss.org" wrote:
Is there any point that the tag lib urls can be overriden?
Pete or. any other Seam/Facelet guru? -
11. Re: Facelets scanning for .taglib.xml is broken in trunk
starksm64 Feb 6, 2008 5:15 PM (in response to pmuir)"alesj" wrote:
But why this worked before, with VFS and the new CL both already being used.
Why it stopped with your war CL changes?
I would guess because tomcat was rebuilding the URLClassLoader classpath, perhaps using the extracted jar so that they were simple file urls to the jars.
This code should be using JarInputStream(InputStream in) rather than a JarFile so that the InputStream can be obtained from an arbitrary URL. JarFile is the least flexible api to be using. -
12. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 6, 2008 8:20 PM (in response to pmuir)"scott.stark@jboss.org" wrote:
This code should be using JarInputStream(InputStream in) rather than a JarFile so that the InputStream can be obtained from an arbitrary URL. JarFile is the least flexible api to be using.
What's to do here?
Have home brew of this on top of VFS?
And push for change of making this search either pluggable or using JIS? -
13. Re: Facelets scanning for .taglib.xml is broken in trunk
starksm64 Feb 6, 2008 9:15 PM (in response to pmuir)If JarFile supported a JarInputStream I would look at support a JarURLConnection from the handler, but you have to have a path to a file as far as I can see.
I would say hacking the facelets code to create patch Classpath to try to use a JarInputStream to find the taglib descriptiors is the best approach. There will be a patched facelets jars required, and we give back the patch. -
14. Re: Facelets scanning for .taglib.xml is broken in trunk
alesj Feb 7, 2008 3:36 PM (in response to pmuir)Yeah!
Got it working. :-)
Hacked the Facelets.
I didn't go into even bigger torture, and I simply implemented search on top of VFS.