Что такое findslide.org?

FindSlide.org - это сайт презентаций, докладов, шаблонов в формате PowerPoint.


Для правообладателей

Обратная связь

Email: Нажмите что бы посмотреть 

Яндекс.Метрика

Презентация на тему Checker Framework. Аннотации для статического анализа кода

Содержание

Это тулза для статик-анализаJDK уже разруливает кейсы типа int count = "hello";IDE подсказывает больше, например DEAD CODE;FindBugs, CheckStyle и прочие утилиты для предсказания ошибок в существующем коде;Для проверок на NPE, взаимодействия между слоями приложения или более
Checker FrameworkАннотации для статического анализа кодаВладимир СмирновСтанислав Матковский Это тулза для статик-анализаJDK уже разруливает кейсы типа int count = Чем же хорош Checker Framework?Недостатки типизации Java компенсируются аннотациями;Он модульный, как конструктор, Checker совместим с Вашим любимым сборщиком:►Maven ►Gradle ►AntВашей незаменимой IDE:IntelliJ IDEA◄ Eclipse◄NetBeans◄ Встроенные анализаторыNullness Checker for null pointer errors Initialization Checker to ensure all fields are Простейший пример Nullness Checker[ERROR] /D:/Coding/acs-server-stub/src/main/java/com/vtb/acs/AcsController.java:[189,28] [dereference.of.nullable] dereference of possibly-null reference o[ERROR] /D:/Coding/acs-server-stub/src/main/java/com/vtb/acs/AcsController.java:[193,26] Еще пример для Nullness Checkerpublic class BaseClass {    public Я использую внешние библиотеки, там нет этих ваших аннотацийФреймворк поддерживает механизм внешнего Subtyping Checkerpublic class Person {   private String id; Subtyping Checkerpublic class Person {   private @PersonGuid String id; Subtyping Checkervoid main() {   Person p = new Person( Альтернативное решение без чекераpublic class PersonGuid extends ValueHolder { Альтернативное решение без чекераvoid main() {   Person p = new Fake Enum Checker@SuppressWarnings( Interning Checker – простейший пример@Interned String foo = Interning Checkerpublic class ActionType {   private static final Map actionsMap Initialization Checkerpublic abstract class BaseController {    private List defaultPuppets; Lock Checkerprivate final ReentrantLock requestsMapLock = new ReentrantLock();  @GuardedBy( Tainting Checkerpublic class BusinessObject {    private String sensitiveData; Tainting Checkerpublic class BusinessObject {    private String sensitiveData; Regex CheckerPattern.compile( Internationalization & Format String Checkersvoid printFloatAndInt(@Format({FLOAT, INT}) String fs) { Map Key Checkerprivate void processKey(String extKey) {   Map map = Units Checker@m int meters = 5 * UnitsTools.m; @s int secs = GUI Effect Checker public void calledFromBackgroundThread() {   jLabel.setText( Aliasing CheckerМетод testPlanet никак не должен менять earth![ERROR] Reference annotated as @Unique Чекеры от сторонних разработчиковОни есть, да. Я не использую Java 8Компилятор фреймворка обработает и List У меня куча легаси без этих ваших аннотаций!Начинаем помаленьку, отдельные чекеры, отдельные Спасибо за внимание!
Слайды презентации

Слайд 2 Это тулза для статик-анализа
JDK уже разруливает кейсы типа

Это тулза для статик-анализаJDK уже разруливает кейсы типа int count =

int count = "hello";
IDE подсказывает больше, например DEAD CODE;
FindBugs,

CheckStyle и прочие утилиты для предсказания ошибок в существующем коде;
Для проверок на NPE, взаимодействия между слоями приложения или более глубоких concurrency errors требуется дополнительная метаинформация в коде.

Слайд 3 Чем же хорош Checker Framework?
Недостатки типизации Java компенсируются

Чем же хорош Checker Framework?Недостатки типизации Java компенсируются аннотациями;Он модульный, как

аннотациями;
Он модульный, как конструктор, и расширяем сообществом;
Есть встроенный компилятор;
Кросс-тулзовый.


Слайд 4 Checker совместим с
Вашим любимым сборщиком:
►Maven
►Gradle
►Ant

Вашей незаменимой

Checker совместим с Вашим любимым сборщиком:►Maven ►Gradle ►AntВашей незаменимой IDE:IntelliJ IDEA◄ Eclipse◄NetBeans◄

IDE:
IntelliJ IDEA◄
Eclipse◄
NetBeans◄


Слайд 5 Встроенные анализаторы
Nullness Checker for null pointer errors
Initialization Checker to

Встроенные анализаторыNullness Checker for null pointer errors Initialization Checker to ensure all fields

ensure all fields are set in the constructor
Map Key

Checker to track which values are keys in a map
Interning Checker for errors in equality testing and interning
Lock Checker for concurrency and lock errors
Fake Enum Checker to allow type-safe fake enum patterns and type aliases or typedefs
Tainting Checker for trust and security errors
Regex Checker to prevent use of syntactically invalid regular expressions
Format String Checker to ensure that format strings have the right number and type of % directives
Internationalization Format String Checker to ensure that i18n format strings have the right number and type of {} directives

Property File Checker to ensure that valid keys are used for property files and resource bundles
Internationalization Checker to ensure that code is properly internationalized
Signature String Checker to ensure that the string representation of a type is properly used, for example in Class.forName
GUI Effect Checker to ensure that non-GUI threads do not access the UI, which would crash the application
Units Checker to ensure operations are performed on correct units of measurement
Signedness Checker to ensure unsigned and signed values are not mixed
Constant Value Checker to determine whether an expression’s value can be known at compile time
Aliasing Checker to identify whether expressions have aliases
Linear Checker to control aliasing and prevent re-use
Subtyping Checker for customized checking without writing any code


Слайд 6 Простейший пример Nullness Checker
[ERROR] /D:/Coding/acs-server-stub/src/main/java/com/vtb/acs/AcsController.java:[189,28] [dereference.of.nullable] dereference of

Простейший пример Nullness Checker[ERROR] /D:/Coding/acs-server-stub/src/main/java/com/vtb/acs/AcsController.java:[189,28] [dereference.of.nullable] dereference of possibly-null reference o[ERROR]

possibly-null reference o
[ERROR] /D:/Coding/acs-server-stub/src/main/java/com/vtb/acs/AcsController.java:[193,26] [argument.type.incompatible] incompatible types in argument.
[ERROR]

found : @Initialized @Nullable Object
[ERROR] required: @Initialized @NonNull Object

void showObjectSafe(@Nullable Object o) { System.out.println(o.toString()); } void showObject(@Nullable Object o) { showObjectUnsafe(o); } void showObjectUnsafe(@NonNull Object o) { if (o != null) { System.out.println(o.toString()); } }


Слайд 7 Еще пример для Nullness Checker
public class BaseClass {

Еще пример для Nullness Checkerpublic class BaseClass {  public @NonNull

public @NonNull Object nnobj; public BaseClass() {

} public void main() { List<@Nullable String> l1 = new ArrayList<>(); l1.add("test"); l1.add(null); for (String s : l1) showStringUnsafe(s); List<@NonNull String> l2 = new ArrayList<>(); l2.add("test"); l2.add(null); for (String s : l2) showStringUnsafe(s); } private void showStringUnsafe(@NonNull String s) {
System.out.println(s.toString());
} }

Слайд 8 Я использую внешние библиотеки, там нет этих ваших

Я использую внешние библиотеки, там нет этих ваших аннотацийФреймворк поддерживает механизм

аннотаций
Фреймворк поддерживает механизм внешнего аннотирования библиотек;
Уже есть набор мета-аннотаций

наиболее популярных библиотек, он расширяется и в этом даже можно поучаствовать;
Некоторые проекты распространяют уже аннотированные версии библиотек.

Слайд 9 Subtyping Checker
public class Person { private String

Subtyping Checkerpublic class Person {  private String id;  private

id; private String jobId; public Person(String id,

String jobId) { this.id = id; this.jobId = jobId; } public String getId() { return id; }
public String getJobId() { return jobId; } }

void main() { Person p = new Person("a", "b"); getStatistics(p.getId(), p.getJobId()); getStatistics(p.getId(), p.getJobId(), "c"); } void getStatistics(String personId, String jobId) { // TODO } void getStatistics(String jobId, String personId, Object o) { // TODO }



Слайд 10 Subtyping Checker
public class Person { private @PersonGuid

Subtyping Checkerpublic class Person {  private @PersonGuid String id;

String id; private @JobGuid String jobId; public

Person(String id, String jobId) { super(); // :: warning: (cast.unsafe) this.id = (@PersonGuid String) id; // :: warning: (cast.unsafe) this.jobId = (@JobGuid String) jobId; } public @PersonGuid String getId() { return id; } public @JobGuid String getJobId() { return jobId; } }

Слайд 11 Subtyping Checker
void main() { Person p =

Subtyping Checkervoid main() {  Person p = new Person(

new Person("a", "b"); getStatistics(p.getId(), p.getJobId()); getStatistics(p.getId(), p.getJobId(),

"c"); // ловим ошибку } void getStatistics(@PersonGuid String personId, @JobGuid String jobId) { // TODO } void getStatistics(@JobGuid String jobId, @PersonGuid String personId, String o) { // TODO }

Слайд 12 Альтернативное решение без чекера
public class PersonGuid extends ValueHolder

Альтернативное решение без чекераpublic class PersonGuid extends ValueHolder {  public

{ public PersonGuid(String value) {

super(value); } }

public class JobGuid extends ValueHolder { public JobGuid(String value) { super(value); } }

public class Person { private PersonGuid id; private JobGuid jobId; public Person(String id, String jobId) { this.id = new PersonGuid(id); this.jobId = new JobGuid(jobId); } public PersonGuid getId() { return id; } public JobGuid getJobId() { return jobId; } }


Слайд 13 Альтернативное решение без чекера
void main() { Person

Альтернативное решение без чекераvoid main() {  Person p = new

p = new Person("a", "b"); getStatistics(p.getId(), p.getJobId());

getStatistics(p.getId(), p.getJobId(), "c"); // Ловим ошибку } void getStatistics(PersonGuid personId, JobGuid jobId) { // TODO } void getStatistics(JobGuid jobId, PersonGuid personId, String o) { // TODO }

Слайд 14 Fake Enum Checker
@SuppressWarnings("assignment.type.incompatible") public class AuthChoice { @Fenum("AuthChoice1")

Fake Enum Checker@SuppressWarnings(

public static final String AUTH_CHOICE_CORRECT = "CORRECT";

@Fenum("AuthChoice1") public static final String AUTH_CHOICE_INCORRECT = "INCORRECT";

@Fenum("AuthChoice2") public static final String AUTH_CHOICE_CORRECT_2 = "CORRECT2"; @Fenum("AuthChoice2") public static final String AUTH_CHOICE_INCORRECT_2 = "INCORRECT2"; }

private Result generateResult(Request authRequest, @Fenum("AuthChoice1") String authChoice) {
switch (authChoice) { case AUTH_CHOICE_CORRECT: return new CorrectResult(); case AUTH_CHOICE_INCORRECT: return new IncorrectResult(); }
return null; }

// Ошибка компиляции! // LOGGER.trace("Генерируется результат {}", authChoice);


Слайд 15 Interning Checker – простейший пример
@Interned String foo =

Interning Checker – простейший пример@Interned String foo =

"foo"; @Interned String bar = "bar"; if (foo == bar) {

System.out.println("foo == bar"); }

Слайд 16 Interning Checker
public class ActionType { private static

Interning Checkerpublic class ActionType {  private static final Map actionsMap

final Map actionsMap = new ConcurrentHashMap(); private

String action; public ActionType(String action) { this.action = action; actionsMap.put(this.action, this); System.out.println(); } public String getAction() { return action; } public static ActionType getValueSafe(String actionTypeName) { actionTypeName = actionTypeName.toUpperCase(); ActionType actionType = actionsMap.get(actionTypeName); return (actionType == null) ? UNKNOWN : actionType; } }

@SuppressWarnings("interning") public static @Interned ActionType getValueSafe(String actionTypeName) { actionTypeName = actionTypeName.toUpperCase(); ActionType actionType = actionsMap.get(actionTypeName); return (actionType == null) ? UNKNOWN : actionType; }

if (ActionType.getValueSafe("DELETE") == clientAction) { // Важная логика } if (ActionType.getValueSafe("DELETE") == new ActionType("DELETE")) { // Важная логика }


Слайд 17 Initialization Checker
public abstract class BaseController { private

Initialization Checkerpublic abstract class BaseController {  private List defaultPuppets;

List defaultPuppets; public BaseController() {

defaultPuppets = new ArrayList<>(); List puppets = initPuppets(); defaultPuppets.addAll(puppets); } protected abstract List initPuppets(); }

public class ChildController extends BaseController { private List puppets; public ChildController() { puppets = new ArrayList<>(); } @Override protected List initPuppets() { // Инициализируем список... return puppets; } }

ChildController childController = new ChildController();

[ERROR] /D:/Coding/acs-server-stub/src/main/java/org/test/BaseController.java:[13,43] [method.invocation.invalid] call to initPuppets() not allowed on the given receiver.
[ERROR] found : @UnderInitialization(org.test.BaseController.class) @NonNull BaseController
[ERROR] required: @Initialized @NonNull BaseController
[ERROR] -> [Help 1]


Слайд 18 Lock Checker
private final ReentrantLock requestsMapLock = new ReentrantLock(); @GuardedBy("requestsMapLock") protected

Map requests = new HashMap();
@MayReleaseLocks public ResponseEntity startRequest(String

termUrl, String md, String paReq) { AuthRequest authRequest = new AuthRequest(validateTermUrl(termUrl), md, paReq); Map succeededRequests; requestsMapLock.lock(); try { succeededRequests = getSucceededRequests(); } finally { requestsMapLock.unlock(); } return ResponseEntity.ok(succeededRequests); } protected Map getSucceededRequests() { return requests.entrySet().stream()
.filter(e -> e.getValue() != null) .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); }

@Holding("requestsMapLock")


Слайд 19 Tainting Checker
public class BusinessObject { private String

Tainting Checkerpublic class BusinessObject {  private String sensitiveData;  public

sensitiveData; public Request(String sensitiveData) {

this.sensitiveData = sensitiveData; } public String getData() { return sensitiveData; } }

public void executeBusinessLogic(String data) { data = validateData(data); BusinessObject obj = new BusinessObject(data); } private String validateData(String data) { // Логика валидации... return pureData; }


Слайд 20 Tainting Checker
public class BusinessObject { private String

Tainting Checkerpublic class BusinessObject {  private String sensitiveData;  public

sensitiveData; public Request(@Untainted String sensitiveData) {

this.sensitiveData = sensitiveData; } public String getData() { return sensitiveData; } }

public void executeBusinessLogic(@Tainted String data) { data = validateData(data); BusinessObject obj = new BusinessObject(data); } @SuppressWarnings("tainting") private @Untainted String validateData(@Tainted String data) { // Логика валидации... return pureData; }


Слайд 21 Regex Checker
Pattern.compile(".*"); // Ловит IDE, если что не

Regex CheckerPattern.compile(

так
Pattern.compile(or(parenthesize("a*"), parenthesize("b*"))); // IDE уже не справится
public String parenthesize(String

regex) { return "(" + regex + ")"; } public String or(String a, String b) { return a + "|" + b; }

public @Regex String parenthesize(@Regex String regex) { return "(" + regex + ")"; } public @Regex String or(@Regex String a, @Regex String b) { return a + "|" + b; }


Слайд 22 Internationalization & Format String Checkers
void printFloatAndInt(@Format({FLOAT, INT}) String

Internationalization & Format String Checkersvoid printFloatAndInt(@Format({FLOAT, INT}) String fs) {

fs) { System.out.printf(fs, 3.1415, 42); } printFloatAndInt("Float %f, Number %d");

// OK printFloatAndInt("Float %f"); // Ошибка

// Нет второго аргумента MessageFormat.format("{0} {1}", 3.1415); // Аргумент нельзя отформатировать как «время» MessageFormat.format("{0, time}", "my string");


@I18nFormat({GENERAL, NUMBER}) String format;
format = "{0} {1} {2}";

Поддерживает также работу с ResourceBundle

System.out.printf("Float %f, number %g", 3.1415, 42);


Слайд 23 Map Key Checker
private void processKey(String extKey) {

Map Key Checkerprivate void processKey(String extKey) {  Map map =

Map map = new HashMap(); Collection

String> coll = new ArrayList<>(); map.put(extKey, new Request());
// Некоторое время спустя coll.add(extKey);
// Еще позже for (String s : coll) { showObjectUnsafe(map.get(s)); } } private void showObjectUnsafe(@NonNull Object o) { System.out.println(o.toString()); }

Слайд 24 Units Checker
@m int meters = 5 * UnitsTools.m; @s

Units Checker@m int meters = 5 * UnitsTools.m; @s int secs

int secs = 2 * UnitsTools.s;
@mPERs double speed =

meters / secs;

@kmPERh double kmph = meters / secs;

@kmPERh double kmph =
UnitsTools.fromMeterPerSecondToKiloMeterPerHour(speed);

@kmPERh double kmph = speed * 3.6;

@kmPERh public static double fromMeterPerSecondToKiloMeterPerHour(@mPERs double mps) { return mps * 3.6D; }


Слайд 25 GUI Effect Checker
public void calledFromBackgroundThread() { jLabel.setText("Foo");

GUI Effect Checker public void calledFromBackgroundThread() {  jLabel.setText(

// Ошибка }
@SafeEffect
@UIEffect private void calledFromUIThread() {

heavyLoad(); } @SafeEffect private void heavyLoad() { // Some really heavy load... }

Слайд 26 Aliasing Checker
Метод testPlanet никак не должен менять earth!
[ERROR]

Aliasing CheckerМетод testPlanet никак не должен менять earth![ERROR] Reference annotated as

Reference annotated as @Unique is leaked.
void testPlanet(Earth earth) {

Earth newPlanet = earth; // Какая-то логика... newPlanet.annihilate(); }

void testPlanet(@Unique Earth earth) { Earth newPlanet = earth; // Какая-то логика... newPlanet.annihilate(); }


Слайд 27 Чекеры от сторонних разработчиков
Они есть, да.

Чекеры от сторонних разработчиковОни есть, да.

Слайд 28 Я не использую Java 8
Компилятор фреймворка обработает и

Я не использую Java 8Компилятор фреймворка обработает и List

List


Слайд 29 У меня куча легаси без этих ваших аннотаций!
Начинаем

У меня куча легаси без этих ваших аннотаций!Начинаем помаленьку, отдельные чекеры,

помаленьку, отдельные чекеры, отдельные ветви проекта;
Думайте об аннотации как

о части спецификации – обычно достаточно понимать и аннотировать сигнатуру метода, а не тело. В том же Javadoc хорошие ребята так же помечают, что например метод может вернуть null;
Старайтесь сделать свой код лучше, как например использование параметризированных типов вместо raw types.


  • Имя файла: checker-framework-annotatsii-dlya-staticheskogo-analiza-koda.pptx
  • Количество просмотров: 95
  • Количество скачиваний: 0