[原创] Java动态添加一个目录到classpath中

通常我们写程序,会用到一些配置文件,这些文件与程序在同一个父目录下,配置文件可能放在config之类的目录下,程序中会使用这些配置文件。
我遇到了这么件事情:因为一个特殊需求,需要把配置文件放到jar包中,最终部署出去的只能是一个jar包(所有东西都在jar包里,包括程序和所需的资源),然后在程序中使用 getClass().getResourceAsStream(文件在jar包中的路径) 的方式来读取配置文件。这也倒没什么不爽的,但是在单元测试中怎么办?

单元测试需要在classpath中能找到同样目录结构下的文件,就需要把你的配置文件路径加入classpath,这里你有几种方法:
『1』修改build.xml
在build.xml中可以指定run test时的classpath,你只要把那个目录添加进去就可以了。这样,nightly build(例如Jenkins)就不会失败,但是这种方法是有局限性的,即:你在命令行运行 ant test没有任何问题,但是你如果你的Java工程使用的是某IDE来开发(例如,IntelliJ 或 Eclipse 等),它们在没有特殊设置的情况下,在classpath中可能是找不到那个配置文件路径的,这时,你可以像这篇文章一样设置一下,单元测试就没问题了。
不过显然,第一次从代码库checkout出项目之后,还必须要设置一下总是让人不爽的,尤其是不熟悉项目的人,怎么会知道该添加哪个路径到classpath呢?
所以这种方法就不详述了,我觉得不好。

『2』修改IDE的项目设置
如上所述,修改IDE的项目设置可以使得在IDE中run test的时候通过,但是对诸如Jenkins之类的工具执行的nightly build(最终是通过build.xml实现的),仅仅修改IDE设置是没用的,nightly build依然会挂掉。所以这种方法只能保证“临时用用”。
文章来源:http://www.codelast.com/
『3』动态添加目录到classpath中
本文的主角登场了。
如果我们能在单元测试中,添加一些代码,动态地将需要的目录添加到classpath中,那么问题不就从最根本上解决了吗?不仅不用修改IDE里的项目设置,也不用修改build.xml,好多啊。是的,你只需要在单元测试中的setUp()里添加下面的代码:

@Before

public void setUp() throws Exception {
    File programRootDir = new File("./");
    URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Method add = URLClassLoader.class.getDeclaredMethod("addURL"new Class[]{URL.class});
    add.setAccessible(true);
    add.invoke(classLoader, programRootDir.toURI().toURL());
}

就可以把目录动态添加到classpath中了。在这里,代码中的“./”表示我把项目的根目录添加到了classpath中。
修改之后,无论是在IDE中run unit test,还是在命令行ant test,都完全没问题了。

文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):

wechat qrcode of codelast

发表评论