java.lang.Class # getAnnotation () возвращает ноль при вызове в плагине eclipse - PullRequest
4 голосов
/ 29 ноября 2011

Я пишу плагин Eclipse для поддержки языка программирования Frege .Я использую платформу метаинструмента IMP и Eclipse Indigo (3.7).Среда выполнения - Java 1.7.

. Плагин использует тот же код, что и пакетный компилятор, для разбора токена, синтаксического анализа и т. Д. Однако я заметил различное поведение при запуске из плагина eclipse и проследил его доследующий метод, который читает файл класса ранее скомпилированного модуля для получения мета-информации, которая хранится там в форме аннотаций 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, который использует плагин, - это сам , написанный на Фреге и *Класс 1037 *, упомянутый выше, является базовой библиотекой, которая необходима каждому модулю, следовательно, он должен быть уже загружен при активации плагина, хотя, конечно, с другим загрузчиком классов.

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

1 Ответ

2 голосов
/ 29 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...