【问题标题】:When deploying a new feature config files are not loaded before bundles are started部署新功能时,在捆绑包启动之前不会加载配置文件
【发布时间】:2016-12-15 15:51:19
【问题描述】:

我正在评估 jboss fuse(使用版本 6.2.1.redhat-084),我遇到了以下问题:

  • 我的项目中有许多功能
  • 每个功能都有一个配置文件
  • 功能存储库文件如下所示:

.

<?xml version="1.0" encoding="UTF-8"?>
<features name="myservice-features" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0">
    <feature name="myservice-common" version="${project.version}">
        <configfile finalname="etc/com.myorg.myservice_common.cfg" override="true">mvn:com.myorg/myservice-common/${project.version}/cfg/${build.environment}</configfile>
        <bundle start-level="100" dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-cache-api/1.0.0_1</bundle>
        <bundle start-level="100" dependency="true">mvn:org.apache.camel/camel-velocity/${camel.version}</bundle>
        <bundle start-level="110">mvn:com.myorg/myservice-common/${project.version}</bundle>
    </feature>
    <feature name="myservice-impl" version="${project.version}">
        <feature>myservice-common</feature>
        <configfile finalname="etc/com.myorg.myservice.cfg" override="true">mvn:com.myorg/myservice-impl/${project.version}/cfg/${build.environment}</configfile>
        <bundle start-level="200">mvn:com.hazelcast/hazelcast/${hazelcast.version}</bundle>
        <bundle start-level="200">mvn:com.hazelcast/hazelcast-client/${hazelcast.version}</bundle>
        <bundle start-level="220">mvn:com.myorg/myservice-impl/${project.version}</bundle>
    </feature>
</features>
  • 服务使用带有相应 PID 的蓝图属性占位符来初始化骆驼上下文中的属性
  • 问题在于,在配置文件中部署功能时,配置文件仅在尝试解析捆绑包后才由 org.apache.felix.fileinstall 拾取,我遇到以下异常:

.

    2016-12-15 10:07:38,384 | ERROR | oyer-49-thread-1 | BlueprintContainerImpl           | 23 - org.apache.aries.blueprint.core - 1.4.4 | Unable to start blueprint container for bundle otc-trade-service-impl/1.0.0.SNAPSHOT
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to initialize bean .camelBlueprint.factory.myservice-impl-context
        at org.apache.aries.blueprint.container.BeanRecipe.runBeanProcInit(BeanRecipe.java:714)[23:org.apache.aries.blueprint.core:1.4.4]
...
Caused by: java.lang.IllegalArgumentException: Property placeholder key: xxxxx not found
        at org.apache.camel.blueprint.BlueprintPropertiesParser.parseProperty(BlueprintPropertiesParser.java:164)
        at org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.doGetPropertyValue(DefaultPropertiesParser.java:306)[198:org.apache.camel.camel-core:2.15.1.redhat-621084]
        at org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.getPropertyValue(DefaultPropertiesParser.java:246)[198:org.apache.camel.camel-core:2.15.1.redhat-621084]
        at org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.readProperty(DefaultPropertiesParser.java:154)[198:org.apache.camel.camel-core:2.15.1.redhat-621084]
        at org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.doParse(DefaultPropertiesParser.java:113)[198:org.apache.camel.camel-core:2.15.1.redhat-621084]
        at org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.parse(DefaultPropertiesParser.java:97)[198:org.apache.camel.camel-core:2.15.1.redhat-621084]
        at org.apache.camel.component.properties.DefaultPropertiesParser.parseUri(DefaultPropertiesParser.java:62)
        at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:178)
        at org.apache.camel.component.properties.PropertiesComponent.parseUri(PropertiesComponent.java:129)
        at org.apache.camel.impl.DefaultCamelContext.resolvePropertyPlaceholders(DefaultCamelContext.java:1956)
        at org.apache.camel.model.ProcessorDefinitionHelper.resolvePropertyPlaceholders(ProcessorDefinitionHelper.java:734)
        at org.apache.camel.model.RouteDefinitionHelper.initRouteInputs(RouteDefinitionHelper.java:379)
        ... 47 more
  • 这看起来类似于问题https://issues.jboss.org/browse/ENTESB-593;但是,看起来该问题的“修复”仅涉及将配置文件复制到 ${karaf.base}/etc 文件夹中,但在启动捆绑包之前实际上并未在 karaf 配置管理器上触发和同步

我有点纠结这个问题。显然我可以为我的包设置 'start="false"' 并在配置文件部署后手动启动所有骆驼上下文包,但我想知道是否有更优化的解决方案。

【问题讨论】:

  • 您尝试过使用 JBoss Fuse 6.3.0 吗?

标签: jbossfuse fabric8


【解决方案1】:

到目前为止,我想出了以下 hacky 解决方法:

  • 为 org.osgi:org.osgi.compendium:5.0.0 和 org.osgi:org.osgi.core:5.0.0 添加依赖项
  • 创建以下 BundleActivator 类:

.

package com.myorg.common;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Dictionary;

public class ConfigurationActivator implements BundleActivator {

    public static final String BUNDLE_CONFIGURATION_WATCH = "bundle.configuration.watch";
    public static final String BUNDLE_SYMBOLIC_NAME = "bundle.symbolic.name";

    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationActivator.class);
    private ServiceRegistration<org.osgi.service.cm.ConfigurationListener> listenerReg;

    public void start(BundleContext context) throws Exception {
        LOG.debug("Bundle " + context.getBundle().getSymbolicName() + " starting");
        listenerReg = context.registerService(org.osgi.service.cm.ConfigurationListener.class,
                new ConfigurationListener(context), null);
    }

    public void stop(BundleContext context) throws Exception {
        LOG.debug("Bundle " + context.getBundle().getSymbolicName() + " stopping");
        if (listenerReg != null) {
            listenerReg.unregister();
        }
    }

    public class ConfigurationListener implements org.osgi.service.cm.ConfigurationListener {
        private BundleContext bundleContext;

        public ConfigurationListener(BundleContext bundleContext) {
            this.bundleContext = bundleContext;
        }

        public void configurationEvent(ConfigurationEvent configurationEvent) {
            try {
                if (configurationEvent.getType() == ConfigurationEvent.CM_UPDATED) {
                    LOG.debug("Configuration update event: " + configurationEvent.getPid());
                    Bundle bundle = bundleContext.getBundle();
                    LOG.trace("Bundle " + bundle.getSymbolicName() + " state: " + bundle.getState());
                    try {
                        Configuration configuration = bundleContext.getService(configurationEvent.getReference()).getConfiguration(configurationEvent.getPid());
                        if (configuration != null) {
                            Dictionary<String, Object> properties = configuration.getProperties();
                            if (properties != null) {
                                if (Boolean.TRUE.toString().equals(properties.get(BUNDLE_CONFIGURATION_WATCH))
                                        && bundle.getSymbolicName().equals(properties.get(BUNDLE_SYMBOLIC_NAME))) {
                                    LOG.info("Updating bundle " + bundle.getSymbolicName() + " due to configuration change");
                                    bundle.update();
                                }
                            }
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            } catch (IllegalStateException se) {
                LOG.warn("Bundle context has been invalidated");
            }
        }
    }
}
  • 将此捆绑激活器添加到捆绑清单中
  • 将以下属性添加到您的配置文件中:

    bundle.configuration.watch=true
    bundle.symbolic.name=<bundle-name>
    
  • 部署该功能。如果在捆绑包已经尝试启动后配置发生了变化,捆绑包将被更新

由于两个原因,这对我来说仍然不雅:

  1. 其他配置属性
  2. 原始问题在部署期间仍会导致日志中出现令人困惑的错误消息

谁能提出更好的答案?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多