为什么Eclipse JUnit4 Runner不能拾取META-INF/services文件?



我正在使用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插件运行时却成功。

M2E开发人员似乎相信任何资源都会影响maven构建,即使META-INF/services/是一个功能部分,尽管是一个资源:

"实际上项目资源文件夹并不需要添加到构建路径中(Maven Builder不需要它也可以工作),但它被认为是方便的,并且在Package Explorer和其他Eclipse视图中看起来更好。"M2E的FAQ

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

最新更新