Issue #1448 - Reduce unncessary URL creation
This commit is contained in:
parent
c285d6f8bb
commit
f53776628f
|
@ -34,8 +34,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.servlet.ServletContainerInitializer;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.annotation.Name;
|
import org.eclipse.jetty.util.annotation.Name;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
@ -723,7 +721,7 @@ public class TypeUtil
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Resource.newResource(URIUtil.getJarSource(url.toString()));
|
return Resource.newResource(URIUtil.getJarSource(url.toURI()));
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// 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 java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLStreamHandlerFactory;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public final class URLStreamHandlerUtil
|
||||||
|
{
|
||||||
|
public static void setFactory(URLStreamHandlerFactory factory)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// First, reset the factory field
|
||||||
|
Field factoryField = getURLStreamHandlerFactoryField();
|
||||||
|
factoryField.setAccessible(true);
|
||||||
|
factoryField.set(null, null);
|
||||||
|
|
||||||
|
if(factory != null)
|
||||||
|
{
|
||||||
|
// Next, set the factory
|
||||||
|
URL.setURLStreamHandlerFactory(factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Throwable ignore)
|
||||||
|
{
|
||||||
|
ignore.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URLStreamHandlerFactory getFactory()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// First, reset the factory field
|
||||||
|
Field factoryField = getURLStreamHandlerFactoryField();
|
||||||
|
factoryField.setAccessible(true);
|
||||||
|
return (URLStreamHandlerFactory) factoryField.get(null);
|
||||||
|
}
|
||||||
|
catch(Throwable ignore)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field getURLStreamHandlerFactoryField()
|
||||||
|
{
|
||||||
|
Optional<Field> optFactoryField = Arrays.stream(URL.class.getDeclaredFields())
|
||||||
|
.filter((f) -> Modifier.isStatic(f.getModifiers()) &&
|
||||||
|
f.getType().equals(URLStreamHandlerFactory.class))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if(optFactoryField.isPresent())
|
||||||
|
return optFactoryField.get();
|
||||||
|
|
||||||
|
throw new RuntimeException( "Cannot find URLStreamHandlerFactory field in " + URL.class.getName() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,15 +18,18 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.webapp;
|
package org.eclipse.jetty.webapp;
|
||||||
|
|
||||||
import static org.eclipse.jetty.toolchain.test.ExtraMatchers.*;
|
import static org.eclipse.jetty.toolchain.test.ExtraMatchers.ordered;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.junit.Assert.*;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assume.assumeThat;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.instrument.IllegalClassFormatException;
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -48,7 +51,7 @@ public class WebAppClassLoaderTest
|
||||||
|
|
||||||
private Path testWebappDir;
|
private Path testWebappDir;
|
||||||
private WebAppContext _context;
|
private WebAppContext _context;
|
||||||
private WebAppClassLoader _loader;
|
protected WebAppClassLoader _loader;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception
|
public void init() throws Exception
|
||||||
|
@ -241,6 +244,9 @@ public class WebAppClassLoaderTest
|
||||||
@Test
|
@Test
|
||||||
public void testResources() throws Exception
|
public void testResources() throws Exception
|
||||||
{
|
{
|
||||||
|
// The existence of a URLStreamHandler changes the behavior
|
||||||
|
assumeThat("No URLStreamHandler in place", URLStreamHandlerUtil.getFactory(), nullValue());
|
||||||
|
|
||||||
List<URL> expected = new ArrayList<>();
|
List<URL> expected = new ArrayList<>();
|
||||||
List<URL> resources;
|
List<URL> resources;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// 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 java.net.URLStreamHandler;
|
||||||
|
import java.net.URLStreamHandlerFactory;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
public class WebAppClassLoaderUrlStreamTest extends WebAppClassLoaderTest
|
||||||
|
{
|
||||||
|
public static class URLHandlers implements URLStreamHandlerFactory
|
||||||
|
{
|
||||||
|
private static final String[] STREAM_HANDLER_PREFIXES;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
STREAM_HANDLER_PREFIXES = new String[]{
|
||||||
|
"sun.net.www.protocol",
|
||||||
|
"org.apache.harmony.luni.internal.net.www.protocol",
|
||||||
|
"javax.net.ssl"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, URLStreamHandler> handlers = new HashMap<>();
|
||||||
|
private ClassLoader loader;
|
||||||
|
|
||||||
|
public URLHandlers(ClassLoader loader)
|
||||||
|
{
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private URLStreamHandler getBuiltInHandler(String protocol, ClassLoader classLoader)
|
||||||
|
{
|
||||||
|
URLStreamHandler handler = handlers.get(protocol);
|
||||||
|
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
for (String prefix : STREAM_HANDLER_PREFIXES)
|
||||||
|
{
|
||||||
|
String className = prefix + '.' + protocol + ".Handler";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> clazz = Class.forName(className, false, classLoader);
|
||||||
|
handler = (URLStreamHandler) clazz.newInstance();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ignore)
|
||||||
|
{
|
||||||
|
ignore.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handlers.put(protocol, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unable to find handler for protocol [" + protocol + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URLStreamHandler createURLStreamHandler(String protocol)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getBuiltInHandler(protocol, loader);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unable to create URLStreamHandler for protocol [" + protocol + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanupURLStreamHandlerFactory()
|
||||||
|
{
|
||||||
|
URLStreamHandlerUtil.setFactory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws Exception
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
URLStreamHandlerUtil.setFactory(new URLHandlers(_loader));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue