使用Java ServiceLoader的类路径结果NoTouchElementException错误
我的类dofindmidle服务扩展了抽象类dofindmddle。 以下是DoFindMiddle类:
public abstract class DoFindMiddle<T extends Comparable<T>> {
public abstract ListItem<T> findMiddle(ListItem<T> paramListItem);
public static <D extends Comparable<D>> DoFindMiddle<D> newInstance() {
return (DoFindMiddle)ServiceLoader.load(DoFindMiddle.class).iterator().next();
}
}
以下是DoFindMiddleService类的第一部分:
package com.nng.interview.homework.applicant.kovacskalman;
import com.nng.interview.homework.exercise.DoFindMiddle;
import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
public class DoFindMiddleService<T extends Comparable<T>> extends DoFindMiddle<T> {
public static DoFindMiddle service;
public volatile ServiceLoader<DoFindMiddleService> loader;
public DoFindMiddleService() {
loader = ServiceLoader.load(DoFindMiddleService.class);
}
public static synchronized DoFindMiddle getInstance() {
if (service == null) {
service = new DoFindMiddleService();
}
return service;
}
public String getDefinition(String word) {
String definition = null;
try {
Iterator<DoFindMiddleService> dictionaries = loader.iterator();
while (definition == null && dictionaries.hasNext()) {
DoFindMiddleService d = dictionaries.next();
definition = d.getDefinition(word);
}
} catch (ServiceConfigurationError serviceError) {
definition = null;
serviceError.printStackTrace();
}
return definition;
}
.....
}
如果我在单元测试中尝试以下操作:
final DoFindMiddle<Integer> instance = new DoFindMiddleService();
然后它就开始工作了。但是当我尝试单元测试时:
final DoFindMiddle<Integer> instance = DoFindMiddle.newInstance();
然后它将导致无接触异常错误。 什么是我的错
我的pom。xml如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nng.interview.homework.applicant</groupId>
<name>Kovács Kálmán</name>
<artifactId>kovacskalman</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.nng.interview.homework</groupId>
<artifactId>comnnginterviewhomework</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
</project>
当我尝试执行时,出现以下错误:
d:\kovacskalman>mvn exec:java -Dexec.mainClass="com.nng.interview.homework.appli
cant.kovacskalman.App"
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Kovacs Kalman 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.3.2:java (default-cli) @ kovacskalman ---
[WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment
on MEXEC-6.
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:357)
at java.util.ServiceLoader$1.next(ServiceLoader.java:445)
at com.nng.interview.homework.exercise.DoFindMiddle.newInstance(DoFindMi
ddle.java:52)
at com.nng.interview.homework.applicant.kovacskalman.App.<init>(App.java
:9)
at com.nng.interview.homework.applicant.kovacskalman.App.main(App.java:1
3)
... 6 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.076 s
[INFO] Finished at: 2014-11-01T15:19:51+01:00
[INFO] Final Memory: 9M/96M
# 1 楼答案
根据javadoc,迭代器()可以:
根据您的异常,迭代器为空,这意味着未找到任何实现
DoFindMiddleService
在你的类路径中吗# 2 楼答案
我必须将META-INF/services/com放入jar中。nng。采访作业运动多芬迪德尔 仅包含一行的命名文件: 通用域名格式。nng。采访作业申请人科瓦茨卡曼。DoFindMiddleService#标准服务提供商
让我们看看Jar文件规范服务提供程序部分:
https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Service_Provider