从Serviceloader获得的子类抛出AbstractMethodError

时间:2016-05-15 20:00:22

标签: java abstract-class serviceloader

我正在尝试创建一个Java应用程序,它可以加载实现抽象类的插件,并且具有一个AbstractMethodError,其中包含从ServiceLoader生成的实例。代码有点沉重,所以我在下面进行了简化。

首先,我有一个抽象类:

package stuff.TheAbstractClass;

public abstract class TheAbstractClass implements ClassInterface{
 //Stuff happens
}

实现以下界面:

package stuff.ClassInterface;

public interface ClassInterface {

    public String getClassName();

}

我有一个服务提供商NotAbstractClass,它扩展了TheAbstractClass并在meta-inf / services文件夹中声明:

package anotherstuff.NotAbstractClass;

public final class NotAbstractClass extends TheAbstractClass implements ClassInterface{
    private String name = "Silent Bob";

    @Override
    public String getClassName() { return name; }

}

然后在主应用程序(实际上是另一个应用程序中的插件)中,我想找到所有扩展TheAbstractClass的类:

package stuff.TheApp;

import java.util.ServiceLoader;

public class TheApp {
    private String name;

    public final static TheApp INSTANCE = new TheApp();

    private TheApp() {
        ServiceLoader<TheAbstractClass> serviceLoader =
            ServiceLoader.load(TheAbstractClass.class);
        for (TheAbstractClass class: serviceLoader) {
            name = class.getClassName;
        }
}

我的应用找到了NotAbstractClass。我知道这一点,因为在for循环中,我可以class.getName()并且它会给我anotherstuff.NotAbstractClass)但是会给出错误: java.lang.AbstractMethodError: stuff.TheAbstractClass.getClassName()Ljava/lang/String;

我很难过。有什么建议吗?谢谢,佩德罗

2 个答案:

答案 0 :(得分:0)

根据AbstractMethodError的API,你得到了这个:

  

当应用程序尝试调用抽象方法时抛出。一般,   编译器捕获此错误;此错误只能在运行时发生   时间,如果某个类的定义自那以后不一致改变了   最后编译了当前正在执行的方法。

只要查看您的代码和评论,我就会发现这只能在运行时发生。

如果是这样的话,那么:

  

某些类自当前正在执行以来已无法更改   方法最后编译

我在Java兼容表单中进行了一些调整后测试了你的逻辑,我没有遇到任何问题。似乎唯一发生的事情是TheAbstractClass

的任何子类的更改

我做的另一件事是使用依赖文件声明依赖项:resources / META-INF / services:

档案:&lt; full-package&gt; .TheAbstractClass

内容:&lt; full-package&gt; .NotAbstractClass

在此之后我没有遇到任何问题。

答案 1 :(得分:0)

似乎问题不在代码中,而是在IDE(IntelliJ)中。我删除了所有以前打包的罐子并制作了新的罐子而没有改变任何东西,它神奇地工作......所以这是一个IDE错误,而不是语言问题! 感谢@Joao和@hotzst花时间阅读。 最好,佩德罗