为什么Eclipse JUnit4 Runner无法识别META-INF/services文件

6
我正在使用Maven和Eclipse(使用M2E)构建一个项目,该项目依赖于java.util.ServiceLoader来动态加载一些工厂类。在Maven中运行时可以正常工作,但是当我使用内置的Eclipse JUnit4 Runner运行测试时,它无法获取服务并且测试失败。
我需要手动将META-INF/services添加到JUnit的构建路径中吗?我无法使其在src/main/resources/META-INF/services或src/main/java/META-INF/services中工作。这是否与M2E设置构建路径的方式有关?我在一个全新的项目中进行了测试,但仍然失败。
基本的失败代码如下:
public class TestServiceLoader<S>
{
   public TestServiceLoader(final Class<S> serviceClass)
   {

       ServiceLoader<S> serviceLoader =
            java.util.ServiceLoader.load(serviceClass, serviceClass.getClassLoader());

       Iterator<S> services = serviceLoader.iterator();

       if(!services.hasNext())
       {
           throw new RuntimeException("Failed to get any services for this class");
       }
   }
}

测试如下所示:
@Test
public final void testTestServiceLoader()
{
    TestServiceLoader<TestFactory> serviceLoader = new TestServiceLoader<TestFactory>(TestFactory.class);
}

TestFactory 的定义如下:

public interface TestFactory
{

}

TestFactoryImpl 的定义如下:

public class TestFactoryImpl implements TestFactory
{

}

我最初使用的是来自 http://weblogs.java.net/blog/kohsuke/archive/2009/03/my_project_of_t.html 的 MetaInfServices 生成器,但当我手动创建文件并删除该生成器后,在使用 Maven Surefire 插件运行时成功了,但在 Eclipse 中仍然失败。


你的 META-INF/services/* 文件在哪个目录下?是在 src/main/resources 目录下吗?在你的 Eclipse 项目中,src/main/resources 目录是否配置为源文件夹? - prunge
抱歉,我在最初发布问题后添加了细节。我已经尝试过src/main/resources和src/main/java两个路径。Java构建路径包含具有Included(All)和Excluded 的src/main/resources。在这里有意义吗? - Peter
我去掉了 **,它可以工作了!现在问题是,我该如何在不手动调整构建路径的情况下始终修复它。 - Peter
显然这是一个众所周知的问题。我在谷歌上搜索了错误的关键词。这是相关的M2E bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=351092,由于我的声望太低,我无法回答自己的问题(还有几个小时)。 - Peter
1个回答

1

M2E的开发人员似乎认为任何资源都会影响Maven构建,即使在META-INF/services/是一个功能部分的情况下,尽管它是一个资源:

“实际上,项目资源文件夹不需要真正添加到构建路径中(Maven Builder可以在没有它的情况下工作),但被认为在Package Explorer和其他Eclipse视图中更方便和美观。” M2E FAQ

如果你想绕过它,显然可以将特殊的M2E配置文件编码到你的pom.xml文件中,以使M2E增量构建过滤器和复制资源。Sonatype M2Eclipse Wiki


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接