java.lang.class#getAnnotation () возвращает NULL при вызове в плагине Eclipse
-
25-10-2019 - |
Вопрос
Я пишу плагин Eclipse, чтобы поддержать Фрег язык программирования. Я использую Имп Meta Tooling Platform и Eclipse Indigo (3.7). Среда времени выполнения - Java 1.7.
Плагин использует тот же код, что и пакетный компилятор для анализа токенов, синтаксического анализа и т. Д. Получите метаинформацию, которая хранится там в форме аннотаций Java:
public static MD.Operator[] getOperators(ClassLoader loader, String pack)
throws ClassNotFoundException {
Class<?> cl = null;
cl = loader.loadClass(pack);
MD.FregePackage os = cl.getAnnotation(MD.FregePackage.class);
if (os == null) return null; // <-- no annotation present
return os.ops();
}
Обратите внимание, что код создает свой собственный экземпляр URLClassLoader
, который передается как аргумент. Если я неправильно устанавливаю путь класса, метод GetOperators правильно выбрасывает ClassNotFoundException, поэтому я думаю, что могу быть уверен, что он загружает класс. Следствие сообщает мне, что загрузчик класса построен с следующим путем (который по умолчанию - это всего лишь классная дорожка):
mkClassLoader:[C:\opt\eclipse\plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar, X:\dev\frege\build]
Поскольку файл класса, не созданный компилятором Frege MD.FregePackage
Аннотация это обычно указывает на то, что пользователь пытался импортировать простой класс Java, и, действительно, я получаю следующее сообщение в плагине:
X:/dev/runtime-EclipseApplication/TestJFrege/src/Neu.fr:1: `frege.prelude.Base` is not a frege package
Тем не менее, из командной строки я могу скомпилировать это просто отлично. Я включил это здесь как доказательство того, что рассматриваемые аннотации действительно могут быть загружены из того же места:
X:\dev\frege>java -cp ./build frege.compiler.Main X:/dev/runtimeEclipseApplication/TestJFrege/src/Neu.fr
mkClassLoader: [./build]
running: javac -cp ./build -d . -encoding UTF-8 ./Neu.java
Возобновление фактов:
- Код, который должен загружать аннотации, работает нормально, когда компилятор вызывает через интерфейс командной строки.
- Код, который должен загружать аннотации, не знает, используется ли он из плагина или командной строки. Фактически, плагин даже не существовал до прошлой недели, в то время как интерфейс командной строки использовался для нормальной работы в течение нескольких месяцев.
- Аннотации, конечно, есть,
RetentionPolicy.RUNTIME
В противном случае компиляция командной строки тоже не распознает их. Но это, возможно, делает.
Итак, единственный вывод, который я могу сделать, это то, что Class.getAnnotation()
Каким -то образом работает неправильно. Это очень прискорбно, так как это эффективно разрушает базовую функциональность, которая мне нужна для модульной системы.
Если это так или иначе: код компилятора Frege, который использует плагин сам написано в Frege и frege.prelude.Base
Класс, упомянутый выше, представляет собой базовую библиотеку, которая необходима каждому модулю, следовательно, он уже должен был быть загружен на активацию плагина, хотя, конечно, с другим загрузчиком класса.
У кого -нибудь есть похожий опыт? Можно ли решить это и как? Любые предложения, как это обойти это, приветствуются.
Решение
Был MD.FregePackage
Класс, загруженный классовым загрузчиком, используемым в вашем методе? Возможно, попробуйте сначала загрузить это, так как два класса не equal()
Если они были загружены различными загрузчиками класса. Это может объяснить, почему это не найдено.