我使用的是谷歌的反思库在类路径查询某些资源。 这些资源都位于相同的位置比我的项目中的类。
我写了一些单元测试时作为Eclipse的一个单元测试执行的成功,但是当我尝试使用Maven来执行它们(用maven install
为例),预期它们不工作。 一些调试后,显然的问题是,当使用Maven执行的思考图书馆找不到类路径URL的资源所在的位置。
我来到这个结论研究思考如何确定应检查类路径的URL。 作为一个例子,下面的方法显示了思考如何找到给定的类加载器可用的类路径的URL(原始的思考方法已被简化一个位):
public static Set<URL> forClassLoader(ClassLoader... classLoaders) {
final Set<URL> result = Sets.newHashSet();
for (ClassLoader classLoader : classLoaders) {
while (classLoader != null) {
if (classLoader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) classLoader).getURLs();
if (urls != null) {
result.addAll(Sets.<URL>newHashSet(urls));
}
}
classLoader = classLoader.getParent();
}
}
return result;
}
总之,它是穿越类装载器层次要求为每个类加载器的URL。
当在Eclipse我从这样的一个单元测试调用以前的方法:
ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader(); //<MyClass> is in the same classpath url than the resources I need to find
Set<URL> urls = forClassLoader(myClassClassLoader);
for(URL url : urls) {
System.out.println("a url: " + url);
正如所料,我可以看到,被配置为我的项目的一部分的类路径的URL(其中包括许多其他的网址):
file:<MY_PROJECT_PATH>/target/classes/
file:<MY_PROJECT_PATH>/target/test-classes/
与思考工程作为魅力(资源思考应该找到位于file:<MY_PROJECT_PATH>/target/classes/
)。
然而,当测试由Maven的执行,我意识到,这些URL条目从被返回的集中缺少forClassLoader
方法,和的思考方法,其余如预期这个问题不工作。
该“令人吃惊”的是,如果我写这篇文章时,单元测试是由行家执行:
ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader();
url = myClassClassLoader.getResource("anExistingResource");
System.out.println("URL: "+url); //a valid URL
我可以看到的类加载器仍然可以解决我试图找到资源。 我很疑惑为什么当使用Maven执行forClassLoader
方法不会在我的项目的返回将classpath设置的URL包括,但同时它能够解决位于此类URL资源(!)。
什么是这种行为的原因是什么? 有任何解决方法,我可以试着让思考图书馆工作时,作为Maven的运行单元测试的一部分调用?