Ask the provided handler factory (if any), then try to find class on current classloader, then try to find class on system classloader for built-in handlers (FELIX-3296).
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1333610 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlers.java b/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
index e3aa475..9133c34 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
@@ -117,11 +117,16 @@
private static final Map m_handlerToURL = new HashMap();
- private void init(String protocol)
+ private void init(String protocol, URLStreamHandlerFactory factory)
{
try
{
- m_handlerToURL.put(getBuiltInStreamHandler(protocol, null), new URL(protocol + ":") );
+ URLStreamHandler handler = getBuiltInStreamHandler(protocol, factory);
+ if (handler != null)
+ {
+ URL url = new URL(protocol, null, -1, "", handler);
+ m_handlerToURL.put(handler, url);
+ }
}
catch (Throwable ex)
{
@@ -139,21 +144,45 @@
**/
private URLHandlers()
{
- init("file");
- init("ftp");
- init("http");
- init("https");
- try
- {
- getBuiltInStreamHandler("jar", null);
- }
- catch (Throwable ex)
- {
- // Ignore, this is a best effort (maybe log it or something)
- }
m_sm = new SecurityManagerEx();
synchronized (URL.class)
{
+ URLStreamHandlerFactory currentFactory = null;
+ try
+ {
+ currentFactory = (URLStreamHandlerFactory) m_secureAction.swapStaticFieldIfNotClass(URL.class,
+ URLStreamHandlerFactory.class, URLHANDLERS_CLASS, "streamHandlerLock");
+ }
+ catch (Exception ex)
+ {
+ // Ignore, this is a best effort (maybe log it or something)
+ }
+
+ init("file", currentFactory);
+ init("ftp", currentFactory);
+ init("http", currentFactory);
+ init("https", currentFactory);
+ try
+ {
+ getBuiltInStreamHandler("jar", currentFactory);
+ }
+ catch (Throwable ex)
+ {
+ // Ignore, this is a best effort (maybe log it or something)
+ }
+
+ if (currentFactory != null)
+ {
+ try
+ {
+ URL.setURLStreamHandlerFactory(currentFactory);
+ }
+ catch (Exception ex)
+ {
+ // Ignore, this is a best effort (maybe log it or something)
+ }
+ }
+
try
{
URL.setURLStreamHandlerFactory(this);
@@ -342,6 +371,15 @@
}
// Check for built-in handlers for the mime type.
// Iterate over built-in packages.
+ URLStreamHandler handler = loadBuiltInStreamHandler(protocol, null);
+ if (handler == null)
+ {
+ handler = loadBuiltInStreamHandler(protocol, ClassLoader.getSystemClassLoader());
+ }
+ return addToCache(protocol, handler);
+ }
+
+ private URLStreamHandler loadBuiltInStreamHandler(String protocol, ClassLoader classLoader) {
StringTokenizer pkgTok = new StringTokenizer(m_streamPkgs, "| ");
while (pkgTok.hasMoreTokens())
{
@@ -350,11 +388,10 @@
try
{
// If a built-in handler is found then cache and return it
- Class handler = m_secureAction.forName(className);
+ Class handler = m_secureAction.forName(className, classLoader);
if (handler != null)
{
- return addToCache(protocol,
- (URLStreamHandler) handler.newInstance());
+ return (URLStreamHandler) handler.newInstance();
}
}
catch (Throwable ex)
@@ -364,16 +401,16 @@
// case other than ignore it.
}
}
- return addToCache(protocol, null);
+ return null;
}
private synchronized URLStreamHandler addToCache(String protocol, URLStreamHandler result)
{
if (!m_builtIn.containsKey(protocol))
- {
- m_builtIn.put(protocol, result);
- return result;
- }
+ {
+ m_builtIn.put(protocol, result);
+ return result;
+ }
return (URLStreamHandler) m_builtIn.get(protocol);
}
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
index 4d51311..64610c4 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -56,11 +56,11 @@
private static final String CONTENT_HANDLER_PACKAGE_PROP = "java.content.handler.pkgs";
private static final String DEFAULT_CONTENT_HANDLER_PACKAGE = "sun.net.www.content|com.ibm.oti.net.www.content|gnu.java.net.content|org.apache.harmony.luni.internal.net.www.content|COM.newmonics.www.content";
-
+
private static final Map m_builtIn = new HashMap();
private static final String m_pkgs;
- static
+ static
{
String pkgs = new SecureAction().getSystemProperty(CONTENT_HANDLER_PACKAGE_PROP, "");
m_pkgs = (pkgs.equals(""))
@@ -73,13 +73,13 @@
private final String m_mimeType;
private final SecureAction m_action;
- public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
+ public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
ContentHandlerFactory factory)
{
m_mimeType = mimeType;
m_action = action;
m_factory = factory;
- }
+ }
//
// ContentHandler interface method.
@@ -111,11 +111,11 @@
// Get the framework instance associated with call stack.
Object framework = URLHandlers.getFrameworkFromContext();
- if (framework == null)
+ if (framework == null)
{
return getBuiltIn();
}
- try
+ try
{
ContentHandler service;
if (framework instanceof Felix)
@@ -128,7 +128,7 @@
m_action.getMethod(framework.getClass(), "getContentHandlerService", STRING_TYPES),
framework, new Object[]{m_mimeType});
}
-
+
return (service == null) ? getBuiltIn() : service;
}
catch (Exception ex)
@@ -169,10 +169,10 @@
try
{
// If a built-in handler is found then cache and return it
- Class handler = m_action.forName(className);
+ Class handler = m_action.forName(className, null);
if (handler != null)
{
- return addToCache(m_mimeType,
+ return addToCache(m_mimeType,
(ContentHandler) handler.newInstance());
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 35d9ae6..853c9ef 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -171,14 +171,14 @@
}
}
- public Class forName(String name) throws ClassNotFoundException
+ public Class forName(String name, ClassLoader classloader) throws ClassNotFoundException
{
if (System.getSecurityManager() != null)
{
try
{
Actions actions = (Actions) m_actions.get();
- actions.set(Actions.FOR_NAME_ACTION, name);
+ actions.set(Actions.FOR_NAME_ACTION, name, classloader);
return (Class) AccessController.doPrivileged(actions, m_acc);
}
catch (PrivilegedActionException ex)
@@ -190,6 +190,10 @@
throw (RuntimeException) ex.getException();
}
}
+ else if (classloader != null)
+ {
+ return Class.forName(name, true, classloader);
+ }
else
{
return Class.forName(name);
@@ -1543,7 +1547,8 @@
case FILE_IS_DIRECTORY_ACTION:
return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE;
case FOR_NAME_ACTION:
- return Class.forName((String) arg1);
+ return (arg2 == null) ? Class.forName((String) arg1) : Class.forName((String) arg1, true,
+ (ClassLoader) arg2);
case GET_ABSOLUTE_PATH_ACTION:
return ((File) arg1).getAbsolutePath();
case GET_CONSTRUCTOR_ACTION: