[ https://issues.apache.org/jira/browse/FELIX-4853?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14500871#comment-14500871 ]
Pierre De Rop commented on FELIX-4853: -------------------------------------- Regarding the java8 example, we can even push the limit of java8 using type inference: In the TCCLCallback, we can introduce a static method that can be used to create a TCCLCallback instance with generic types inferred from the Consumer parameter: {code} /** * Tool that allows to delegate a dependency callback with TCCL set to the injected service dependency. * * @param <T> The type of the class where the service dependency has to be injected to, but with TCCL set to the injected service class loader. * @param <U> The type of the injected service. */ public class TCCLCallback<T, U> { private final BiConsumer<T, U> consumer; /** * Creates a TCCLCallback instance with generic types automatically infered from the consumer parameter. */ static <U,V> TCCLCallback<U,V> tccl(BiConsumer<U,V> consumer) { return new TCCLCallback<U,V>(consumer); } public TCCLCallback(BiConsumer<T, U> consumer) { this.consumer = consumer; } void bind(Component component, ServiceReference ref, U service) { Thread t = Thread.currentThread(); ClassLoader current = t.getContextClassLoader(); Bundle bundle = ref.getBundle(); BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); ClassLoader cl = bundleWiring.getClassLoader(); try { t.setContextClassLoader(cl); T instance = component.getInstance(); consumer.accept(instance, service); } finally { t.setContextClassLoader(current); } } } {code} And using the static tccl factory method above, we can now reduce again the "code ceremony" in the Activator: {code} import static tcclcallback.TCCLCallback.tccl; ... public class Activator extends DependencyActivatorBase { @Override public void init(BundleContext bc, DependencyManager dm) throws Exception { dm.add(createComponent() .setImplementation(ServiceImpl.class) .setInterface(Service.class.getName(), null)); dm.add(createComponent() .setImplementation(Pojo.class) .add(createServiceDependency() .setService(Service.class).setCallbacks(tccl(Pojo::bind), "bind", null))); } } {code} > Create a new ServiceDependency that sets the TCCL to the incoming > servicereference bundle's classloader before invoking callbaks > -------------------------------------------------------------------------------------------------------------------------------- > > Key: FELIX-4853 > URL: https://issues.apache.org/jira/browse/FELIX-4853 > Project: Felix > Issue Type: New Feature > Components: Dependency Manager > Affects Versions: dependencymanager-3.2.0 > Reporter: Carlos Sierra > Attachments: examples.tgz > > > The invoke method would go like this: > {code:title=TCCLServiceDependencyImpl.java|borderStyle=solid} > @Override > @SuppressWarnings("rawtypes") > public void invoke( > Object[] callbackInstances, DependencyService dependencyService, > ServiceReference reference, Object service, String name) { > Bundle bundle = reference.getBundle(); > BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); > ClassLoader bundleClassLoader = bundleWiring.getClassLoader(); > Thread currentThread = Thread.currentThread(); > ClassLoader contextClassLoader = > currentThread.getContextClassLoader(); > currentThread.setContextClassLoader(bundleClassLoader); > try { > super.invoke( > callbackInstances, dependencyService, > reference, service, name); > } > finally { > currentThread.setContextClassLoader(contextClassLoader); > } > } > {code} > If you think this is useful I can provide a patch. Which version and which > repo should I use for it? -- This message was sent by Atlassian JIRA (v6.3.4#6332)