classpath对获取配置文件的影响

506 查看

Java中经常要用到各种配置文件xxx.properties来控制程序的运行或进行国际化等
但是也常常遇到配置文件放置路径找不到的问题,这里以java.uitl.ResourceBundle为例,
小结一下:
1.Classloader搜索的路径是classpath指定的
2.搜索文件时走的路径顺序是按照各目录或jar文件在classpath中的出现位置顺序来的
3.配置文件相对路径的参考root就是classpath中指定的目录或jar文件包起点

例如:位于package cn.flipme.util中的Resource要读取cache目录里的config.properties
我们可以这样写:

package cn.flipme.util;

import java.util.ResourceBundle;


public class Resource {
    public static void main( String[] args )
    {
        ResourceBundle rb=ResourceBundle.getBundle("cache.config");
        System.out.println(rb.getString("name"));
    }
}

这时我们把cache目录放在src目录下面,或者用Maven的话在src/main/resources目录下面,
不管怎么样编译后都会移到classes目录下, 执行就能顺利获取到config文件:

classes-|
        -cache-|
            -config.properties
        -cn-|
            -flipme-|
                -util-|
                    -Resource.class
                    

现在我们把这个工程打包成jar,假设叫resource.jar,存放在dist目录下,
可以通过在cmd里cd到 dist目录下并输入以下命令来执行包里的Resource.class

 java -cp resource.jar cn.flipme.util.Resource

注意类Resource前面必须写上完整的包路径
Ok,到现在为止一切都按部就班,执行上面的命令 Resource正常运行,读取resource.jar里面的cache/config.properties文件,并输出相应的name属性。

那么,如果我们想改变配置文件的内容是否需要修改源文件里的config.properties然后重新打包成jar呢?
显然这样做太麻烦也不太合理,你可以在jar外面配置一个新的config.properties让jar里的Resource去读取。

问题来了,新的config应该放在哪里呢?
答案是随便,你爱放哪里都可以,只要保证它呆在某个目录的cache/目录下,并且在-cp里指定放到地方。

最简单的就是放在dist目录里,也就是和.jar同级的目录,dist/cache/config.properties
执行:java -cp .;resource.jar cn.flipme.util.Resource
这次读取的就是新的config,而不是jar里面的config
请注意到以上命令中的.;这非常重要,因为它告诉java从当前目录里找文件
还有一点非常重要,那就是.;出现的位置是在resource.jar前面,所以顺序优先了,
当java从.目录也就是当前目录里找到了cache/config.properties就停止搜索了。

为了验证顺序的重要性,你不妨试试:
执行:java -cp resource.jar;. cn.flipme.util.Resource
你会发现 ;. 放到resource.jar后面时读取的config就是jar包里的那个config

好了,搞清楚以上两点之后,可以再试试在别的地方放置config文件,比如D:\test\cache\config.properties
执行:java -cp D:\test;resource.jar cn.flipme.util.Resource
同样的读取到的就是D盘里刚刚配置的新config。

就到这里吧,发现自己太唐僧了