<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8968638556698348235</id><updated>2012-02-16T16:20:11.561-08:00</updated><category term='Lenny'/><category term='TestNG'/><category term='JBoss'/><category term='EJB3'/><category term='Debian'/><category term='OpenSessionInView'/><category term='backlight'/><category term='Hibernate'/><category term='HP6730B'/><category term='GB988EA'/><category term='OpenEJB'/><category term='Sybase'/><category term='Oracle'/><category term='volume control'/><category term='site'/><category term='xrandr'/><category term='plugin'/><category term='Maven'/><category term='amixer'/><category term='sp_dboption'/><category term='mute control'/><category term='Linux'/><category term='multi-project'/><category term='KDE4'/><category term='XFCE'/><category term='Spring'/><category term='compiz'/><category term='into/bulkcopy'/><category term='testing'/><category term='6730B'/><category term='laptop'/><category term='dual monitor'/><title type='text'>TECH MIND</title><subtitle type='html'>S/W development aspects</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-807912383333269262</id><published>2009-06-12T12:08:00.000-07:00</published><updated>2009-06-13T06:46:32.559-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XFCE'/><category scheme='http://www.blogger.com/atom/ns#' term='compiz'/><category scheme='http://www.blogger.com/atom/ns#' term='amixer'/><category scheme='http://www.blogger.com/atom/ns#' term='volume control'/><category scheme='http://www.blogger.com/atom/ns#' term='mute control'/><title type='text'>XFCE, or KDE4 is not my choice</title><content type='html'>After struggling with KDE4 and it's bugs (I wrote about that in my last post, in Russian) I had a dilemma - continue using so loved window manager (I started with KDE1) or find an alternative that would just work, run faster, probably be not so reach for features, but still offer me nice look and feel.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a href="http://www.gnome.org/"&gt;Gnome&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;On of the most popular window managers ever. I tried it years ago but dislike - there are too many panels, they occupy space on top and bottom of desktop. Trying to combine everything on a single panel takes too much to spend on such a stupid thing.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a href="http://www.lxde.org/"&gt;LXDE&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;There were many advices to try this window manager out, and at first glance it looks &lt;a href="http://www.lxde.org/image_galleries/screenshots"&gt;great&lt;/a&gt;. But after X session restart the panel started blinking so I had not other choice killing X server. My plan was to find a replacement for KDE, fixing bugs was out of scope. Sorry, next time maybe...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a href="http://www.xfce.org/"&gt;XFCE&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;Well, looks good but with issues - multimedia buttons do not work, seems not many settings (after KDE of course). But wait, I need a panel, multiple desktops, and nice look and feel. Want it be as cool as possible, but run fast, really fast. Will it?&lt;br /&gt;Now we will pass through configuration steps and check whether result is what we expect. I can say I'm just happy with it :)&lt;br /&gt;XFCE offers configuration tool that allows configure themes, keyboard layout, shortcuts, window and mouse behavior and so on. Let's try to configure them to look and feel like we used to. I skip many steps like looking through a list of window themes and choosing the best one, to save our time.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DpEQInQwvDI/SjKvCHIbLGI/AAAAAAAAALU/irID1YJQ55c/s1600-h/settings.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_DpEQInQwvDI/SjKvCHIbLGI/AAAAAAAAALU/irID1YJQ55c/s320/settings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346528158451182690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_DpEQInQwvDI/SjKvO027sRI/AAAAAAAAALc/viMLS6895fs/s1600-h/panel-settings.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 270px; height: 320px;" src="http://3.bp.blogspot.com/_DpEQInQwvDI/SjKvO027sRI/AAAAAAAAALc/viMLS6895fs/s320/panel-settings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346528376884277522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Autostarting application&lt;/h3&gt;&lt;br /&gt;This is one of the most important features KDE provides. Many of window managers (including Gnome?) do not save which applications were started in the session and run minimized into tray bar almost all the time. Applications like skype are good targets to be started on session startup, but if they don't itt looks annoying.&lt;br /&gt;We may configure all the applications to start automatically on "Application Autostart" page. For example, skype is what I have on my laptop.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_DpEQInQwvDI/SjKvfJaxMUI/AAAAAAAAALs/k2C2odEHVxM/s1600-h/autostart-settings.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_DpEQInQwvDI/SjKvfJaxMUI/AAAAAAAAALs/k2C2odEHVxM/s320/autostart-settings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346528657281200450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Shortcuts&lt;/h3&gt;&lt;br /&gt;KDE has many well defined shortcuts that we want to have on XFDE too. Unfortunately on KDE3.5 on Debian I had some multimedia keys, like &lt;a href="http://tech-mind.blogspot.com/2009/03/installing-debian-5-lenny-on-hp6730b.html"&gt;Mute&lt;/a&gt;, unrecognized so extra work with xmodmap was required. In XFCE the issue does not exist so will just assign them to applications/actions.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_DpEQInQwvDI/SjKvX0lTGMI/AAAAAAAAALk/VhjCopOK2yw/s1600-h/shortcuts-settings.png"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_DpEQInQwvDI/SjKvX0lTGMI/AAAAAAAAALk/VhjCopOK2yw/s320/shortcuts-settings.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346528531429136578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On "Application Shortcuts" page of "Keyboard" configuration tool I assigned Amarok to be launched on "Music" button press, Opera browser on "WWW", tvtime on "Video":&lt;br /&gt;&lt;pre&gt;amarok &lt;-&gt; XF86Music&lt;br /&gt;opera &lt;-&gt; XF86WWW&lt;br /&gt;tvtime &lt;-&gt; XF86Video&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Volume and mute control keys presses handled with amixer application. At first I thought popup window with volume % bar would be great but later changed my mind - when control volume/mute from TV tuner remote so do not get bored with popups. Also XFCE mixer plugin handles mixer control events properly and changes icon in system tray accordingly. amixer has many commands and options, so probably you will want to change some:&lt;br /&gt;&lt;pre&gt;amixer -q -c 1 sset 'Master',0 10%- &lt;-&gt; XF86AudioLowerVolume&lt;br /&gt;amixer -q -c 1 sset 'Master',0 10%+ &lt;-&gt; XF86AudioRaiseVolume&lt;br /&gt;amixer -q -c 1 sset 'Master',0 toggle &lt;-&gt; XF86AudioMute&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Launch application&lt;/h3&gt;&lt;br /&gt;The applet behavior at first glance looks too simple - there is no autocompletion by executable file name, instead it saves command history and gives a choice from it. Simple, but works. Also, like Gnome, it fails running applications, like Synaptic, that require root privileges. I'm not sure how KDE handles this, even for Gtk applications, but it does. So looking for a command in main menu is the only way if you do not want to play with $DISPLAY and xhost.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Window decoration&lt;/h3&gt;&lt;br /&gt;Compiz ... uses 3D graphics hardware to create fast compositing desktop effects for window management (thanks to Wikipedia :) ). It creates really cool effects which combined with XFCE give you a replacement to KDE and it's graphic features (btw Compiz can be used with KDE as well).&lt;br /&gt;To configure Compiz use configuration settings manager:&lt;br /&gt;&lt;pre&gt;ccsm&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DpEQInQwvDI/SjOfp4Wn-oI/AAAAAAAAAME/3DhrCosEMkw/s1600-h/ccsm.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 243px;" src="http://4.bp.blogspot.com/_DpEQInQwvDI/SjOfp4Wn-oI/AAAAAAAAAME/3DhrCosEMkw/s320/ccsm.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5346792724469643906" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Just select effects you like and then launch Compiz daemon:&lt;br /&gt;&lt;pre&gt;compiz --replace&lt;/pre&gt;&lt;br /&gt;Add this command to "Application Autostart" so next time you login Compiz is launched automatically.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DpEQInQwvDI/SjOVI-O3WrI/AAAAAAAAAL0/pet-iCx4ONI/s1600-h/compiz-windows.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://4.bp.blogspot.com/_DpEQInQwvDI/SjOVI-O3WrI/AAAAAAAAAL0/pet-iCx4ONI/s320/compiz-windows.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346781163995749042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_DpEQInQwvDI/SjOVOViOiNI/AAAAAAAAAL8/K5JK5uQlN_E/s1600-h/compiz-desktop.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://1.bp.blogspot.com/_DpEQInQwvDI/SjOVOViOiNI/AAAAAAAAAL8/K5JK5uQlN_E/s320/compiz-desktop.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346781256150321362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_DpEQInQwvDI/SjOhY4D9F6I/AAAAAAAAAMM/lUiEsdB7azQ/s1600-h/compiz-switcher.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://2.bp.blogspot.com/_DpEQInQwvDI/SjOhY4D9F6I/AAAAAAAAAMM/lUiEsdB7azQ/s320/compiz-switcher.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5346794631356815266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I should  say that THERE IS life out of KDE, and if you are tired dealing with bugs, lost settings, and slow UI, give XFCE a chance.&lt;br /&gt;&lt;br /&gt;More official screenshots &lt;a href="http://www.xfce.org/about/screenshots"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-807912383333269262?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/807912383333269262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/06/xfce-or-kde4-is-not-my-choice.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/807912383333269262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/807912383333269262'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/06/xfce-or-kde4-is-not-my-choice.html' title='XFCE, or KDE4 is not my choice'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_DpEQInQwvDI/SjKvCHIbLGI/AAAAAAAAALU/irID1YJQ55c/s72-c/settings.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-8903254062203380072</id><published>2009-06-07T04:38:00.001-07:00</published><updated>2009-06-13T06:48:17.199-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='KDE4'/><title type='text'>KDE4 fornever</title><content type='html'>Был такой интересный фильм &lt;a href="http://www.exler.ru/films/14-08-2008.htm"&gt;Memento&lt;/a&gt; (рекомендую кто не видел), так вот события в фильме разворачиваются с конца. Для тек, кому лень читать, скажу сразу - Run baby, run! Не смейте устанавливать KDE4! Не меняйте 3.5 (или особенно если вы на другом менеджере окон) на это издевательство. Я предупредил. Ниже всего-лишь краткий список проблем, багов, которые были обнаружены после обновления Debian Etch на Squeeze, в течение дня. Совершенствование продукта - вещь необходимая, но путь, выбранный разработчиками, кажется ммм... неправильным что ли. Вспоминаю старые добрые времена KDE 1, 2, 3, когда обновление приносило радость, а не убитые нервные клетки и кучу вопросов вроде "Ну и, что дальше?".&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DpEQInQwvDI/Siu4TN3SxkI/AAAAAAAAAKs/7p0D7Ho2zyw/s1600-h/kde4-defects.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 247px;" src="http://4.bp.blogspot.com/_DpEQInQwvDI/Siu4TN3SxkI/AAAAAAAAAKs/7p0D7Ho2zyw/s320/kde4-defects.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5344568023083828802" /&gt;&lt;/a&gt;&lt;br /&gt;Итак, визуальные дефекты. Надо признать, эта проблема пропала после обновления на последнее ядро (2.6.29.4 с 2.6.23.12), соответственно с пересборкой новых драйверов от nVidia, после чего появилось множество 3D эффектов. Но мальчик то все равно был!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_DpEQInQwvDI/Siu5HISPWVI/AAAAAAAAAK0/CdUtzd5LM0M/s1600-h/kde4-mousetheme.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 248px;" src="http://1.bp.blogspot.com/_DpEQInQwvDI/Siu5HISPWVI/AAAAAAAAAK0/CdUtzd5LM0M/s320/kde4-mousetheme.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5344568914939435346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/kdebase-kde4/+bug/305201"&gt;Еще один баг в KDE4&lt;/a&gt; - после установки курсора мыши в KDE Classic, DMZ или любой другой Oxygen, настройка применяется полностью или частично к некоторым окнам, после перезапуска KDE сбрасывается в Oxygen Black. Раздражает - не то слово. В Gnome создается впечатление, что Qt приложения используют курсор установленный в KDE. Называется не хочешь KDE - попробуй в других менеджерах поработать. Ну где же альтернатива (к этому еще вернусь)?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_DpEQInQwvDI/SivCr0-QyHI/AAAAAAAAAK8/a8XwNwpYurs/s1600-h/kde4-qterror.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 206px;" src="http://1.bp.blogspot.com/_DpEQInQwvDI/SivCr0-QyHI/AAAAAAAAAK8/a8XwNwpYurs/s320/kde4-qterror.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5344579441015179378" /&gt;&lt;/a&gt;&lt;br /&gt;Мультимедиа кнопки в KDE не работают, кроме разве что управления звуком. Что интересно, регулировка звука работает на тот канал, на который настроена. Т.е. звук с TVTime может никак не регулироваться, кроме как из самого TVTime. Темная история, и вероятно, еще не оконченная. При попытке привязать кнопки вроде WWW к запуску приложений имеем &lt;a href="https://bugs.kde.org/show_bug.cgi?id=182672"&gt;баг в Qt&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Была еще масса приколов с опциями - настраивать черный текст на белом фоне в konsole приходилось раз 10 точно. Управление его профайлами - высший пилотаж, когда при 2 профайлов ты видишь 4, и какой же из них активный не понять. Если бы количество нервных клеток было неограничено, их падеж составил бы примерно число Гугл.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_DpEQInQwvDI/SivEPq59HlI/AAAAAAAAALE/BlQUMQPySkA/s1600-h/kde4-shutdown.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 315px; height: 108px;" src="http://1.bp.blogspot.com/_DpEQInQwvDI/SivEPq59HlI/AAAAAAAAALE/BlQUMQPySkA/s320/kde4-shutdown.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5344581156299677266" /&gt;&lt;/a&gt;&lt;br /&gt;Еще хотелось бы покритиковать такие себе "усовершенствования", как главное меню и окно завершения работы в частности. Ну почему столько много пунктов в меню, и всегда один и тот же диалог "Жду XXX секунд..."? В 3.5 меню выглядело более продуманным что ли, здесь же навигация без мыши словно битье головой об стену. Диалог System settings переносит нас в эпоху темного средневековья и инквизиции, в смысле Windows 3.1-like. Найти нужную опцию - непростая задача. Разделение на вкладки главных и расширенных настроек - вершина деградации в разработке пользовательского интерфейса. Desktop folders - вообще непонятно что. Кому в голову могло прийти группировать кучу ярлыков в папки, да еще обведенные этими идиотскими рамочками, портящими обои? Поворот фолдера градусов на 30 вовсе не кажется необходимой опцией. Поскольку рамка имеет границы, то становится непонятно, а зачем же тогда эта всплывающая панель с 3 кнопками?&lt;br /&gt;&lt;br /&gt;Для тех, кто все же выбрал путь воина, стоит уделить внимание обновлению того, что могло устареть. Я не про железо, но например, запуск KDE обрывался где-то после ввода пароля в gdm/kdm с появлением окна загрузки, и перед стартом KDE. Что-то вроде could not connect to ksmserver, хотя каждый раз по-разному. Проблема решилась обновлением конфигурации X (/etc/X11/xorg.conf). То же с lirc - irrecord не читал из девайса, пока не пересобрал ядро, с самим lirc. &lt;br /&gt;&lt;br /&gt;Итог мучений&lt;br/&gt;&lt;br /&gt;С одной стороны, команда разработчиков приклала массу усилий для усовершенствования и развития проекта, за что им, несомненно, спасибо, но такие проблемы в версии 4.2 - это печально... Ищу альтернативу.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DpEQInQwvDI/SivLWKYefFI/AAAAAAAAALM/oYhqAJv_Dug/s1600-h/kde4-snapshot.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://4.bp.blogspot.com/_DpEQInQwvDI/SivLWKYefFI/AAAAAAAAALM/oYhqAJv_Dug/s320/kde4-snapshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5344588964409801810" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-8903254062203380072?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/8903254062203380072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/06/memento.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/8903254062203380072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/8903254062203380072'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/06/memento.html' title='KDE4 fornever'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_DpEQInQwvDI/Siu4TN3SxkI/AAAAAAAAAKs/7p0D7Ho2zyw/s72-c/kde4-defects.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-4382851449669042259</id><published>2009-05-30T09:41:00.000-07:00</published><updated>2009-06-16T23:45:55.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xrandr'/><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='dual monitor'/><category scheme='http://www.blogger.com/atom/ns#' term='backlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Configuring external monitor on Debian laptop</title><content type='html'>Here I'll try to describe how external monitor can be used on laptop in mirroring mode.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Hardware details&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Laptop supports maximum resolution 1280x800.&lt;br /&gt;Monitor SCALEOVIEW D22W-1 maximum resolution is 1680x1050.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;X configuration&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Here is /etc/X11/xorg.conf configuration adopted for HP6730b internal&lt;br /&gt;display and external monitor:&lt;br /&gt;&lt;pre&gt;Section "InputDevice"&lt;br /&gt; Identifier "Generic Keyboard"&lt;br /&gt; Driver  "kbd"&lt;br /&gt; Option  "XkbRules" "xorg"&lt;br /&gt; Option  "XkbModel" "pc105"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "InputDevice"&lt;br /&gt; Identifier "Configured Mouse"&lt;br /&gt; Driver  "mouse"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Device"&lt;br /&gt; Identifier "Primary Video Device"&lt;br /&gt;        # Intel driver&lt;br /&gt; Driver  "intel"&lt;br /&gt; Option  "MergedFB" "true"&lt;br /&gt;        # These modes specify mapping of internal monitor resolution to external&lt;br /&gt;        # monitor resolution, as list of two pairs (X by Y) separated with -&lt;br /&gt; Option  "MetaModes" "1024x768-1680x1050 1024x768-1280x1024 1024x768-1024x768 1024x768-800x600"&lt;br /&gt; Option  "MergedDPI" "100 100"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Device"&lt;br /&gt; Identifier "Secondary Video Device"&lt;br /&gt; Screen  1&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Monitor"&lt;br /&gt; Identifier "Laptop Monitor"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Monitor"&lt;br /&gt; Identifier "External Monitor"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Screen"&lt;br /&gt; Identifier "Internal Screen"&lt;br /&gt; Device  "Primary Video Device"&lt;br /&gt; Monitor  "Laptop Monitor"&lt;br /&gt; DefaultDepth 24&lt;br /&gt; SubSection "Display"&lt;br /&gt;  Depth 24&lt;br /&gt;                # Resolutions supported by laptop display&lt;br /&gt;  Modes "1024x768" "800x600"&lt;br /&gt; EndSubSection&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "Screen"&lt;br /&gt; Identifier "External Screen"&lt;br /&gt; Device  "Secondary Video Device"&lt;br /&gt; Monitor  "External Monitor"&lt;br /&gt; DefaultDepth 24&lt;br /&gt; SubSection "Display"&lt;br /&gt;  Depth 24&lt;br /&gt;                # Resolutions supported by external display&lt;br /&gt;  Modes "1680x1050" "1600x1200" "1280x1024" "1024x768" "800x600"&lt;br /&gt; EndSubSection&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "ServerLayout"&lt;br /&gt; Identifier "Default Layout"&lt;br /&gt; Screen  0 "Internal Screen"&lt;br /&gt; InputDevice "Generic Keyboard"&lt;br /&gt;EndSection&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Please notice that driver set to "intel" - generic driver does not work with VGA output.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Switching resolution&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;To switch to external monitor with (probably) higher&lt;br /&gt;resolution, create desktop.sh script in /usr/local/bin with following content:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;xrandr --output LVDS --mode 1024x768 --set BACKLIGHT_CONTROL legacy --output VGA --mode 1680x1050&lt;br /&gt;# This will completely turn laptop display off, commented out since we control backlight instead&lt;br /&gt;# xrandr --output LVDS --off&lt;br /&gt;# This will set backlight to 10%&lt;br /&gt;xbacklight -set 10&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To switch to smaller resolution (that laptop display supports), create&lt;br /&gt;laptop.sh script with content:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;xrandr --output LVDS --mode 1024x768 --set BACKLIGHT_CONTROL legacy --output VGA --mode 1024x768&lt;br /&gt;# This will restore backlight to 100%&lt;br /&gt;xbacklight -set 100&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I found it much safer/useful to control laptop display backlight,&lt;br /&gt;instead of switching LVDS output off, because it is easier to switch&lt;br /&gt;resolution back, to smaller (something is still visible on display) when&lt;br /&gt;the external monitor is taken away by crazy administrator guy :)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;br /&gt;&lt;a href="http://www.thinkwiki.org/wiki/Xorg_RandR_1.2"&gt;Xorg RandR 1.2 Wiki&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;&lt;a href="http://ozlabs.org/~jk/docs/mergefb/"&gt;mergefb - dual monitor setup on a linux laptop&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-4382851449669042259?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/4382851449669042259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/05/configuring-external-monitor-on-debian.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/4382851449669042259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/4382851449669042259'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/05/configuring-external-monitor-on-debian.html' title='Configuring external monitor on Debian laptop'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-6358461433389416431</id><published>2009-04-19T01:56:00.000-07:00</published><updated>2009-04-19T07:39:56.491-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSessionInView'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEJB'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB3'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='TestNG'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Testing EJB out of application server - Part 3. Spring managed DAO tier</title><content type='html'>After a short delay and thinking about giving Spring to manage stateless DAO tier beans, here comes 3-rd part of the article. There were some issues that had to be investigated to make the topic complete. Most of all, there was an open question of controlling Hibernate &lt;i&gt;Session&lt;/i&gt;&lt;br /&gt;life cycle, to have OpenSessionInView pattern working.&lt;br /&gt;Let's define what we want to gain with DAO bean management by Spring:&lt;br /&gt;1. Keep DAO beans working with &lt;i&gt;EntityManager&lt;/i&gt; to make CRUD operations with entities.&lt;br /&gt;2. Make switch from EJB' &lt;i&gt;@Stateless&lt;/i&gt; (and even &lt;i&gt;@Stateful&lt;/i&gt;) annotations to Spring' &lt;i&gt;@Service&lt;/i&gt; (or have beans configured in XML file).&lt;br /&gt;3. Have bean auto wiring in DAO with Spring IoC, avoiding JNDI lookups and extra configuration in XML file.&lt;br /&gt;4. Ensure transaction and session management is compliant with EJB approach to handle entity beans lazy initialization problem (here I refer to interceptor and callback/template approaches).&lt;br /&gt;&lt;br /&gt;Let's examine what changes are to be done to our simple Internet shop application.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;DAO tier&lt;/h2&gt;&lt;br /&gt;Since we do not need to manage DAO beans with EJB but Spring, just change annotations on DAO bean class level:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Service("purchaseDAO")&lt;br /&gt;public class PurchaseDAOImpl extends AbstractDAO&amp;lt;Purchase&amp;gt; implements PurchaseDAO {&lt;br /&gt;    public PurchaseDAOImpl() {&lt;br /&gt;        super(Purchase.class);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here, we used &lt;i&gt;@Service&lt;/i&gt; that is recognized by Spring component scanning functionality we already familiar with. Also, DAO interfaces do not need &lt;i&gt;@Local&lt;/i&gt; nor &lt;i&gt;@Remote&lt;/i&gt; annotation (so they are removed):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public interface PurchaseDAO extends DAO&amp;lt;Purchase&amp;gt; {&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There is also a simplification in application context configuration file - DAO beans refering through JNDI to stateful beans managed by EJB have been removed.&lt;br /&gt;Important configuration step is adding &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config"&gt;&amp;lt;context:annotation-config/&amp;gt;&lt;/a&gt; to application context configuration file. This will include support for JPA annotations like &lt;i&gt;@PersistenceContext&lt;/i&gt;. To have everything working we need to define bean, with name of persistence unit, which refers to &lt;i&gt;EntityManagerFactory&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;bean id="entityManagerFactory"&lt;br /&gt;      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&amp;gt;&lt;br /&gt;    &amp;lt;property name="targetObject"&lt;br /&gt;              ref="entityManagerBean"/&amp;gt;&lt;br /&gt;    &amp;lt;property name="targetMethod"&lt;br /&gt;              value="getEntityManagerFactory"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;alias alias="ishopPU"&lt;br /&gt;       name="entityManagerFactory"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;OpenSessionInView pattern&lt;/h2&gt;&lt;br /&gt;To be correct, in Spring terms pattern is named OpenEntityManagerInView. There is a significant difference between this new approach and  old-style one used by applications, built upon Hibernate ORM, to keep Hibernate &lt;i&gt;Session&lt;/i&gt; open for a request processing cycle.&lt;br /&gt;Opening Hibernate &lt;i&gt;Session&lt;/i&gt; in filter and binding it to &lt;i&gt;SessionFactory&lt;/i&gt; these applications relied on the fact entity beans extracted in DAO tier are kept attached to this session until request has been processed and session is closed, so access to lazily initialized references would not cause an exception.&lt;br /&gt;But the approach, in it's original implementation, does not work for EJB - each transactional method is completed within its own &lt;i&gt;EntityManager&lt;/i&gt; instance which holds reference to it's distinct Hibernate &lt;i&gt;Session&lt;/i&gt;; opening new session does not make any affect.&lt;br /&gt;Instead, using &lt;i&gt;TransactionSynchronizationManager&lt;/i&gt;, we bind &lt;i&gt;EntityManager&lt;/i&gt; to &lt;i&gt;EntityManagerFactory&lt;/i&gt; so each transactional method executed with the same &lt;i&gt;EntityManager&lt;/i&gt;, and as result the same &lt;i&gt;Session&lt;/i&gt;, instance used:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Stateful(name = "openSessionInViewCallback")&lt;br /&gt;@LocalBinding(jndiBinding = "openSessionInViewCallbackLocal")&lt;br /&gt;public class OpenSessionInViewCallbackImpl implements OpenSessionInViewCallback {&lt;br /&gt;@PersistenceContext(type = PersistenceContextType.EXTENDED)&lt;br /&gt;    private EntityManager entityManager;&lt;br /&gt;&lt;br /&gt;    @PersistenceUnit(unitName = "ishopPU")&lt;br /&gt;    private EntityManagerFactory entityManagerFactory;&lt;br /&gt;&lt;br /&gt;    @Init&lt;br /&gt;    public void invoke(Runnable r) {&lt;br /&gt;        TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));&lt;br /&gt;&lt;br /&gt;        r.run();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Remove&lt;br /&gt;    public void remove() {&lt;br /&gt;        TransactionSynchronizationManager.unbindResource(entityManagerFactory);&lt;br /&gt;        EntityManagerFactoryUtils.closeEntityManager(entityManager);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In &lt;i&gt;@Init&lt;/i&gt; method we bind entity manager, and unbind it on callback method completion with &lt;i&gt;@Remove&lt;/i&gt; cleanup. For more information on Spring implementation of the pattern please refer to &lt;i&gt;org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter&lt;/i&gt; and &lt;i&gt;org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Source code&lt;/h2&gt;&lt;br /&gt;Can be downloaded &lt;a href="http://sites.google.com/site/mindplanet9/Home/ejb/ishop.jpa-testng-spring.zip?attredirects=0"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-6358461433389416431?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/6358461433389416431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/04/testing-ejb-out-of-application-server_19.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/6358461433389416431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/6358461433389416431'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/04/testing-ejb-out-of-application-server_19.html' title='Testing EJB out of application server - Part 3. Spring managed DAO tier'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-4061099761904359945</id><published>2009-04-05T00:05:00.000-07:00</published><updated>2009-04-05T02:50:09.177-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSessionInView'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEJB'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB3'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='TestNG'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Testing EJB out of application server - Part 2. Integrating Spring</title><content type='html'>&lt;h2&gt;The aim&lt;/h2&gt;&lt;br /&gt;In &lt;a href="http://tech-mind.blogspot.com/2009/03/testing-ejb-out-of-application-server.html"&gt;Part 1&lt;/a&gt; I mentioned Spring's transaction management API. I believe this is quite a serious reason to think about integrating Spring framework into EJB application. But not the only one. Spring provides easy way to maintain multiple application configurations with IoC making testing configuration of your application independent of production one. Other features, like JNDI support, integration with JMS, JMX, mail and other services make the framework so popular. &lt;br /&gt;Returning to our internet shop application we have to decide what we want to leave managed by EJB and what we want to put under Spring's control, and look at other options we have.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Data access&lt;/i&gt;. We considered JPA as an appropriate way to configure entity and DAO beans that provide basic functionality to access former. DAO stateless beans usually do not depend upon any other application tier, and really seldom use each other; &lt;i&gt;EntityManager&lt;/i&gt; gives all an ordinal DAO needs.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Business services&lt;/i&gt;. This is really a good place Spring may take care of. Injecting dependencies on other beans (e.g. DAOs), configuration parameters provided within application configuration files, managing transactions is where Spring really strong. Moreover, with Spring &lt;i&gt;testing&lt;/i&gt; module we can use these features directly in test classes.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Web services&lt;/i&gt;. JSR-181 defines API that is available within stateless beans to define them as providing Web services methods. EJB3 greatly supports this API, and though there is an option to use XFire framework together with Spring, to configure Web services, I see no reason to keep away from standard. Sometimes it is better avoid getting deep into framework hell. Though not always :)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Sample application changes&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;Domain tier&lt;/h3&gt;&lt;br /&gt;It is not a surprise that there is nothing to be changed. Entity beans still use JPA for O/R mapping that is controlled by EJB container.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Data access tier&lt;/h3&gt;&lt;br /&gt;There is one thing that needs to be done to each DAO implementation bean. Since we are going to publish DAO stateless beans in JNDI, so they will be available to Spring, we will use &lt;i&gt;@LocalBinding&lt;/i&gt; JBoss annotation to provide bean JNDI name for production environment, as follows:&lt;br /&gt;&lt;pre&gt;@Stateless(name = "productDAO")&lt;br /&gt;@LocalBinding(jndiBinding = "productDAOLocal")&lt;br /&gt;public class ProductDAOImpl extends AbstractDAO&amp;lt;Product&amp;gt; implements ProductDAO {&lt;br /&gt;    // methods implementations&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Every DAO bean is configured in application context configuration file like this one:&lt;br /&gt;&lt;pre&gt;&amp;lt;jee:jndi-lookup id="productDAO"&lt;br /&gt;                proxy-interface="org.ishop.dao.ProductDAO"&lt;br /&gt;                jndi-name="productDAOLocal"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;Unfortunatelly I do not know if there is any way to avoid this, like using automatic scanning.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Service tier&lt;/h3&gt;&lt;br /&gt;Minor changes should be done to service methods - to switch to Spring transaction API we change &lt;i&gt;@TransactionAttribute&lt;/i&gt; to &lt;i&gt;@Transactional&lt;/i&gt; and specify other options, if needed. Also dependency injection is now controlled by Spring, based on bean name or type wiring, or on &lt;i&gt;@Autowired&lt;/i&gt; annotation:&lt;br /&gt;&lt;pre&gt;@Service("productService")&lt;br /&gt;public class ProductServiceImpl implements ProductService {&lt;br /&gt;    @Autowired&lt;br /&gt;    private ProductDAO productDAO;&lt;br /&gt;    @Autowired&lt;br /&gt;    private PurchaseDAO purchaseDAO;&lt;br /&gt;&lt;br /&gt;    @Transactional&lt;br /&gt;    public void save(Product product) {&lt;br /&gt;        productDAO.save(product);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Transactional(readOnly = true)&lt;br /&gt;    public Product getProduct(Long id) {&lt;br /&gt;        return productDAO.get(id);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Transactional&lt;br /&gt;    public Purchase purchase(Long productId, Date paymentDate) {&lt;br /&gt;        // method implementation&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Please notice that we used &lt;i&gt;@Service&lt;/i&gt; that allows us to skip configuring bean in application context configuration file, relying on &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-scanning-autodetection"&gt;auto-detection&lt;/a&gt; option:&lt;br /&gt;&lt;pre&gt;&lt;context:component-scan base-package="org.ishop"/&gt;&lt;/pre&gt;&lt;br /&gt;We need to configure transaction management - Spring will use container JTA transaction manager to which it will redirect all transaction processing requests, based on own transaction annotations support and handling:&lt;br /&gt;&lt;pre&gt;&amp;lt;bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect"&lt;br /&gt;     factory-method="aspectOf"&amp;gt;&lt;br /&gt;   &amp;lt;property name="transactionManager"&lt;br /&gt;             ref="platformTransactionManager"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="platformTransactionManager"&lt;br /&gt;      class="org.springframework.transaction.jta.JtaTransactionManager"/&amp;gt;&lt;/pre&gt;&lt;br /&gt;Here we configured aspect to support &lt;i&gt;@Transactional&lt;/i&gt; annotations. One principal change is made to the build script - Java classes are processed by AspectJ compiler. Another option is use dynamic proxies that will do the same thing. One significant disadvantage of this approach is that to handle calls between business methods of the same service properly they should be made through the proxy.&lt;br /&gt;One more good thing about Spring transaction management API is that service method may throw any exception (checked or unchecked). Instead of annotating exception class with &lt;i&gt;@ApplicationException&lt;/i&gt; as EJB spec requires, in &lt;i&gt;@Transactional&lt;/i&gt; annotation parameters we may specify which exception(s) should cause transaction rollback and which will lead to commit. Really nice.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Web services&lt;/h3&gt;&lt;br /&gt;As well as within business tier, Web service need just minor changes in API - replacement of &lt;i&gt;@EJB&lt;/i&gt; with &lt;i&gt;@Autowired&lt;/i&gt; and adding &lt;i&gt;SpringContextInterceptor&lt;/i&gt; interceptor to the list of method call interceptors:&lt;br /&gt;&lt;pre&gt;@Interceptors({SpringContextInterceptor.class, OpenSessionInViewInterceptor.class})&lt;br /&gt;public class ProductWebServiceImpl implements ProductWebService {&lt;br /&gt;    @Autowired&lt;br /&gt;    private ProductService productService;&lt;br /&gt;    // methods skipped&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;i&gt;SpringContextInterceptor&lt;/i&gt; is responsible for application context startup when application Web service accessed the first time.&lt;br /&gt;&lt;pre&gt;public class SpringContextInterceptor extends SpringBeanAutowiringInterceptor {&lt;br /&gt;    private BeanFactory beanFactory;&lt;br /&gt;&lt;br /&gt;    protected BeanFactory getBeanFactory(Object o) {&lt;br /&gt;        if (beanFactory == null) {&lt;br /&gt;            beanFactory = new ClassPathXmlApplicationContext("/applicationContext.xml").getAutowireCapableBeanFactory();&lt;br /&gt;        }&lt;br /&gt;        return beanFactory;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @PreDestroy&lt;br /&gt;    @PrePassivate&lt;br /&gt;    public void releaseBean(InvocationContext invocationContext) {&lt;br /&gt;        super.releaseBean(invocationContext);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @PostConstruct&lt;br /&gt;    @PostActivate&lt;br /&gt;    public void autowireBean(InvocationContext invocationContext) {&lt;br /&gt;        super.autowireBean(invocationContext);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changes to unit tests&lt;/h3&gt;&lt;br /&gt;Spring provides a module to support bean wiring into test classes for both jUnit and TestNG. What we need to change in &lt;i&gt;AbstractPersistenceTest&lt;/i&gt; is set up application context and remove &lt;i&gt;lookup()&lt;/i&gt; method since we do not rely on bean wiring with EJB:&lt;br /&gt;&lt;pre&gt;@ContextConfiguration(locations = {"classpath:/test-applicationContext.xml"})&lt;br /&gt;public abstract class AbstractPersistenceTest extends AbstractTestNGSpringContextTests {&lt;br /&gt;    @BeforeClass(groups = "database")&lt;br /&gt;    public final void setUpDatabase() throws NamingException, IOException {&lt;br /&gt;        Properties props = new Properties();&lt;br /&gt;        props.load(AbstractPersistenceTest.class.getResourceAsStream("/persistence.properties"));&lt;br /&gt;        new InitialContext(props);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @BeforeClass(dependsOnMethods = "setUpDatabase")&lt;br /&gt;    protected void springTestContextPrepareTestInstance() throws Exception {&lt;br /&gt;        super.springTestContextPrepareTestInstance();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Here method &lt;i&gt;springTestContextPrepareTestInstance&lt;/i&gt; has been overriden to be called when EJB container has been set up by &lt;i&gt;setUpDatabase()&lt;/i&gt;.&lt;br /&gt;Testing code does not need serious changes as well as production code does not - use dependency injection with &lt;i&gt;@Autowired&lt;/i&gt; instead of looking up for required resource in JNDI.&lt;br /&gt;I strongly believe Spring offers a lot of features which when used in enterprise level applications may reduce coupling of beans and tiers, making daily development and testing easier.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Source code&lt;/h2&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/mindplanet9/Home/ejb/ishop.ejb-testng-spring.zip?attredirects=0"&gt;ishop.ejb-testng-spring.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thanks you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-4061099761904359945?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/4061099761904359945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/04/testing-ejb-out-of-application-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/4061099761904359945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/4061099761904359945'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/04/testing-ejb-out-of-application-server.html' title='Testing EJB out of application server - Part 2. Integrating Spring'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-3016041129347534404</id><published>2009-04-01T02:46:00.000-07:00</published><updated>2009-04-01T02:53:57.501-07:00</updated><title type='text'>Getting Maven plugin information</title><content type='html'>Recently I have discovered (what a shame I haven't done it much earlier! :) ) that to get information on Maven plugin goals and parameters it is possible to use help plugin (and not dive into plugin descriptor files packaged into JARs):&lt;br /&gt;&lt;pre&gt;mvn help:describe -Dplugin=surefire -Dmojo=compile -Ddetail&lt;/pre&gt;&lt;br /&gt;Here is a plugin self-explanation that does not need extra comments:&lt;br /&gt;&lt;pre&gt;$ mvn help:describe -Dplugin=help -Dmojo=describe -Ddetail&lt;br /&gt;[INFO] Scanning for projects...&lt;br /&gt;[INFO] Searching repository for plugin with prefix: 'help'.&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] Building Maven Default Project&lt;br /&gt;[INFO]    task-segment: [help:describe] (aggregator-style)&lt;br /&gt;[INFO] ------------------------------------------------------------------------&lt;br /&gt;[INFO] [help:describe]&lt;br /&gt;[INFO] Mojo: 'help:describe'&lt;br /&gt;help:describe&lt;br /&gt;  Description: Displays a list of the attributes for a Maven Plugin and/or&lt;br /&gt;    goals (aka Mojo - Maven plain Old Java Object).&lt;br /&gt;  Deprecated. No reason given&lt;br /&gt;  Implementation: org.apache.maven.plugins.help.DescribeMojo&lt;br /&gt;  Language: java&lt;br /&gt;&lt;br /&gt;  Available parameters:&lt;br /&gt;&lt;br /&gt;    artifactId&lt;br /&gt;      The Maven Plugin artifactId to describe.&lt;br /&gt;      Note: Should be used with groupId parameter.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    cmd&lt;br /&gt;      A Maven command like a single goal or a single phase following the Maven&lt;br /&gt;      command line:&lt;br /&gt;      mvn [options] [&lt;goal(s)&gt;] [&lt;phase(s)&gt;]&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    detail (Default: false)&lt;br /&gt;      This flag specifies that a detailed (verbose) list of goal (Mojo)&lt;br /&gt;      information should be given.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    goal&lt;br /&gt;      The goal name of a Mojo to describe within the specified Maven Plugin. If&lt;br /&gt;      this parameter is specified, only the corresponding goal (Mojo) will be&lt;br /&gt;      described, rather than the whole Plugin.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    groupId&lt;br /&gt;      The Maven Plugin groupId to describe.&lt;br /&gt;      Note: Should be used with artifactId parameter.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    medium (Default: true)&lt;br /&gt;      This flag specifies that a medium list of goal (Mojo) information should&lt;br /&gt;      be given.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    minimal (Default: false)&lt;br /&gt;      This flag specifies that a minimal list of goal (Mojo) information should&lt;br /&gt;      be given.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    output&lt;br /&gt;      Optional parameter to write the output of this help in a given file,&lt;br /&gt;      instead of writing to the console.&lt;br /&gt;      Note: Could be a relative path.&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    plugin&lt;br /&gt;      The Maven Plugin to describe. This must be specified in one of three&lt;br /&gt;      ways:&lt;br /&gt;&lt;br /&gt;      1.  plugin-prefix, i.e. 'help'&lt;br /&gt;      2.  groupId:artifactId, i.e. 'org.apache.maven.plugins:maven-help-plugin'&lt;br /&gt;      3.  groupId:artifactId:version, i.e.&lt;br /&gt;        'org.apache.maven.plugins:maven-help-plugin:2.0'&lt;br /&gt;      Deprecated. No reason given&lt;br /&gt;&lt;br /&gt;    version&lt;br /&gt;      The Maven Plugin version to describe.&lt;br /&gt;      Note: Should be used with groupId/artifactId parameters.&lt;br /&gt;      Deprecated. No reason given&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-3016041129347534404?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/3016041129347534404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/04/getting-maven-plugin-information.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/3016041129347534404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/3016041129347534404'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/04/getting-maven-plugin-information.html' title='Getting Maven plugin information'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-7887400305071064170</id><published>2009-03-21T02:22:00.001-07:00</published><updated>2009-04-05T02:42:35.909-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSessionInView'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenEJB'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='EJB3'/><category scheme='http://www.blogger.com/atom/ns#' term='JBoss'/><category scheme='http://www.blogger.com/atom/ns#' term='TestNG'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Testing EJB out of application server - Part 1</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Earlier I had a couple of projects that used Hibernate as a persistence framework of choice. Hibernate provides rich API, that is actually a superset of what EJB3 provides, and at the same time it gives an opportunity to test core application modules and services without application server running with the application deployed on it. But using Hibernate for persistence we at the same time stay far from technologies that are standards de jure nowadays. The question is whether it is possible to follow industrial standards and still have things implemented as simple as possible. In this post I'll try to show on example the way how EJB can be used as the primary technology for persistence, bean management and Web services implementation. The most important thing it covers is testing EJBs without deploying developing application onto application server.&lt;br /&gt;&lt;br /&gt;EJB spec offers standard way to develop enterprise level application that can be deployed on any application server, that follows the standard, but does not say how we can easily test EJBs. And usually the first what developers decide is to test them remotely on application server. The approach perhaps is the most significant time consumer and requires great experience in EJB development - each redeployment may cost too much in comparison to how much time spent on writing production code that is tested.&lt;br /&gt;&lt;br /&gt;Fortunately there is a solution (of course there is always something we can do) - "&lt;a href="http://openejb.apache.org/"&gt;OpenEJB&lt;/a&gt; offers an "embeddable and lightweight  EJB 3.0 implementation that can be used as a standalone server or embedded into Tomcat, JUnit, TestNG, Eclipse, IntelliJ, Maven, Ant,  and any IDE or application. OpenEJB is included in Apache Geronimo, IBM WebSphere Application Server CE, and Apple's WebObjects." - the title page states.&lt;br /&gt;So, in this post we will focus on using EJB - entity and session beans, and Web services - and testing the application without application server. Since JBoss is a widely used application server, it is evident why it was chosen for development, also evident that there is Hibernate behind the scene. Next time I'm going to focus on integration with Spring framework, so stay tuned..&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The price&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;First of all, you should consider whether functionality Hibernate provides, that is not accessible in EJB, is critical or not for your application. For example, Hibernate Criteria API, perhaps the most significant feature, can be helpful in organizing quick and efficient search on multiple criterions. Without this feature StringBuilder with multiple if/else constructs become our best friends and the worst enemies. Though EntityManager can be cast to HibernateEntityManager to access Hibernate internals, the code will not look so perfect and clear anymore as it was when the Earth had been created. Also EJB needs another approaches to solve familiar problems, like re-implementing OpenSessionInView (Hibernate solution can be found &lt;a href="http://www.jroller.com/kbaum/entry/orm_lazy_initialization_with_dao"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Example application&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Domain tier&lt;/h3&gt;&lt;br /&gt;Let's focus on a simple Internet shop application that sells products and tracks each product purchase in database. For mapping entities to database tables JPA annotations are used. Sure, Hibernate specific annotations, like &lt;i&gt;@Index&lt;/i&gt;, still can be used, especially if you need to generate database schema script. Let's just keep things simpler.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Entity&lt;br /&gt;@Table(name = "product")&lt;br /&gt;@SequenceGenerator(name = "product_generator", sequenceName = "product_seq")&lt;br /&gt;public class Product {&lt;br /&gt;    @Id&lt;br /&gt;    @Column(name = "id")&lt;br /&gt;    @GeneratedValue(generator = "product_generator")&lt;br /&gt;    private Long id;&lt;br /&gt;&lt;br /&gt;    @Column(name = "code", nullable = false)&lt;br /&gt;    private String code;&lt;br /&gt;&lt;br /&gt;    @OneToMany(mappedBy = "product", fetch = FetchType.LAZY)&lt;br /&gt;    private Set&amp;lt;Purchase&amp;gt; purchases = new HashSet&amp;lt;Purchase&amp;gt;();&lt;br /&gt;&lt;br /&gt;    // ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name = "purchase")&lt;br /&gt;@SequenceGenerator(name = "purchase_generator", sequenceName = "purchase_seq")&lt;br /&gt;public class Purchase {&lt;br /&gt;    @Id&lt;br /&gt;    @Column(name = "id")&lt;br /&gt;    @GeneratedValue(generator = "purchase_generator")&lt;br /&gt;    private Long id;&lt;br /&gt;&lt;br /&gt;    @ManyToOne(fetch = FetchType.LAZY)&lt;br /&gt;    @JoinColumn(name = "product_id", nullable = false)&lt;br /&gt;    private Product product;&lt;br /&gt;&lt;br /&gt;    @Column(name = "payment_date", nullable = false)&lt;br /&gt;    private Date paymentDate;&lt;br /&gt;&lt;br /&gt;    // ...&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;No magic here - things look really familiar. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Data access tier&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;DAO beans are simple as well, and rely on EJB3 interfaces:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public interface DAO&amp;lt;T&amp;gt; {&lt;br /&gt;    void save(T obj);&lt;br /&gt;&lt;br /&gt;    T get(Long id);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Local&lt;br /&gt;public interface ProductDAO extends DAO&amp;lt;Product&amp;gt; {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public abstract class AbstractDAO&amp;lt;T&amp;gt; implements DAO&amp;lt;T&amp;gt; {&lt;br /&gt;    @PersistenceContext(unitName = "ishopPU")&lt;br /&gt;    private EntityManager entityManager;&lt;br /&gt;&lt;br /&gt;    public void save(T obj) {&lt;br /&gt;        entityManager.persist(obj);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // other methods&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Stateless(name = "productDAO")&lt;br /&gt;public class ProductDAOImpl extends AbstractDAO&amp;lt;Product&amp;gt; implements ProductDAO {&lt;br /&gt;    // ProductDAO interface methods&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;@Local marks business interface for DAO and &lt;i&gt;@Stateless&lt;/i&gt; controls DAO implementation beans management by EJB container. Also &lt;i&gt;AbstractDAO&lt;/i&gt; takes reference to the entity manager for the &lt;i&gt;ishopPU&lt;/i&gt; persistence unit, configured in &lt;i&gt;persistence.xml&lt;/i&gt; configuration file. Persistence unit name is required when we have more than one unit listed in this file.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Service tier&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Stateless session beans that provide business methods to clients, like Web services and UI, may look as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Local&lt;br /&gt;public interface ProductService {&lt;br /&gt;    // business methods&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@TransactionManagement&lt;br /&gt;@Stateless(name = "productService", mappedName = "productService")&lt;br /&gt;public class ProductServiceImpl implements ProductService {&lt;br /&gt;    @EJB&lt;br /&gt;    private ProductDAO productDAO;&lt;br /&gt;&lt;br /&gt;    @TransactionAttribute&lt;br /&gt;    public void save(Product product) {&lt;br /&gt;        productDAO.save(product);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @TransactionAttribute&lt;br /&gt;    public Product getProduct(Long id) {&lt;br /&gt;        return productDAO.get(id);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @TransactionAttribute&lt;br /&gt;    public Purchase purchase(Long productId, Date paymentDate) throws BusinessException {&lt;br /&gt;        // implementation&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Business method &lt;i&gt;purchase()&lt;/i&gt; throws &lt;i&gt;BusinessException&lt;/i&gt; that is annotated with &lt;i&gt;@ApplicationException&lt;/i&gt; on class level. I have to say that Spring transaction management API is much cleaner and allows to control more aspects, like isolation level, read-only option and commit/rollback behavior depending on thrown exception type, on method and not on exception class level. That's one more reason you may consider it's use in the project.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Web service&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Web service looks the same way as business service except implementation class is annotated with JBoss specific annotation to specify concrete URL and JNDI context name we want to bind the service to:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@WebService(name = "ishop",&lt;br /&gt;        targetNamespace = "http://ishop.org",&lt;br /&gt;        serviceName = "productWebService")&lt;br /&gt;@WebContext(contextRoot = "/ishop-ws", urlPattern = "/productWebService")&lt;br /&gt;@Remote(ProductWebService.class)&lt;br /&gt;@RemoteBinding(jndiBinding = "productWebServiceRemote")&lt;br /&gt;@Stateless&lt;br /&gt;public class ProductWebServiceImpl implements ProductWebService {&lt;br /&gt;    @WebMethod&lt;br /&gt;    public ProductBean getProduct(@WebParam(name = "id") long id) {&lt;br /&gt;        // implementation&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Production code configuration&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Persistence unit configuration is also plain, but you should notice that &lt;i&gt;ishopPU&lt;/i&gt; unit is configured to be used with &lt;a href="http://openejb.apache.org/3.0/hibernate.html"&gt;Hibernate&lt;/a&gt; as persistence provider (&lt;i&gt;org.hibernate.ejb.HibernatePersistence&lt;/i&gt;) and properties listed in properties XML element go directly to the provider. The most important is that we specify dialect to use - Oracle (&lt;i&gt;org.hibernate.dialect.OracleDialect&lt;/i&gt;) and other options like log SQL statements executed (set to &lt;i&gt;true&lt;/i&gt;) and automatic database schema generation (set to &lt;i&gt;none&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;persistence xmlns="http://java.sun.com/xml/ns/persistence"&lt;br /&gt;             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"&lt;br /&gt;             version="1.0"&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;persistence-unit name="ishopPU" transaction-type="JTA"&amp;gt;&lt;br /&gt;        &amp;lt;provider&amp;gt;org.hibernate.ejb.HibernatePersistence&amp;lt;/provider&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!-- Data source name --&amp;gt;&lt;br /&gt;        &amp;lt;jta-data-source&amp;gt;java:/ishopDS&amp;lt;/jta-data-source&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!-- Persistent classes --&amp;gt;&lt;br /&gt;        &amp;lt;class&amp;gt;org.ishop.domain.Product&amp;lt;/class&amp;gt;&lt;br /&gt;        &amp;lt;class&amp;gt;org.ishop.domain.Purchase&amp;lt;/class&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;properties&amp;gt;&lt;br /&gt;            &amp;lt;!-- Hibernate specific properties --&amp;gt;&lt;br /&gt;            &amp;lt;property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/&amp;gt;&lt;br /&gt;            &amp;lt;property name="hibernate.show_sql" value="true"/&amp;gt;&lt;br /&gt;            &amp;lt;property name="hibernate.hbm2ddl.auto" value="none"/&amp;gt;&lt;br /&gt;        &amp;lt;/properties&amp;gt;&lt;br /&gt;    &amp;lt;/persistence-unit&amp;gt;&lt;br /&gt;&amp;lt;/persistence&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Properties specified for Hibernate will be used in production. For testing we will use HSQLDB as we do not need to access any pre-existing data, and will generate it for each test. Below is discussed how to change these properties (at least database dialect), for testing environment.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Testing code configuration&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Let's consider what we do to test all the stuff out of application server. Assume we want to test DAO, business logic and call Web service remotely to check that application was deployed successfully in production environment, and works well.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;At first, to keep session beans JNDI names consistent, we &lt;a href="http://openejb.apache.org/3.0/jndi-names.html"&gt;configure&lt;/a&gt; OpenEJB descriptor file &lt;b&gt;openejb-jar.xml&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1"&amp;gt;&lt;br /&gt;    &amp;lt;properties&amp;gt;&lt;br /&gt;        openejb.deploymentId.format = {ejbName}&lt;br /&gt;        openejb.jndiname.format = {deploymentId}{interfaceType.annotationName}&lt;br /&gt;    &amp;lt;/properties&amp;gt;&lt;br /&gt;&amp;lt;/openejb-jar&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;so each session bean JNDI name consists of two components - bean name and interface type name (either &lt;i&gt;Local&lt;/i&gt; or &lt;i&gt;Remote&lt;/i&gt;).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;JNDI Configuration file for testing environment - &lt;i&gt;jndi.properties&lt;/i&gt; - initializes JNDI context factory for OpenEJB:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;The last what we do is &lt;a href="http://openejb.apache.org/3.0/configuring-datasources-in-tests.html"&gt;&gt;re-configure&lt;/a&gt; persistence context, in &lt;i&gt;persistence.xml&lt;/i&gt; file to switch to testing data source:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;java.naming.factory.initial=org.apache.openejb.client.LocalInitialContextFactory&lt;br /&gt;&lt;br /&gt;# Data source configuration&lt;br /&gt;ishopPU=new://Resource?type=DataSource&lt;br /&gt;ishopPU.JdbcDriver=org.hsqldb.jdbcDriver&lt;br /&gt;ishopPU.JdbcUrl=jdbc:hsqldb:localdb/localdb&lt;br /&gt;&lt;br /&gt;# These properties override specified in persistence.xml&lt;br /&gt;ishopPU.hibernate.dialect=org.hibernate.dialect.HSQLDialect&lt;br /&gt;ishopPU.hibernate.hbm2ddl.auto=create-drop&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now in unit tests OpenEJB uses HSQLDB for persistence, with correct dialect and other Hibernate properties.&lt;br /&gt;The syntax for property is following:&lt;br /&gt;&lt;pre&gt;&amp;lt;PERSISTENCE UNIT NAME&amp;gt;.&amp;lt;HIBERNATE PROPERTY NAME&amp;gt;=&amp;lt;PROPERTY VALUE&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Writing testing code&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;I won't be explaining here why I chose TestNG - you may easily switch to jUnit if you want to. Let's create abstract base class for tests that need access to database, and add &lt;i&gt;setUpDatabase()&lt;/i&gt; method that initializes local database before class test methods run, loading configuration from &lt;i&gt;persistence.properties&lt;/i&gt; file. Since all session beans are published by the container in JNDI, to access them we create an utility method &lt;i&gt;lookup()&lt;/i&gt; that returns any bean from JNDI contaxt, by bean JNDI name:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public abstract class AbstractPersistenceTest {&lt;br /&gt;    private Context context;&lt;br /&gt;&lt;br /&gt;    @BeforeClass(groups = "database")&lt;br /&gt;    public final void setUpDatabase() throws NamingException, IOException {&lt;br /&gt;        Properties props = new Properties();&lt;br /&gt;        props.load(AbstractPersistenceTest.class.getResourceAsStream("/persistence.properties"));&lt;br /&gt;        context = new InitialContext(props);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @SuppressWarnings("unchecked")&lt;br /&gt;    protected final &amp;lt;T&amp;gt; T lookup(String name) throws NamingException {&lt;br /&gt;        return (T) context.lookup(name);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Below is a simple business service test class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class ProductServiceTest extends AbstractPersistenceTest {&lt;br /&gt;    private ProductService productService;&lt;br /&gt;&lt;br /&gt;    private Product product;&lt;br /&gt;&lt;br /&gt;    @BeforeClass(groups = "database")&lt;br /&gt;    public void setUpService() throws NamingException {&lt;br /&gt;        productService = lookup("productServiceLocal");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @BeforeMethod(groups = "database")&lt;br /&gt;    public void createProduct() {&lt;br /&gt;        product = new Product();&lt;br /&gt;        product.setCode("ABCDEF");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test(groups = "database")&lt;br /&gt;    public void testSave() {&lt;br /&gt;        productService.save(product);&lt;br /&gt;&lt;br /&gt;        Assert.assertNotNull(product.getId());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // other tests&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Before class test methods run, &lt;i&gt;setUpService()&lt;/i&gt; and &lt;i&gt;createProduct()&lt;/i&gt; methods are invoked to get reference to &lt;i&gt;ProductService&lt;/i&gt; bean and create test &lt;i&gt;Product&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Lazy initialization problem&lt;/h2&gt;&lt;br /&gt;The problem is caused by dynamic proxies Hibernate generates instead of loading business entities or collections from database. Usually that is &lt;i&gt;FetchType.LAZY&lt;/i&gt; specified for &lt;i&gt;fetch&lt;/i&gt; attribute in &lt;i&gt;@OneToMany&lt;/i&gt; and similar mapping configuration annotations. Solution existing for enterprise applications using Hibernate for persistence is opening Hibernate &lt;i&gt;Session&lt;/i&gt; for HTTP request and keeping it open till request processing is complete. Entities loaded in any transaction stay attached to HTTP session so Web page may access lazily loaded collections and entities without &lt;i&gt;LazyInitializationException&lt;/i&gt; being thrown. &lt;br /&gt;Assume that in EJB we have no access to Hibernate internals, but there are choices how we may solve the problem.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Access lazily loaded objects in transaction.&lt;/i&gt;&lt;br/&gt;&lt;br /&gt;For this purpose we access all our business methods in a single transaction. For example, annotate Web service bean with &lt;i&gt;@TransactionManagement&lt;/i&gt; (that is actually done by EJB container by default) configured to use container transaction management (&lt;i&gt;TransactionManagementType.CONTAINER&lt;/i&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@TransactionManagement&lt;br /&gt;// other annotations suppresses&lt;br /&gt;public class ProductWebServiceImpl implements ProductWebService {&lt;br /&gt;    // implementation&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This will grant that Web service and business methods are executed in the same transaction. Not the best solution, expecially because it damages business methods transaction boundaries, causing unexpected errors and probably missing results. It may not work for business methods with propagation level &lt;i&gt;REQUIRES_NEW&lt;/i&gt;, and certainly will cause problems with &lt;i&gt;NEVER&lt;/i&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Template method.&lt;/i&gt;&lt;br/&gt;&lt;br /&gt;The idea is to wrap multiple business methods and execute them in a single transaction boundary. Seems there is no difference with the previous approach, but we can use &lt;i&gt;EXTENDED&lt;/i&gt; persistence context mode when persistent entities kept attached to stateful bean till the moment the bean is removed from context:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Local&lt;br /&gt;interface OpenSessionInViewCallback {&lt;br /&gt;    void invoke(Runnable r);&lt;br /&gt;&lt;br /&gt;    void remove();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Stateful(name = "openSessionInViewCallback")&lt;br /&gt;public class OpenSessionInViewCallbackImpl implements OpenSessionInViewCallback {&lt;br /&gt;    @PersistenceContext(type = PersistenceContextType.EXTENDED)&lt;br /&gt;    private EntityManager entityManager;&lt;br /&gt;&lt;br /&gt;    @Init&lt;br /&gt;    public void invoke(Runnable r) {&lt;br /&gt;        r.run();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Remove&lt;br /&gt;    public void remove() {&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Template class gets reference to the stateful bean from JNDI context and removes bean from context when callback method is executed:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public final class OpenSessionInViewTemplate {&lt;br /&gt;    public static void invoke(Runnable r) {&lt;br /&gt;        OpenSessionInViewCallback callback = null;&lt;br /&gt;        try {&lt;br /&gt;            // make lookup for callback bean&lt;br /&gt;            Context context = new InitialContext();&lt;br /&gt;            callback = (OpenSessionInViewCallback) context.lookup("openSessionInViewCallbackLocal");&lt;br /&gt;&lt;br /&gt;            // invoke runnable&lt;br /&gt;            callback.invoke(r);&lt;br /&gt;        } catch (NamingException e) {&lt;br /&gt;            throw new RuntimeException(e);&lt;br /&gt;        } finally {&lt;br /&gt;            if (callback != null) {&lt;br /&gt;                // remove bean&lt;br /&gt;                callback.remove();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Any business methods calls can be done in &lt;i&gt;run()&lt;/i&gt; method of &lt;i&gt;Runnable&lt;/i&gt; without &lt;br /&gt;&lt;i&gt;LazyInitializationException&lt;/i&gt; thrown and affecting business methods transactions boundaries. Unit tests may need to use template method approach.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Interceptor.&lt;/i&gt;&lt;br/&gt;&lt;br /&gt;The solution is similar to the previous one but the calling code will look much simple now:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;@Remote(ProductWebService.class)&lt;br /&gt;@Stateless(name = "productWebService")&lt;br /&gt;@TransactionManagement(TransactionManagementType.BEAN)&lt;br /&gt;@Interceptors(OpenSessionInViewInterceptor.class)&lt;br /&gt;public class ProductWebServiceImpl implements ProductWebService {&lt;br /&gt;    @EJB&lt;br /&gt;    private ProductService productService;&lt;br /&gt;&lt;br /&gt;    @WebMethod&lt;br /&gt;    public ProductBean getProduct(@WebParam(name = "id") long id) {&lt;br /&gt;        ProductBean bean = null;&lt;br /&gt;&lt;br /&gt;        Product product = productService.getProduct(id);&lt;br /&gt;        if (product != null) {&lt;br /&gt;            bean = new ProductBean();&lt;br /&gt;            bean.setId(product.getId());&lt;br /&gt;            bean.setCode(product.getCode());&lt;br /&gt;            Date lastPaid = null;&lt;br /&gt;            for (Purchase purchase : product.getPurchases()) {&lt;br /&gt;                if (lastPaid == null || lastPaid.after(purchase.getPaymentDate())) {&lt;br /&gt;                    lastPaid = purchase.getPaymentDate();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            bean.setLastPaid(lastPaid);&lt;br /&gt;        }&lt;br /&gt;        return bean;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this example, thankfully to &lt;i&gt;OpenSessionInViewInterceptor&lt;/i&gt; interceptor, invocation of &lt;i&gt;getPurchases()&lt;/i&gt; will not cause error, at the same time any transaction boundary is not affected as well.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Deploying application and running tests&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;After application has been built with Maven:&lt;br /&gt;&lt;pre&gt;mvn package&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and everything was fine (pray first), you need to copy &lt;i&gt;ishop-ear/src/main/resources/ishop-ds.xml&lt;/i&gt; to JBoss &lt;i&gt;server/&amp;lt;CONFIGURATION&amp;gt;/deploy&lt;/i&gt; directory and configure according to your environment. Ensure that database driver JAR file is in JBoss application server class path. Execute &lt;i&gt;schema.sql&lt;/i&gt; and &lt;i&gt;sample.sql&lt;/i&gt; scripts to populate database with required tables and add sample data (databases other than Oracle may need to have them tuned). Copy &lt;i&gt;ishop-ear/target/ishop-ear-1.0.ear&lt;/i&gt; to the same application server deployment directory. Start JBoss for that configuration:&lt;br /&gt;&lt;pre&gt;$JBOSS_HOME/bin/run.sh -c &amp;lt;CONFIGURATION&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To check Web services change to &lt;i&gt;ishop-wsclient/target&lt;/i&gt; and launch application like follows:&lt;br /&gt;&lt;pre&gt;java -jar ishop-wsclient-1.0.jar 1&lt;/pre&gt;&lt;br /&gt;where &lt;i&gt;1&lt;/i&gt; is the first product ID in production database. To have Web service client working ensure that application server has been started and available on port &lt;i&gt;8080&lt;/i&gt; on local host (default settings).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;Though following enterprise standards sometimes is a difficult decision and has its consequences, in many cases switching to EJB may increase application portability making, in the future, migration to another platform more transparent, reducing costs spent on application development and further support. At the same time, it is not so hard, as we may imagine at first, to develop and especially test enterprise application, based on EJB, out of application server. And OpenEJB helps with this.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Source code&lt;/h2&gt;&lt;br /&gt;&lt;a href="http://sites.google.com/site/mindplanet9/Home/ejb/ishop.ejb-testng.zip?attredirects=0"&gt;ishop.ejb-testng.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Thank you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-7887400305071064170?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/7887400305071064170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/03/testing-ejb-out-of-application-server.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/7887400305071064170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/7887400305071064170'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/03/testing-ejb-out-of-application-server.html' title='Testing EJB out of application server - Part 1'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-593407908487316669</id><published>2009-03-20T12:47:00.000-07:00</published><updated>2009-03-20T12:55:02.713-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sp_dboption'/><category scheme='http://www.blogger.com/atom/ns#' term='into/bulkcopy'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='Sybase'/><title type='text'>Setting select into/bulkcopy option in Sybase</title><content type='html'>Oh, how often Sybase makes me like mad. Why should I turn options on or off just to make an ordinal action like adding column which can not be NULL? Here is a snippet that helps to deal with those 'select into/bulkcopy option is disabled' errors. Not sure somebody does not know it yet, Rather I want to be sure I will not forget it before we migrate to Oracle.&lt;br /&gt;&lt;pre&gt;USE master;&lt;br /&gt;EXEC sp_dboption mydb,'select into/bulkcopy/pllsort',true;&lt;br /&gt;USE mydb;&lt;br /&gt;-- ALTER TABLE goes here&lt;br /&gt;USE master;&lt;br /&gt;EXEC sp_dboption mydb,'select into/bulkcopy/pllsort',false;&lt;/pre&gt;&lt;br /&gt;mydb is a database name, should be properly selected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-593407908487316669?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/593407908487316669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/03/setting-select-intobulkcopy-option-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/593407908487316669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/593407908487316669'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/03/setting-select-intobulkcopy-option-in.html' title='Setting select into/bulkcopy option in Sybase'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-6775352761498158331</id><published>2009-03-20T09:56:00.000-07:00</published><updated>2009-03-24T01:31:44.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GB988EA'/><category scheme='http://www.blogger.com/atom/ns#' term='laptop'/><category scheme='http://www.blogger.com/atom/ns#' term='6730B'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Lenny'/><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><category scheme='http://www.blogger.com/atom/ns#' term='HP6730B'/><title type='text'>Installing Debian 5 (Lenny) on HP6730B laptop (model GB988EA#ECB)</title><content type='html'>&lt;h2&gt;Audio support&lt;/h2&gt;&lt;br /&gt;Following information published on &lt;a href="http://www.linlap.com/wiki/HP-Compaq+6730B"&gt;Wiki&lt;/a&gt; and &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/269027"&gt;Issue page&lt;/a&gt;, I was able to configure audio module so it is recognized properly and sound is available both on speakers and microphone audio output. In short, following was done: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;In file /etc/modprobe.d/options added one more&lt;br /&gt;line:&lt;br /&gt;options snd-hda-intel model=mobile&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In file /etc/modprobe.d/als-base added the same (not sure whether it was necessary):&lt;br /&gt;options snd-hda-intel model=mobile&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Then just reboot.&lt;br /&gt;&lt;h2&gt;Keyboard&lt;/h2&gt;&lt;br /&gt;To configure multimedia buttons need to create /etc/X11/Xmodmap file and add following lines:&lt;br /&gt;&lt;pre&gt;keycode 129 = XF86Music&lt;br /&gt;keycode 162 = XF86Video&lt;br /&gt;keycode 160 = XF86AudioMute&lt;br /&gt;keycode 174 = XF86AudioLowerVolume&lt;br /&gt;keycode 176 = XF86AudioRaiseVolume&lt;br /&gt;keycode 178 = XF86WWW&lt;/pre&gt;&lt;br /&gt;This file is read by xmodmap utility, launched by display manager on X session startup. Key codes were taken from xev command output, and mapping from /usr/include/X11/XF86keysym.h and&lt;br /&gt;/usr/include/X11/keysymdef.h files of the linux kernel source tree. The laptop supports only audio control keys (which are software keys), e.g. mute and volume +/- control. Other keys I keep because my external keyboard Logitech UltraX supports them. I wonder why these are still not set by the Debian installer automatically (are codes are non-standard?). Binding to KDE events can be changed in KDE &lt;br /&gt;Control Center-&gt;Regional settings-&gt;Keyboard layout.&lt;br /&gt;For example, for Opera application I set combination XF86WWW.&lt;br /&gt;&lt;h2&gt;Touchpad&lt;/h2&gt;&lt;br /&gt;Works well.&lt;br /&gt;&lt;h2&gt;Wi-FI&lt;/h2&gt;&lt;br /&gt;Reported it works, but I have not checked it out. Recognized as Hewlett-Packard Wireless (Bluetooth + WLAN) Interface.&lt;br /&gt;&lt;h2&gt;Camera&lt;/h2&gt;&lt;br /&gt;Upgrade Linux kernel to 2.6.28, which has support for HP WebCam. Cheese, XawTV and Skype work well.&lt;br /&gt;&lt;h2&gt;Power management&lt;/h2&gt;&lt;br /&gt;While compiling kernel, enabled power management and ACPI extensions, so when either the lid is closed or on Fn+F3, laptop goes to suspend mode. Here are some issues I watch from time to time:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;laptop sometimes does not switch into suspend mode. Still have no idea what is wrong with it (some kind of resources are busy?).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On wake up fan starts turning with 100% speed. This seems to be a &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/77370"&gt;bug&lt;/a&gt;. This happens every 4th time or so, suspending and wakening up helps, but is really annoying.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;USB&lt;/h2&gt;&lt;br /&gt;Flash drives, keyboards and mices work well.&lt;br /&gt;&lt;h2&gt;Display&lt;/h2&gt;&lt;br /&gt;Works well, backlight can be configured with xrandr. My following entry will touch this, describing external monitors attachment.&lt;br /&gt;&lt;h2&gt;Video&lt;/h2&gt;&lt;br /&gt;Recognized Intel Corporation Mobile 4 Series Chipset Integrated Graphics Controller, by default X configuration uses some default driver. To change to Intel one, add line in /etc/X11/xorg.conf:&lt;br /&gt;&lt;pre&gt;Section "Device"&lt;br /&gt;    Identifier      "Primary Video Device"&lt;br /&gt;    Driver          "intel"&lt;br /&gt;# options may go here ...&lt;br /&gt;EndSection&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Fingerprint&lt;/h2&gt;&lt;br /&gt;Does not work due to absence of appropriate driver. Maybe there is, I do not care so much about it.&lt;br /&gt;&lt;h2&gt;DVD&lt;/h2&gt;&lt;br /&gt;Works just fine. Recognized as CDDVDW TS-L633L.&lt;br /&gt;&lt;h2&gt;Card reader&lt;/h2&gt;&lt;br /&gt;Recognized as HP Flash Media Reader. Works - tested on SD card.&lt;br /&gt;&lt;h2&gt;Network adapter&lt;/h2&gt;&lt;br /&gt;Installed adapter is recognized as NetLink BCM5787M Gigabit Ethernet PCI Express, and works well.&lt;br /&gt;&lt;h2&gt;Firewire&lt;/h2&gt;&lt;br /&gt;Recognized as Agere Systems FW323, have no idea whether it works or not.&lt;br /&gt;&lt;h2&gt;Laptop user opinion&lt;/h2&gt;&lt;br /&gt;&lt;h3&gt;Pros&lt;/h3&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Price. I beleive it corresponds to performance, which is quite enough to develop enterprise applications for Java platform. It simultaneously runs Web browser (Opera), mail client (Icedove), IDE (IntelliJ IDEA) and JBoss on deployment, and some other staff, with sufficient performance. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Key board layout is really good one, though that's my first notebook. Also Fn key is not the most left one, and that's great.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Not to heavy to carry in business trips.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h3&gt;Cons&lt;/h3&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Absance of Caps Lock indicator. Well, there could not be one because there is no such key, but it would be great to have some indicator I could watch keyboard layout indicator state (except English I have Russian one). Sounds really funny, but that's what I am accustomed to.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Keys next to Power button seem to be hardware ones and are not recognized by xev, what makes them useless.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There is no DVI output, but VGA and HDMI instead. Is DVI dead yet?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Thanks for reading.&lt;br /&gt;&lt;a href="http://tuxmobil.org/"&gt;&lt;img src="http://tuxmobil.org/pics/tuxmobil_sticker.png" width="88" height="31" border="0" alt="TuxMobil - Linux on Laptops, Notebooks, PDAs and Mobile Phones"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-6775352761498158331?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/6775352761498158331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/03/installing-debian-5-lenny-on-hp6730b.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/6775352761498158331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/6775352761498158331'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/03/installing-debian-5-lenny-on-hp6730b.html' title='Installing Debian 5 (Lenny) on HP6730B laptop (model GB988EA#ECB)'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8968638556698348235.post-9187954699263911944</id><published>2009-01-01T23:18:00.000-08:00</published><updated>2009-03-20T10:29:04.089-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='multi-project'/><category scheme='http://www.blogger.com/atom/ns#' term='site'/><title type='text'>Configure site plugin for Maven multi-project</title><content type='html'>Sometimes we want to configure look-and-feel for the product site generated by Maven. There is no need to describe how to do that for a single project - Maven documentation quite clearly describes it on &lt;a href="http://maven.apache.org/plugins/maven-site-plugin/examples/creating-content.html"&gt;Creating Content page&lt;/a&gt;. On the other hand there is no need to repeat the same configuration for each sub-module's POM in multi-module project. Here is a short description what steps need to be performed to reduce code/markup duplication to add custom logo and make changes to CSS for every site to be generated, both root module one's and sub-modules'.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The first step is  creating &lt;span style="font-size:85%;"&gt;src/site/resources&lt;/span&gt; directory that will contain our images and CSS files, in the root module. As it is described on the site plugin documentation page, we need to configure &lt;span style="font-size:85%;"&gt;src/site/site.xml&lt;/span&gt; descriptor for our sites:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;project name="My project"&amp;gt;&lt;br /&gt;    &amp;lt;bannerLeft&amp;gt;&lt;br /&gt;        &amp;lt;name&amp;gt;myproject&amp;lt;/name&amp;gt;&lt;br /&gt;        &amp;lt;src&amp;gt;images/logo.jpg&amp;lt;/src&amp;gt;&lt;br /&gt;        &amp;lt;href&amp;gt;http://en.wikipedia.org/wiki/My_Science_Project&amp;lt;/href&amp;gt;&lt;br /&gt;    &amp;lt;/bannerLeft&amp;gt;&lt;br /&gt;    &amp;lt;skin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.apache.maven.skins&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;maven-classic-skin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/skin&amp;gt;&lt;br /&gt;    &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;links&amp;gt;&lt;br /&gt;            &amp;lt;item name="${project.name}" href="${project.url}"/&amp;gt;&lt;br /&gt;        &amp;lt;/links&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;menu ref="parent"/&amp;gt;&lt;br /&gt;        &amp;lt;menu ref="modules"/&amp;gt;&lt;br /&gt;        &amp;lt;menu ref="reports"/&amp;gt;&lt;br /&gt;        &amp;lt;menu name="Links"&amp;gt;&lt;br /&gt;            &amp;lt;item name="Wiki page" href="http://en.wikipedia.org/wiki/My_Science_Project"/&amp;gt;&lt;br /&gt;        &amp;lt;/menu&amp;gt;&lt;br /&gt;    &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;&lt;/pre&gt;Here we declared that index page will have banner on top left and click on it will lead to &lt;a href="http://en.wikipedia.org/wiki/My_Science_Project"&gt;My Science Project&lt;/a&gt; movie Wiki page (as example). We use Maven classic skin (some styling we will change later). In &lt;span style="font-size:85%;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt; element we configure default &lt;span style="font-size:85%;"&gt;parent&lt;/span&gt;, &lt;span style="font-size:85%;"&gt;modules&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;reports&lt;/span&gt; menu items, and provide one more link to Wiki page as part of &lt;span style="font-size:85%;"&gt;Links&lt;/span&gt; menu. Nothing special yet.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Following plugin documentation, create two sub-directories - &lt;span style="font-size:85%;"&gt;css&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;images&lt;/span&gt;. We use the first one to keep all our CSS files - for that we create &lt;span style="font-size:85%;"&gt;site.css&lt;/span&gt; file that will contain content similar to&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;h2 {&lt;br /&gt;    background-color: #5587B7;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;By default &lt;span style="font-size:85%;"&gt;site.css&lt;/span&gt; generated (and used) by site plugin is empty, and providing this we change styling for HTML element specified in &lt;span style="font-size:85%;"&gt;maven-theme.css&lt;/span&gt;.&lt;br /&gt;Next, we copy our site logo image &lt;span style="font-size:85%;"&gt;logo.jpg&lt;/span&gt; into &lt;span style="font-size:85%;"&gt;images&lt;/span&gt; sub-directory.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The last but not the least is configuring our POMs. It is predictable that all changes should be done to the root POM - that's the aim of our configuration and the post itself:) Main difference between parent and children POMs is difference in path to site descriptor file and resources. So we need to divide configuration used by the root and child POMs. Here how we do this:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&amp;lt;build&amp;gt;&lt;br /&gt;    &amp;lt;plugins&amp;gt;&lt;br /&gt;        &amp;lt;plugin&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;maven-site-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;inherited&amp;gt;false&amp;lt;/inherited&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;                &amp;lt;siteDirectory&amp;gt;${project.basedir}/src/site&amp;lt;/siteDirectory&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;        &amp;lt;/plugin&amp;gt;&lt;br /&gt;    &amp;lt;/plugins&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;pluginManagement&amp;gt;&lt;br /&gt;        &amp;lt;plugins&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-site-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;configuration&amp;gt;&lt;br /&gt;                    &amp;lt;siteDirectory&amp;gt;${project.parent.basedir}/src/site&amp;lt;/siteDirectory&amp;gt;&lt;br /&gt;                &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;        &amp;lt;/plugins&amp;gt;&lt;br /&gt;    &amp;lt;/pluginManagement&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;&lt;/pre&gt;Plugin configuration in &lt;span style="font-size:85%;"&gt;pligins&lt;/span&gt; element overrides configuration of the one in &lt;span style="font-size:85%;"&gt;pluginManagement&lt;/span&gt;, it also has &lt;span style="font-size:85%;"&gt;inherited&lt;/span&gt; attribute set to &lt;span style="font-size:85%;"&gt;false&lt;/span&gt; so the changes are not propagated to child modules and their POMs. So, configuration of in &lt;span style="font-size:85%;"&gt;pluginManagement&lt;/span&gt; element specifies correct path for sub-modules - they access site resources through their parent.&lt;/li&gt;&lt;/ol&gt;Sample multi project can be found here: &lt;a href="http://sites.google.com/site/mindplanet9/Home/maven-tips/configure-site-plugin-for-maven-multi-project/myproject.zip?attredirects=0"&gt;myproject.zip&lt;/a&gt;&lt;br /&gt;That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8968638556698348235-9187954699263911944?l=tech-mind.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-mind.blogspot.com/feeds/9187954699263911944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-mind.blogspot.com/2009/01/configure-site-plugin-for-maven-multi.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/9187954699263911944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8968638556698348235/posts/default/9187954699263911944'/><link rel='alternate' type='text/html' href='http://tech-mind.blogspot.com/2009/01/configure-site-plugin-for-maven-multi.html' title='Configure site plugin for Maven multi-project'/><author><name>mind</name><uri>http://www.blogger.com/profile/10794145663817889983</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_DpEQInQwvDI/SYCU_T0rsAI/AAAAAAAAAGo/myCtQ0uTcJE/S220/me.jpg'/></author><thr:total>1</thr:total></entry></feed>
