Issue #1467
This commit is contained in:
parent
5d6bda39b6
commit
70160c5b3f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue