java.lang.class#getAnnotation () возвращает NULL при вызове в плагине Eclipse

StackOverflow https://stackoverflow.com/questions/8309444

Вопрос

Я пишу плагин 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

Возобновление фактов:

  1. Код, который должен загружать аннотации, работает нормально, когда компилятор вызывает через интерфейс командной строки.
  2. Код, который должен загружать аннотации, не знает, используется ли он из плагина или командной строки. Фактически, плагин даже не существовал до прошлой недели, в то время как интерфейс командной строки использовался для нормальной работы в течение нескольких месяцев.
  3. Аннотации, конечно, есть, RetentionPolicy.RUNTIME В противном случае компиляция командной строки тоже не распознает их. Но это, возможно, делает.

Итак, единственный вывод, который я могу сделать, это то, что Class.getAnnotation() Каким -то образом работает неправильно. Это очень прискорбно, так как это эффективно разрушает базовую функциональность, которая мне нужна для модульной системы.

Если это так или иначе: код компилятора Frege, который использует плагин сам написано в Frege и frege.prelude.Base Класс, упомянутый выше, представляет собой базовую библиотеку, которая необходима каждому модулю, следовательно, он уже должен был быть загружен на активацию плагина, хотя, конечно, с другим загрузчиком класса.

У кого -нибудь есть похожий опыт? Можно ли решить это и как? Любые предложения, как это обойти это, приветствуются.

Это было полезно?

Решение

Был MD.FregePackage Класс, загруженный классовым загрузчиком, используемым в вашем методе? Возможно, попробуйте сначала загрузить это, так как два класса не equal() Если они были загружены различными загрузчиками класса. Это может объяснить, почему это не найдено.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top