Pull to refresh
34
0
forketyfork @forketyfork

User

Send message
В Java 6 появился так называемый Pluggable Annotation Processing API.
Он позволяет определять процессоры аннотаций, которые подключаются автоматически на этапе компиляции проекта. Достаточно включить процессор в classpath.
Пример см. здесь.
Точно так же, например, работает генератор метамодели в JPA.
Никаких особых проблем во время дебага под IntelliJ IDEA я не обнаружил. Например, вызов сгенерированного аксессора корректно «прошагивается», хотя войти внутрь метода, конечно, не получится.
Если быть точным, заголовок объекта — это два машинных слова, соответственно, на 64-битной Java это будет уже не 8, а 16 байт.
Аналогично, заголовок массива — три машинных слова, на 64-битной Java — 24 байта.
Рекомендую также по теме вот эту презентацию. Один из разработчиков Twitter делится своим опытом в части модели памяти Java, сборки мусора и оптимизации.
У меня вроде изменился. Я создал в качестве теста такой класс:
import lombok.extern.log4j.Log4j;
@Log4j
public class Test {
    public static void main(String... args) {
        log.info("lol");
    }
}

Затем выполнил:
java -jar lombok.jar delombok -p Test.java

Утилита вывела в консоль следующее:
error: package org.apache.log4j does not exist
error: package org.apache.log4j does not exist
// Generated by delombok at Thu Apr 19 20:27:33 YEKT 2012

public class Test {
	private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Test.class);
	
	
	public static void main(String... args) {
		log.info("lol");
	}
}

Ошибки связаны с отсутствием log4j в classpath, но если учесть это при запуске утилиты, то проблем быть не должно.
Да, возможно, вы правы. С другой стороны, когда в языке появляются стандартные средства расширения функциональности компилятора (препроцессинг аннотаций), понятие «корректного кода» несколько размывается.
В библиотеке присутсвует утилита delombok, которая позволяет преобразовать любой исходник к тому виду, в котором он будет скомпилирован. Подробно её работа описана здесь. Например, вот так можно преобразовать одиночный файл:
java -jar lombok.jar delombok -p MyJavaFile.java

Да, благодарю, с отсутствием final — это была моя ошибка. Исправил.
Разумеется, в многопоточности очень легко допустить трудноотлавливаемую ошибку. Но double-checked locking при грамотной реализации, на мой взгляд, является антипаттерном не в большей степени, чем вся система многопоточности с общей памятью. Иногда его приходится всё-таки использовать, и я бы вполне доверил его этой библиотеке, так как она учитывает общеизвестные питфоллы, как, например, упомянутый вами volatile.
1. Всё верно, но Lombok позволяет указать геттеры и сеттеры отдельно для каждого поля, а если в аксессоре требуется какая-то дополнительная функциональность — мы просто убираем соответствующую аннотацию с поля и пишем этот аксессор вручную.

2. Всё так, но, как я сказал в самом начале статьи, наибольшие проблемы причиняет не генерация бойлерплейта, а его поддержание в актуальном состоянии. Например, добавили поле — нужно не забыть перегенерировать equals и hashCode, вставить его в конструктор, написать геттеры. Это всего лишь один из способов решения проблемы, которая, возможно, и не «адская», но, тем не менее, существует.

3. Я бы не сказал, что это какая-либо прослойка. Это, скорее, кодогенератор. Конечно, любая дополнительная библиотека в проекте добавляет сложность. Но большой плюс Lombok заключается в том, что он не нужен в рантайме.
Да, это препроцессор аннотаций, и он генерирует весь код, который в любом случае пришлось бы писать. Почти всю функциональность он реализует на этапе компиляции проекта. В рантайме библиотека lombok.jar не нужна, соответственно, никакого влияния на производительность она не оказывает.

Кажется, единственной функцией, которая требует включения библиотеки в рантайм, является перехват исключений с помощью @SneakyThrows. Но к этой функции я отнёсся с осторожностью и пока решил не применять в продакшне. Хотя я не ожидаю каких-либо проблем с производительностью и в этом случае.
Спасибо за наводку. Вообще, от Groovy в своё время остались не очень хорошие впечатления в плане производительности, требований к памяти и скорости разработки. Возможно, Groovy++ может решить часть этих проблем, хотя пока что он производит несколько «сырое» впечатление.
На Scala сейчас активно смотрим, но ввиду его сложности и необходимости менять парадигму пока остерегаемся применять где-либо, кроме тестов и служебного кода. Kotlin ещё явно не готов к продакшну. А с переходом на Xtend пришлось бы отказывать разработчикам в свободном выборе IDE и пересадить всех на Eclipse, чего мы пока что стараемся избегать.
Тоже вариант. Вопрос выбора заключается лишь в необходимой функциональности и плате за неё. Мы обнаружили, что для наших целей Lombok убивает именно то, что нужно, и не требует смены парадигмы, стиля кодирования или привязки к инструментам. Переход на альтернативный JVM-язык — тоже решение проблемы, но это достаточно серьёзный шаг. Особенно если этот язык привязан к конкретной среде разработки, что в нашем случае недопустимо.
Я имел ввиду, что она не решаема в общем виде автоматически средствами генерации миграций, без ручного написания дополнительного кода.
Речь ведь не только о том, чтобы сгенерировать скрипт различий, но и чтобы он корректно отрабатывал на любой базе, неважно, какие данные в ней уже есть. Простейший пример:

Было:
create table person (
  id bigint(20) not null,
  post_id bigint(20) not null,
  primary key(id),
  foreign key (fk_post) references post(id)
);

create table post (
  id bigint(20) not null,
  description varchar(20),
  primary key(id)
);

Стало:
create table person (
  id bigint(20) not null,
  post_description varchar(20),
  primary key(id)
);

В поле human.postDescription я переместил данные из поля post.description.

Написать скрипт, производящий такие изменения на существующей непустой базе — несложно. Сгенерировать такой скрипт автоматически на основании анализа двух схем — невозможно.
Я не имею ничего принципиального против XML. Но в том-то и дело, что при достаточно сложных изменениях (а они никогда не бывают простыми, особенно на непустой базе, когда требуется определить логику реструктуризации данных) без SQL-скрипта не обойтись. Стоит ли городить ради этого XML, если всё равно придётся предусматривать SQL-вкрапления.
Думаю, это связано с тем, что эта задача достаточно сложная, и в общем виде нерешаемая, особенно когда речь заходит об изменениях в непустой базе.
Например, буквально вчера мне понадобилось грохнуть справочник и подставить вместо него в ссылающуюся таблицу обычное текстовое поле, взятое из поля справочника. Ни один инструмент анализа ни за что в жизни не «догадается», что это изменение было произведено именно так, а не как-то иначе, и, таким образом, сгенерированный им скрипт будет не работоспособен на базе с другим наполнением.
Я решил ограничиться упоминанием сравнительной таблички различных решений (в том числе LiquiBase) на странице Flyway. От LiquiBase меня отпугнуло именно XML-описание изменений. Когда идёт речь о миграциях, то хочется быть «ближе к телу», т.е. к SQL. Меньше будет turnaround при написании и отладке скрипта, да и опыт показывает, что случается необходимость быстро накатить изменения скриптом, минуя систему миграции.
Кроме того, не вполне понимаю, как XML-формат связан с возможностью отката миграций. В случае Flyway это вполне обоснованное техническое решение by design, т.к. ничего не стоило бы включать в пакет изменений SQL-скрипт, восстанавливающий базу.
Спасибо за информацию, обязательно попробую и такой вариант.
Спасибо, думаю, это не последняя статья, так как я вижу, что тема оказалась достаточно интересной.
Я так понимаю, имеется ввиду нечто подобное:
var page = require('webpage').create();

page.open('test.html', function(success) {

    page.onConsoleMessage = function (msg) {
        console.log(msg);
    };

    page.evaluate(function() {
        document.getElementById('sel').onchange = function() {
            console.log('onchange');
        };
        document.getElementById('sel').onchange();
    });
    
    phantom.exit();
    
});

Такой код при запуске выводит в консоль 'onchange'. Но обработчик приходится задавать прямо в evaluate. Насколько я понял из документации, передать внутрь evaluate что-либо снаружи нельзя.
Да, основные плюсы PhantomJS в том, что он достаточно быстро отрабатывает и не требует UI. Но при этом он по необходимости позволяет выгрузить рендер страницы в файл.

Для наших целей мы сейчас рассматриваем различные варианты тестирования компонентов и приложений на ExtJS. Смотрим на Selenium, QUnit, тот же JsTestDriver. Не факт, что в итоге остановимся именно на PhantomJS, но в ходе его опробования накопилась некоторая информация, которой я и решил поделиться.

Information

Rating
Does not participate
Location
Екатеринбург, Свердловская обл., Россия
Registered
Activity