Я пишу плагин 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
Возобновление фактов:
- Код, который должен загружатьаннотации работают нормально, когда компилятор вызывается через интерфейс командной строки.
- Код, который должен загружать аннотации, не знает, вызывается ли он из плагина или из командной строки.Фактически, плагин даже не существовал до прошлой недели, в то время как интерфейс командной строки работал нормально в течение нескольких месяцев.
- Аннотации, конечно,
RetentionPolicy.RUNTIME
, иначе компиляция командной строки не распознала быих тоже.Но это очевидно.
Таким образом, единственный вывод, который я могу сделать, состоит в том, что Class.getAnnotation()
почему-то работает неправильно.Это очень прискорбно, поскольку это эффективно разрушает основные функциональные возможности, которые мне нужны для модульной системы.
Если это так или иначе имеет значение: код компилятора Frege, который использует плагин, - это сам , написанный на Фреге и *Класс 1037 *, упомянутый выше, является базовой библиотекой, которая необходима каждому модулю, следовательно, он должен быть уже загружен при активации плагина, хотя, конечно, с другим загрузчиком классов.
Есть ли у кого-нибудь подобные опыты?Можно ли это решить и как?Любые предложения, как обойти это, приветствуются.