четверг, 19 октября 2006 г.

Устали ждать обновление Debian пакета?

Оказывается в debian'е пакеты можно не только собирать из исходников, а еще эти исходники можно обновлять до upstream версии с сайта автора, а потом собирать deb пакет.

akshaal@akshaal:/tmp% apt-get source libtorrent9
Чтение списков пакетов... Готово
Построение дерева зависимостей... Готово
Нужно загрузить 472kB архивов с исходными текстами.
Получено:1 http://debian.org.ua unstable/main libtorrent 0.10.2-1 (dsc) [634B]
Получено:2 http://debian.org.ua unstable/main libtorrent 0.10.2-1 (tar) [453kB]
Получено:3 http://debian.org.ua unstable/main libtorrent 0.10.2-1 (diff) [18,2kB]
Получено 472kB за 3s (143kB/c)
gpg: Подпись создана Чтв 21 Сен 2006 07:41:55 EEST ключом DSA с ID 1880283C
gpg: Не могу проверить подпись: открытый ключ не найден
dpkg-source: extracting libtorrent in libtorrent-0.10.2
dpkg-source: unpacking libtorrent_0.10.2.orig.tar.gz
dpkg-source: applying ./libtorrent_0.10.2-1.diff.gz

akshaal@akshaal:/tmp% cd libtorrent-0.10.2

akshaal@akshaal:/tmp/libtorrent-0.10.2% uscan
libtorrent: Newer version (0.10.3) available on remote site:
http://libtorrent.rakshasa.no/downloads/libtorrent-0.10.3.tar.gz
(local version is 0.10.2)
libtorrent: Successfully downloaded updated package libtorrent-0.10.3.tar.gz
and symlinked libtorrent_0.10.3.orig.tar.gz to it

akshaal@akshaal:/tmp/libtorrent-0.10.2% uupdate ../libtorrent-0.10.3.tar.gz
New Release will be 0.10.3-1.
-- Untarring the new sourcecode archive ../libtorrent-0.10.3.tar.gz
Success! The diffs from version 0.10.2-1 worked fine.
Remember: Your current directory is the OLD sourcearchive!
Do a "cd ../libtorrent-0.10.3" to see the new package

akshaal@akshaal:/tmp/libtorrent-0.10.2% cd ../libtorrent-0.10.3/

akshaal@akshaal:/tmp/libtorrent-0.10.3% dpkg-buildpackage -rfakeroot -us -uc

вторник, 17 октября 2006 г.

JCA

Допустим мы пишем JCA RA который поддерживает исходящие соединения к EIS. Все написали. Верифицировали. Продеплоили в GlassFish. Все OK. Теперь продеплоили какое-то приложение, чтобы протестировать соединение к EIS. Запускаем. А оно нам @#%!: "Exception in NamingManagerImpl copyMutableObject() ... java.io.NotSerializableException".
Покопавшись мы выясняем, что падение происходит при копировании нашей имплементации java.resource.cci.ConnectionFactory интерфейса. А имеено в нашем классе ConnectionFactoryImpl есть не Serealizable поле, например ManagedConnectionFactory (содержащая сокет например). Убив N часов времени на поиски в гугле, выясняем, что GlassFish в JNDI помещает копии объектов! Наматерившись и решив, что разработчикам JNDI реализации виднее, мы делаем неугодное в ConnectionFactoryImpl поле transient'ым. А вдруг этот объект будет использоваться, только чтобы getReference вызвать? Хрен там. Повозившись еще, оказывается, что dependency injection отдает нам именно копию из JNDI у которой наше transient поле установленно в NULL!

Даём GlassFish'у последний шанс. Читаем его исходники и оказывается, что не все объекты помещаются в JNDI в сереализованном виде. Так например Connector'ы должны помещаться не сереализованными! Хм, а как же оно определяет, что этот объект коннектор? А вот как:

private boolean isConnector(String logicalJndiName){
return (logicalJndiName.indexOf(EIS_STRING)!=-1);
}
где EIS_STRING = "/eis/".

Короче, чтобы не иметь лишний геморрой: ConnectionFactory экземпляры должны помещаться в субконтексте /eis/ ! Если теперь поискать в гугле по словам "eis subcontext" то находятся рекомендации, а не требования!.

Вообще, это частая ошибка, проявляется в виде NPE (null pointer exception) при вызове transient полей (activemq этим страдает). Мне кажется, в ConnectionFactoryImpl разумно вставить:

/**
* Ensure that managedConnectionFactory is not null.
* @throws ResourceException if managedConnectionFactory is null.
*/
protected void ensureManagedConnectionFactory () throws ResourceException {
if (this.managedConnectionFactory == null) {
throw new ResourceException (
"No reference to managed connection factory exists."
+ " Either it is a bug of the RA or your JNDI resource"
+ " is not in the /eis/ subcontext");
}

и вызывать этот метод перед использованием this.managedConnectionFactory внутри ConnectionFactoryImpl.

среда, 11 октября 2006 г.

Из спецификации по JNI

"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."

понедельник, 9 октября 2006 г.

Смысл javax.resource.cci.*

Я наконец-то понял зачем нужен CCI. Все время казалось, что из-за него в простых RA много ненужного кода. А теперь ощутил зачем этот CCI нужен.

Если реализовывать RA без CCI, то наш MCF возвращает CF который не CCI-compliant, а тот уже в свою очередь по запросу RA клиента делегирует обращение в RM и получает соединение к RA отдавая его клиенту. Все просто и хорошо, но:
- в этом случае мы не может использовать DI, оказывается @Resource работает только для набора предопределенных интерфейсов (типа тогоа же CCI CF), поэтому CF придется ручками из JNDI доставать.
- если RA не продеплоена как EAR, а задеплоена в виде одельного RAR файла и клиент RA задеплоен соответственно как отдельный JAR, то, чтобы клиент мог использовать наш собственный CF, у него должен быть на руках интерфейс этого CF. В случае CCI CF этого не требуется, так как CCI CF определен в java.resource.cci.
- наверное есть еще что-то, но мне хватило этого

Доздравствует CCI!

четверг, 5 октября 2006 г.

SUNWappserver uninstall

Если кто-то пытается переустановить Sun Application Server 9.0 Platform Edition и у него не получается это в течении часа (то already installed, то unexpected exception), то стоит грохнуть нахрен (или аккуратно почистить) /var/tmp/productregistry или /tmp/productregistry.

Навеяно вот этим советом в котором неправильно указан путь.

среда, 4 октября 2006 г.

Mastering EJB 4ed

Офигенный код в книге Mastering EJB 4ed!
Chapter 15, конец метода execute:
if (out != null) {
return true;
} else {
return false;
}
класс! :))
А еще в этой книге есть строки в раздели Best Practice:
Many organizations have tried—and failed—to truly reuse components. Because of this, it is a perfectly valid strategy to not attempt true reuse at all. Rather, you can shoot for a copy-and-paste reuse strategy, which means to make the source code for components available in a registry to other team members or other teams. They can take your components’ code and change it as necessary to fit their business problem. While this may not be true reuse, it still offers some benefits.
Эта запись писалась в течении 7 минут 37 секунд.