среда, 16 декабря 2009 г.

NetBeans 6.8. Проблема с примером AsyncRequest.

Давненько не писал. Почему-то никак не находилось тем, которые можно написать, да и со временем не всегда легко. Но как бы то ни было, время шло и вышел Netbeans 6.8, примечательный поддержкой и содержанием GlassFish 3, который, в свою очередь, является эталонной реализацией JEE6.

Ну, грех было не посмотреть это чудо по-ближе..
Начал с попытки развернуть с kenai.com своего тестового grails-проекта, но дело не пошло. Не буду описывать подробно, в общем, не срослось.. ( Ну сразу не вышло, значит потом как-нить добью - не впервой!..
Затем решил посмотреть, как обстоят дела с JEE6. К счастью, в NetBeans имеются несколько примеров, на мой взгляд достаточно удачные. Очень впечатлил пример "LeanServiceECBComponentWithAjax", ну и остальные, порадовали не меньше. Скажем так, ясности во всем стало намного больше. Код стал легко читаться, в то же время чувствуется гибкость, хотя это примеры..
В общем, мельком глянул все примеры по JEE6, кроме "AsyncRequest" - тот почему-то отказался компилироваться. Как ни странно в инете не смог найти решение проблемы, решил глянуть исходники, их под рукой не оказалось, однако были JavaDoc. В общем за несколько минут, используя дедукцию нашел решение проблемы.
В общем, по какой-то причине, не правильно написана работа с HttpServletRequest. Точнее, ему пытаются задать настройки асинхронности методами "setAsyncTimeout", "addAsyncListener", которые тот не поддерживает. А при этом еще инициируют AsyncContext, который как бы и должен этим заниматься. Так и есть у него есть подобные методы, правда немного по другому называются: "setTimeout" и "addListener". Ну это логично. После правки, остается еще дописать в "AsyncListener" недостающий метод, и вуаля! Всё работает.

Интересно, откуда выдрали код? Из классического Comet?

среда, 15 июля 2009 г.

Java в Opensolaris

На днях настраивал maven в opensolaris. Приятно удивила отзывчивость java приложений. Ещё раньше заметил, что на ноуте Eclipse 3.4 - под солярис запускается на порядок быстрее (плагинов в принципе почти одинаково), а netbeans вроде только чуть быстрее, чем в vista (возможно что я ошибаюсь, но там много плагинов, поэтому это имхо не показатель).
Ну так к чему я это всё... Настроил переменные окружения: MAVEN_HOME, JAVA_HOME и пр.
В том числе запускаю "java" (для проверки) и не успеваю прочитать вывод в консоль, команда выполняется сразу, без пауз. Затем работал уже с maven`ом, так никаких пауз при старте не ощущал. Если то же самое провернуть в винде, то перед выводом списка параметров чувствуется ощутимая пауза. (для команды "mvn" в XP, на работе (Athlon 64 3200+) - это несколько секунд; под debian, команда "java" на сервере - меньше секунды, но всё равно заметно).

Это приятно удивило, и немного обеспокоило. Вроде логично, но вызывает разные мысли..

среда, 13 мая 2009 г.

Ubuntu 9.04

Изначально поставил 7.10, потом обновил до 8.04. Теперь вот пришёл черёд 9.04. Новый сразу порадовал быстрой загрузкой и скоростью compiz`а.

В общем остался рад. Над новой версией поработали. Правда возникла проблема с gnome. Он почему-то сильно грузил проц, причём только под моим пользователем. Из top было не понятно в чём причина. Промучился изрядно, но нашёл решение. Проблема решилась только отключением служб и удалением лишних приложений из авто-запуска. Искать причину более точно не стал - вроде заработало. Может, в будущем, разберусь и отпишусь.

Переформатировал, наконец, старый раздел с fat32 в ext4. Fat32 действительно сильно мешала загрузке системы (читал, что нужно его дефрагментировать - судя по сообщениям, мне кажется, что тормозила fsck при загрузке, так что система у меня грузилась в районе минут 5!!! - хорошо, что я редко выключаюсь и перезагружаюсь). В общем, посмотрим - что за зверь ext4...

вторник, 27 января 2009 г.

Транзакции и ORACLE LOB вручную в spring

Недавно столкнулся с необходимостью сохранения LOB-объектов в базу Oracle из Spring приложения. Проблема была в записи кусков более 32k (Меньшие в CLOB пишутся через String, без мучений).
Пример использования транзакций без аннотаций:


Application Context:

<bean id="reportDao" class="***">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="lobHandler" ref="${reportDao.lobHandler}"/>
</bean>

<!-- Transaction manager for DataSource -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- LobHandler for Oracle JDBC drivers -->
<!-- (refers to the NativeJdbcExtractor above to get access to native OracleConnections) -->

<bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">
<property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
</bean>


DAO implements:

private DataSourceTransactionManager transactionManager;
public void setReport(int numRep, String code) {
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
MyTransaction transaction = new MyTransaction(numRep, code);
try {
txTemplate.execute(transaction);
} catch (Exception e) {
log.warn("TRANSACTION EXCEPTION! " +e, e);
}
}

private class MyTransaction extends TransactionCallbackWithoutResult {
/** Logger for this class and subclasses */
protected final Log log = LogFactory.getLog(getClass());

private String clobData;
private int numRep;

public MyTransaction(int numRep, String clobData) {
this.clobData = clobData;
this.numRep = numRep;
}

public void doInTransactionWithoutResult(TransactionStatus status) {
JdbcTemplate jdbcTemplate = getJdbcTemplate();

Integer id = numRep; //obtain ID for new record
CLOB clob = null;

try {
clob = CLOB.empty_lob();

jdbcTemplate.update(
"update Report set report_text=? where id = ? ",
new Object[] { clob, id },
new int[] { Types.CLOB, Types.INTEGER });

List packetList = jdbcTemplate.query(
"select report_text from Report where id=? for update",
new Object[]{ id },
new int[] { Types.INTEGER },
new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getClob("report_text");
}
});

if (packetList.size() == 1) {
Writer os = ((CLOB)packetList.get(0)).getCharacterOutputStream();
os.write(clobData);
os.flush();
os.close();
} else {
//handle - this shouldn't happen
}
} catch (SQLException e) {
log.warn(e,e);
} catch (IOException e) {
log.warn(e,e);
}
}
}

Всё просто.
Увы, не помню линк, окуда вытащил пример.

понедельник, 26 января 2009 г.

Подсказки

Часто у меня спрашивают вопросы по какой-нибудь технологии. Я частенько даю книжку или посылаю искать в инете или читать документацию.
На меня обижаются, что вместо того чтобы подсказать, я посылаю.. Ну и пусть, зато знаний прибавиться. Смысл отвечать на элементарные вопросы? Пусть помучаются, поищут, зато знаний прибавится и запомнят лучше, чем на халяву подскажу что-нить.
Я стараюсь объяснять только конкретно по своему коду или логику работы куска кода, которую проще и внятнее объяснить, чем заставлять разбираться в коде или часто (увы) криво написанной документации.

"Размазаная" логика.

Недавно неделю убил на один глюк. История поучительная. В общем передали мне приложение - на сокетах, сервер плюс клиент написанное на java. Сервер управляет логикой и посылает/принимает сигналы с клиента. Плюс имеется диспетчерское приложение на делфе, которое я не трогаю (ну и слава богу ;)). Связь не ахти какая, да и просто доступность клиентов не гарантируется. Вот.
Ну и очень грубо описание... Требовалось обеспечить выполнение длительных процессов, автоматических, управляемых сервером, в которых с клиентов только выбирали задания, а потом получали уточнения о ходе выполнения. Для блокировок заданий между сеансами клиентов, используется таблица со звучным названием "block". В неё записывается id клиента, и тип блокировки (грубое представление).
Я всё это протестил, кое где потом поставили, вроде работало. (Система не единая, разбита на полностью независимые группы). И в одной такой группе повалились глюки. Задания не выбирались в автоматическом режиме.
Перешерстили весь код клиента и сервера, по ходу исправили пару узких мест (это плюс), но никак не могли понять в чём дело. У нас работает, у заказчика нет, причём видно, что нарушается логика обработки заданий. В тех логах, что имелись, было не ясно, что происходит. В БД нет возможности отследить состояние на момент возникновения глюка и эмулировать проблему.
Постепенно, частично уже от отчаянья, вышли на уровень проверки всех программ. И, в итоге, выяснилось, что Делфийская программа, при определённых условиях "вычищала" блокировки клиентов и логика заданий просто рушилась. Причём, чистка зависела от настроек и пр.
Комментировать не буду. В общем учитесь на чужих ошибках.

четверг, 22 января 2009 г.

Сегодня день моей специальности (22.01).

Всех поздравляю. Учился на системотехника (22.01) - работаю java-программистом..
Постоянно забываю про эту дату, но, к счастью, находятся добрые люди, напоминают!
Ну и немного скучноватое пожелание: всем с моей специальности найти достойную и интересную работу!