Статьи

Java: платформа Checker

Одним из интересных инструментов, о которых я узнал на JavaOne 2012, является The Checker Framework . На одной из веб-страниц Checker Framework говорится, что Checker Framework «улучшает систему типов Java, делая ее более мощной и полезной,« позволяя разработчикам программного обеспечения »обнаруживать и предотвращать ошибки в своих программах Java». Один из способов взглянуть на Checker Framework — это реализация того, что могло бы произойти в JSR 305 («Аннотации для обнаружения дефектов программного обеспечения»), если бы он не попал в стадию бездействия .

Целью JSR 308 («Аннотации на типах Java») является «расширение синтаксиса аннотаций Java для разрешения аннотаций в любом случае типа». Как только JSR 308 будет утвержден и станет частью языка программирования Java, аннотации будут разрешены там, где они в настоящее время не разрешены. Хотя JSR 308 все еще находится на этапе раннего предварительного просмотра 2 , Checker Framework позволяет разработчику включать закомментированный код аннотации в местах, которые в настоящее время не разрешены, пока не станут доступны в JSR 308. Здесь важно отметить, что JSR 308 делает аннотации только в более общем виде. доступный (указывает больше типов исходного кода, к которому они могут быть применены) и не указывает никаких новых аннотаций.

Для Checker Framework требуется Java SE 6 или более поздняя версия. Среду Checker Framework можно загрузить в виде одного ZIP-файла по адресу http://types.cs.washington.edu/checker-framework/current/checkers.zip . Загруженный файл может быть разархивирован в платформу checker-framework каталогов, а затем может быть установлена ​​переменная среды CHECKERS указывающая на подкаталог этого расширенного каталога ‘checkers’. Например, если CHECKERS checkers.zip разархивирован в C:\checker-framework , для переменной среды CHECKERS должно быть установлено C:\checker-framework\checkers .

Когда Checkers Framework checkers.zip был загружен, расширен и указан переменной среды CHECKERS , пришло время попробовать Checker Framework. Далее показан «длинный путь» запуска Checker Framework, который используется с тегом -version для проверки того, что Checker Framework применяется:

Windows

1
java -Xbootclasspath/p:%CHECKERS%/binary/jsr308-all.jar -jar %CHECKERS%/binary/jsr308-all.jar -version

Linux

1
java -Xbootclasspath/p:$CHECKERS/binary/jsr308-all.jar -jar $CHECKERS/binary/jsr308-all.jar -version

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

Установленная Checker Framework теперь может быть применена для компиляции кода. В следующем листинге кода показан простой класс, который указывает, что аргумент метода не должен быть нулевым с помощью аннотации checkers.nullness.quals.NonNull ( @NonNull ).

Пример использования Checker Framework @NonNull

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package dustin.examples;
 
import checkers.nullness.quals.NonNull;
import static java.lang.System.out;
 
public class CheckersDemo
{
   public void printNonNullToString(@NonNull final Object object)
   {
      out.println(object.toString());
   }
 
   public static void main(final String[] arguments)
   {
      final CheckersDemo me = new CheckersDemo();
      final String nullStr = null;
      me.printNonNullToString(nullStr);
   }
}

Приведенный выше листинг кода показывает, что в метод передается значение NULL с аргументом, аннотированным @NonNull . NetBeans 7.3 помечает это желтыми загогулинами и предупреждает, если наведен. Это показано на следующих снимках экрана.

Хотя NetBeans отмечает нулевое значение параметра, помеченного аннотацией @NonNull , компилятор создает этот код без жалоб. Вот тут-то и появляется Checker Framework. Поскольку вводить длинную команду, которую я показывал ранее, неудобно, я либо запускаю указанную выше команду со скриптом, либо устанавливаю псевдоним, как описано в инструкциях по установке Checker Framework . В этом случае я буду использовать псевдоним:

Настройка псевдонима командной строки Windows для проверки Java

1
doskey javachecker=java -Xbootclasspath/p:%CHECKERS%\binary\jsr308-all.jar -jar %CHECKERS%\binary\jsr308-all.jar $*

Настройка этого псевдонима и запуск его с флагом -version продемонстрирован на следующем снимке экрана.

Гораздо проще применить этот подход с набором псевдонимов. Это может быть использовано для компиляции рассматриваемого класса, как показано ниже (команда, использующая мой псевдоним ‘javachecker’ и изображение, показывающее результат).

1
javachecker -d classes src\dustin\examples\*.java

Приведенная выше команда демонстрирует, что я могу использовать обычные параметры javac , такие как -d чтобы указать каталог назначения для скомпилированных файлов .class и передать исходные файлы Java для компиляции в обычном режиме. В этом примере также показано, что без указания процессора проверки для запуска в процессе компиляции дополнительная типизация @NotNull не применяется во время компиляции.

Прежде чем показать, как указать процессор для принудительного применения @NonNull во время компиляции, я хочу быстро продемонстрировать, что этот подход к компиляции все равно будет сообщать о стандартных ошибках компилятора. Как раз для этого примера я переименовал переменную ‘nullStr’, переданную интересующему методу в строке 17, в ‘nullStry’, чтобы это было ошибкой компилятора. На следующих двух снимках экрана показано это изменение (и сообщенная ошибка компиляции NetBeans) и то, как подход компиляции Checker Framework также сообщает об ошибке javac .

Показав, что этот подход к компиляции нормально компилирует компилируемый код, нормально сообщает об ошибках компилятора и соответствующим образом показывает версию, пришло время применить его для более строгого применения типов. Я исправляю ошибку компилятора в своем коде, удаляя лишние «y», которые я добавил. Затем мне нужно передать -processor checkers.nullness.NullnessChecker в качестве дополнительного флага и аргумента процесса компиляции. Обратите внимание, что есть и другие процессоры, кроме NullnessChecker , но я использую NullnessChecker здесь для принудительного применения @NonNull во время компиляции.

Ниже показана команда вместе с окном вывода, демонстрирующее эту команду в действии. Обратите внимание, что процесс компиляции не может быть завершен, и сообщается об ошибке, @NonNull с @NonNull типизации @NonNull .

1
javachecker -processor checkers.nullness.NullnessChecker -d classes src\dustin\examples\*.java

В этом сообщении в блоге рассказывается о Checker Framework и показано, как быстро применить его для более строгого соблюдения типов в исходном коде Java. Здесь я сосредоточился только на одном типе более строгой типизации, но Checker Framework предоставляет другие встроенные проверки типов и поддерживает возможность написания пользовательских проверок принудительного исполнения типов.

Ссылка: Checker Framework от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .