CAMEL-7920 Make sure the JAXB fallback converter is the last one loaded
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7f730a86 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7f730a86 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7f730a86 Branch: refs/heads/camel-2.14.x Commit: 7f730a86bf4f471d32b403aef87c1e8737096ca8 Parents: 48823dd Author: Willem Jiang <willem.ji...@gmail.com> Authored: Fri Oct 17 11:07:26 2014 +0800 Committer: Willem Jiang <willem.ji...@gmail.com> Committed: Fri Oct 17 11:39:01 2014 +0800 ---------------------------------------------------------------------- .../converter/BaseTypeConverterRegistry.java | 1 + .../org/apache/camel/impl/osgi/Activator.java | 18 ++++++++--- .../camel/core/osgi/OsgiTypeConverter.java | 33 ++++++++++++++------ 3 files changed, 38 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/7f730a86/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java index af4e1b3..962c415 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java +++ b/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java @@ -390,6 +390,7 @@ public abstract class BaseTypeConverterRegistry extends ServiceSupport implement log.trace("Adding fallback type converter: {} which can promote: {}", typeConverter, canPromote); // add in top of fallback as the toString() fallback will nearly always be able to convert + // the last one which is add to the FallbackTypeConverter will be called at the first place fallbackConverters.add(0, new FallbackTypeConverter(typeConverter, canPromote)); if (typeConverter instanceof TypeConverterAware) { TypeConverterAware typeConverterAware = (TypeConverterAware) typeConverter; http://git-wip-us.apache.org/repos/asf/camel/blob/7f730a86/camel-core/src/main/java/org/apache/camel/impl/osgi/Activator.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/osgi/Activator.java b/camel-core/src/main/java/org/apache/camel/impl/osgi/Activator.java index 9502a1d..9900207 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/osgi/Activator.java +++ b/camel-core/src/main/java/org/apache/camel/impl/osgi/Activator.java @@ -61,8 +61,8 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; +import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -176,7 +176,8 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer { URL url1 = bundle.getEntry(META_INF_TYPE_CONVERTER); URL url2 = bundle.getEntry(META_INF_FALLBACK_TYPE_CONVERTER); if (url1 != null || url2 != null) { - resolvers.add(new BundleTypeConverterLoader(bundle)); + LOG.debug("Found TypeConverter in bundle {}", bundle.getSymbolicName()); + resolvers.add(new BundleTypeConverterLoader(bundle, url2 != null)); } } } @@ -264,11 +265,13 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer { private final AnnotationTypeConverterLoader loader = new Loader(); private final Bundle bundle; + private final boolean hasFallbackTypeConverter; - public BundleTypeConverterLoader(Bundle bundle) { + public BundleTypeConverterLoader(Bundle bundle, boolean hasFallbackTypeConverter) { super(bundle, TypeConverter.class); ObjectHelper.notNull(bundle, "bundle"); this.bundle = bundle; + this.hasFallbackTypeConverter = hasFallbackTypeConverter; } public synchronized void load(TypeConverterRegistry registry) throws TypeConverterLoaderException { @@ -282,7 +285,13 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer { } public void register() { - doRegister(TypeConverterLoader.class); + if (hasFallbackTypeConverter) { + // The FallbackTypeConverter should have a higher ranking + doRegister(TypeConverterLoader.class, Constants.SERVICE_RANKING, new Integer(100)); + } else { + // The default service ranking is Integer(0); + doRegister(TypeConverterLoader.class); + } } class Loader extends AnnotationTypeConverterLoader { @@ -360,6 +369,7 @@ public class Activator implements BundleActivator, BundleTrackerCustomizer { // register fallback converters URL fallbackUrl = bundle.getEntry(META_INF_FALLBACK_TYPE_CONVERTER); if (fallbackUrl != null) { + LOG.debug("Found {} to load the FallbackTypeConverter", META_INF_FALLBACK_TYPE_CONVERTER); TypeConverter tc = createInstance("FallbackTypeConverter", fallbackUrl, registry.getInjector()); registry.addFallbackTypeConverter(tc, false); } http://git-wip-us.apache.org/repos/asf/camel/blob/7f730a86/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiTypeConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiTypeConverter.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiTypeConverter.java index 8bd1c00..0c3ab78 100644 --- a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiTypeConverter.java +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiTypeConverter.java @@ -16,6 +16,8 @@ */ package org.apache.camel.core.osgi; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; @@ -60,12 +62,16 @@ public class OsgiTypeConverter extends ServiceSupport implements TypeConverter, public Object addingService(ServiceReference<TypeConverterLoader> serviceReference) { LOG.trace("AddingService: {}", serviceReference); TypeConverterLoader loader = bundleContext.getService(serviceReference); - if (loader != null) { + // just make sure we don't load the bundle converter this time + if (delegate != null) { try { - loader.load(getDelegate()); - } catch (Throwable t) { - throw ObjectHelper.wrapRuntimeCamelException(t); + ServiceHelper.stopService(this.delegate); + } catch (Exception e) { + // ignore + LOG.debug("Error stopping service due: " + e.getMessage() + ". This exception will be ignored.", e); } + // It can force camel to reload the type converter again + this.delegate = null; } return loader; } @@ -81,6 +87,7 @@ public class OsgiTypeConverter extends ServiceSupport implements TypeConverter, // ignore LOG.debug("Error stopping service due: " + e.getMessage() + ". This exception will be ignored.", e); } + // It can force camel to reload the type converter again this.delegate = null; } @@ -185,14 +192,20 @@ public class OsgiTypeConverter extends ServiceSupport implements TypeConverter, throw new RuntimeCamelException("Error loading CoreTypeConverter due: " + e.getMessage(), e); } - // load the type converters the tracker has been tracking - Object[] services = this.tracker.getServices(); - if (services != null) { - for (Object o : services) { + // Load the type converters the tracker has been tracking + // Here we need to use the ServiceReference to check the ranking + ServiceReference<TypeConverterLoader>[] serviceReferences = this.tracker.getServiceReferences(); + if (serviceReferences != null) { + ArrayList<ServiceReference<TypeConverterLoader>> servicesList = + new ArrayList<ServiceReference<TypeConverterLoader>>(Arrays.asList(serviceReferences)); + // Just make sure we install the high ranking fallback converter at last + Collections.sort(servicesList); + for (ServiceReference<TypeConverterLoader> sr : servicesList) { try { - ((TypeConverterLoader) o).load(answer); + LOG.debug("loading the type converter from bundle{} ", sr.getBundle().getSymbolicName()); + ((TypeConverterLoader)this.tracker.getService(sr)).load(answer); } catch (Throwable t) { - throw new RuntimeCamelException("Error loading type converters from service: " + o + " due: " + t.getMessage(), t); + throw new RuntimeCamelException("Error loading type converters from service: " + sr + " due: " + t.getMessage(), t); } } }