Подкласс, полученный из Serviceloader, генерирует AbstractMethodError

Я пытаюсь сделать приложение 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, Я знаю это, так как в цикле я могу сделать class.getName() и это даст мне anotherstuff.NotAbstractClass) но выдает ошибку:java.lang.AbstractMethodError: stuff.TheAbstractClass.getClassName()Ljava/lang/String;

Я в тупике. Любое предложение? Спасибо, Педро

2 ответа

Кажется, проблема была не в коде, а в IDE (IntelliJ). Я удалил все ранее упакованные фляги и сделал новые фляги, ничего не изменяя, и это волшебно работало... Так что это ошибка IDE, а не проблема языка! Спасибо @Joao и @hotzst за то, что нашли время почитать. Бест, Педро

Согласно API для AbstractMethodError вы получите это:

Брошенный, когда приложение пытается вызвать абстрактный метод. Обычно эта ошибка отлавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение некоторого класса несовместимо изменилось с момента последней компиляции выполняемого в данный момент метода.

Просто глядя на ваш код и ваш комментарий, я вижу, что это могло произойти только во время выполнения.

Если это так, то:

какой-то класс несовместимо изменился, так как текущий выполняемый метод был скомпилирован последним

Я проверил вашу логику после некоторых настроек в Java-совместимой форме, и у меня не было проблем. Единственное, что, кажется, происходит, - это изменение в любом из подклассов TheAbstractClass,

Еще я хотел объявить зависимости, используя файлы зависимостей в: resources/META-INF/services:

файл: <полный пакет>.TheAbstractClass

content: <полный пакет>.NotAbstractClass

После этого у меня не было проблем.

Другие вопросы по тегам