Return-Path: X-Original-To: apmail-felix-dev-archive@www.apache.org Delivered-To: apmail-felix-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0347C17BE4 for ; Fri, 17 Apr 2015 23:06:59 +0000 (UTC) Received: (qmail 64896 invoked by uid 500); 17 Apr 2015 23:06:58 -0000 Delivered-To: apmail-felix-dev-archive@felix.apache.org Received: (qmail 64823 invoked by uid 500); 17 Apr 2015 23:06:58 -0000 Mailing-List: contact dev-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list dev@felix.apache.org Received: (qmail 64811 invoked by uid 99); 17 Apr 2015 23:06:58 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Apr 2015 23:06:58 +0000 Date: Fri, 17 Apr 2015 23:06:58 +0000 (UTC) From: "Pierre De Rop (JIRA)" To: dev@felix.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (FELIX-4853) Create a new ServiceDependency that sets the TCCL to the incoming servicereference bundle's classloader before invoking callbaks MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ 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 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 The type of the injected service. */ public class TCCLCallback { private final BiConsumer consumer; /** * Creates a TCCLCallback instance with generic types automatically infered from the consumer parameter. */ static TCCLCallback tccl(BiConsumer consumer) { return new TCCLCallback(consumer); } public TCCLCallback(BiConsumer 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)