This commit is contained in:
Jan Bartel 2017-04-13 16:49:07 +10:00
parent 5d6bda39b6
commit 70160c5b3f
12 changed files with 345 additions and 28 deletions

View File

@ -344,8 +344,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
{
context.getObjectFactory().addDecorator(new AnnotationDecorator(context));
//Even if metadata is complete, we still need to scan for ServletContainerInitializers - if there are any
if (!context.getMetaData().isMetaDataComplete())
{
//If metadata isn't complete, if this is a servlet 3 webapp or isConfigDiscovered is true, we need to search for annotations

View File

@ -19,6 +19,8 @@
package org.eclipse.jetty.annotations;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import java.io.File;
import java.net.URL;
@ -38,6 +40,76 @@ import org.junit.Test;
*/
public class TestAnnotationConfiguration
{
public class TestableAnnotationConfiguration extends AnnotationConfiguration
{
public void assertAnnotationDiscovery (boolean b)
{
if (!b)
assertTrue(_discoverableAnnotationHandlers.isEmpty());
else
assertFalse(_discoverableAnnotationHandlers.isEmpty());
}
}
@Test
public void testAnnotationScanControl() throws Exception
{
File web25 = MavenTestingUtils.getTestResourceFile("web25.xml");
File web31 = MavenTestingUtils.getTestResourceFile("web31.xml");
File web31false = MavenTestingUtils.getTestResourceFile("web31false.xml");
//check that a 2.5 webapp won't discover annotations
TestableAnnotationConfiguration config25 = new TestableAnnotationConfiguration();
WebAppContext context25 = new WebAppContext();
context25.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE);
context25.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, new Integer(0));
context25.getMetaData().setWebXml(Resource.newResource(web25));
context25.getServletContext().setEffectiveMajorVersion(2);
context25.getServletContext().setEffectiveMinorVersion(5);
config25.configure(context25);
config25.assertAnnotationDiscovery(false);
//check that a 2.5 webapp with configurationDiscovered will discover annotations
TestableAnnotationConfiguration config25b = new TestableAnnotationConfiguration();
WebAppContext context25b = new WebAppContext();
context25b.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE);
context25b.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, new Integer(0));
context25b.setConfigurationDiscovered(true);
context25b.getMetaData().setWebXml(Resource.newResource(web25));
context25b.getServletContext().setEffectiveMajorVersion(2);
context25b.getServletContext().setEffectiveMinorVersion(5);
config25b.configure(context25b);
config25b.assertAnnotationDiscovery(true);
//check that a 3.x webapp with metadata true won't discover annotations
TestableAnnotationConfiguration config31 = new TestableAnnotationConfiguration();
WebAppContext context31 = new WebAppContext();
context31.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE);
context31.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, new Integer(0));
context31.getMetaData().setWebXml(Resource.newResource(web31));
context31.getServletContext().setEffectiveMajorVersion(3);
context31.getServletContext().setEffectiveMinorVersion(1);
config31.configure(context31);
config31.assertAnnotationDiscovery(false);
//check that a 3.x webapp with metadata false will discover annotations
TestableAnnotationConfiguration config31b = new TestableAnnotationConfiguration();
WebAppContext context31b = new WebAppContext();
context31b.setAttribute(AnnotationConfiguration.MULTI_THREADED, Boolean.FALSE);
context31b.setAttribute(AnnotationConfiguration.MAX_SCAN_WAIT, new Integer(0));
context31b.getMetaData().setWebXml(Resource.newResource(web31false));
context31b.getServletContext().setEffectiveMajorVersion(3);
context31b.getServletContext().setEffectiveMinorVersion(1);
config31b.configure(context31b);
config31b.assertAnnotationDiscovery(true);
}
@Test
public void testGetFragmentFromJar() throws Exception
{

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Test 2.5 WebApp</display-name>
</web-app>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="true"
version="3.1">
<display-name>Test 31 WebApp</display-name>
</web-app>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<display-name>Test 31 WebApp</display-name>
</web-app>

View File

@ -31,16 +31,12 @@ import org.eclipse.jetty.util.resource.Resource;
public class FragmentConfiguration extends AbstractConfiguration
{
public final static String FRAGMENT_RESOURCES="org.eclipse.jetty.webFragments";
@Override
public void preConfigure(WebAppContext context) throws Exception
{
if (!context.isConfigurationDiscovered())
return;
//find all web-fragment.xmls
findWebFragments(context, context.getMetaData());
//add all discovered web-fragment.xmls
addWebFragments(context, context.getMetaData());
}
@ -49,16 +45,33 @@ public class FragmentConfiguration extends AbstractConfiguration
{
context.setAttribute(FRAGMENT_RESOURCES, null);
}
/* ------------------------------------------------------------------------------- */
/**
* Look for any web-fragment.xml fragments in META-INF of jars in WEB-INF/lib
* Add in fragment descriptors that have already been discovered by MetaInfConfiguration
*
* @param context the web app context to look in
* @param metaData the metadata to populate with fragments
*
* @throws Exception if unable to find web fragments
* @deprecated
*/
public void findWebFragments (final WebAppContext context, final MetaData metaData)
throws Exception
{
addWebFragments(context, metaData);
}
/* ------------------------------------------------------------------------------- */
/**
* Add in fragment descriptors that have already been discovered by MetaInfConfiguration
*
* @param context the web app context to look in
* @param metaData the metadata to populate with fragments
*
* @throws Exception if unable to find web fragments
*/
public void findWebFragments (final WebAppContext context, final MetaData metaData) throws Exception
public void addWebFragments (final WebAppContext context, final MetaData metaData) throws Exception
{
@SuppressWarnings("unchecked")
Map<Resource, Resource> frags = (Map<Resource,Resource>)context.getAttribute(FRAGMENT_RESOURCES);

View File

@ -24,11 +24,14 @@ import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
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.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ -69,14 +72,19 @@ public class MetaInfConfiguration extends AbstractConfiguration
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 List<String> __allScanTypes = (List<String>) Arrays.asList(METAINF_TLDS, METAINF_RESOURCES, METAINF_FRAGMENTS);
@Override
public void preConfigure(final WebAppContext context) throws Exception
{
{
boolean useContainerCache = DEFAULT_USE_CONTAINER_METAINF_CACHE;
Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE);
if (attr != null)
useContainerCache = attr.booleanValue();
if (context.getServer() != null)
{
Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE);
if (attr != null)
useContainerCache = attr.booleanValue();
}
if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache);
@ -89,9 +97,28 @@ public class MetaInfConfiguration extends AbstractConfiguration
context.setAttribute(METAINF_RESOURCES, new HashSet<Resource>());
if (context.getAttribute(METAINF_FRAGMENTS) == null)
context.setAttribute(METAINF_FRAGMENTS, new HashMap<Resource, Resource>());
scanJars(context, context.getMetaData().getContainerResources(), useContainerCache);
scanJars(context, context.getMetaData().getWebInfJars(), false);
//always scan everything from the container's classpath
scanJars(context, context.getMetaData().getContainerResources(), useContainerCache, __allScanTypes);
//only look for fragments if web.xml is not metadata complete, or it version 3.0 or greater
List<String> scanTypes = new ArrayList<>(__allScanTypes);
if (context.getMetaData().isMetaDataComplete() || (context.getServletContext().getEffectiveMajorVersion() < 3) && !context.isConfigurationDiscovered())
scanTypes.remove(METAINF_FRAGMENTS);
scanJars(context, context.getMetaData().getWebInfJars(), false, scanTypes);
}
/**
* For backwards compatibility. This method will always scan for all types of data.
*
* @param context the context for the scan
* @param jars the jars to scan
* @param useCaches if true, the scanned info is cached
* @throws Exception
*/
public void scanJars (final WebAppContext context, Collection<Resource> jars, boolean useCaches)
throws Exception
{
scanJars(context, jars, useCaches, __allScanTypes);
}
/**
@ -102,9 +129,10 @@ public class MetaInfConfiguration extends AbstractConfiguration
* @param context the context for the scan
* @param jars the jars resources to scan
* @param useCaches if true, cache the info discovered
* @param scanTypes the type of things to look for in the jars
* @throws Exception if unable to scan the jars
*/
public void scanJars (final WebAppContext context, Collection<Resource> jars, boolean useCaches)
public void scanJars (final WebAppContext context, Collection<Resource> jars, boolean useCaches, List<String> scanTypes )
throws Exception
{
ConcurrentHashMap<Resource, Resource> metaInfResourceCache = null;
@ -131,16 +159,18 @@ public class MetaInfConfiguration extends AbstractConfiguration
context.getServer().setAttribute(CACHED_CONTAINER_TLDS, metaInfTldCache);
}
}
//Scan jars for META-INF information
if (jars != null)
{
for (Resource r : jars)
{
scanForResources(context, r, metaInfResourceCache);
scanForFragment(context, r, metaInfFragmentCache);
scanForTlds(context, r, metaInfTldCache);
{
if (scanTypes.contains(METAINF_RESOURCES))
scanForResources(context, r, metaInfResourceCache);
if (scanTypes.contains(METAINF_FRAGMENTS))
scanForFragment(context, r, metaInfFragmentCache);
if (scanTypes.contains(METAINF_TLDS))
scanForTlds(context, r, metaInfTldCache);
}
}
}

View File

@ -185,7 +185,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
private Map<String, String> _resourceAliases;
private boolean _ownClassLoader=false;
private boolean _configurationDiscovered=true;
private boolean _configurationDiscovered=false;
private boolean _allowDuplicateFragmentNames = false;
private boolean _throwUnavailableOnStartupException = false;

View File

@ -0,0 +1,140 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.webapp;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.Test;
/**
* MetaInfConfigurationTest
*
*
*/
public class MetaInfConfigurationTest
{
public class TestableMetaInfConfiguration extends MetaInfConfiguration
{
List<String> _expectedContainerScanTypes;
List<String> _expectedWebAppScanTypes;
int _invocationCount = 0;
public TestableMetaInfConfiguration(List<String> expectedContainerScanTypes, List<String> expectedWebAppScanTypes)
{
_expectedContainerScanTypes = expectedContainerScanTypes;
_expectedWebAppScanTypes = expectedWebAppScanTypes;
}
/**
* @see org.eclipse.jetty.webapp.MetaInfConfiguration#scanJars(org.eclipse.jetty.webapp.WebAppContext, java.util.Collection, boolean, java.util.List)
*/
@Override
public void scanJars(WebAppContext context, Collection<Resource> jars, boolean useCaches, List<String> scanTypes) throws Exception
{
assertNotNull(scanTypes);
List<String> expectedScanTypes = null;
switch (_invocationCount)
{
case 0:
{
expectedScanTypes = _expectedContainerScanTypes;
break;
}
case 1:
{
expectedScanTypes = _expectedWebAppScanTypes;
break;
}
default:
{
fail("Too many invocations");
}
}
++_invocationCount;
assertNotNull(expectedScanTypes);
assertTrue(expectedScanTypes.containsAll(scanTypes));
assertEquals(expectedScanTypes.size(), scanTypes.size());
}
}
@Test
public void testScanTypes()
throws Exception
{
File web25 = MavenTestingUtils.getTestResourceFile("web25.xml");
File web31 = MavenTestingUtils.getTestResourceFile("web31.xml");
File web31false = MavenTestingUtils.getTestResourceFile("web31false.xml");
//test a 2.5 webapp will not look for fragments by default
MetaInfConfiguration meta25 = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes,
Arrays.asList(MetaInfConfiguration.METAINF_TLDS, MetaInfConfiguration.METAINF_RESOURCES));
WebAppContext context25 = new WebAppContext();
context25.getMetaData().setWebXml(Resource.newResource(web25));
context25.getServletContext().setEffectiveMajorVersion(2);
context25.getServletContext().setEffectiveMinorVersion(5);
meta25.preConfigure(context25);
//test a 2.5 webapp will look for fragments if configurationDiscovered==true
MetaInfConfiguration meta25b = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes,
MetaInfConfiguration.__allScanTypes);
WebAppContext context25b = new WebAppContext();
context25b.setConfigurationDiscovered(true);
context25b.getMetaData().setWebXml(Resource.newResource(web25));
context25b.getServletContext().setEffectiveMajorVersion(2);
context25b.getServletContext().setEffectiveMinorVersion(5);
meta25b.preConfigure(context25b);
//test a 3.x metadata-complete webapp will not look for fragments
MetaInfConfiguration meta31 = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes,
Arrays.asList(MetaInfConfiguration.METAINF_TLDS, MetaInfConfiguration.METAINF_RESOURCES));
WebAppContext context31 = new WebAppContext();
context31.getMetaData().setWebXml(Resource.newResource(web31));
context31.getServletContext().setEffectiveMajorVersion(3);
context31.getServletContext().setEffectiveMinorVersion(1);
meta31.preConfigure(context31);
//test a 3.x non metadata-complete webapp will look for fragments
MetaInfConfiguration meta31false = new TestableMetaInfConfiguration(MetaInfConfiguration.__allScanTypes,
MetaInfConfiguration.__allScanTypes);
WebAppContext context31false = new WebAppContext();
context31false.setConfigurationDiscovered(true);
context31false.getMetaData().setWebXml(Resource.newResource(web31false));
context31false.getServletContext().setEffectiveMajorVersion(3);
context31false.getServletContext().setEffectiveMinorVersion(1);
meta31false.preConfigure(context31false);
}
}

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Test 2.5 WebApp</display-name>
</web-app>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="true"
version="3.1">
<display-name>Test 31 WebApp</display-name>
</web-app>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<display-name>Test 31 WebApp</display-name>
</web-app>