我正在使用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