From 13d914aa7c8ba87eb7a8176de52da59f5f756228 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 10 Mar 2016 04:41:30 +1100 Subject: [PATCH] Work in progress on Features Moved jar discovery to META-INF --- .../jetty/webapp/MetaInfConfiguration.java | 254 +++++++++++++++++- .../jetty/webapp/WebInfConfiguration.java | 240 ----------------- 2 files changed, 252 insertions(+), 242 deletions(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java index f648ab3897a..3ea84b787b7 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/MetaInfConfiguration.java @@ -24,21 +24,29 @@ import java.io.IOException; import java.net.JarURLConnection; import java.net.URI; import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.stream.Collectors; +import org.eclipse.jetty.util.PatternMatcher; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.EmptyResource; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceCollection; /** * MetaInfConfiguration @@ -65,11 +73,19 @@ public class MetaInfConfiguration extends AbstractConfiguration public static final boolean DEFAULT_USE_CONTAINER_METAINF_CACHE = true; public static final String CACHED_CONTAINER_TLDS = "org.eclipse.jetty.tlds.cache"; public static final String CACHED_CONTAINER_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES+".cache"; - public static final String CACHED_CONTAINER_RESOURCES = WebInfConfiguration.RESOURCE_DIRS+".cache"; + public static final String CACHED_CONTAINER_RESOURCES = "org.eclipse.jetty.resources.cache"; public static final String METAINF_TLDS = "org.eclipse.jetty.tlds"; public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES; - public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_DIRS; + public static final String METAINF_RESOURCES = "org.eclipse.jetty.resources"; + public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"; + public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern"; + /** + * If set, to a list of URLs, these resources are added to the context + * resource base as a resource collection. + */ + public static final String RESOURCE_DIRS = "org.eclipse.jetty.resources"; + /* ------------------------------------------------------------------------------- */ public MetaInfConfiguration() { @@ -87,6 +103,53 @@ public class MetaInfConfiguration extends AbstractConfiguration @Override public void preConfigure(final WebAppContext context) throws Exception { + // discover matching container jars + if (context.getClassLoader() != null) + { + ClassLoader loader = context.getClassLoader().getParent(); + List uris = new ArrayList<>(); + while (loader != null && (loader instanceof URLClassLoader)) + { + URL[] urls = ((URLClassLoader)loader).getURLs(); + if (urls != null) + for(URL url:urls) + uris.add(new URI(url.toString().replaceAll(" ","%20"))); + loader = loader.getParent(); + } + + new PatternMatcher () + { + public void matched(URI uri) throws Exception + { + context.getMetaData().addContainerResource(Resource.newResource(uri)); + } + }.match((String)context.getAttribute(CONTAINER_JAR_PATTERN), + uris.toArray(new URI[uris.size()]), + false); + } + + + //Discover matching WEB-INF/lib jars + List jars = findJars(context); + if (jars!=null) + { + List uris = jars.stream().map(Resource::getURI).collect(Collectors.toList()); + + new PatternMatcher () + { + @Override + public void matched(URI uri) throws Exception + { + context.getMetaData().addWebInfJar(Resource.newResource(uri)); + } + }.match((String)context.getAttribute(WEBINF_JAR_PATTERN), + uris.toArray(new URI[uris.size()]), + true); + } + + //No pattern to appy to classes, just add to metadata + context.getMetaData().setWebInfClassesDirs(findClassDirs(context)); + boolean useContainerCache = DEFAULT_USE_CONTAINER_METAINF_CACHE; Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE); if (attr != null) @@ -107,6 +170,27 @@ public class MetaInfConfiguration extends AbstractConfiguration scanJars(context, context.getMetaData().getContainerResources(), useContainerCache); scanJars(context, context.getMetaData().getWebInfJars(), false); } + + + + @Override + public boolean configure(WebAppContext context) throws Exception + { + + // Look for extra resource + @SuppressWarnings("unchecked") + Set resources = (Set)context.getAttribute(RESOURCE_DIRS); + if (resources!=null && !resources.isEmpty()) + { + Resource[] collection=new Resource[resources.size()+1]; + int i=0; + collection[i++]=context.getBaseResource(); + for (Resource resource : resources) + collection[i++]=resource; + context.setBaseResource(new ResourceCollection(collection)); + } + return true; + } /** * Look into the jars to discover info in META-INF. If useCaches == true, then we will @@ -434,4 +518,170 @@ public class MetaInfConfiguration extends AbstractConfiguration jarFile.close(); return tlds; } + + + protected List findClassDirs (WebAppContext context) + throws Exception + { + if (context == null) + return null; + + List classDirs = new ArrayList(); + + Resource webInfClasses = findWebInfClassesDir(context); + if (webInfClasses != null) + classDirs.add(webInfClasses); + List extraClassDirs = findExtraClasspathDirs(context); + if (extraClassDirs != null) + classDirs.addAll(extraClassDirs); + + return classDirs; + } + + + /** + * Look for jars that should be treated as if they are in WEB-INF/lib + * + * @param context the context to find the jars in + * @return the list of jar resources found within context + * @throws Exception if unable to find the jars + */ + protected List findJars (WebAppContext context) + throws Exception + { + List jarResources = new ArrayList(); + List webInfLibJars = findWebInfLibJars(context); + if (webInfLibJars != null) + jarResources.addAll(webInfLibJars); + List extraClasspathJars = findExtraClasspathJars(context); + if (extraClasspathJars != null) + jarResources.addAll(extraClasspathJars); + return jarResources; + } + + /** + * Look for jars in WEB-INF/lib + * + * @param context the context to find the lib jars in + * @return the list of jars as {@link Resource} + * @throws Exception if unable to scan for lib jars + */ + protected List findWebInfLibJars(WebAppContext context) + throws Exception + { + Resource web_inf = context.getWebInf(); + if (web_inf==null || !web_inf.exists()) + return null; + + List jarResources = new ArrayList(); + Resource web_inf_lib = web_inf.addPath("/lib"); + if (web_inf_lib.exists() && web_inf_lib.isDirectory()) + { + String[] files=web_inf_lib.list(); + for (int f=0;files!=null && f findExtraClasspathJars(WebAppContext context) + throws Exception + { + if (context == null || context.getExtraClasspath() == null) + return null; + + List jarResources = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(context.getExtraClasspath(), ",;"); + while (tokenizer.hasMoreTokens()) + { + Resource resource = context.newResource(tokenizer.nextToken().trim()); + String fnlc = resource.getName().toLowerCase(Locale.ENGLISH); + int dot = fnlc.lastIndexOf('.'); + String extension = (dot < 0 ? null : fnlc.substring(dot)); + if (extension != null && (extension.equals(".jar") || extension.equals(".zip"))) + { + jarResources.add(resource); + } + } + + return jarResources; + } + + /** + * Get WEB-INF/classes dir + * + * @param context the context to look for the WEB-INF/classes directory + * @return the Resource for the WEB-INF/classes directory + * @throws Exception if unable to find the WEB-INF/classes directory + */ + protected Resource findWebInfClassesDir (WebAppContext context) + throws Exception + { + if (context == null) + return null; + + Resource web_inf = context.getWebInf(); + + // Find WEB-INF/classes + if (web_inf != null && web_inf.isDirectory()) + { + // Look for classes directory + Resource classes= web_inf.addPath("classes/"); + if (classes.exists()) + return classes; + } + return null; + } + + + /** + * Get class dirs from WebAppContext.getExtraClasspath as resources + * + * @param context the context to look for extra classpaths in + * @return the list of Resources to the extra classpath + * @throws Exception if unable to find the extra classpaths + */ + protected List findExtraClasspathDirs(WebAppContext context) + throws Exception + { + if (context == null || context.getExtraClasspath() == null) + return null; + + List dirResources = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(context.getExtraClasspath(), ",;"); + while (tokenizer.hasMoreTokens()) + { + Resource resource = context.newResource(tokenizer.nextToken().trim()); + if (resource.exists() && resource.isDirectory()) + dirResources.add(resource); + } + + return dirResources; + } + } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index b93a1efe461..d76886a8412 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -20,21 +20,12 @@ package org.eclipse.jetty.webapp; import java.io.File; import java.io.IOException; -import java.net.URI; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; import java.util.Locale; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.stream.Collectors; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.PatternMatcher; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -47,15 +38,6 @@ public class WebInfConfiguration extends AbstractConfiguration private static final Logger LOG = Log.getLogger(WebInfConfiguration.class); public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured"; - public static final String CONTAINER_JAR_PATTERN = "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"; - public static final String WEBINF_JAR_PATTERN = "org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern"; - - /** - * If set, to a list of URLs, these resources are added to the context - * resource base as a resource collection. - */ - public static final String RESOURCE_DIRS = "org.eclipse.jetty.resources"; - protected Resource _preUnpackBaseResource; @@ -79,52 +61,6 @@ public class WebInfConfiguration extends AbstractConfiguration //Extract webapp if necessary unpack (context); - // discover matching container jars - if (context.getClassLoader() != null) - { - ClassLoader loader = context.getClassLoader().getParent(); - List uris = new ArrayList<>(); - while (loader != null && (loader instanceof URLClassLoader)) - { - URL[] urls = ((URLClassLoader)loader).getURLs(); - if (urls != null) - for(URL url:urls) - uris.add(new URI(url.toString().replaceAll(" ","%20"))); - loader = loader.getParent(); - } - - new PatternMatcher () - { - public void matched(URI uri) throws Exception - { - context.getMetaData().addContainerResource(Resource.newResource(uri)); - } - }.match((String)context.getAttribute(CONTAINER_JAR_PATTERN), - uris.toArray(new URI[uris.size()]), - false); - } - - - //Discover matcghing WEB-INF/lib jars - List jars = findJars(context); - if (jars!=null) - { - List uris = jars.stream().map(Resource::getURI).collect(Collectors.toList()); - - new PatternMatcher () - { - @Override - public void matched(URI uri) throws Exception - { - context.getMetaData().addWebInfJar(Resource.newResource(uri)); - } - }.match((String)context.getAttribute(WEBINF_JAR_PATTERN), - uris.toArray(new URI[uris.size()]), - true); - } - - //No pattern to appy to classes, just add to metadata - context.getMetaData().setWebInfClassesDirs(findClassDirs(context)); } @@ -147,18 +83,6 @@ public class WebInfConfiguration extends AbstractConfiguration ((WebAppClassLoader)context.getClassLoader()).addJars(lib); } - // Look for extra resource - @SuppressWarnings("unchecked") - Set resources = (Set)context.getAttribute(RESOURCE_DIRS); - if (resources!=null && !resources.isEmpty()) - { - Resource[] collection=new Resource[resources.size()+1]; - int i=0; - collection[i++]=context.getBaseResource(); - for (Resource resource : resources) - collection[i++]=resource; - context.setBaseResource(new ResourceCollection(collection)); - } return true; } @@ -634,169 +558,5 @@ public class WebInfConfiguration extends AbstractConfiguration } - protected List findClassDirs (WebAppContext context) - throws Exception - { - if (context == null) - return null; - - List classDirs = new ArrayList(); - - Resource webInfClasses = findWebInfClassesDir(context); - if (webInfClasses != null) - classDirs.add(webInfClasses); - List extraClassDirs = findExtraClasspathDirs(context); - if (extraClassDirs != null) - classDirs.addAll(extraClassDirs); - - return classDirs; - } - - - /** - * Look for jars that should be treated as if they are in WEB-INF/lib - * - * @param context the context to find the jars in - * @return the list of jar resources found within context - * @throws Exception if unable to find the jars - */ - protected List findJars (WebAppContext context) - throws Exception - { - List jarResources = new ArrayList(); - List webInfLibJars = findWebInfLibJars(context); - if (webInfLibJars != null) - jarResources.addAll(webInfLibJars); - List extraClasspathJars = findExtraClasspathJars(context); - if (extraClasspathJars != null) - jarResources.addAll(extraClasspathJars); - return jarResources; - } - - /** - * Look for jars in WEB-INF/lib - * - * @param context the context to find the lib jars in - * @return the list of jars as {@link Resource} - * @throws Exception if unable to scan for lib jars - */ - protected List findWebInfLibJars(WebAppContext context) - throws Exception - { - Resource web_inf = context.getWebInf(); - if (web_inf==null || !web_inf.exists()) - return null; - - List jarResources = new ArrayList(); - Resource web_inf_lib = web_inf.addPath("/lib"); - if (web_inf_lib.exists() && web_inf_lib.isDirectory()) - { - String[] files=web_inf_lib.list(); - for (int f=0;files!=null && f findExtraClasspathJars(WebAppContext context) - throws Exception - { - if (context == null || context.getExtraClasspath() == null) - return null; - - List jarResources = new ArrayList(); - StringTokenizer tokenizer = new StringTokenizer(context.getExtraClasspath(), ",;"); - while (tokenizer.hasMoreTokens()) - { - Resource resource = context.newResource(tokenizer.nextToken().trim()); - String fnlc = resource.getName().toLowerCase(Locale.ENGLISH); - int dot = fnlc.lastIndexOf('.'); - String extension = (dot < 0 ? null : fnlc.substring(dot)); - if (extension != null && (extension.equals(".jar") || extension.equals(".zip"))) - { - jarResources.add(resource); - } - } - - return jarResources; - } - - /** - * Get WEB-INF/classes dir - * - * @param context the context to look for the WEB-INF/classes directory - * @return the Resource for the WEB-INF/classes directory - * @throws Exception if unable to find the WEB-INF/classes directory - */ - protected Resource findWebInfClassesDir (WebAppContext context) - throws Exception - { - if (context == null) - return null; - - Resource web_inf = context.getWebInf(); - - // Find WEB-INF/classes - if (web_inf != null && web_inf.isDirectory()) - { - // Look for classes directory - Resource classes= web_inf.addPath("classes/"); - if (classes.exists()) - return classes; - } - return null; - } - - - /** - * Get class dirs from WebAppContext.getExtraClasspath as resources - * - * @param context the context to look for extra classpaths in - * @return the list of Resources to the extra classpath - * @throws Exception if unable to find the extra classpaths - */ - protected List findExtraClasspathDirs(WebAppContext context) - throws Exception - { - if (context == null || context.getExtraClasspath() == null) - return null; - - List dirResources = new ArrayList(); - StringTokenizer tokenizer = new StringTokenizer(context.getExtraClasspath(), ",;"); - while (tokenizer.hasMoreTokens()) - { - Resource resource = context.newResource(tokenizer.nextToken().trim()); - if (resource.exists() && resource.isDirectory()) - dirResources.add(resource); - } - - return dirResources; - } - }