Я действительно не знал, как задать заголовок моего вопроса, потому что он настолько конкретен и для его полного описания потребуется слишком много места.
Вот что я пытаюсь сделать:
Я разработал приложение, и часть его позволяет другим людям программировать для него свои собственные плагины. Для этого им необходимо загрузить мою библиотеку и расширить свой класс подключаемого модуля до одного из моих абстрактных классов в библиотеке: 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 (я просто упростил имена для этого вопроса).
Если вы не хотите копаться в файлах, вот все файлы, которые, я думаю, могут быть вам важны:
StreamSAKFileHandler (отвечает за загрузку в плагинах, прокрутите вниз к низу)




Вы пробовали заменить член методом? Переопределите его с каждой реализацией, Java не имеет реализации интерфейса по умолчанию, поэтому, возможно, вам нужно заставить создателя плагина расширить некоторые из ваших абстрактных классов, а не просто реализовать интерфейс.
Вы пробовали убрать его из интерфейса? Зачем ты туда положил?
Так что я почти уверен, что имею хорошее представление о том, что происходило, и почему, что бы я ни делал, я не смог достичь желаемого результата. Когда я загружал свои плагины, мне приходилось преобразовывать их в классы, содержащиеся в моей сборке библиотеки Текущий. Таким образом, независимо от того, какие данные могли нести плагины, они были перезаписаны преобразованием.
Чтобы преодолеть это, я немного переработал свой код и файловую структуру. Теперь в моей библиотеке есть файл со ссылкой на его номер сборки. Таким образом, когда моя программа запускается, она может прочитать номер сборки из этого файла, а затем также прочитать номер сборки из этого файла в любой программе, использующей библиотеку в качестве ресурса.
Это то, что я пробовал сначала. Раньше у меня был метод
getLocalBuild, который был реализован в абстрактных классах и тоже был в интерфейсе, но он по-прежнему давал тот же результат, когда я его вызвал после создания объектаPluginиз файлов .class при загрузке всего. in. Мне просто нужно быть осторожным при использовании методов и хранении переменнойbuild, потому что я хочу убедиться, что у пользователя нет возможности изменить ее при разработке своего плагина.