java.lang.IllegalStateException:

2019-07-23  本文已影响0人  站在海边看远方

项目启动的时候,抛了如下异常:
java.lang.IllegalStateException: No such application config! Please add <dubbo:application name="..." /> to your spring config.

在配置加载的过程中,<dubbo:application name="xx" />这个配置项没有读取到,配置文件使用xml+properties的配置方式,在dubbo-provider.xml中配置<dubbo service />配置项,其他的一些公共配置比如application、registry、 portocol等放到dubbo.properties文件中读取。

1.问题分析

根据异常来看,是加载配置文件的时候出问题了,首先看了一下dubbo.properties文件,这个配置项是有的,排除配置文件书写错误。那接下来考虑一下配置文件是否没读取到。

dubbo配置文件,默认有4种来源:

下图展示了配置覆盖关系的优先级,从上到下优先级依次降低:

image
参考了dubbo官网内容:
dubbo配置加载流程

2.问题解决过程

2.1 -D参数配置

首先尝试了以-Ddubbo.properties.file=dubbo.properties的方式,还是报错,我电脑的系统是windows,百度发现这篇文章,windows下指定文件路径需要加一个 /,这样才能读取到文件路径。
dubbo.properties配置文件路径修改
ConfigUtil.class类中对路径有判断,当为/开头时,为文件路径,否者就是classpath路径;文件路径前一定要加"/",否者dubbo会按classpath路径去加载。ps:此只对window路径,Linux路径是默认/开头的。
代码如下:

public static Properties loadProperties(String fileName, boolean allowMultiFile, boolean optional) {
        Properties properties = new Properties();
        if (fileName.startsWith("/")) {
            try {
                FileInputStream input = new FileInputStream(fileName);
                try {
                    properties.load(input);
                } finally {
                    input.close();
                }
            } catch (Throwable e) {
                logger.warn("Failed to load " + fileName + " file from " + fileName + "(ingore this file): " + e.getMessage(), e);
            }
            return properties;
        }
        
        List<java.net.URL> list = new ArrayList<java.net.URL>();
        try {
            Enumeration<java.net.URL> urls = ClassHelper.getClassLoader().getResources(fileName);
            list = new ArrayList<java.net.URL>();
            while (urls.hasMoreElements()) {
                list.add(urls.nextElement());
            }
        } catch (Throwable t) {
            logger.warn("Fail to load " + fileName + " file: " + t.getMessage(), t);
        }
        
        if(list.size() == 0) {
            if (! optional) {
                logger.warn("No " + fileName + " found on the class path.");
            }
            return properties;
        }
        
        if(! allowMultiFile) {
            if (list.size() > 1) {
                String errMsg = String.format("only 1 %s file is expected, but %d dubbo.properties files found on class path: %s",
                        fileName, list.size(), list.toString());
                logger.warn(errMsg);
                // throw new IllegalStateException(errMsg); // see http://code.alibabatech.com/jira/browse/DUBBO-133
            }

            // fall back to use method getResourceAsStream
            try {
                properties.load(ClassHelper.getClassLoader().getResourceAsStream(fileName));
            } catch (Throwable e) {
                logger.warn("Failed to load " + fileName + " file from " + fileName + "(ingore this file): " + e.getMessage(), e);
            }
            return properties;
        }
        
        logger.info("load " + fileName + " properties file from " + list);
        
        for(java.net.URL url : list) {
            try {
                Properties p = new Properties();
                InputStream input = url.openStream();
                if (input != null) {
                    try {
                        p.load(input);
                        properties.putAll(p);
                    } finally {
                        try {
                            input.close();
                        } catch (Throwable t) {}
                    }
                }
            } catch (Throwable e) {
                logger.warn("Fail to load " + fileName + " file from " + url + "(ingore this file): " + e.getMessage(), e);
            }
        }
        
        return properties;
    }

2.2 设置系统环境变量

我用的dubbo的jar包是公司内部基于dubbo修改而来的,对配置文件读取做了一定的修改:

public static Properties getProperties() {
        if (PROPERTIES == null) {
            synchronized (ConfigUtils.class) {
                if (PROPERTIES == null) {
                    String path = System.getProperty(Constants.DUBBO_PROPERTIES_KEY);
                    if (path == null || path.length() == 0) {
                        path = System.getenv(Constants.DUBBO_PROPERTIES_KEY);
                        if(path == null || path.length() == 0){
                             path = System.getenv(Constants.ZSMART_HOME) + File.separator + Constants.ZSMART_HOME_CONF;
                             File file = new File(path);
                             if (file.exists()) {
                                 try {
                                    Properties properties = new Properties();
                                    FileInputStream input = new FileInputStream(path);
                                    try {
                                        properties.load(input);
                                    } finally {
                                        input.close();
                                    }
                                    PROPERTIES = properties;
                                    return PROPERTIES;
                                    
                                } catch (Throwable e) {
                                    logger.info("Failed to load " + path, e);
                                }
                             }else{
                                 path = Constants.DEFAULT_DUBBO_PROPERTIES;
                             }
                        }
                    }
                    PROPERTIES = ConfigUtils.loadProperties(path, false, true);
                }
            }
        }
        return PROPERTIES;
    }

我项目加的-DZSMART_HOME属于jvm变量,代码中取ZSMART_HOME是从系统环境变量中取的,所以启动一直报错。

3.总结

windows下使用-D参数指定dubbo.properties位置,一定要以"/"开头,不然还是会加载classpath路径下的配置文件
示例:

-Ddubbo.properties.file="/D:\dubbo.properties"

/D中间不能有空格
错误示范
/ D
正确示范
/D

上一篇下一篇

猜你喜欢

热点阅读