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

Номер строки журнала выполненного кода Java

Я пишу часть веб-приложения PHP (которое будет использоваться в конкурсе на поиск ошибок в школе), где пользователь должен найти ошибки в данной программе Java. В рамках этого, когда программа Java выполняется, мы хотим выделить строки источника Java-программы, в которой выполнялся код. Для этого нам нужны только номера строк исходного кода, т.е. Путь к коду (или он называется покрытием кода?). Мы выделим строки в исходном файле, используя номера строк.

Мы будем использовать PHP shell-exec() для выполнения программы Java и инструмента для получения кода (независимо от того, что будет). Каков самый простой способ получить номера строк кода?

Большое спасибо!

Вот картина, которая описывает, что мы хотели бы

enter image description here

4b9b3361

Ответ 1

PHP взаимодействует с кодом, что означает, что он запускается через источник каждый раз, когда вы запускаете программу. Это может привести к взрыву при чтении кода (что делает распечатки номера строки тривиальными); однако он часто дорог другими способами, так как вы не можете глубоко оптимизировать (или выполнять проверку ошибок перед запуском).

Java компилирует свой код на язык ассемблера JVM, называемый "байт-код" . Это означает, что то, что работает, обычно не имеет доступа ( или даже использовать) исходный код. Тем не менее, есть методы. Скомпилированный Java-класс имеет возможность добавлять "дополнительные данные", и один из этих "дополнительных элементов данных" таблица номеров строк, которая является индекс, позволяющий кому-то запустить сборку "искать" номер строки, когда компилятор записал ее.

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

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

Если вам нужно что-то с более точным разрешением (что-то, что может обработать, какая часть строки была выполнена), вам нужно копать глубже. В конце концов вы даже можете подумать о написании собственного компилятора (или расширения компилятора), который сохранит вашу собственную таблицу номеров номеров, которая преодолеет недостатки существующих решений.

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

В любом случае, надеюсь, это даст вам представление о том, почему он не всегда работает точно так же, как PHP.

Ответ 2

Взгляните на Cobertura. Он вычисляет охват и тому подобное, и если он этого еще не делает, должно быть относительно легко добавить номер строки, который он собирает. Там очень хакерская попытка сделать это, но это так медленно, что вы не сможете использовать его в производстве https://bitbucket.org/jowu/myriapod/wiki/Home

Ответ 3

Вы можете получить номер linenumber, если вы скомпилируете программу с параметром -g, выполните printStackTrace(), запишите вывод трассировки и извлеките из него номер строки.

Ответ 4

Я никогда не делал и не видел ничего подобного, но это похоже на интересную проблему. Я думал бы использовать java debugger (jdb) для запуска кода, а не только команду java.

Вы можете выполнить код по строкам (через команду step в jdb), и каждый раз, когда строка выполняет номер строки, вырывается. Для этого потребуется небольшая помощь со стороны PHP (она должна будет анализировать номер строки, а также выполнить команду следующего шага), но номера строк есть. Вот пример вывода из очень простой java-программы.

Java (TestClass.java)

public class TestClass {
   public static void main(String[] args) {
      System.out.println("foo");
      System.out.println("bar");
   }
}

jdb (jdb TestClass после запуска javac TestClass.java)

Initializing jdb ...
> stop at TestClass:3
Deferring breakpoint TestClass:3.
It will be set after the class is loaded.
> run
run TestClass
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
> 
VM Started: Set deferred breakpoint TestClass:3

Breakpoint hit: "thread=main", TestClass.main(), line=3 bci=0
3          System.out.println("foo");

main[1] step
> foo

Step completed: "thread=main", TestClass.main(), line=4 bci=8
4          System.out.println("bar");

main[1] step
> bar

Step completed: "thread=main", TestClass.main(), line=5 bci=16
5        }

main[1] step
> 
The application exited

Ответ 5

Попробуйте обратиться к этой ссылке JVMDI

Вы можете попытаться получить доступ к значениям счетчика программы, а затем сопоставить его с линиейNumberTable. ИЛИ Я думаю, что у JVMDI есть метод, который может получить доступ к номеру строки исполняемого кода. Я не уверен в последнем, ссылаюсь на ссылку выше и надеюсь, что это поможет.