Загрузка классов и их данных из файла JAR не работает полностью?

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

Вот что я пытаюсь сделать:

Я разработал приложение, и часть его позволяет другим людям программировать для него свои собственные плагины. Для этого им необходимо загрузить мою библиотеку и расширить свой класс подключаемого модуля до одного из моих абстрактных классов в библиотеке: SimplePlugin и AdvancedPlugin. У меня также есть интерфейс под названием Plugin, который реализуют оба класса. Чтобы динамически загружать плагины во время выполнения, у меня есть ClassLoader, настроенный для поиска интерфейса Plugin, когда он просматривает файлы .class. У меня не было никаких проблем с этим, и я мог без проблем создавать плагины.

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

public interface Plugin {

    public static String PluginLibrary_BUILD = "0.1.1";

    //methods...
}

Вот два других класса для наглядности:

public abstract class SimplePlugin implements Plugin { 

    //methods...
}

public abstract class AdvancedPlugin extends SimplePlugin implements Plugin {

    //methods...
}

Но каждый раз, когда я загружаю новый плагин и пытаюсь прочитать переменную сборки, он всегда получает значение, содержащееся в классе Plugin внутри моего проект, а не (как я предполагаю, должно быть) значение внутри Файл JAR I сгенерировать из экспорта моего плагина.

Вот пример:

//import dependencies from my library

public class TestPlugin extends SimplePlugin {

    public TestPlugin() {
        super("TestPlugin", "v1.0");
    }

    @Override
    public void doOnAction() {
        System.out.println("Hello World!");
    }

}

Отсюда я бы экспортировал класс TestPlugin как файл JAR, и он экспортировал бы зависимости из моей библиотеки вместе с ним. Затем я перетащил файл JAR в папку, которую я создал, и оттуда мое приложение прочитало бы его как плагин и сделало бы свое дело. К сожалению, «его вещь» включает чтение моей переменной PluginLibrary_BUILD из моих файлов проекта, а не из файла JAR (возможно?), Потому что, если я изменю ее в своих файлах проекта, плагин сообщит мне, что его сборка также изменилась.

Я не совсем уверен, что происходит, это всего лишь мое предположение, поэтому я ищу некоторое представление о том, почему то, что происходит, и как решить проблему. Если вы хотите посмотреть на исходные файлы именно так, как они представлены, я загружаю их здесь. Plugin - это StreamSAKPlugin, а два абстрактных класса расположены в / types и являются StreamSAKSimplePlugin и StreamSAKAdvancedPlugin (я просто упростил имена для этого вопроса).

Если вы не хотите копаться в файлах, вот все файлы, которые, я думаю, могут быть вам важны:

StreamSAKPlugin

StreamSAKSimplePlugin

StreamSAKAdvancedPlugin

StreamSAKFileHandler (отвечает за загрузку в плагинах, прокрутите вниз к низу)

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
24
2

Ответы 2

Вы пробовали заменить член методом? Переопределите его с каждой реализацией, Java не имеет реализации интерфейса по умолчанию, поэтому, возможно, вам нужно заставить создателя плагина расширить некоторые из ваших абстрактных классов, а не просто реализовать интерфейс.

Это то, что я пробовал сначала. Раньше у меня был метод getLocalBuild, который был реализован в абстрактных классах и тоже был в интерфейсе, но он по-прежнему давал тот же результат, когда я его вызвал после создания объекта Plugin из файлов .class при загрузке всего. in. Мне просто нужно быть осторожным при использовании методов и хранении переменной build, потому что я хочу убедиться, что у пользователя нет возможности изменить ее при разработке своего плагина.

ShermanZero 10.04.2018 18:26

Вы пробовали убрать его из интерфейса? Зачем ты туда положил?

tomasb 11.04.2018 14:46

Так что я почти уверен, что имею хорошее представление о том, что происходило, и почему, что бы я ни делал, я не смог достичь желаемого результата. Когда я загружал свои плагины, мне приходилось преобразовывать их в классы, содержащиеся в моей сборке библиотеки Текущий. Таким образом, независимо от того, какие данные могли нести плагины, они были перезаписаны преобразованием.

Чтобы преодолеть это, я немного переработал свой код и файловую структуру. Теперь в моей библиотеке есть файл со ссылкой на его номер сборки. Таким образом, когда моя программа запускается, она может прочитать номер сборки из этого файла, а затем также прочитать номер сборки из этого файла в любой программе, использующей библиотеку в качестве ресурса.

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