Switch URLHandlers to the old behavior of not overriding built-in handlers by default. Overriding can be enabled using a felix.service.urlhandlers.override=true system property. Furthermore, fix a bug that made URLHandlersBundleStreamHandler.openConnection(URL) fail when extending Felix. (FELIX-756, FELIX-800)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@710105 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 20906eb..8253dab 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
@@ -66,7 +66,15 @@
**/
class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
{
+ private static final String STREAM_HANDLER_PACKAGE_PROP = "java.protocol.handler.pkgs";
+ private static final String DEFAULT_STREAM_HANDLER_PACKAGE = "sun.net.www.protocol|com.ibm.oti.net.www.protocol|gnu.java.net.protocol|wonka.net|com.acunia.wonka.net|org.apache.harmony.luni.internal.net.www.protocol|weblogic.utils|weblogic.net|javax.net.ssl|COM.newmonics.www.protocols";
+
+ 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 SecureAction m_secureAction = new SecureAction();
+ private static final boolean OVERRIDE = m_secureAction.getSystemProperty(
+ "felix.service.urlhandlers.override", "false").equalsIgnoreCase("true");
private static volatile SecurityManagerEx m_sm = null;
private static volatile URLHandlers m_handler = null;
@@ -77,6 +85,7 @@
// The list to hold all enabled frameworks registered with this handlers
private static final List m_frameworks = new ArrayList();
+ private static int m_counter = 0;
private static Map m_contentHandlerCache = null;
private static Map m_streamHandlerCache = null;
@@ -252,7 +261,7 @@
* @param protocol the protocol for which a stream handler should be returned.
* @return a stream handler proxy for the specified protocol.
**/
- public synchronized URLStreamHandler createURLStreamHandler(String protocol)
+ public URLStreamHandler createURLStreamHandler(String protocol)
{
// See if there is a cached stream handler.
// IMPLEMENTATION NOTE: Caching is not strictly necessary for
@@ -260,13 +269,7 @@
// performed for code consistency between stream and content
// handlers and also because caching behavior may not be guaranteed
// across different JRE implementations.
- if (m_streamHandlerCache == null)
- {
- m_streamHandlerCache = new HashMap();
- }
-
- URLStreamHandler handler = (URLStreamHandler)
- m_streamHandlerCache.get(protocol);
+ URLStreamHandler handler = getFromStreamCache(protocol);
if (handler != null)
{
@@ -277,9 +280,8 @@
// allowed to deal with it.
if (protocol.equals(FelixConstants.BUNDLE_URL_PROTOCOL))
{
- handler = new URLHandlersBundleStreamHandler(m_secureAction);
- m_streamHandlerCache.put(protocol, handler);
- return handler;
+ return addToStreamCache(protocol,
+ new URLHandlersBundleStreamHandler(m_secureAction));
}
// If this is the framework's "felix:" extension protocol, then
@@ -289,7 +291,7 @@
// URLClassloader.
if (protocol.equals("felix"))
{
- handler = new URLStreamHandler()
+ return addToStreamCache(protocol, new URLStreamHandler()
{
protected URLConnection openConnection(URL url)
throws IOException
@@ -311,16 +313,54 @@
throw new IOException(ex.getMessage());
}
}
- };
- m_streamHandlerCache.put(protocol, handler);
- return handler;
+ });
}
- // If built-in or unknown content handler, then create a proxy handler.
- handler = new URLHandlersStreamHandlerProxy(protocol, m_secureAction,
- (m_streamHandlerFactory != this) ? m_streamHandlerFactory : null);
- m_streamHandlerCache.put(protocol, handler);
- return handler;
+ if (!OVERRIDE)
+ {
+ // If there was a custom factory then try to get the handler form it
+ if (m_streamHandlerFactory != this)
+ {
+ handler =
+ addToStreamCache(protocol, m_streamHandlerFactory.createURLStreamHandler(protocol));
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+ // Check for built-in handlers for the protocol.
+ String pkgs = m_secureAction.getSystemProperty(STREAM_HANDLER_PACKAGE_PROP, "");
+ pkgs = (pkgs.equals(""))
+ ? DEFAULT_STREAM_HANDLER_PACKAGE
+ : pkgs + "|" + DEFAULT_STREAM_HANDLER_PACKAGE;
+
+ // Iterate over built-in packages.
+ StringTokenizer pkgTok = new StringTokenizer(pkgs, "| ");
+ while (pkgTok.hasMoreTokens())
+ {
+ String pkg = pkgTok.nextToken().trim();
+ String className = pkg + "." + protocol + ".Handler";
+ try
+ {
+ // If a built-in handler is found then let the
+ // JRE handle it.
+ if (m_secureAction.forName(className) != null)
+ {
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ // This could be a class not found exception or an
+ // instantiation exception, not much we can do in either
+ // case other than ignore it.
+ }
+ }
+ }
+ // If built-in content handler, then create a proxy handler.
+ return addToStreamCache(protocol, new URLHandlersStreamHandlerProxy(protocol, m_secureAction,
+ (m_streamHandlerFactory != this) ? m_streamHandlerFactory : null, OVERRIDE));
}
/**
@@ -333,19 +373,116 @@
* @param mimeType the mime type for which a content handler should be returned.
* @return a content handler proxy for the specified mime type.
**/
- public synchronized ContentHandler createContentHandler(String mimeType)
+ public ContentHandler createContentHandler(String mimeType)
+ {
+ // See if there is a cached stream handler.
+ // IMPLEMENTATION NOTE: Caching is not strictly necessary for
+ // stream handlers since the Java runtime caches them. Caching is
+ // performed for code consistency between stream and content
+ // handlers and also because caching behavior may not be guaranteed
+ // across different JRE implementations.
+ ContentHandler handler = getFromContentCache(mimeType);
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ if (!OVERRIDE)
+ {
+ // If there was a custom factory then try to get the handler form it
+ if (m_contentHandlerFactory != this)
+ {
+ handler = addToContentCache(mimeType,
+ m_contentHandlerFactory.createContentHandler(mimeType));
+
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+
+ // Check for built-in handlers for the mime type.
+ String pkgs = m_secureAction.getSystemProperty(CONTENT_HANDLER_PACKAGE_PROP, "");
+ pkgs = (pkgs.equals(""))
+ ? DEFAULT_CONTENT_HANDLER_PACKAGE
+ : pkgs + "|" + DEFAULT_CONTENT_HANDLER_PACKAGE;
+
+ // Remove periods, slashes, and dashes from mime type.
+ String fixedType = mimeType.replace('.', '_').replace('/', '.').replace('-', '_');
+
+ // Iterate over built-in packages.
+ StringTokenizer pkgTok = new StringTokenizer(pkgs, "| ");
+ while (pkgTok.hasMoreTokens())
+ {
+ String pkg = pkgTok.nextToken().trim();
+ String className = pkg + "." + fixedType;
+ try
+ {
+ // If a built-in handler is found then let the
+ // JRE handle it.
+ if (m_secureAction.forName(className) != null)
+ {
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ // This could be a class not found exception or an
+ // instantiation exception, not much we can do in either
+ // case other than ignore it.
+ }
+ }
+ }
+
+ return addToContentCache(mimeType,
+ new URLHandlersContentHandlerProxy(mimeType, m_secureAction,
+ (m_contentHandlerFactory != this) ? m_contentHandlerFactory : null, OVERRIDE));
+ }
+
+ private synchronized ContentHandler addToContentCache(String mimeType, ContentHandler handler)
{
if (m_contentHandlerCache == null)
{
m_contentHandlerCache = new HashMap();
}
- if (m_contentHandlerCache.containsKey(mimeType))
+ return (ContentHandler) addToCache(m_contentHandlerCache, mimeType, handler);
+ }
+
+ private synchronized ContentHandler getFromContentCache(String mimeType)
+ {
+ return (ContentHandler) ((m_contentHandlerCache != null) ?
+ m_contentHandlerCache.get(mimeType) : null);
+ }
+
+ private synchronized URLStreamHandler addToStreamCache(String protocol, URLStreamHandler handler)
+ {
+ if (m_streamHandlerCache == null)
{
- return (ContentHandler) m_contentHandlerCache.get(mimeType);
+ m_streamHandlerCache = new HashMap();
}
- ContentHandler result = new URLHandlersContentHandlerProxy(mimeType, m_secureAction,
- (m_contentHandlerFactory != this) ? m_contentHandlerFactory : null);
- m_contentHandlerCache.put(mimeType, result);
+ return (URLStreamHandler) addToCache(m_streamHandlerCache, protocol, handler);
+ }
+
+ private synchronized URLStreamHandler getFromStreamCache(String protocol)
+ {
+ return (URLStreamHandler) ((m_streamHandlerCache != null) ?
+ m_streamHandlerCache.get(protocol) : null);
+ }
+
+ private Object addToCache(Map cache, String key, Object value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+
+ Object result = cache.get(key);
+
+ if (result == null)
+ {
+ cache.put(key, value);
+ result = value;
+ }
return result;
}
@@ -376,6 +513,7 @@
}
m_frameworks.add(framework);
}
+ m_counter++;
}
}
@@ -391,6 +529,7 @@
{
synchronized (m_frameworks)
{
+ m_counter--;
if (m_frameworks.remove(framework) && m_frameworks.isEmpty())
{
if (m_handler.m_streamHandlerFactory.getClass().getName().equals(
@@ -429,6 +568,20 @@
**/
public static Object getFrameworkFromContext()
{
+ // This is a hack. The idea is to return the only registered framework
+ synchronized (m_classloaderToFrameworkLists)
+ {
+ if (m_classloaderToFrameworkLists.isEmpty())
+ {
+ synchronized (m_frameworks)
+ {
+ if ((m_counter == 1) && (m_frameworks.size() == 1))
+ {
+ return m_frameworks.get(0);
+ }
+ }
+ }
+ }
// get the current class call stack.
Class[] stack = m_sm.getClassContext();
// Find the first class that is loaded from a bundle.
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
index 8e81e05..8d06590 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
@@ -51,15 +51,18 @@
if (framework != null)
{
- // TODO: optimize this to not use reflection if not needed
+ if (framework instanceof Felix)
+ {
+ return new URLHandlersBundleURLConnection(url, (Felix) framework);
+ }
try
{
Class targetClass = framework.getClass().getClassLoader().loadClass(
URLHandlersBundleURLConnection.class.getName());
return (URLConnection) m_action.invoke(m_action.getConstructor(targetClass,
- new Class[]{URL.class, framework.getClass()}),
- new Object[]{url, framework});
+ new Class[]{URL.class, framework.getClass().getClassLoader().loadClass(
+ Felix.class.getName())}), new Object[]{url, framework});
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index aaa2473..834d577 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -52,7 +52,11 @@
// one from the call context.
if (m_framework == null)
{
- m_framework = (Felix) URLHandlers.getFrameworkFromContext();
+ Object tmp = URLHandlers.getFrameworkFromContext();
+ if (tmp instanceof Felix)
+ {
+ m_framework = (Felix) framework;
+ }
}
// If there is still no framework, then error.
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 6e7dd0a..f436ba5 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
@@ -62,13 +62,15 @@
private final Map m_trackerMap = new HashMap();
private final String m_mimeType;
private final SecureAction m_action;
+ private final boolean m_override;
public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
- ContentHandlerFactory factory)
+ ContentHandlerFactory factory, boolean override)
{
m_mimeType = mimeType;
m_action = action;
m_factory = factory;
+ m_override = override;
}
//
@@ -101,9 +103,9 @@
// Get the framework instance associated with call stack.
Object framework = URLHandlers.getFrameworkFromContext();
- if (framework == null)
+ if (framework == null)
{
- return getBuiltIn();
+ return m_override ? getBuiltIn() : null;
}
// Get the service tracker for the framework instance or create one.
@@ -129,7 +131,8 @@
tracker = m_action.invoke(m_action.getConstructor(
framework.getClass().getClassLoader().loadClass(
URLHandlersServiceTracker.class.getName()),
- new Class[]{framework.getClass(), String.class}),
+ new Class[]{framework.getClass().getClassLoader().loadClass(
+ Felix.class.getName()), String.class}),
new Object[]{framework, filter});
// Cache the simple service tracker.
synchronized (m_trackerMap)
@@ -144,12 +147,21 @@
}
}
}
- ContentHandler result = (ContentHandler) m_action.invoke(
- m_action.getMethod(tracker.getClass(), "getService", null),
- tracker, null);
- if (result == null)
+ ContentHandler result;
+ if (tracker instanceof URLHandlersServiceTracker)
{
- return getBuiltIn();
+ result = (ContentHandler)
+ ((URLHandlersServiceTracker) tracker).getService();
+ }
+ else
+ {
+ result = (ContentHandler) m_action.invoke(
+ m_action.getMethod(tracker.getClass(), "getService", null),
+ tracker, null);
+ }
+ if ((result == null) && m_override)
+ {
+ result = getBuiltIn();
}
return result;
}
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java
index 302ef0d..0df00fd 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java
@@ -32,10 +32,10 @@
**/
class URLHandlersServiceTracker
{
- private BundleContext m_context = null;
- private String m_filter = null;
+ private final BundleContext m_context;
+ private final String m_filter;
private ServiceReference m_ref = null;
- private Object m_svcObj = null;
+ private volatile Object m_svcObj = null;
private long m_id = -1;
private int m_rank = -1;
@@ -126,7 +126,7 @@
* service before selecting the best available service.
* </p>
**/
- private void selectBestService()
+ private synchronized void selectBestService()
{
// If there is an existing service, then unget it.
if (m_ref != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
index af13c02..7cc5a83 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
@@ -54,11 +54,49 @@
* stream handler service at any given time.
* </p>
**/
-public class URLHandlersStreamHandlerProxy extends URLStreamHandler
+public final class URLHandlersStreamHandlerProxy extends URLStreamHandler
implements URLStreamHandlerSetter, InvocationHandler
{
private static final String STREAM_HANDLER_PACKAGE_PROP = "java.protocol.handler.pkgs";
private static final String DEFAULT_STREAM_HANDLER_PACKAGE = "sun.net.www.protocol|com.ibm.oti.net.www.protocol|gnu.java.net.protocol|wonka.net|com.acunia.wonka.net|org.apache.harmony.luni.internal.net.www.protocol|weblogic.utils|weblogic.net|javax.net.ssl|COM.newmonics.www.protocols";
+
+ private static final Method EQUALS;
+ private static final Method GET_DEFAULT_PORT;
+ private static final Method GET_HOST_ADDRESS;
+ private static final Method HASH_CODE;
+ private static final Method HOSTS_EQUAL;
+ private static final Method OPEN_CONNECTION;
+ private static final Method PARSE_URL;
+ private static final Method SAME_FILE;
+ private static final Method TO_EXTERNAL_FORM;
+
+ static {
+ try
+ {
+ EQUALS = URLStreamHandler.class.getDeclaredMethod("equals",
+ new Class[]{URL.class, URL.class});
+ GET_DEFAULT_PORT = URLStreamHandler.class.getDeclaredMethod("getDefaultPort", null);
+ GET_HOST_ADDRESS = URLStreamHandler.class.getDeclaredMethod(
+ "getHostAddress", new Class[]{URL.class});
+ HASH_CODE = URLStreamHandler.class.getDeclaredMethod(
+ "hashCode", new Class[]{URL.class});
+ HOSTS_EQUAL = URLStreamHandler.class.getDeclaredMethod(
+ "hostsEqual", new Class[]{URL.class, URL.class});
+ OPEN_CONNECTION = URLStreamHandler.class.getDeclaredMethod(
+ "openConnection", new Class[]{URL.class});
+ PARSE_URL = URLStreamHandler.class.getDeclaredMethod(
+ "parseURL", new Class[]{URL.class, String.class, Integer.TYPE, Integer.TYPE});
+ SAME_FILE = URLStreamHandler.class.getDeclaredMethod(
+ "sameFile", new Class[]{URL.class, URL.class});
+ TO_EXTERNAL_FORM = URLStreamHandler.class.getDeclaredMethod(
+ "toExternalForm", new Class[]{URL.class});
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
private static final Map m_builtIn = new HashMap();
private final URLStreamHandlerFactory m_factory;
@@ -67,14 +105,16 @@
private final String m_protocol;
private final Object m_service;
private final SecureAction m_action;
+ private final boolean m_override;
public URLHandlersStreamHandlerProxy(String protocol, SecureAction action,
- URLStreamHandlerFactory factory)
+ URLStreamHandlerFactory factory, boolean override)
{
m_protocol = protocol;
m_service = null;
m_action = action;
m_factory = factory;
+ m_override = override;
}
private URLHandlersStreamHandlerProxy(Object service, SecureAction action)
@@ -83,12 +123,12 @@
m_service = service;
m_action = action;
m_factory = null;
+ m_override = false;
}
//
// URLStreamHandler interface methods.
//
-
protected boolean equals(URL url1, URL url2)
{
Object svc = getStreamHandlerService();
@@ -103,8 +143,7 @@
}
try
{
- return ((Boolean) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class, "equals",
- new Class[]{URL.class, URL.class}), svc, new Object[]{url1, url2})).booleanValue();
+ return ((Boolean) m_action.invoke(EQUALS, svc, new Object[]{url1, url2})).booleanValue();
}
catch (Exception ex)
{
@@ -126,8 +165,7 @@
}
try
{
- return ((Integer) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "getDefaultPort", null), svc, null)).intValue();
+ return ((Integer) m_action.invoke(GET_DEFAULT_PORT, svc, null)).intValue();
}
catch (Exception ex)
{
@@ -150,8 +188,7 @@
}
try
{
- return (InetAddress) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "getHostAddress", new Class[]{URL.class}), svc, new Object[]{url});
+ return (InetAddress) m_action.invoke(GET_HOST_ADDRESS, svc, new Object[]{url});
}
catch (Exception ex)
{
@@ -174,8 +211,7 @@
}
try
{
- return ((Integer) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "hashCode", new Class[]{URL.class}), svc, new Object[]{url})).intValue();
+ return ((Integer) m_action.invoke(HASH_CODE, svc, new Object[]{url})).intValue();
}
catch (Exception ex)
{
@@ -198,8 +234,7 @@
}
try
{
- return ((Boolean) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "hostsEqual", new Class[]{URL.class, URL.class}), svc, new Object[]{url1, url2})).booleanValue();
+ return ((Boolean) m_action.invoke(HOSTS_EQUAL, svc, new Object[]{url1, url2})).booleanValue();
}
catch (Exception ex)
{
@@ -221,8 +256,7 @@
}
try
{
- return (URLConnection) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "openConnection", new Class[]{URL.class}), svc, new Object[]{url});
+ return (URLConnection) m_action.invoke(OPEN_CONNECTION, svc, new Object[]{url});
}
catch (Exception ex)
{
@@ -247,10 +281,9 @@
{
try
{
- URL test = new URL(null, url.toExternalForm(), (URLStreamHandler) svc);
+ URL test = new URL(null, toExternalForm(url, svc), (URLStreamHandler) svc);
- m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "parseURL", new Class[]{URL.class, String.class, Integer.TYPE, Integer.TYPE}),
+ m_action.invoke(PARSE_URL,
svc, new Object[]{test, spec, new Integer(start), new Integer(limit)});
super.setURL(url, test.getProtocol(), test.getHost(), test.getPort(),test.getAuthority(),
test.getUserInfo(), test.getPath(), test.getQuery(), test.getRef());
@@ -277,8 +310,7 @@
}
try
{
- return ((Boolean) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "sameFile", new Class[]{URL.class, URL.class}),
+ return ((Boolean) m_action.invoke(SAME_FILE,
svc, new Object[]{url1, url2})).booleanValue();
}
catch (Exception ex)
@@ -303,7 +335,11 @@
protected String toExternalForm(URL url)
{
- Object svc = getStreamHandlerService();
+ return toExternalForm(url, getStreamHandlerService());
+ }
+
+ private String toExternalForm(URL url, Object svc)
+ {
if (svc == null)
{
throw new IllegalStateException(
@@ -315,8 +351,7 @@
}
try
{
- return (String) m_action.invoke(m_action.getDeclaredMethod(URLStreamHandler.class,
- "toExternalForm", new Class[]{URL.class}),
+ return (String) m_action.invoke(TO_EXTERNAL_FORM,
svc, new Object[]{url});
}
catch (Exception ex)
@@ -342,9 +377,9 @@
// Get the framework instance associated with call stack.
Object framework = URLHandlers.getFrameworkFromContext();
- if (framework == null)
+ if (framework == null)
{
- return getBuiltIn();
+ return m_override ? getBuiltIn() : null;
}
// Get the service tracker for the framework instance or create one.
@@ -370,7 +405,8 @@
tracker = m_action.invoke(m_action.getConstructor(
framework.getClass().getClassLoader().loadClass(
URLHandlersServiceTracker.class.getName()),
- new Class[]{framework.getClass(), String.class}),
+ new Class[]{framework.getClass().getClassLoader().loadClass(
+ Felix.class.getName()), String.class}),
new Object[]{framework, filter});
// Cache the simple service tracker.
@@ -386,11 +422,19 @@
}
}
}
- Object service = m_action.invoke(m_action.getMethod(
- tracker.getClass(), "getService", null), tracker, null);
- if (service == null)
+ Object service;
+ if (tracker instanceof URLHandlersServiceTracker)
{
- return getBuiltIn();
+ service = ((URLHandlersServiceTracker) tracker).getService();
+ }
+ else
+ {
+ service = m_action.invoke(m_action.getMethod(
+ tracker.getClass(), "getService", null), tracker, null);
+ }
+ if (service == null)
+ {
+ return m_override ? getBuiltIn() : null;
}
if (service instanceof URLStreamHandlerService)
{