Подтвердить что ты не робот

Понимание поиска исходного кода Eclipse с динамически скомпилированным и загруженным кодом

Для тех, кому не нравится читать длинные предложения:

Я хотел бы изложить это, отметив, что у меня есть специфический вопрос, связанный с поиском исходного кода отладчика eclipse в сочетании с удаленной отладкой. Чтобы обеспечить более локализованную картину того, что я испытываю и почему эта информация актуальна, я предоставляю фоновый контекст ниже. Зная, что средний SO'er довольно ленив и, вероятно, сразу проголосует за это, я настоятельно рекомендую вам прочитать фактический вопрос. Вы можете обнаружить, что это не так широко или локализованно, как вы думали.

Фоновая информация:

У меня есть эта java-инфраструктура, предназначенная для запуска внешних скриптов. Для этого я использую комбинацию загрузчика классов и системного java-компилятора для компиляции файлов .java "script", которые НЕ существуют на моем пути построения проекта. Все это работает, компилятор черной магии и все.

Врожденное усложнение с внешним загруженным кодом - это трудность для отладки. Я обратился к этому с помощью функции удаленной отладки Java-среды выполнения.

Итак, у меня есть конфигурация отладки, которая прикрепляется к моей исполняемой банке, которая имеет каталог с внешними java-скриптами на пути поиска источника. Это действительно РАБОТАЛО какое-то время. На самом деле, он никогда не работал должным образом, у меня просто были сценарии случайно на моем пути сборки. Достаточно путаю, я могу поставить точки останова в сценариях, и отладчик фактически STOPS там (постоянный номер строки, -verbose:class logging и все). Понимание того, как eclipse находит исходные файлы, является тем, что могло бы помочь. Большинство документов eclipse состоит из руководств пользователя.

ЧТО Я ПОДОЗРЕВАЛ было то, что я случайно продублировал определенные файлы script и, таким образом, путал исходный поиск с исходным файлом вне синхронизации. Это не тот случай, с тех пор я удалил дублированные файлы, и затмение все еще не может найти источник.

Что я пробовал

  • double, triple, fouruple проверяет пути поиска источника, обеспечивая включение всех соответствующих каталогов
  • включенные/отключенные поисковые подпапки
  • активированные/отключенные дубликаты поиска
  • используя абсолютный путь к каталогу вместо относительного пути к рабочей области

Обход

Единственным обходным решением здесь является добавление файлов script в путь сборки проекта, что неприемлемо для меня.

Что я делаю сейчас

Я медленно проскальзываю свой путь через репозиторий баз данных проекта открытого проекта eclipse, который ищет ответ. Eclipse, как оказалось, - довольно большой проект.

Вопрос

Может ли кто-нибудь предоставить точное алгоритмическое представление о том, как работает поиск источника Eclipse?

Зная это, я мог бы выяснить способ заставить отладчика Eclipse использовать правильный путь, используя отражение. Насколько мне известно, нет технических ограничений, которые предотвращают отладку динамически скомпилированного кода. Я знаю это, потому что мои точки останова приостанавливают мои потоки, как я ожидаю, исходный код просто не хочет загружаться: (

Связанные исследования: Кажется, что это может быть связано с тем, как класс определен с нулевым местоположением CodeSource, но, по-видимому, правильная вещь, которую нужно делать, когда динамически компилировать код в память - это дать null arg... остается вопрос о том, как/почему это важно, чтобы затмить отладчик.

Обновление 4/22 3:30: Поэтому я преследовал решение CodeSource, связанное выше. Теперь я вижу, что мой класс IS загружается из правильного расположения пути к файлу с помощью переключателя -verbose:class, но исходный поиск по-прежнему не работает. Точки останова все еще правильно пойманы, но меня приветствуют знакомые красные надписи Source not found.

Обновлено 5/6 3:15:Я преследовал решение javap, обсуждаемое в ответе Эндрю. Оказывается, атрибут исходного файла в моем .class байт-кодеке точно соответствует файлу, который должен существовать на моем пути поиска источника. Это меня смущает, потому что это указывает на иерархию папок, влияющую на исходный поиск. Тем не менее, я создал иерархии пакетов "phantom", представляющие "истинные" пакеты (как определено в верхней части моих .java файлов) и перемещение исходных файлов в эти папки, но исходный поиск по-прежнему не работает, когда я добавляю эти пути к пути поиска исходного кода. Любое дополнительное понимание того, какие дополнительные факторы играют в исходном поиске, будет огромным.

4b9b3361

Ответ 1

У меня есть немного опыта в этой области, проделав некоторую работу по отладке динамически скомпилированных скриптов groovy, хотя JDT. Я никогда не получал, чтобы это работало отлично, и я думаю, что это в основном ограничение JDT, которое никогда не предназначалось для обработки динамически скомпилированного кода.

TL;DR: Я предполагаю, что ваши динамически скомпилированные скрипты имеют неправильный атрибут исходного файла в байтовом коде. Этот атрибут устанавливается в файле класса компилятором. См. https://en.wikipedia.org/wiki/Java_class_file

Ваша путаница, я думаю, заключается в том, что отладчик правильно останавливается на контрольных точках, установленных вами в сценариях, но среда IDE не может загрузить источник. Это, конечно, запутывает, но для этого есть хорошее объяснение.

Точки останова фактически обрабатываются виртуальной машиной, и виртуальная машина отслеживает их через полное имя и номер строки. Это позволяет удалять точки останова независимо от того, какой загрузчик классов загружает файл класса, но это может привести к некоторой путанице, если несколько файлов классов загружаются через разные загрузчики классов с одним и тем же квалифицированным именем, но с другим исходным кодом. Этот алгоритм для определения того, когда останавливать виртуальную машину, не имеет ничего общего с фактическим поиском исходного кода, когда виртуальная машина останавливается.

Поиск исходного кода выполняется с помощью IDE. Поскольку даже в статически скомпилированном мире имя исходного файла может не совпадать с именем класса (внутренние классы, анонимные классы и т.д.). Имя класса не может использоваться для поиска исходного файла.

Вот упрощение того, что делает IDE, когда оно останавливается в точке останова:

  • Найти файл класса в этой точке останова
  • Получить атрибут источника
  • Найти исходный файл в пути поиска источника, который соответствует имени атрибута источника
  • Используйте некоторые эвристики, если найдено несколько исходных файлов с таким же именем (я думаю, что это будет ранжирование на вкладке поиска источника)
  • Возврат наиболее подходящего исходного файла.

(Caveat, я думаю, что исходный атрибут - это простое имя исходного файла (т.е. нет каталога), поэтому я считаю, что среда IDE преобразует имя пакета в структуру каталога как часть поиска, но я могу ошибайтесь в этом).

Таким образом, поиск не сработает, если ваш динамически скомпилированный script не имеет надлежащего атрибута источника. Вы можете проверить эту теорию, посмотрев на байтовый код. Вам придется как-то скомпилировать script и сохранить бит на диск. Затем вы можете запустить javap -v myScript на нем. Я бы поспорил, что это проблема. Я видел, как это произошло раньше на других динамически скомпилированных языках.

Ответ 2

У меня была схожая, но менее сложная проблема. Это было вызвано использованием двух разных компиляторов. Вы написали, что в своем случае вы используете системный java-компилятор, убедитесь, что ваш Eclipse использует тот же JDK и системный компилятор, включая информацию об отладке в скомпилированных классах, используя параметры -g: vars.