Как стать автором
Поиск
Написать публикацию
Обновить

ByteWeaver в Open Source: инструментирование байт-кода Java во имя великого блага

Уровень сложностиСложный
Время на прочтение14 мин
Количество просмотров5.5K
Всего голосов 41: ↑39 и ↓2+44
Комментарии11

Комментарии 11

выглядит так, словно было лень разобраться с aspectj и вы за это потратили в 100+ раз больше времени, чтобы сделать то же самое. Или я что-то не уловил?

Имхо, так можно практически про любой продукт или библиотеку сказать :) "Лень было разбираться с даггером, поэтому написали toothpick" и т.д.

С вашего позволения часть про в "100+ раз больше времени" оставлю без комментариев :)

Это есть в статье, но я ещё раз подчеркну. При написании библиотеки мы ориентировались в первую очередь на скорость работы. На наших сценариях в нашем аппе aspectJ работал на порядки(!) дольше.

Во вторых, по нашему мнению, для большинства прикладных задач связанных с манипуляцией байткодом на Андроиде aspectJ избыточен. Как в силу своего общего функционала так и порогом входа. В нашей библиотеке за основу взят синтаксис полгода с котором сталкивалось подавляющее большинство андроид разработчиков.

Насильно библиотеку никто использовать не заставляет разумеется. Если вам для ваших задач подходит aspectJ - супер. Но не вижу причин, почему наличие альтернатив это плохо)

Дальше что собираетесь с библиотекой делать ?

Самый ближайший шаг, написать нормальную доку к библиотеке на гитхабе :)

Если говорить про конкретные шаги по развитию библиотеки, то её автор, Саша Асанов их подсветил в своём докладе на мобиусе https://youtu.be/KPRPJLwdf8Y?t=2527 По сути это её обогащение несколькими приятными фичами.

Саму библиотеку мы планируем так же поддерживать и развивать на основании фидбека от комьюнити. Главное, мы не хотим, чтобы она превращалась "в монстра" способного делать всё) По нашему мнению, воткнуть код в начало или конец метода, или заменить вызов метода целиком достаточно для 95% задач. И хочется, чтобы разработчики смогли делать такие манипуляции просто и быстро.

Я уж думал не ответят, дока да... must have

aspectJ - вот точно перегружен не нужной терминологией, да и функциональность у него все же узкая, по сравнению с asm

Вы не зависимо от asm разрабатываете или поверх asm ?

Поверх asm.

Все это интересно, но вот тут https://github.com/gochaorg/jvmbc/tree/main/jvmbc-score3/jvmbc-score3 ради интереса писал компилятор/декомпилятор из/в class <-> json (цель немного другая была, а это побочка, пот тому никаких комментов prod ready нет)

Байт код можно в json, а с ним значительно легче работать, поменял его как надо, и сохранил обратно class

А тут у вас и свой язык еще... это как-то over попахивает, вы прикрутили langaue server к своему языку ?

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

Проблема с аннотациями в том, что их нужно где-то писать) И у аннотации гораздо менее выразительный синтаксис.

Мы взяли за основу синтаксис от proguard. Сделали мы это по нескольким причинам:
1. Он и так знаком большинству разработчиков под андроид.
2. По сути это уже готовый синтаксис для указания того, где и какие манипуляции с байткодом нужно делать. То есть он буквально задизайнен под наши задачи) То есть всё что нам нужно было сделать, это дополнить его парой своих команд)

Ну и никто не мешает пользоваться аннотациями. Более того, это даже поощряется)
Возьмем пример из статьи. Ты можешь написать правило для аннотации @AutoTraceCompat и по нему будет применено преобразование для всех методов помеченных этой аннотацией. Что очень удобно и наглядно. Но не всегда возможно, если твой метод находится в теле библиотеки и тебе туда со своей аннотацией не подлезть. Ну или если ты хочешь разметить все вызовы onCreate к примеру. Расставлять руками 1к+ аннотаций такое себе.

коль знаком, тогда меняет дело

Я имел ввиду примерно такое

есть такой синтаксис

class * {
   @ru.ok.android.commons.os.AutoTraceCompat
   * *(***) {
       before void TraceCompat.beginTraceSection(trace);
       after void TraceCompat.endSection();
   }
}

Тут указанна аннотация и способ ее интерпретации

В целом аннотация на ура переноситься в что-то типа такого

class MyFeature123 {
   @Wrap(ru.ok.android.commons.os.AutoTraceCompat.class)
   void wrapImpl1234(){
      method.before(traceData.get());
      method.after(resultData.get());
   }
}

В первом случае - синтаксис ByteWaever, во втором Java

Аналогично строиться логика для

class * extends android.app.Activity {}

В такое на java

@Extends(android.app.Activity.class)
class MyFeature124 {
    @SourceMethods({
        @SourceMethod{"meth1",args={TypeArg1.class,TypeArg2.class}},
        @SourceMethod{"meth2",args={TypeArg3.class,TypeArg4.class}},
    })
    void wrapImpl1235(){}
}

Просто это напоминает грабли с AspectJ ранних версий или кто там... у них был/есть свой язык для аспектов ajc как то так было расширение.

Язык, если не ошибаюсь, буквально 1-2 ide поддерживался каких то версий

А если синтаксис ByteWeaver синтаксис умещается 10-20 грамматических правил, без типов (ну типов для корректности компиляции ByteWeaver), то в целом то...

Как понимаю парсер на antlr 4/3 ?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий