0

我正在尝试制作一个 Java 应用程序,该应用程序可以加载实现抽象类的插件,并且在从 ServiceLoader 生成的实例中出现 AbstractMethodError。代码有点重,所以我在下面做了一个简化。

首先,我有一个抽象类:

package stuff.TheAbstractClass;

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

它实现了以下接口:

package stuff.ClassInterface;

public interface ClassInterface {

    public String getClassName();

}

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

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;

我难住了。有什么建议吗?谢谢你,佩德罗

4

2 回答 2

0

根据AbstractMethodError API你得到这个:

当应用程序尝试调用抽象方法时抛出。通常,这个错误会被编译器捕获;如果自上次编译当前执行的方法以来某些类的定义发生了不兼容的更改,则此错误只会在运行时发生。

仅通过查看您的代码和您的评论,我发现这只能在运行时发生。

如果是这样的话:

自上次编译当前执行的 方法以来,某些类发生了不兼容的更改

在以 Java 兼容形式进行一些调整后,我已经测试了你的逻辑,我没有遇到任何问题。唯一似乎正在发生的事情是TheAbstractClass.

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

文件:<完整包>.TheAbstractClass

内容:<完整包>.NotAbstractClass

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

于 2016-05-15T22:27:58.297 回答
0

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

于 2016-05-16T10:48:56.320 回答