Index: jasper/src/share/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java =================================================================== --- jasper/src/share/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java (revision 787738) +++ jasper/src/share/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java (working copy) @@ -17,6 +17,7 @@ package org.apache.jasper.compiler; +import java.net.URL; import java.util.*; import javax.servlet.jsp.tagext.FunctionInfo; import javax.servlet.jsp.tagext.TagLibraryInfo; @@ -123,9 +124,11 @@ TagInfo tagInfo = null; try { tagInfo = TagFileProcessor.parseTagFileDirectives(pc, - shortName, - path, - this); + shortName, + path, + (URL) pc.getJspCompilationContext().getTagFileJarUrls( + ).get(path), + this); } catch (JasperException je) { throw new RuntimeException(je.toString()); } Index: jasper/src/share/org/apache/jasper/compiler/JspUtil.java =================================================================== --- jasper/src/share/org/apache/jasper/compiler/JspUtil.java (revision 787738) +++ jasper/src/share/org/apache/jasper/compiler/JspUtil.java (working copy) @@ -851,10 +851,31 @@ * * @return Fully-qualified class name of the tag handler corresponding to * the given tag file path + * + * @deprecated Use {@link #getTagHandlerClassName(String, String, + * ErrorDispatcher) + * See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 */ public static String getTagHandlerClassName(String path, ErrorDispatcher err) throws JasperException { + return getTagHandlerClassName(path, null, err); + } + + /** + * Gets the fully-qualified class name of the tag handler corresponding to + * the given tag file path. + * + * @param path + * Tag file path + * @param err + * Error dispatcher + * + * @return Fully-qualified class name of the tag handler corresponding to + * the given tag file path + */ + public static String getTagHandlerClassName(String path, String urn, + ErrorDispatcher err) throws JasperException { String className = null; int begin = 0; @@ -880,20 +901,29 @@ className = "org.apache.jsp.tag.web."; begin = index + WEB_INF_TAGS.length(); } else { - index = path.indexOf(META_INF_TAGS); - if (index != -1) { - className = "org.apache.jsp.tag.meta."; - begin = index + META_INF_TAGS.length(); - } else { - err.jspError("jsp.error.tagfile.illegalPath", path); - } - } + index = path.indexOf(META_INF_TAGS); + if (index != -1) { + className = getClassNameBase(urn); + begin = index + META_INF_TAGS.length(); + } else { + err.jspError("jsp.error.tagfile.illegalPath", path); + } + } className += makeJavaPackage(path.substring(begin)); return className; } + private static String getClassNameBase(String urn) { + StringBuffer base = new StringBuffer("org.apache.jsp.tag.meta."); + if (urn != null) { + base.append(makeJavaPackage(urn)); + base.append('.'); + } + return base.toString(); + } + /** * Converts the given path to a Java package or fully-qualified class name * Index: jasper/src/share/org/apache/jasper/compiler/ParserController.java =================================================================== --- jasper/src/share/org/apache/jasper/compiler/ParserController.java (revision 787738) +++ jasper/src/share/org/apache/jasper/compiler/ParserController.java (working copy) @@ -124,15 +124,31 @@ * This is invoked by the compiler * * @param inFileName The name of the tag file to be parsed. + * @deprecated Use {@link #parseTagFileDirectives(String, URL)} + * See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 */ public Node.Nodes parseTagFileDirectives(String inFileName) throws FileNotFoundException, JasperException, IOException { + return parseTagFileDirectives( + inFileName, (URL) ctxt.getTagFileJarUrls().get(inFileName)); + } + + /** + * Extracts tag file directive information from the given tag file. + * + * This is invoked by the compiler + * + * @param inFileName The name of the tag file to be parsed. + * @param tagFileJarUrl The location of the tag file. + */ + public Node.Nodes parseTagFileDirectives(String inFileName, + URL tagFileJarUrl) + throws FileNotFoundException, JasperException, IOException { boolean isTagFileSave = isTagFile; boolean directiveOnlySave = directiveOnly; isTagFile = true; directiveOnly = true; - Node.Nodes page = doParse(inFileName, null, - (URL) ctxt.getTagFileJarUrls().get(inFileName)); + Node.Nodes page = doParse(inFileName, null, tagFileJarUrl); directiveOnly = directiveOnlySave; isTagFile = isTagFileSave; return page; Index: jasper/src/share/org/apache/jasper/compiler/TagFileProcessor.java =================================================================== --- jasper/src/share/org/apache/jasper/compiler/TagFileProcessor.java (revision 787738) +++ jasper/src/share/org/apache/jasper/compiler/TagFileProcessor.java (working copy) @@ -19,6 +19,7 @@ import java.io.FileNotFoundException; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Iterator; @@ -310,7 +311,8 @@ bodycontent = TagInfo.BODY_CONTENT_SCRIPTLESS; } - String tagClassName = JspUtil.getTagHandlerClassName(path, err); + String tagClassName = JspUtil.getTagHandlerClassName(path, + tagLibInfo.getReliableURN(), err); TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()]; @@ -430,18 +432,49 @@ * @param tagfile the path for the tagfile * @param tagLibInfo the TagLibraryInfo object associated with this TagInfo * @return a TagInfo object assembled from the directives in the tag file. + * @deprecated Use {@link TagFileProcessor#parseTagFileDirectives( + * ParserController, String, String, URL, TagLibraryInfo)} + * See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 */ public static TagInfo parseTagFileDirectives(ParserController pc, String name, String path, TagLibraryInfo tagLibInfo) throws JasperException { + return parseTagFileDirectives(pc, name, path, + (URL) pc.getJspCompilationContext().getTagFileJarUrls( + ).get(path), + tagLibInfo); + } + + /** + * Parses the tag file, and collects information on the directives included + * in it. The method is used to obtain the info on the tag file, when the + * handler that it represents is referenced. The tag file is not compiled + * here. + * + * @param pc + * the current ParserController used in this compilation + * @param name + * the tag name as specified in the TLD + * @param tagfile + * the path for the tagfile + * @param tagFileJarUrl + * the url for the Jar containign the tag file + * @param tagLibInfo + * the TagLibraryInfo object associated with this TagInfo + * @return a TagInfo object assembled from the directives in the tag file. + */ + public static TagInfo parseTagFileDirectives(ParserController pc, + String name, String path, URL tagFileJarUrl, TagLibraryInfo tagLibInfo) + throws JasperException { + ErrorDispatcher err = pc.getCompiler().getErrorDispatcher(); Node.Nodes page = null; try { - page = pc.parseTagFileDirectives(path); + page = pc.parseTagFileDirectives(path, tagFileJarUrl); } catch (FileNotFoundException e) { err.jspError("jsp.error.file.not.found", path); } catch (IOException e) { @@ -465,10 +498,27 @@ PageInfo parentPageInfo) throws JasperException { + URL tagFileJarUrl = null; + if (tagFilePath.startsWith("/META-INF/")) { + try { + tagFileJarUrl = new URL("jar:" + + compiler.getCompilationContext().getTldLocation( + tagInfo.getTagLibrary().getURI())[0] + "!/"); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + String tagFileJarPath; + if (tagFileJarUrl == null) { + tagFileJarPath = ""; + } else { + tagFileJarPath = tagFileJarUrl.toString(); + } + JspCompilationContext ctxt = compiler.getCompilationContext(); JspRuntimeContext rctxt = ctxt.getRuntimeContext(); JspServletWrapper wrapper = - (JspServletWrapper) rctxt.getWrapper(tagFilePath); + rctxt.getWrapper(tagFileJarPath +tagFilePath); synchronized(rctxt) { if (wrapper == null) { @@ -477,8 +527,8 @@ tagFilePath, tagInfo, ctxt.getRuntimeContext(), - (URL) ctxt.getTagFileJarUrls().get(tagFilePath)); - rctxt.addWrapper(tagFilePath,wrapper); + tagFileJarUrl); + rctxt.addWrapper(tagFileJarUrl + tagFilePath, wrapper); // Use same classloader and classpath for compiling tag files wrapper.getJspEngineContext().setClassLoader( Index: jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java =================================================================== --- jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java (revision 787738) +++ jasper/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java (working copy) @@ -492,6 +492,9 @@ if (path.startsWith("/META-INF/tags")) { // Tag file packaged in JAR + // See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 + // This needs to be removed once all the broken code that depends on + // it has been removed // check if jarFileUrl is not null before adding it, or this will // cause a NPE. if (jarFileUrl != null) { @@ -503,7 +506,7 @@ TagInfo tagInfo = TagFileProcessor.parseTagFileDirectives(parserController, name, - path, this); + path, jarFileUrl, this); return new TagFileInfo(name, path, tagInfo); } @@ -550,7 +553,7 @@ } } else if ("description".equals(tname) || // Ignored elements false) { - ; + // Do nothing } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage(