使用Reflections google库的单元测试仅在Maven执行时失败 [英] Unit test using the Reflections google library fails only when executed by Maven

查看:121
本文介绍了使用Reflections google库的单元测试仅在Maven执行时失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Google 反思库查询类路径中的某些资源。这些资源位于与我的项目中的类相同的位置。

I am using the Google Reflections library for querying certain resources in the classpath. Those resources are located in the same location than the classes in my project.

我在Eclipse中执行单元测试时,写了一些成功的单元测试,但是当我尝试使用Maven(例如使用 maven install )来执行它们,它们没有按预期工作。
经过一些调试,显然问题是当使用Maven执行时,Reflections库找不到资源所在的类路径url。

I wrote some unit tests that succeed when executed as a unit test in Eclipse, but when I try to execute them with Maven (with a maven install for example), they are not working as expected. After some debugging, apparently the problem is that when executed with Maven, the Reflections library cannot find the classpath url where the resources are located.

我到达该结论研究了反思如何确定应检查的类路径URL。作为示例,以下方法显示了Reflections如何找到给定类加载器的可用类路径URL(原始的Reflections方法已被简化):

I arrived to that conclusion researching how Reflections determines the classpath URLs that should be inspected. As an example, the following method shows how Reflections finds the available classpath URLs given a class loader (the original Reflections method has been simplified a bit):

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;
}

简而言之,它正在遍历类加载器层次结构,要求每个单个类加载器。

In short, it is traversing the class loader hierarchy asking for the URLs of each individual classloader.

在Eclipse中,我从单元测试中调用以前的方法,如下所示:

When in Eclipse I invoke the previous method from a unit test with something like this:

    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中)配置为我的项目:

as expected, I can see (among many other URLs) the classpath URLs that are configured as part of my project:

file:<MY_PROJECT_PATH>/target/classes/
file:<MY_PROJECT_PATH>/target/test-classes/

和反射作为一个魅力(Reflections应该找到的资源位于 file:< MY_PROJECT_PATH> / target / classes /

and Reflections works as a charm (the resources Reflections should find are located in file:<MY_PROJECT_PATH>/target/classes/).

但是,当Maven执行测试时,我意识到这些URL条目从 forClassLoader 方法返回的集合中丢失,而其余的Reflections方法不能像预期的那样工作。

However, when the test is executed by Maven, I realized that these URL entries are missing from the set returned by the forClassLoader method, and the rest of the Reflections methods are not working as expected for this problem.

令人惊讶的事情是,如果我在单元测试由maven执行时写下来:

The "surprising" thing is that if I write this when the unit test is executed by maven:

ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader();
url = myClassClassLoader.getResource("anExistingResource");
System.out.println("URL: "+url); //a valid URL

我可以看到,类加载器仍然可以解决我正在尝试的资源找。
我很困惑,为什么当用Maven执行时,code> forClassLoader 方法不包括在返回的集合中我的项目的类路径URL,但同时它是能够解决位于这样的URL中的资源(!)。

I can see that the class loader still can resolve the resource I am trying to find. I am puzzled about why when executed with Maven the forClassLoader method does not include in the returned set the classpath URLs of my project, although at the same time it is able to resolve resources that are located in such urls(!).

此行为的原因是什么?有没有任何解决方法可以尝试使Reflections库作为Maven运行的单元测试的一部分调用?

What is the reason of this behavior? Is there any workaround I can try to make the Reflections library work when invoked as part of a unit test run by Maven ?

推荐答案

你可能正在使用M2Eclipse,它将自己的东西添加到类路径中。命令行Maven的工作方式不同。您可能会发现一些可以帮助的选项

You're probably using M2Eclipse, which adds stuff to the classpath on its own. Command-line Maven works differently. You might find some options that will help.

这篇关于使用Reflections google库的单元测试仅在Maven执行时失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆