Search in sources :

Example 6 with ProxyManager

use of org.apache.aries.proxy.ProxyManager in project karaf by apache.

the class GuardProxyCatalogTest method testCreateProxy.

@SuppressWarnings({ "unchecked", "rawtypes" })
public Object testCreateProxy(BundleContext bc, Class[] objectClasses, final Class[] proxyRegClasses, Object testService, final Map<ServiceReference, Object> serviceMap) throws Exception {
    // A linked hash map to keep iteration order over the keys predictable
    final LinkedHashMap<String, Class> objClsMap = new LinkedHashMap<>();
    for (Class cls : objectClasses) {
        objClsMap.put(cls.getName(), cls);
    }
    // A linked hash map to keep iteration order over the keys predictable
    final LinkedHashMap<String, Class> proxyRegClsMap = new LinkedHashMap<>();
    for (Class cls : proxyRegClasses) {
        proxyRegClsMap.put(cls.getName(), cls);
    }
    // Create the object that is actually being tested here
    GuardProxyCatalog gpc = new GuardProxyCatalog(bc);
    // The service being proxied has these properties
    long serviceID = Long.MAX_VALUE;
    final Hashtable<String, Object> serviceProps = new Hashtable<>();
    serviceProps.put(Constants.OBJECTCLASS, objClsMap.keySet().toArray(new String[] {}));
    serviceProps.put(Constants.SERVICE_ID, serviceID);
    // will be overwritten
    serviceProps.put(GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY, Arrays.asList("everyone"));
    serviceProps.put("bar", "foo");
    // The mock bundle context for the bundle providing the service is set up here
    BundleContext providerBC = EasyMock.createMock(BundleContext.class);
    // These are the expected service properties of the proxy registration. Note the proxy marker...
    final Hashtable<String, Object> expectedProxyProps = new Hashtable<>(serviceProps);
    expectedProxyProps.put(GuardProxyCatalog.PROXY_SERVICE_KEY, Boolean.TRUE);
    // This will check that the right proxy is being registered.
    EasyMock.expect(providerBC.registerService(EasyMock.isA(String[].class), EasyMock.anyObject(), EasyMock.isA(Dictionary.class))).andAnswer((IAnswer) () -> {
        if (!runningUnderCoverage) {
            assertArrayEquals(proxyRegClsMap.keySet().toArray(new String[] {}), (String[]) EasyMock.getCurrentArguments()[0]);
            Object svc = EasyMock.getCurrentArguments()[1];
            assertTrue(svc instanceof ServiceFactory);
        }
        Dictionary<String, Object> props = (Dictionary<String, Object>) EasyMock.getCurrentArguments()[2];
        for (String key : expectedProxyProps.keySet()) {
            if (GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY.equals(key)) {
                assertTrue("The roles property should have been overwritten", !Arrays.asList("everyone").equals(props.get(key)));
            } else {
                assertEquals(expectedProxyProps.get(key), props.get(key));
            }
        }
        ServiceRegistration reg = EasyMock.createMock(ServiceRegistration.class);
        ServiceReference sr = mockServiceReference(props);
        EasyMock.expect(reg.getReference()).andReturn(sr).anyTimes();
        reg.unregister();
        EasyMock.expectLastCall().once();
        EasyMock.replay(reg);
        serviceMap.put(sr, EasyMock.getCurrentArguments()[1]);
        return reg;
    }).once();
    EasyMock.expect(providerBC.getService(EasyMock.isA(ServiceReference.class))).andAnswer(() -> serviceMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(providerBC);
    // In some cases the proxy-creating code is looking for a classloader (e.g. when run through
    // a coverage tool such as EclEmma). This will satisfy that.
    BundleWiring bw = EasyMock.createMock(BundleWiring.class);
    EasyMock.expect(bw.getClassLoader()).andReturn(getClass().getClassLoader()).anyTimes();
    EasyMock.replay(bw);
    // The mock bundle that provides the original service (and also the proxy is registered with this)
    Bundle providerBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(providerBundle.getBundleContext()).andReturn(providerBC).anyTimes();
    EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw).anyTimes();
    EasyMock.replay(providerBundle);
    ServiceReference sr = mockServiceReference(providerBundle, serviceProps);
    // The mock bundle context for the client bundle
    BundleContext clientBC = EasyMock.createMock(BundleContext.class);
    EasyMock.expect(clientBC.getService(sr)).andReturn(testService).anyTimes();
    EasyMock.replay(clientBC);
    // The mock bundle that consumes the service
    Bundle clientBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(clientBundle.getBundleId()).andReturn(2999L).anyTimes();
    EasyMock.expect(clientBundle.getBundleContext()).andReturn(clientBC).anyTimes();
    EasyMock.expect(clientBundle.loadClass(EasyMock.isA(String.class))).andAnswer((IAnswer) () -> objClsMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(clientBundle);
    assertEquals("Precondition", 0, gpc.proxyMap.size());
    assertEquals("Precondition", 0, gpc.createProxyQueue.size());
    // Create the proxy for the service
    gpc.proxyIfNotAlreadyProxied(sr);
    assertEquals(1, gpc.proxyMap.size());
    // The actual proxy creation is done asynchronously.
    GuardProxyCatalog.ServiceRegistrationHolder holder = gpc.proxyMap.get(serviceID);
    assertNull("The registration shouldn't have happened yet", holder.registration);
    assertEquals(1, gpc.createProxyQueue.size());
    // Mimic the thread that works the queue to create the proxy
    GuardProxyCatalog.CreateProxyRunnable runnable = gpc.createProxyQueue.take();
    ProxyManager pm = getProxyManager();
    runnable.run(pm);
    // The runnable should have put the actual registration in the holder
    ServiceReference<?> proxySR = holder.registration.getReference();
    for (String key : expectedProxyProps.keySet()) {
        if (GuardProxyCatalog.SERVICE_GUARD_ROLES_PROPERTY.equals(key)) {
            assertTrue("The roles property should have been overwritten", !Arrays.asList("everyone").equals(proxySR.getProperty(key)));
        } else {
            assertEquals(expectedProxyProps.get(key), proxySR.getProperty(key));
        }
    }
    // Check that the proxy registration was done on the original provider bundle's context
    EasyMock.verify(providerBC);
    // Test that the actual proxy invokes the original service...
    ServiceFactory proxyServiceSF = (ServiceFactory) serviceMap.get(proxySR);
    Object proxyService = proxyServiceSF.getService(clientBundle, null);
    assertNotSame("The proxy should not be the same object as the original service", testService, proxyService);
    return proxyService;
}
Also used : Dictionary(java.util.Dictionary) ServiceFactory(org.osgi.framework.ServiceFactory) CreateProxyRunnable(org.apache.karaf.service.guard.impl.GuardProxyCatalog.CreateProxyRunnable) Hashtable(java.util.Hashtable) Bundle(org.osgi.framework.Bundle) ServiceRegistrationHolder(org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder) BundleWiring(org.osgi.framework.wiring.BundleWiring) ProxyManager(org.apache.aries.proxy.ProxyManager) AsmProxyManager(org.apache.aries.proxy.impl.AsmProxyManager) LinkedHashMap(java.util.LinkedHashMap) ServiceReference(org.osgi.framework.ServiceReference) IAnswer(org.easymock.IAnswer) BundleContext(org.osgi.framework.BundleContext) ServiceRegistration(org.osgi.framework.ServiceRegistration)

Example 7 with ProxyManager

use of org.apache.aries.proxy.ProxyManager in project karaf by apache.

the class GuardProxyCatalogTest method testProxyCreationThread.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testProxyCreationThread() throws Exception {
    ProxyManager proxyManager = getProxyManager();
    ConfigurationAdmin ca = EasyMock.createMock(ConfigurationAdmin.class);
    EasyMock.expect(ca.listConfigurations(EasyMock.anyObject(String.class))).andReturn(null).anyTimes();
    EasyMock.replay(ca);
    ServiceReference pmSref = EasyMock.createMock(ServiceReference.class);
    EasyMock.replay(pmSref);
    ServiceReference pmSref2 = EasyMock.createMock(ServiceReference.class);
    EasyMock.replay(pmSref2);
    ServiceReference cmSref = EasyMock.createMock(ServiceReference.class);
    EasyMock.replay(cmSref);
    Bundle b = EasyMock.createMock(Bundle.class);
    EasyMock.expect(b.getBundleId()).andReturn(23992734L).anyTimes();
    EasyMock.replay(b);
    BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
    EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
    EasyMock.expect(bc.createFilter(EasyMock.isA(String.class))).andAnswer(() -> FrameworkUtil.createFilter((String) EasyMock.getCurrentArguments()[0])).anyTimes();
    final ServiceListener[] pmListenerHolder = new ServiceListener[1];
    String pmFilter = "(&(objectClass=" + ProxyManager.class.getName() + ")" + "(!(" + GuardProxyCatalog.PROXY_SERVICE_KEY + "=*)))";
    bc.addServiceListener(EasyMock.isA(ServiceListener.class), EasyMock.eq(pmFilter));
    EasyMock.expectLastCall().andAnswer(() -> {
        pmListenerHolder[0] = (ServiceListener) EasyMock.getCurrentArguments()[0];
        return null;
    }).anyTimes();
    EasyMock.expect(bc.getServiceReferences(EasyMock.anyObject(String.class), EasyMock.contains(ConfigurationAdmin.class.getName()))).andReturn(new ServiceReference[] { cmSref }).anyTimes();
    EasyMock.expect(bc.getService(pmSref)).andReturn(proxyManager).anyTimes();
    EasyMock.expect(bc.getService(pmSref2)).andReturn(proxyManager).anyTimes();
    EasyMock.expect(bc.getService(cmSref)).andReturn(ca).anyTimes();
    EasyMock.replay(bc);
    // This should put a ServiceListener in the pmListenerHolder, the ServiceTracker does that
    GuardProxyCatalog gpc = new GuardProxyCatalog(bc);
    // The service being proxied has these properties
    final Hashtable<String, Object> serviceProps = new Hashtable<>();
    serviceProps.put(Constants.OBJECTCLASS, new String[] { TestServiceAPI.class.getName() });
    serviceProps.put(Constants.SERVICE_ID, 162L);
    final Map<ServiceReference<?>, Object> serviceMap = new HashMap<>();
    // The mock bundle context for the bundle providing the service is set up here
    BundleContext providerBC = EasyMock.createMock(BundleContext.class);
    // These are the expected service properties of the proxy registration. Note the proxy marker...
    final Hashtable<String, Object> expectedProxyProps = new Hashtable<>(serviceProps);
    expectedProxyProps.put(GuardProxyCatalog.PROXY_SERVICE_KEY, Boolean.TRUE);
    EasyMock.expect(providerBC.registerService(EasyMock.isA(String[].class), EasyMock.anyObject(), EasyMock.isA(Dictionary.class))).andAnswer((IAnswer) () -> {
        Dictionary<String, Object> props = (Dictionary<String, Object>) EasyMock.getCurrentArguments()[2];
        ServiceRegistration reg = EasyMock.createMock(ServiceRegistration.class);
        ServiceReference sr = mockServiceReference(props);
        EasyMock.expect(reg.getReference()).andReturn(sr).anyTimes();
        reg.unregister();
        EasyMock.expectLastCall().once();
        EasyMock.replay(reg);
        serviceMap.put(sr, EasyMock.getCurrentArguments()[1]);
        return reg;
    }).once();
    EasyMock.expect(providerBC.getService(EasyMock.isA(ServiceReference.class))).andAnswer(() -> serviceMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(providerBC);
    // In some cases the proxy-creating code is looking for a classloader (e.g. when run through
    // a coverage tool such as EclEmma). This will satisfy that.
    BundleWiring bw = EasyMock.createMock(BundleWiring.class);
    EasyMock.expect(bw.getClassLoader()).andReturn(getClass().getClassLoader()).anyTimes();
    EasyMock.replay(bw);
    // The mock bundle that provides the original service (and also the proxy is registered with this)
    Bundle providerBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(providerBundle.getBundleContext()).andReturn(providerBC).anyTimes();
    EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw).anyTimes();
    EasyMock.replay(providerBundle);
    ServiceReference sr = mockServiceReference(providerBundle, serviceProps);
    assertEquals("Precondition", 0, gpc.proxyMap.size());
    assertEquals("Precondition", 0, gpc.createProxyQueue.size());
    // Create the proxy for the service
    gpc.proxyIfNotAlreadyProxied(sr);
    assertEquals(1, gpc.proxyMap.size());
    assertEquals(1, gpc.createProxyQueue.size());
    // The actual proxy creation is done asynchronously.
    GuardProxyCatalog.ServiceRegistrationHolder holder = gpc.proxyMap.get(162L);
    assertNull("The registration shouldn't have happened yet", holder.registration);
    assertEquals(1, gpc.createProxyQueue.size());
    Thread[] tarray = new Thread[Thread.activeCount()];
    Thread.enumerate(tarray);
    for (Thread t : tarray) {
        if (t != null) {
            assertTrue(!GuardProxyCatalog.PROXY_CREATOR_THREAD_NAME.equals(t.getName()));
        }
    }
    // make the proxy manager appear
    pmListenerHolder[0].serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, pmSref));
    // give the system some time to send the events...
    Thread.sleep(400);
    Thread ourThread = null;
    Thread[] tarray2 = new Thread[Thread.activeCount()];
    Thread.enumerate(tarray2);
    for (Thread t : tarray2) {
        if (t != null) {
            if (t.getName().equals(GuardProxyCatalog.PROXY_CREATOR_THREAD_NAME)) {
                ourThread = t;
            }
        }
    }
    assertNotNull(ourThread);
    assertTrue(ourThread.isDaemon());
    assertTrue(ourThread.isAlive());
    assertNotNull(holder.registration);
    assertEquals(0, gpc.createProxyQueue.size());
    int numProxyThreads = 0;
    pmListenerHolder[0].serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, pmSref2));
    // give the system some time to send the events...
    Thread.sleep(300);
    Thread[] tarray3 = new Thread[Thread.activeCount()];
    Thread.enumerate(tarray3);
    for (Thread t : tarray3) {
        if (t != null) {
            if (t.getName().equals(GuardProxyCatalog.PROXY_CREATOR_THREAD_NAME)) {
                numProxyThreads++;
            }
        }
    }
    assertEquals("Maximum 1 proxy thread, even if there is more than 1 proxy service", 1, numProxyThreads);
    // Clean up thread
    pmListenerHolder[0].serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, pmSref));
    // Give the system some time to stop the threads...
    Thread.sleep(300);
    Thread[] tarray4 = new Thread[Thread.activeCount()];
    Thread.enumerate(tarray4);
    for (Thread t : tarray4) {
        if (t != null) {
            assertTrue(!GuardProxyCatalog.PROXY_CREATOR_THREAD_NAME.equals(t.getName()));
        }
    }
}
Also used : Dictionary(java.util.Dictionary) ServiceListener(org.osgi.framework.ServiceListener) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ProxyManager(org.apache.aries.proxy.ProxyManager) AsmProxyManager(org.apache.aries.proxy.impl.AsmProxyManager) ServiceEvent(org.osgi.framework.ServiceEvent) ServiceRegistration(org.osgi.framework.ServiceRegistration) Bundle(org.osgi.framework.Bundle) Hashtable(java.util.Hashtable) ServiceRegistrationHolder(org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder) BundleWiring(org.osgi.framework.wiring.BundleWiring) ServiceReference(org.osgi.framework.ServiceReference) IAnswer(org.easymock.IAnswer) ConfigurationAdmin(org.osgi.service.cm.ConfigurationAdmin) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Example 8 with ProxyManager

use of org.apache.aries.proxy.ProxyManager in project karaf by apache.

the class GuardProxyCatalogTest method testServiceFactoryBehaviour.

@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testServiceFactoryBehaviour() throws Exception {
    final Map<ServiceReference, Object> serviceMap = new HashMap<>();
    TestServiceAPI testService = new TestService();
    BundleContext bc = mockConfigAdminBundleContext();
    GuardProxyCatalog gpc = new GuardProxyCatalog(bc);
    // The service being proxied has these properties
    long serviceID = 117L;
    final Hashtable<String, Object> serviceProps = new Hashtable<>();
    serviceProps.put(Constants.OBJECTCLASS, new String[] { TestServiceAPI.class.getName() });
    serviceProps.put(Constants.SERVICE_ID, serviceID);
    serviceProps.put("bar", 42L);
    BundleContext providerBC = EasyMock.createMock(BundleContext.class);
    EasyMock.expect(providerBC.registerService(EasyMock.isA(String[].class), EasyMock.anyObject(), EasyMock.isA(Dictionary.class))).andAnswer((IAnswer) () -> {
        Dictionary<String, Object> props = (Dictionary<String, Object>) EasyMock.getCurrentArguments()[2];
        ServiceRegistration reg = EasyMock.createMock(ServiceRegistration.class);
        ServiceReference sr = mockServiceReference(props);
        EasyMock.expect(reg.getReference()).andReturn(sr).anyTimes();
        EasyMock.replay(reg);
        serviceMap.put(sr, EasyMock.getCurrentArguments()[1]);
        return reg;
    }).once();
    EasyMock.expect(providerBC.getService(EasyMock.isA(ServiceReference.class))).andAnswer(() -> serviceMap.get(EasyMock.getCurrentArguments()[0])).anyTimes();
    EasyMock.replay(providerBC);
    // In some cases the proxy-creating code is looking for a classloader (e.g. when run through
    // a coverage tool such as EclEmma). This will satisfy that.
    BundleWiring bw = EasyMock.createMock(BundleWiring.class);
    EasyMock.expect(bw.getClassLoader()).andReturn(getClass().getClassLoader()).anyTimes();
    EasyMock.replay(bw);
    // The mock bundle that provides the original service (and also the proxy is registered with this)
    Bundle providerBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(providerBundle.getBundleContext()).andReturn(providerBC).anyTimes();
    EasyMock.expect(providerBundle.adapt(BundleWiring.class)).andReturn(bw).anyTimes();
    EasyMock.replay(providerBundle);
    ServiceReference sr = mockServiceReference(providerBundle, serviceProps);
    // The mock bundle context for the client bundle
    BundleContext clientBC = EasyMock.createMock(BundleContext.class);
    EasyMock.expect(clientBC.getService(sr)).andReturn(testService).anyTimes();
    EasyMock.replay(clientBC);
    // The mock bundle that consumes the service
    Bundle clientBundle = EasyMock.createNiceMock(Bundle.class);
    EasyMock.expect(clientBundle.getBundleContext()).andReturn(clientBC).anyTimes();
    EasyMock.replay(clientBundle);
    gpc.proxyIfNotAlreadyProxied(sr);
    // The actual proxy creation is done asynchronously.
    GuardProxyCatalog.ServiceRegistrationHolder holder = gpc.proxyMap.get(serviceID);
    // Mimic the thread that works the queue to create the proxy
    GuardProxyCatalog.CreateProxyRunnable runnable = gpc.createProxyQueue.take();
    assertEquals(117L, runnable.getOriginalServiceID());
    ProxyManager pm = getProxyManager();
    runnable.run(pm);
    // The runnable should have put the actual registration in the holder
    ServiceReference<?> proxySR = holder.registration.getReference();
    // Check that the proxy registration was done on the original provider bundle's context
    EasyMock.verify(providerBC);
    // Test that the actual proxy invokes the original service...
    ServiceFactory proxyServiceSF = (ServiceFactory) serviceMap.get(proxySR);
    TestServiceAPI proxyService = (TestServiceAPI) proxyServiceSF.getService(clientBundle, null);
    assertNotSame("The proxy should not be the same object as the original service", testService, proxyService);
    assertEquals("Doing it", proxyService.doit());
    EasyMock.reset(clientBC);
    EasyMock.expect(clientBC.ungetService(sr)).andReturn(true).once();
    EasyMock.replay(clientBC);
    proxyServiceSF.ungetService(clientBundle, null, proxyService);
    EasyMock.verify(clientBC);
}
Also used : Dictionary(java.util.Dictionary) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CreateProxyRunnable(org.apache.karaf.service.guard.impl.GuardProxyCatalog.CreateProxyRunnable) ServiceFactory(org.osgi.framework.ServiceFactory) Hashtable(java.util.Hashtable) Bundle(org.osgi.framework.Bundle) ServiceRegistrationHolder(org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder) BundleWiring(org.osgi.framework.wiring.BundleWiring) ProxyManager(org.apache.aries.proxy.ProxyManager) AsmProxyManager(org.apache.aries.proxy.impl.AsmProxyManager) ServiceReference(org.osgi.framework.ServiceReference) IAnswer(org.easymock.IAnswer) BundleContext(org.osgi.framework.BundleContext) ServiceRegistration(org.osgi.framework.ServiceRegistration) Test(org.junit.Test)

Example 9 with ProxyManager

use of org.apache.aries.proxy.ProxyManager in project karaf by apache.

the class Activator method doStart.

@Override
protected void doStart() throws Exception {
    ProxyManager proxyManager = getTrackedService(ProxyManager.class);
    register(InitialContextFactory.class, new KarafInitialContextFactory());
    JndiServiceImpl service = new JndiServiceImpl();
    service.setBundleContext(bundleContext);
    service.setProxyManager(proxyManager);
    Hashtable<String, String> props = new Hashtable<>();
    // bind the JNDI service itself in the JNDI context
    props.put("osgi.jndi.service.name", "jndi");
    register(JndiService.class, service, props);
    JndiMBeanImpl mbean = new JndiMBeanImpl();
    mbean.setJndiService(service);
    registerMBean(mbean, "type=jndi");
}
Also used : KarafInitialContextFactory(org.apache.karaf.jndi.KarafInitialContextFactory) JndiServiceImpl(org.apache.karaf.jndi.internal.JndiServiceImpl) Hashtable(java.util.Hashtable) ProxyManager(org.apache.aries.proxy.ProxyManager) JndiMBeanImpl(org.apache.karaf.jndi.internal.JndiMBeanImpl)

Example 10 with ProxyManager

use of org.apache.aries.proxy.ProxyManager in project aries by apache.

the class ServiceHelper method proxyPrivileged.

private static Object proxyPrivileged(String interface1, String filter, boolean dynamicRebind, BundleContext ctx, ServicePair pair, int timeout) {
    String[] interfaces = null;
    if (interface1 != null) {
        interfaces = new String[] { interface1 };
    } else {
        interfaces = (String[]) pair.ref.getProperty(Constants.OBJECTCLASS);
    }
    List<Class<?>> clazz = new ArrayList<Class<?>>(interfaces.length);
    // We load the interface classes the service is registered under using the defining bundle. 
    // This is ok because the service must be able to see the classes to be registered using them. 
    // We then check to see if isAssignableTo on the reference  works for the owning bundle and 
    // the interface name and only use the interface if true is returned there.
    // This might seem odd, but equinox and felix return true for isAssignableTo if the 
    // Bundle provided does not import the package. This is under the assumption the
    // caller will then use reflection. The upshot of doing it this way is that a utility
    // bundle can be created which centralizes JNDI lookups, but the service will be used
    // by another bundle. It is true that class space consistency is less safe, but we
    // are enabling a slightly odd use case anyway.
    // August 13th 2013: We've found valid use cases in which a Bundle is exporting 
    // services that the Bundle itself cannot load. We deal with this rare case by
    // noting the classes that we failed to load. If as a result we have no classes 
    // to proxy, we try those classes again but instead pull the Class objects off 
    // the service rather than from the bundle exporting that service. 
    Bundle serviceProviderBundle = pair.ref.getBundle();
    Bundle owningBundle = ctx.getBundle();
    ProxyManager proxyManager = Activator.getProxyManager();
    Collection<String> classesNotFound = new ArrayList<String>();
    for (String interfaceName : interfaces) {
        try {
            Class<?> potentialClass = serviceProviderBundle.loadClass(interfaceName);
            if (pair.ref.isAssignableTo(owningBundle, interfaceName)) {
                clazz.add(potentialClass);
            }
        } catch (ClassNotFoundException e) {
            classesNotFound.add(interfaceName);
        }
    }
    if (clazz.isEmpty() && !classesNotFound.isEmpty()) {
        Class<?>[] ifacesOnService = ctx.getService(pair.ref).getClass().getInterfaces();
        for (String interfaceName : classesNotFound) {
            Class<?> thisClass = null;
            for (Class<?> c : getAllInterfaces(ifacesOnService)) {
                if (c.getName().equals(interfaceName)) {
                    thisClass = c;
                    break;
                }
            }
            if (thisClass != null) {
                if (pair.ref.isAssignableTo(owningBundle, interfaceName)) {
                    clazz.add(thisClass);
                }
            }
        }
    }
    if (clazz.isEmpty()) {
        throw new IllegalArgumentException(Arrays.asList(interfaces).toString());
    }
    Callable<Object> ih = new JNDIServiceDamper(ctx, interface1, filter, pair, dynamicRebind, timeout);
    try {
        return proxyManager.createDelegatingProxy(serviceProviderBundle, clazz, ih, null);
    } catch (UnableToProxyException e) {
        throw new IllegalArgumentException(e);
    } catch (RuntimeException e) {
        throw new IllegalArgumentException(MESSAGES.getMessage("unable.to.create.proxy", pair.ref), e);
    }
}
Also used : Bundle(org.osgi.framework.Bundle) ArrayList(java.util.ArrayList) ProxyManager(org.apache.aries.proxy.ProxyManager) UnableToProxyException(org.apache.aries.proxy.UnableToProxyException)

Aggregations

ProxyManager (org.apache.aries.proxy.ProxyManager)10 Bundle (org.osgi.framework.Bundle)8 Hashtable (java.util.Hashtable)6 BundleContext (org.osgi.framework.BundleContext)6 Dictionary (java.util.Dictionary)4 LinkedHashMap (java.util.LinkedHashMap)4 AsmProxyManager (org.apache.aries.proxy.impl.AsmProxyManager)4 ServiceRegistrationHolder (org.apache.karaf.service.guard.impl.GuardProxyCatalog.ServiceRegistrationHolder)4 IAnswer (org.easymock.IAnswer)4 ServiceReference (org.osgi.framework.ServiceReference)4 ServiceRegistration (org.osgi.framework.ServiceRegistration)4 BundleWiring (org.osgi.framework.wiring.BundleWiring)4 HashMap (java.util.HashMap)3 CreateProxyRunnable (org.apache.karaf.service.guard.impl.GuardProxyCatalog.CreateProxyRunnable)3 ServiceFactory (org.osgi.framework.ServiceFactory)3 Collection (java.util.Collection)2 Callable (java.util.concurrent.Callable)2 Test (org.junit.Test)2 InvocationHandler (java.lang.reflect.InvocationHandler)1 Method (java.lang.reflect.Method)1