From: Tom Pantelis Date: Thu, 18 Aug 2016 14:31:00 +0000 (-0400) Subject: Fix FinalModifierException due to BindingToNormalizedNodeCodec final X-Git-Tag: release/carbon~517 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=ed940fc416097e519428eaa3bba9e0d7d126b8cf Fix FinalModifierException due to BindingToNormalizedNodeCodec final The BindingToNormalizedNodeCodec class is final which prevents blueprint from being able to create a proxy instance when advertising as a service. This is is OK as it will use the actual instance but it logs an exception: 2016-08-11 23:03:18,215 | INFO | rint Extender: 2 | ServiceRecipe | 15 - org.apache.aries.blueprint.core - 1.6.1 | Unable to create a proxy object for the service .component-2 defined in bundle org.opendaylight.controller.sal-binding-broker-impl/1.5.0.SNAPSHOT with id. Returning the original object instead. org.apache.aries.proxy.FinalModifierException: The class org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec is final. at org.apache.aries.proxy.impl.gen.ProxySubclassGenerator.scanForFinalModifiers(ProxySubclassGenerator.java:330)[12:org.apache.aries.proxy.impl:1.0.5] Although it's logged at INFO level we should avoid it. Changing BindingToNormalizedNodeCodec to non-final fixes the exception however it causes an error when it tries to create the proxy b/c some methods are final. To avoid this, weneed to avoid the proxy creation altogether so I added a method to BindingToNormalizedNodeCodecFactory to advertise the OSGi service instead of using the blueprint element. Note: it's not good practice to advertise a service with the actual class but it's needed with BindingToNormalizedNodeCodec for backwards compatibility with CSS modules that inject the BindingToNormalizedNodeCodec instance and not its interfaces. The BindingToNormalizedNodeCodec CSS service identity is deprecated and will/should go away in the future. Change-Id: I96b6cb8b030de39808de17142d79f8bbd09bf735 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodecFactory.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodecFactory.java index bb123a15f1..f1ae5cb1c5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodecFactory.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodecFactory.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.md.sal.binding.impl; +import java.util.Dictionary; +import java.util.Hashtable; import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; @@ -14,6 +16,8 @@ import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeC import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; /** * Factory class for creating and initializing the BindingToNormalizedNodeCodec instances. @@ -62,4 +66,27 @@ public class BindingToNormalizedNodeCodecFactory { SchemaService schemaService) { return schemaService.registerSchemaContextListener(instance); } + + /** + * This method is called via blueprint to register a BindingToNormalizedNodeCodec instance with the OSGI + * service registry. This is done in code instead of directly via blueprint because the BindingToNormalizedNodeCodec + * instance must be advertised with the actual class for backwards compatibility with CSS modules and blueprint + * will try to create a proxy wrapper which is problematic with BindingToNormalizedNodeCodec because it's final + * and has final methods which can't be proxied. + * + * @param instance the BindingToNormalizedNodeCodec instance + * @param bundleContext the BundleContext + * @return ServiceRegistration instance + */ + public static ServiceRegistration registerOSGiService(BindingToNormalizedNodeCodec instance, + BundleContext bundleContext) { + Dictionary props = new Hashtable<>(); + + // Set the appropriate service properties so the corresponding CSS module is restarted if this + // blueprint container is restarted + props.put("config-module-namespace", "urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl"); + props.put("config-module-name", "runtime-generated-mapping"); + props.put("config-instance-name", "runtime-mapping-singleton"); + return bundleContext.registerService(BindingToNormalizedNodeCodec.class, instance, props ); + } } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/resources/org/opendaylight/blueprint/binding-broker.xml b/opendaylight/md-sal/sal-binding-broker/src/main/resources/org/opendaylight/blueprint/binding-broker.xml index 79d0868d0d..f1438c650e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/resources/org/opendaylight/blueprint/binding-broker.xml +++ b/opendaylight/md-sal/sal-binding-broker/src/main/resources/org/opendaylight/blueprint/binding-broker.xml @@ -13,7 +13,7 @@ - @@ -30,16 +30,11 @@ - - - - - - - - + + + +