<?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-8941320698391889475</id><updated>2011-12-19T12:13:04.878+04:00</updated><category term='logging'/><category term='xa'/><category term='rmi'/><category term='jcr'/><category term='jdbc'/><category term='web'/><category term='jndi'/><category term='pidgin'/><category term='tomcat'/><category term='sfguardplugin'/><category term='jencks'/><category term='odbc'/><category term='xml-rpc'/><category term='mssql'/><category term='chrome'/><category term='gnome'/><category term='interface'/><category term='firefox'/><category term='css'/><category term='configuration'/><category term='wicket'/><category term='python'/><category term='helper'/><category term='browser'/><category term='spring'/><category term='gimp'/><category term='hardy heron'/><category term='unicode'/><category term='injection'/><category term='ubuntu java netbeans ant'/><category term='ndiswrapper'/><category term='database'/><category term='debug'/><category term='jackrabbit'/><category term='transaction'/><category term='commons-logging'/><category term='rpc'/><category term='java'/><category term='mysql'/><category term='php'/><category term='photoshop'/><category term='livejournal'/><category term='syndication'/><category term='context'/><category term='django'/><category term='slf4j'/><category term='blog'/><category term='netbeans'/><category term='log4j'/><category term='regex'/><category term='print'/><category term='photo'/><category term='wireless'/><category term='html'/><category term='highlights'/><category term='jboss'/><category term='server'/><category term='symfony'/><category term='ubuntu'/><category term='j2ee'/><category term='google'/><title type='text'>thirtyseven</title><subtitle type='html'>There will be no such thing as web development after World War III</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-4078858271846873159</id><published>2009-08-28T19:16:00.003+05:00</published><updated>2009-08-28T19:28:13.345+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='print'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Print Images Across Multiple Pages in Ubuntu</title><content type='html'>Ubuntu, which I use as my primary desktop OS is sweet, but it always has these little issues, when things you're used to in Windows are either hard or impossible to achieve. Well, there's nothing impossible when it comes to Linux, it just depends whether it'd take two minutes or five years to achieve whatever it is you want.&lt;br /&gt;&lt;br /&gt;Today I had to print a large image across multiple pages and couldn't find an easy way to do this. Apparently, this is a &lt;a href="http://www.google.com/search?aq=f&amp;ie=UTF-8&amp;q=ubuntu+print+image+multiple+pages"&gt;known issue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One messy way to do this (assuming you have the time and resources to get the right size) is this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ lp -d hp -o scaling=200 -o media=a4 filename.png&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where &lt;code&gt;hp&lt;/code&gt; is the name of the printer and &lt;code&gt;200&lt;/code&gt; is the size of the original image in percents.&lt;br /&gt;&lt;br /&gt;Sadly enough, this only works for bitmap images. I had to export my original &lt;code&gt;.svg&lt;/code&gt; file to &lt;code&gt;.png&lt;/code&gt;, otherwise I was getting just a part of my svg which was cut to fit the A4 sheet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-4078858271846873159?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/4078858271846873159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=4078858271846873159' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/4078858271846873159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/4078858271846873159'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/08/print-images-across-multiple-pages-in.html' title='Print Images Across Multiple Pages in Ubuntu'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-5510590121373534057</id><published>2009-08-20T13:37:00.006+05:00</published><updated>2009-08-20T14:23:22.400+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Page Title in Wicket</title><content type='html'>For a simple Wicket webapp, setting page title can be as easy as using the &lt;code&gt;wicket:message&lt;/code&gt; tag, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt; &amp;lt;head&amp;gt;&lt;br /&gt;   &amp;lt;title&amp;gt;&amp;lt;wicket:message key="page.title"&amp;gt;&amp;lt;/wicket:message&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt; &amp;lt;/head&amp;gt;&lt;br /&gt; ...&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Where in the &lt;code&gt;.property&lt;/code&gt; file, related to each page, the &lt;code&gt;page.title&lt;/code&gt; property can be set to whatever the page is titled.&lt;br /&gt;&lt;br /&gt;When you have a complex application, however, you might need to have more control over the page title, specifically when the title has to be dynamically generated depending on, e.g., product name.&lt;br /&gt;&lt;br /&gt;There might be different approaches to this, but the one I'm using allows to have a default title for all pages which can be overriden for each particular page.&lt;br /&gt;&lt;br /&gt;Most of the times, there's a base page for all the other pages. The &lt;code&gt;pageTitle&lt;/code&gt; label is added to the page, HTML placeholder for which is the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;BasePage.html&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt; &amp;lt;head&amp;gt;&lt;br /&gt;   &amp;lt;title wicket:id="pageTitle"&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt; &amp;lt;/head&amp;gt;&lt;br /&gt; ...&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we add the component to the page.&lt;br /&gt;The idea is to have a quick method to replace the &lt;code&gt;pageTitle&lt;/code&gt; component model once the data required to construct title is loaded. So the &lt;code&gt;setPageTitle(IModel model)&lt;/code&gt; method is added.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;BasePage.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class BasePage {&lt;br /&gt;&lt;br /&gt; public BasePage() {&lt;br /&gt;   add(new Label("pageTitle", new StringResourceModel("page.title", this, null)));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected void setPageTitle(IModel model) {&lt;br /&gt;   get("pageTitle").setModel(model);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, in the &lt;code&gt;ProductPage&lt;/code&gt; that extends the base page, we fetch the product data and update the page title:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ProductPage.java&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;public class ProductPage {&lt;br /&gt;&lt;br /&gt; final int id;&lt;br /&gt;&lt;br /&gt; public ProductPage(PageParameters params) {&lt;br /&gt;   id = params.getInt("id");&lt;br /&gt;   final Product p = productDao.get(id);&lt;br /&gt;   ...&lt;br /&gt;   // add components or whatever&lt;br /&gt;   ...&lt;br /&gt;   setPageTitle(new StringResourceModel("pageTitle", this, new Model(p)));&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;code&gt;ProductPage.properties&lt;/code&gt; has also to be updated, assuming the product has &lt;code&gt;getTitle()&lt;/code&gt; and &lt;code&gt;getPrice()&lt;/code&gt; methods:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ProductPage.properties&lt;/b&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;page.title=Shiny ${title} for just ${price}!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's the basic idea. I'm not particularly happy with this approach as it requires to always remember to update the &lt;code&gt;pageTitle&lt;/code&gt; component and push the title into the page. I'd actually prefer a way to override something so the title would be pulled for me. Ideally, that would look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;add(new Label("pageTitle", getPageTitle()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, in this case if the label is added on the &lt;code&gt;BasePage&lt;/code&gt;, even if the &lt;code&gt;getPageTitle()&lt;/code&gt; is overriden in the &lt;code&gt;ProductPage&lt;/code&gt;, since &lt;code&gt;BasePage&lt;/code&gt; is constructed prior to any logic found in &lt;code&gt;ProductPage&lt;/code&gt;, there is no data to return in &lt;code&gt;getPageTitle()&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-5510590121373534057?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/5510590121373534057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=5510590121373534057' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5510590121373534057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5510590121373534057'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/08/page-title-in-wicket.html' title='Page Title in Wicket'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7999223950294578052</id><published>2009-05-29T17:34:00.003+05:00</published><updated>2009-05-29T17:43:23.422+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu java netbeans ant'/><title type='text'>Switching to Sun JDK/JRE/JVM in Ubuntu</title><content type='html'>Turns out, I've been using OpenJDK all this time. Apparently, this is &lt;a href="http://ubuntuforums.org/showthread.php?p=7195065"&gt;not so bad&lt;/a&gt;, but when I tried to play with Ant from command line, I got &lt;i&gt;BUILD FAILED&lt;/i&gt; kind of errors.&lt;br /&gt;&lt;br /&gt;The symptoms are:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ ant -version&lt;br /&gt;Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-6-openjdk/lib/tools.jar&lt;br /&gt;Apache Ant version 1.7.1 compiled on November 10 2008&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ java -version&lt;br /&gt;java version "1.6.0_0"&lt;br /&gt;OpenJDK Runtime Environment (IcedTea6 1.4.1) (6b14-1.4.1-0ubuntu10)&lt;br /&gt;OpenJDK Server VM (build 14.0-b08, mixed mode)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The easiest way to solve this for me was to &lt;a href="http://www.cyberciti.biz/faq/howto-ubuntu-linux-install-configure-jdk-jre/"&gt;force&lt;/a&gt; Sun's &amp;ldquo;original&amp;rdquo; JDK.&lt;br /&gt;&lt;br /&gt;Apparently, once you've installed &lt;code&gt;sun-java6-bin&lt;/code&gt;, &lt;code&gt;-jre&lt;/code&gt; and &lt;code&gt;-jdk&lt;/code&gt; packages, you have to&lt;br /&gt;&lt;pre&gt;$ sudo update-java-alternatives -s java-6-sun&lt;/pre&gt;&lt;br /&gt;and then edit &lt;code&gt;/etc/jvm&lt;/code&gt; so that it looks something like this, with &lt;code&gt;/usr/lib/jvm/java-6-sun&lt;/code&gt; on top:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/usr/lib/jvm/java-6-sun&lt;br /&gt;/usr/lib/jvm/java-gcj&lt;br /&gt;/usr/lib/jvm/ia32-java-1.5.0-sun&lt;br /&gt;/usr/lib/jvm/java-1.5.0-sun&lt;br /&gt;/usr&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7999223950294578052?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7999223950294578052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7999223950294578052' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7999223950294578052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7999223950294578052'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/05/switching-to-sun-jdkjrejvm-in-ubuntu.html' title='Switching to Sun JDK/JRE/JVM in Ubuntu'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-2039312476490996719</id><published>2009-05-24T00:37:00.004+05:00</published><updated>2009-05-24T16:35:05.082+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='context'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Configure Tomcat To Serve Static Files</title><content type='html'>Tomcat is often considered to be too slow to serve static content. That is why on production servers, static files are often served by a separate web server like Apache Server or lighthttpd.&lt;br /&gt;&lt;br /&gt;In development, however, you sometimes might need a quick-and-dirty solution for serving large amounts of static files stored somewhere on hard disk. One example of such usage would be an service that stores and organizes image files.&lt;br /&gt;&lt;br /&gt;Suppose you have a /var/project/images directory which stores a number of images for your project. If you want this directory to be exposed through http protocol, all you have to do is to add a &lt;code&gt;&amp;lt;Context&amp;gt;&lt;/code&gt; parameter to the &lt;code&gt;&amp;lt;Host&amp;gt;&lt;/code&gt; section of Tomcat's &lt;code&gt;server.xml&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;Server port=&amp;quot;8025&amp;quot; shutdown=&amp;quot;SHUTDOWN&amp;quot;&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;Service name=&amp;quot;Catalina&amp;quot;&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;    &amp;lt;Engine defaultHost=&amp;quot;localhost&amp;quot; name=&amp;quot;Catalina&amp;quot;&amp;gt;&lt;br /&gt;      ...&lt;br /&gt;      &amp;lt;Host appBase=&amp;quot;webapps&amp;quot;&lt;br /&gt;          autoDeploy=&amp;quot;false&amp;quot; name=&amp;quot;localhost&amp;quot; unpackWARs=&amp;quot;true&amp;quot;&lt;br /&gt;          xmlNamespaceAware=&amp;quot;false&amp;quot; xmlValidation=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;        ...&lt;br /&gt;        &amp;lt;Context&lt;br /&gt;            docBase=&amp;quot;/var/project/images&amp;quot;&lt;br /&gt;            path=&amp;quot;/project/images&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/Host&amp;gt;&lt;br /&gt;    &amp;lt;/Engine&amp;gt;&lt;br /&gt;  &amp;lt;/Service&amp;gt;&lt;br /&gt;&amp;lt;/Server&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that &lt;code&gt;docBase&lt;/code&gt; parameter is set to the path on hard drive and &lt;code&gt;path&lt;/code&gt; parameter is set to the context path for your files. Now, if you have a &lt;code&gt;/var/project/images/sample.png&lt;/code&gt; file, it can be seen at &lt;code&gt;http://localhost:8084/project/images/sample.png&lt;/code&gt;. Host name and port number may be different on your system, the ones listed here are default for the version of Tomcat bundled with NetBeans.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-2039312476490996719?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/2039312476490996719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=2039312476490996719' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/2039312476490996719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/2039312476490996719'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/05/tomcat-is-often-considered-to-be-too.html' title='Configure Tomcat To Serve Static Files'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-8678513438823199028</id><published>2009-05-20T17:30:00.002+05:00</published><updated>2009-05-20T17:58:39.930+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='syndication'/><category scheme='http://www.blogger.com/atom/ns#' term='xml-rpc'/><category scheme='http://www.blogger.com/atom/ns#' term='livejournal'/><category scheme='http://www.blogger.com/atom/ns#' term='rpc'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Add Syndication to symfony-driven Blog</title><content type='html'>If you have a standalone blog powered by symfony framework, and would like to add syndication with major blog services like Blogger or LiveJournal, you could use a PEAR &amp;ldquo;&lt;a href="http://pear.php.net/package/Services_Blogging/"&gt;Services_Blogging&lt;/a&gt;&amp;rdquo; package.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Download&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;First, you &lt;a href="http://download.pear.php.net/package/Services_Blogging-0.2.3.tgz"&gt;download&lt;/a&gt; it and then install following &lt;a href="http://www.symfony-project.org/jobeet/1_2/Propel/en/16#chapter_16_sending_emails"&gt;this tutorial&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Extract the archive and put the contents in your symphony's &lt;code&gt;lib/vendor/serviceblogging&lt;/code&gt; directory. You will also have to add the XML-RPC PEAR package. Download it, extract, then put &lt;code&gt;XML_RPC_x.x.x&lt;/code&gt; folder in the &lt;code&gt;servicesblogging&lt;/code&gt; directory (there must be a &lt;code&gt;Services&lt;/code&gt; folder there) and rename from &amp;ldquo;&lt;code&gt;XML_RPC_x.x.x&lt;/code&gt;&amp;rdquo; to &amp;ldquo;&lt;code&gt;XML&lt;/code&gt;&amp;rdquo;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Install&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Now, install the package as a symfony plugin. For this, edit the &lt;code&gt;config/ProjectConfiguration.php&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class ProjectConfiguration extends sfProjectConfiguration&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  static protected $sbLoaded = false;&lt;br /&gt;  &lt;br /&gt;  static public function registerServicesBlogging() {&lt;br /&gt;    if (self::$sbLoaded) {&lt;br /&gt;      return;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    set_include_path(sfConfig::get('sf_lib_dir').'/vendor/servicesblogging'&lt;br /&gt;        .PATH_SEPARATOR.get_include_path());&lt;br /&gt;    require_once sfConfig::get('sf_lib_dir').'/vendor/servicesblogging/Services/Blogging.php';&lt;br /&gt;    self::$sbLoaded = true;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public function setup()&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Enjoy&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Now in your php code you can do the following to add a new post:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    $bl = Services_Blogging::factory(&lt;br /&gt;        "LiveJournal",&lt;br /&gt;        "username", "password",&lt;br /&gt;        "http://livejournal.com",&lt;br /&gt;        "/interface/xmlrpc");&lt;br /&gt;        &lt;br /&gt;    $post = $bl-&gt;createNewPost();&lt;br /&gt;    $post-&gt;title = $title;&lt;br /&gt;    $post-&gt;content = $text;&lt;br /&gt;    $bl-&gt;savePost($post);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Disable Auto-formatting&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;A little something for livejournal users: you can disable auto-formatting if you pass a special parameter to livejournal XML-RPC service. To do this the dirty, way, edit &lt;code&gt;Services/Blogging/Driver/LiveJournal.php&lt;/code&gt; file of the Services_Blogging package.&lt;br /&gt;&lt;br /&gt;Specifically, in the the &lt;code&gt;Driver.savePost()&lt;/code&gt; method, add &lt;code&gt;props&lt;/code&gt; parameter to the RPC call value:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;            $value = new XML_RPC_Value(&lt;br /&gt;    array(&lt;br /&gt;        'username'       =&gt; $this-&gt;userdata['rpc_user'],&lt;br /&gt;        'auth_method'    =&gt; new XML_RPC_Value('challenge', 'string'),&lt;br /&gt;        'auth_challenge' =&gt; new XML_RPC_Value(&lt;br /&gt;            $authdata['challenge'], 'string'&lt;br /&gt;        ),&lt;br /&gt;        'auth_response'  =&gt; new XML_RPC_Value(&lt;br /&gt;            $authdata['response'] , 'string'&lt;br /&gt;        ),&lt;br /&gt;&lt;br /&gt;        'subject'        =&gt; new XML_RPC_Value(&lt;br /&gt;            $post-&gt;{Services_Blogging_Post::TITLE}&lt;br /&gt;        ),&lt;br /&gt;        'event'          =&gt; new XML_RPC_Value(&lt;br /&gt;            $post-&gt;{Services_Blogging_Post::CONTENT}&lt;br /&gt;        ),&lt;br /&gt;        'lineendings'    =&gt; new XML_RPC_Value('pc'),&lt;br /&gt;&lt;br /&gt;        'year'           =&gt; new XML_RPC_Value(date('Y', $time), 'int'),&lt;br /&gt;        'mon'            =&gt; new XML_RPC_Value(date('n', $time), 'int'),&lt;br /&gt;        'day'            =&gt; new XML_RPC_Value(date('j', $time), 'int'),&lt;br /&gt;        'hour'           =&gt; new XML_RPC_Value(date('G', $time), 'int'),&lt;br /&gt;        'min'            =&gt; new XML_RPC_Value(date('i', $time), 'int'),&lt;br /&gt;        &lt;br /&gt;        'props'          =&gt; new XML_RPC_Value(&lt;br /&gt;            array('opt_preformatted' =&gt; new XML_RPC_VALUE(true, 'boolean')),&lt;br /&gt;            'struct'),&lt;br /&gt;    ),&lt;br /&gt;    'struct'&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&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/8941320698391889475-8678513438823199028?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/8678513438823199028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=8678513438823199028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8678513438823199028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8678513438823199028'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/05/add-syndication-to-symfony-driven-blog.html' title='Add Syndication to symfony-driven Blog'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-1250865836396430935</id><published>2009-03-24T19:30:00.017+04:00</published><updated>2009-03-24T22:53:29.243+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jcr'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jackrabbit'/><category scheme='http://www.blogger.com/atom/ns#' term='jencks'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='transaction'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='xa'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Spring: Distributed Transactions across JCR and MySQL Database</title><content type='html'>Before following the steps described next, please be aware that this isn't an example of something you should use in production, but merely a sketch of how to wire Jackrabbit repository and a MySQL database to participate in distributed transactions. I haven't worked with XA before, nor I have a lot of experience with Spring, and it took me some time to get this working (mostly because of my ignorance in this area), so certain things are simplified, certain libraries are outdated, and sometimes I am not entirely sure what exactly I am doing. Hopefully, in future I will improve and update this example.&lt;br /&gt;&lt;br /&gt;If you're new to Spring and transactions, you might want to read &lt;a href="http://www.infoq.com/minibooks/JTDS"&gt;Java Transaction Design Strategies&lt;/a&gt;, a free book from InfoQ, and &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html"&gt;Chapter 9&lt;/a&gt; of the Spring Reference.&lt;br /&gt;&lt;br /&gt;To have transactions distributed across multiple datasources in Spring, you need an external transaction manager. By now, I am aware of three distributions that provide such functionality. Those are &lt;a href="http://www.atomikos.com/Main/TransactionsEssentials"&gt;Atomikos&lt;/a&gt;, &lt;a href="http://jotm.ow2.org/xwiki/bin/view/Main/WebHome"&gt;JOTM&lt;/a&gt; and &lt;a href="http://jencks.codehaus.org/"&gt;Jencks&lt;/a&gt;. I will be using Jencks despite the fact that the library development seems to be discontinued since 2007, and it's not supported in any way. The reason is simply that it's the only library I've managed to configure by now. The even-more-outdated &lt;a href="https://springmodules.dev.java.net/source/browse/springmodules/samples/jcr/src/"&gt;Jackrabbit-JTA example&lt;/a&gt; uses Jencks as well.&lt;br /&gt;&lt;br /&gt;To deal with the problem of configuration, I've created a simple web application called &amp;ldquo;Wijax&amp;rdquo; (as I'm using Wicket for presentation, so it's &lt;b&gt;Wi&lt;/b&gt;cket-&lt;b&gt;Jack&lt;/b&gt;rabbit-&lt;b&gt;S&lt;/b&gt;pring). You can get the source of it in a form of a NetBeans project &lt;a href="http://1322134.com/code/wijax/Wijax.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Once you have your minimal &lt;a href="http://th1rty7.blogspot.com/2008/08/wicket-spring-with-jdbc-configuration.html"&gt;Wicket-Spring application&lt;/a&gt; up and running, it's time to add some JCR.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Dependencies&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;If you haven't yet discovered the magic and pain of using Maven (like yours truly here), you will need the following libraries:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="https://springmodules.dev.java.net/servlets/ProjectDocumentList"&gt;Spring-Modules-JCR&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://jcp.org/en/jsr/detail?id=170"&gt;JCR-1.0&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://jackrabbit.apache.org/downloads.html"&gt;Jackrabbit-related&lt;/a&gt; JARs&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Concurrent&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Commons-Collections&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Commons IO&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Derby&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrabbit-API&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrabbit-JCA&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrabbit-Core&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrrabbit-JCR-Commons&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrrabbit-Text-Extractors&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrrabbit-SPI&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Jackrrabbit-SPI-Commons&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lucene Core&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;All Jackrabbit-related jars might be found in Jackrabbit-Webapp distribution.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Jencks&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://repository.codehaus.org/org/jencks/jencks/2.1/"&gt;Jencks-All-2.1&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://ibiblio.org/pub/packages/maven2/org/apache/geronimo/components/geronimo-transaction/2.0.2/geronimo-transaction-2.0.2.jar"&gt;Geronimo-Transaction-2.0.2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://ibiblio.org/pub/packages/maven2/org/apache/geronimo/components/geronimo-connector/2.0.2/geronimo-connector-2.0.2.jar"&gt;Geronimo-Connector-2.0.2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;For the latter two links I must thank Les Hazlewood who &lt;a href="http://www.nabble.com/geronimo-transaction-jar-not-included-tp14278433p14280133.html"&gt;pointed those out&lt;/a&gt; at the Jencks discussion forum, potentially saving me a couple of hours of searching. This is not all, however. Jencks depends on JTA and JCA packages, and they are included in Jencks-All package. However, in the version of Jencks 2.1 they are both outdated as versions 1.0 of both libraries are included, when they are supposed to be 1.1 and 1.5 respectively. I just replaced whatever was found in javax.* folders included in Jencks-All by required versions.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Spring&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;You also might want to get AspectJWeaver in case you will be using AOP-based Spring configuration (like I'm going to) and move Commons Logging from Tomcat lib folder to WEB-INF in case you have it there and experiencing &lt;a href="http://th1rty7.blogspot.com/2009/03/configure-logging-in-spring-with-log4j.html"&gt;logging problems&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Obviously, all the libraries mentioned above can be found in the Wijax project archive, but I provided links just so you might want to get newer versions of maintaned jars.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Business Objects&lt;/h3&gt;&lt;br /&gt;We'll have two business objects called &amp;ldquo;Dumb&amp;rdquo; and &amp;ldquo;Silly&amp;rdquo; with Dumb being stored in database and Silly kept in repository. Both will have an &amp;ldquo;id&amp;rdquo; and &amp;ldquo;version&amp;rdquo; parameters, however, we will only deal with the version.&lt;br /&gt;&lt;br /&gt;Create MySQL database &amp;ldquo;wijax&amp;rdquo; and import this sql in it:&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;CREATE TABLE IF NOT EXISTS `dumb` (&lt;br /&gt;  `id` bigint(11) unsigned NOT NULL auto_increment,&lt;br /&gt;  `version` int(5) unsigned NOT NULL default '0',&lt;br /&gt;  PRIMARY KEY  (`id`)&lt;br /&gt;) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For both objects, we'll have DAOs and DTOs.&lt;br /&gt;&lt;br /&gt;Dumb DTO:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.dumb;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class DumbDto implements Serializable {&lt;br /&gt;&lt;br /&gt;    private final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;    private long id;&lt;br /&gt;    private int version;&lt;br /&gt;&lt;br /&gt;    public DumbDto(long id) {&lt;br /&gt;        this.id = id;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the id&lt;br /&gt;     */&lt;br /&gt;    public long getId() {&lt;br /&gt;        return id;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the version&lt;br /&gt;     */&lt;br /&gt;    public int getVersion() {&lt;br /&gt;        return version;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param version the version to set&lt;br /&gt;     */&lt;br /&gt;    public void setVersion(int version) {&lt;br /&gt;        this.version = version;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dumb DAO interface:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.dumb;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public interface DumbDao extends Serializable {&lt;br /&gt;&lt;br /&gt;    public void save(DumbDto dto);&lt;br /&gt;&lt;br /&gt;    public void saveWithRollback(DumbDto dto);&lt;br /&gt;&lt;br /&gt;    public DumbDto load(long id);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dumb DAO JDBC implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Java"&gt;&lt;br /&gt;package ru.sadninja.wijax.dumb;&lt;br /&gt;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;import org.springframework.dao.DataAccessException;&lt;br /&gt;import org.springframework.jdbc.core.ResultSetExtractor;&lt;br /&gt;import org.springframework.jdbc.core.support.JdbcDaoSupport;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class DumbJdbcDao extends JdbcDaoSupport implements DumbDao {&lt;br /&gt;&lt;br /&gt;    private final static long serialVersionUID = 1L;&lt;br /&gt;    &lt;br /&gt;    static Logger dLogger = Logger.getLogger(DumbJdbcDao.class.getName());&lt;br /&gt;&lt;br /&gt;    private final static String INSERT_DUMB_QUERY_STRING =&lt;br /&gt;        "insert into dumb (version) values (?)";&lt;br /&gt;&lt;br /&gt;    private final static String SAVE_DUMB_QUERY_STRING =&lt;br /&gt;        "update dumb set version=? where id=?";&lt;br /&gt;&lt;br /&gt;    private final static String LOAD_DUMB_BY_ID =&lt;br /&gt;        "select version from dumb where id=?";&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void save(DumbDto dumb) {&lt;br /&gt;        if (dumb == null || dumb.getId() == 0) {&lt;br /&gt;            insert(dumb);&lt;br /&gt;        } else {&lt;br /&gt;            Object[] param = new Object[] { dumb.getVersion(), dumb.getId() };&lt;br /&gt;            if (getJdbcTemplate().update(SAVE_DUMB_QUERY_STRING, param) == 0) {&lt;br /&gt;                insert(dumb);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void saveWithRollback(DumbDto dumb) {&lt;br /&gt;        throw new RuntimeException("Whoops, runtime exception");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void insert(DumbDto dumb) {&lt;br /&gt;        Object[] param = new Object[] { dumb.getVersion() };&lt;br /&gt;        getJdbcTemplate().update(INSERT_DUMB_QUERY_STRING, param);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public DumbDto load(final long id) {&lt;br /&gt;        dLogger.info("reading dumb #" + id);&lt;br /&gt;        Object[] params = new Object[] { id };&lt;br /&gt;        DumbDto dumb = (DumbDto) getJdbcTemplate().query(LOAD_DUMB_BY_ID, params,&lt;br /&gt;                new ResultSetExtractor() {&lt;br /&gt;            public Object extractData(ResultSet rs)&lt;br /&gt;                    throws SQLException, DataAccessException {&lt;br /&gt;                rs.next();&lt;br /&gt;                DumbDto  dumb = new DumbDto(id);&lt;br /&gt;                dumb.setVersion(rs.getInt("version"));&lt;br /&gt;                return dumb;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        });&lt;br /&gt;&lt;br /&gt;        dLogger.info("dumb #" + id + " is of version " + dumb.getVersion());&lt;br /&gt;&lt;br /&gt;        return dumb;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Silly DTO:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.silly;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class SillyDto implements Serializable {&lt;br /&gt;&lt;br /&gt;    private final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt;    private long id;&lt;br /&gt;    private int version;&lt;br /&gt;&lt;br /&gt;    public SillyDto(long id) {&lt;br /&gt;        this.id = id;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the id&lt;br /&gt;     */&lt;br /&gt;    public long getId() {&lt;br /&gt;        return id;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the version&lt;br /&gt;     */&lt;br /&gt;    public int getVersion() {&lt;br /&gt;        return version;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param version the version to set&lt;br /&gt;     */&lt;br /&gt;    public void setVersion(int version) {&lt;br /&gt;        this.version = version;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Silly DAO:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.silly;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public interface SillyDao extends Serializable {&lt;br /&gt;&lt;br /&gt;    public void read();&lt;br /&gt;&lt;br /&gt;    public void save(SillyDto silly);&lt;br /&gt;&lt;br /&gt;    public void saveWithRollback(SillyDto silly);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Silly DAO JCR implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class SillyJcrDao extends JcrDaoSupport implements SillyDao {&lt;br /&gt;&lt;br /&gt;    private final static long serialVersionUID = 1L;&lt;br /&gt;    static Logger sLogger = Logger.getLogger(SillyJcrDao.class.getName());&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void read() {&lt;br /&gt;        sLogger.debug("reading...");&lt;br /&gt;        final Session session = getSession();&lt;br /&gt;        try {&lt;br /&gt;            Node root = session.getRootNode();&lt;br /&gt;            if (root.hasNode("silly")) {&lt;br /&gt;                sLogger.info("silly node present");&lt;br /&gt;                Node silly = root.getNode("silly");&lt;br /&gt;                if (silly.hasProperty("version")) {&lt;br /&gt;                    sLogger.info("silly is of version "&lt;br /&gt;                            + silly.getProperty("version").getLong());&lt;br /&gt;                }&lt;br /&gt;            } else {&lt;br /&gt;                sLogger.info("silly node missing");&lt;br /&gt;            }&lt;br /&gt;        } catch (RepositoryException re) {&lt;br /&gt;            throw convertJcrAccessException(re);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void save(SillyDto sillyDto) {&lt;br /&gt;        sLogger.debug("saving...");&lt;br /&gt;        final Session session = getSession();&lt;br /&gt;        try {&lt;br /&gt;            Node root = session.getRootNode();&lt;br /&gt;&lt;br /&gt;            Node silly;&lt;br /&gt;            if (root.hasNode("silly")) {&lt;br /&gt;                silly = root.getNode("silly");&lt;br /&gt;            } else {&lt;br /&gt;                sLogger.debug("silly node missing, create one");&lt;br /&gt;                silly = root.addNode("silly");&lt;br /&gt;            }&lt;br /&gt;            silly.setProperty("version", sillyDto.getVersion());&lt;br /&gt;            session.save();&lt;br /&gt;            sLogger.info("silly is now of version "&lt;br /&gt;                    + silly.getProperty("version").getLong());&lt;br /&gt;        } catch (RepositoryException re) {&lt;br /&gt;            throw convertJcrAccessException(re);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void saveWithRollback(SillyDto sillyDto) {&lt;br /&gt;        throw new RuntimeException("Whoa, runtime exception!");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now it gets interesting: a service which performs a transactions with both DAOs involved. I called it Creepy Service.&lt;br /&gt;&lt;br /&gt;An interface:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.service;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public interface CreepyService extends Serializable {&lt;br /&gt;&lt;br /&gt;    public void updateVersion(int n);&lt;br /&gt;&lt;br /&gt;    public void readVersion();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.service;&lt;br /&gt;&lt;br /&gt;import ru.sadninja.wijax.dumb.DumbDao;&lt;br /&gt;import ru.sadninja.wijax.dumb.DumbDto;&lt;br /&gt;import ru.sadninja.wijax.silly.SillyDao;&lt;br /&gt;import ru.sadninja.wijax.silly.SillyDto;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class CreepyServiceImpl implements CreepyService {&lt;br /&gt;&lt;br /&gt;    private final static long serialVersionUID = 2L;&lt;br /&gt;&lt;br /&gt;    private DumbDao dumbDao;&lt;br /&gt;    private SillyDao sillyDao;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void updateVersion(int n) {&lt;br /&gt;        &lt;br /&gt;        DumbDto dumb = new DumbDto(1);&lt;br /&gt;        dumb.setVersion(n);&lt;br /&gt;        dumbDao.save(dumb);&lt;br /&gt;        &lt;br /&gt;        SillyDto silly = new SillyDto(1);&lt;br /&gt;        silly.setVersion(n);&lt;br /&gt;        sillyDao.save(silly);&lt;br /&gt;&lt;br /&gt;        if (n == 11) {&lt;br /&gt;            sillyDao.saveWithRollback(silly);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;//        dumbDao.saveWithRollback(dumb);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void readVersion() {&lt;br /&gt;        dumbDao.load(1);&lt;br /&gt;        sillyDao.read();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setDumbDao(DumbDao dumbDao) {&lt;br /&gt;        this.dumbDao = dumbDao;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public DumbDao getDumbDao() {&lt;br /&gt;        return dumbDao;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @return the sillyDao&lt;br /&gt;     */&lt;br /&gt;    public SillyDao getSillyDao() {&lt;br /&gt;        return sillyDao;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param sillyDao the sillyDao to set&lt;br /&gt;     */&lt;br /&gt;    public void setSillyDao(SillyDao sillyDao) {&lt;br /&gt;        this.sillyDao = sillyDao;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And a page we will call be calling all this from:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package ru.sadninja.wijax.web.page;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;import org.apache.wicket.markup.html.form.Form;&lt;br /&gt;import org.apache.wicket.markup.html.form.TextField;&lt;br /&gt;import org.apache.wicket.markup.html.panel.FeedbackPanel;&lt;br /&gt;import org.apache.wicket.model.CompoundPropertyModel;&lt;br /&gt;import org.apache.wicket.spring.injection.annot.SpringBean;&lt;br /&gt;import org.springframework.dao.DataAccessException;&lt;br /&gt;import ru.sadninja.wijax.service.CreepyService;&lt;br /&gt;import ru.sadninja.wijax.silly.SillyDao;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; * @author sp&lt;br /&gt; */&lt;br /&gt;public class SillyPage extends WebPage {&lt;br /&gt;    &lt;br /&gt;    private final static long serialVersionUID = 2L;&lt;br /&gt;&lt;br /&gt;    @SpringBean(name="sillyDao")&lt;br /&gt;    SillyDao sillyDao;&lt;br /&gt;    @SpringBean(name="creepyService")&lt;br /&gt;    CreepyService creepyService;&lt;br /&gt;&lt;br /&gt;    private int version = 0;&lt;br /&gt;&lt;br /&gt;    public SillyPage() {&lt;br /&gt;        sillyDao.read();&lt;br /&gt;        add(new SillyForm());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public int getVersion() {&lt;br /&gt;        return version;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setVersion(int version) {&lt;br /&gt;        this.version = version;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class SillyForm extends Form {&lt;br /&gt;        public SillyForm() {&lt;br /&gt;            super("sillyForm", new CompoundPropertyModel(SillyPage.this));&lt;br /&gt;            add(new FeedbackPanel("feedback"));&lt;br /&gt;            add(new TextField("version"));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        public void onSubmit() {&lt;br /&gt;            try {&lt;br /&gt;                creepyService.updateVersion(getVersion());&lt;br /&gt;                setResponsePage(SillyPage.class);&lt;br /&gt;            } catch (DataAccessException dae) {&lt;br /&gt;                error(dae.getMessage());&lt;br /&gt;            } catch (RuntimeException re) {&lt;br /&gt;                error("Got a transaction exception: " + re.getMessage());&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;HTML for the page:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;      &amp;lt;form wicket:id=&amp;quot;sillyForm&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;div wicket:id=&amp;quot;feedback&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;          &amp;lt;div&amp;gt;&lt;br /&gt;              &amp;lt;input type=&amp;quot;text&amp;quot; wicket:id=&amp;quot;version&amp;quot; /&amp;gt;&lt;br /&gt;              &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;write&amp;quot; /&amp;gt;&lt;br /&gt;          &amp;lt;/div&amp;gt;&lt;br /&gt;      &amp;lt;/form&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Okay, here comes the sweetest part: Spring application context configuration. What we have to do is provide some sort of access to both data sources, make the accessing mechanisms aware of the global transaction context and configure our DAOs and Service to be transactional.&lt;br /&gt;&lt;br /&gt;Here goes:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/WEB-INF/applicationContext.xml&lt;/code&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;     xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;     xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;     xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;     xsi:schemaLocation=&amp;quot;&lt;br /&gt;     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt;     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd&lt;br /&gt;     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;wijaxApplication&amp;quot; class=&amp;quot;ru.sadninja.wijax.WijaxApplication&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jtaTransactionManager&amp;quot; class=&amp;quot;org.jencks.factory.TransactionManagerFactoryBean&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jrConnectionManager&amp;quot;&lt;br /&gt;        class=&amp;quot;org.jencks.factory.ConnectionManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;transactionManager&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;ref local=&amp;quot;jtaTransactionManager&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;transaction&amp;quot; value=&amp;quot;xa&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jdbcConnectionManager&amp;quot;&lt;br /&gt;        class=&amp;quot;org.jencks.factory.ConnectionManagerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;transactionManager&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;ref local=&amp;quot;jtaTransactionManager&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;transaction&amp;quot; value=&amp;quot;xa&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jdbcManagedConnectionFactory&amp;quot; class=&amp;quot;org.jencks.tranql.DataSourceMCF&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;driverName&amp;quot; value=&amp;quot;com.mysql.jdbc.Driver&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;url&amp;quot; value=&amp;quot;jdbc:mysql://localhost/wijax&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;user&amp;quot; value=&amp;quot;root&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;password&amp;quot; value=&amp;quot;root&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jdbcXaDataSource&amp;quot; class=&amp;quot;org.jencks.factory.ConnectionFactoryFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;managedConnectionFactory&amp;quot; ref=&amp;quot;jdbcManagedConnectionFactory&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;connectionManager&amp;quot; ref=&amp;quot;jdbcConnectionManager&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;repository&amp;quot; class=&amp;quot;org.jencks.factory.ConnectionFactoryFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;managedConnectionFactory&amp;quot;&lt;br /&gt;            ref=&amp;quot;repositoryManagedConnectionFactory&amp;quot;/&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;connectionManager&amp;quot; ref=&amp;quot;jrConnectionManager&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;repositoryManagedConnectionFactory&amp;quot;&lt;br /&gt;        class=&amp;quot;org.apache.jackrabbit.jca.JCAManagedConnectionFactory&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;homeDir&amp;quot; value=&amp;quot;/var/jackrabbit2&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;configFile&amp;quot; value=&amp;quot;/var/jackrabbit2/repository.xml&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jcrSessionFactory&amp;quot; class=&amp;quot;org.springmodules.jcr.JcrSessionFactory&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;repository&amp;quot; ref=&amp;quot;repository&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;credentials&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;bean class=&amp;quot;javax.jcr.SimpleCredentials&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;constructor-arg index=&amp;quot;0&amp;quot; value=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;          &amp;lt;constructor-arg index=&amp;quot;1&amp;quot; value=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;          &amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;      &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- The JCR Template. --&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;jcrTemplate&amp;quot; class=&amp;quot;org.springmodules.jcr.JcrTemplate&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;sessionFactory&amp;quot; ref=&amp;quot;jcrSessionFactory&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;allowCreate&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;tx:advice id=&amp;quot;txSillyAdvice&amp;quot; transaction-manager=&amp;quot;jtaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;tx:attributes&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;get*&amp;quot; read-only=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;*&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/tx:attributes&amp;gt;&lt;br /&gt;    &amp;lt;/tx:advice&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;aop:config&amp;gt;&lt;br /&gt;      &amp;lt;aop:pointcut id=&amp;quot;sillyDaoOperation&amp;quot;&lt;br /&gt;          expression=&amp;quot;execution(* ru.sadninja.wijax.silly.SillyDao.*(..))&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;aop:advisor advice-ref=&amp;quot;txSillyAdvice&amp;quot; pointcut-ref=&amp;quot;sillyDaoOperation&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/aop:config&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;sillyDao&amp;quot; class=&amp;quot;ru.sadninja.wijax.silly.SillyJcrDao&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;template&amp;quot; ref=&amp;quot;jcrTemplate&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;tx:advice id=&amp;quot;txDumbAdvice&amp;quot; transaction-manager=&amp;quot;jtaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;tx:attributes&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;get*&amp;quot; read-only=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;*&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/tx:attributes&amp;gt;&lt;br /&gt;    &amp;lt;/tx:advice&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;aop:config&amp;gt;&lt;br /&gt;      &amp;lt;aop:pointcut id=&amp;quot;dumbDaoOperation&amp;quot;&lt;br /&gt;          expression=&amp;quot;execution(* ru.sadninja.wijax.dumb.DumbDao.*(..))&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;aop:advisor advice-ref=&amp;quot;txDumbAdvice&amp;quot; pointcut-ref=&amp;quot;dumbDaoOperation&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/aop:config&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;dumbDao&amp;quot; class=&amp;quot;ru.sadninja.wijax.dumb.DumbJdbcDao&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;jdbcXaDataSource&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;tx:advice id=&amp;quot;txCreepyAdvice&amp;quot; transaction-manager=&amp;quot;jtaTransactionManager&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;tx:attributes&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;get*&amp;quot; read-only=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;tx:method name=&amp;quot;*&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/tx:attributes&amp;gt;&lt;br /&gt;    &amp;lt;/tx:advice&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;aop:config&amp;gt;&lt;br /&gt;      &amp;lt;aop:pointcut id=&amp;quot;creepyServiceOperation&amp;quot;&lt;br /&gt;          expression=&amp;quot;execution(* ru.sadninja.wijax.service.CreepyService.*(..))&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;aop:advisor advice-ref=&amp;quot;txCreepyAdvice&amp;quot; pointcut-ref=&amp;quot;creepyServiceOperation&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/aop:config&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;creepyService&amp;quot; class=&amp;quot;ru.sadninja.wijax.service.CreepyServiceImpl&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;dumbDao&amp;quot; ref=&amp;quot;dumbDao&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;property name=&amp;quot;sillyDao&amp;quot; ref=&amp;quot;sillyDao&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My two main sources of inspiration for the above config were excerpts from the Chapter Nine mentioned above, and an example of &lt;a href="http://svn.codehaus.org/jencks/trunk/jencks/src/test/resources/org/jencks/samples/outbound/jencks-multiple.xml"&gt;Jencks configuration for multiple datasources&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Finally, you might want to add &lt;code&gt;&lt;a href="http://th1rty7.blogspot.com/2009/03/configure-logging-in-spring-with-log4j.html"&gt;log4j.xml&lt;/a&gt;&lt;/code&gt; to watch Spring driving the transactions.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Test-drive&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;That seems like it. If you've done everything right, accessing &lt;code&gt;SillyPage&lt;/code&gt; for the first time will give the output message that silly node is missing. Try putting something except &amp;ldquo;11&amp;rdquo; (as that will throw an exception) in the form and submitting it. In the log, you should get something like:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;234824 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Creating new transaction with name [ru.sadninja.wijax.service.CreepyService.updateVersion]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT&lt;br /&gt;234825 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating in existing transaction&lt;br /&gt;234825 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL update&lt;br /&gt;234825 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL statement [update dumb set version=? where id=?]&lt;br /&gt;234825 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource&lt;br /&gt;234828 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Registering transaction synchronization for JDBC Connection&lt;br /&gt;234830 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows&lt;br /&gt;234831 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating in existing transaction&lt;br /&gt;234831 [http-8084-1] DEBUG ru.sadninja.wijax.silly.SillyJcrDao  - saving...&lt;br /&gt;234831 [http-8084-1] DEBUG ru.sadninja.wijax.silly.SillyJcrDao  - silly node missing, create one&lt;br /&gt;234832 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly is now of version 4&lt;br /&gt;234832 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource&lt;br /&gt;234832 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Initiating transaction commit&lt;br /&gt;234979 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Creating new transaction with name [ru.sadninja.wijax.silly.SillyDao.read]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT&lt;br /&gt;234979 [http-8084-1] DEBUG ru.sadninja.wijax.silly.SillyJcrDao  - reading...&lt;br /&gt;234980 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly node present&lt;br /&gt;234980 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly is of version 4&lt;br /&gt;234980 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Initiating transaction commit&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you check your &amp;ldquo;dumb&amp;rdquo; table, you'll see a row with id=1 and version=4.&lt;br /&gt;&lt;br /&gt;Now try and put &amp;ldquo;11&amp;rdquo; in the form on the &lt;code&gt;SillyPage&lt;/code&gt;. You should get an error message on the page, and in the output console:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;407268 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Creating new transaction with name [ru.sadninja.wijax.service.CreepyService.updateVersion]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT&lt;br /&gt;407268 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating in existing transaction&lt;br /&gt;407268 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL update&lt;br /&gt;407268 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL statement [update dumb set version=? where id=?]&lt;br /&gt;407268 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource&lt;br /&gt;407270 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Registering transaction synchronization for JDBC Connection&lt;br /&gt;407271 [http-8084-1] DEBUG org.springframework.jdbc.core.JdbcTemplate  - SQL update affected 1 rows&lt;br /&gt;407272 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating in existing transaction&lt;br /&gt;407272 [http-8084-1] DEBUG ru.sadninja.wijax.silly.SillyJcrDao  - saving...&lt;br /&gt;407273 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly is now of version 11&lt;br /&gt;407274 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating in existing transaction&lt;br /&gt;407274 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Participating transaction failed - marking existing transaction as rollback-only&lt;br /&gt;407274 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Setting JTA transaction rollback-only&lt;br /&gt;407274 [http-8084-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource&lt;br /&gt;407274 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Initiating transaction rollback&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, try to hit &amp;ldquo;Back&amp;rdquo; and reload the page. You'll see that the silly version in repository is still &amp;ldquo;4&amp;rdquo;:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;539452 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Creating new transaction with name [ru.sadninja.wijax.silly.SillyDao.read]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT&lt;br /&gt;539452 [http-8084-1] DEBUG ru.sadninja.wijax.silly.SillyJcrDao  - reading...&lt;br /&gt;539453 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly node present&lt;br /&gt;539453 [http-8084-1] INFO  ru.sadninja.wijax.silly.SillyJcrDao  - silly is of version 4&lt;br /&gt;539453 [http-8084-1] DEBUG org.springframework.transaction.jta.JtaTransactionManager  - Initiating transaction commit&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-1250865836396430935?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/1250865836396430935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=1250865836396430935' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/1250865836396430935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/1250865836396430935'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/03/spring-distributed-transactions-across.html' title='Spring: Distributed Transactions across JCR and MySQL Database'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-6421115726385151447</id><published>2009-03-16T20:19:00.006+04:00</published><updated>2009-03-16T20:58:50.792+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='commons-logging'/><title type='text'>Configure Logging in Spring With Log4J</title><content type='html'>Configuring logging for Spring is easy as long as you keep in mind that anything related to classpath is a total mess.&lt;br /&gt;&lt;br /&gt;First, you want to obtain commons-logging and log4j libraries, if you haven't yet put them in server's lib folder or added to the web application.&lt;br /&gt;&lt;br /&gt;Second, create a &lt;code&gt;/WEB-INF/log4j.xml&lt;/code&gt; file with the following content:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE log4j:configuration SYSTEM &amp;quot;log4j.dtd&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;log4j:configuration xmlns:log4j=&amp;quot;http://jakarta.apache.org/log4j/&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;appender name=&amp;quot;console&amp;quot; class=&amp;quot;org.apache.log4j.ConsoleAppender&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;param name=&amp;quot;Target&amp;quot; value=&amp;quot;System.out&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;layout class=&amp;quot;org.apache.log4j.PatternLayout&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;param name=&amp;quot;ConversionPattern&amp;quot; value=&amp;quot;%-4r [%t] %-5p %c %x - %m%n&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/layout&amp;gt;&lt;br /&gt;  &amp;lt;/appender&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;root&amp;gt;&lt;br /&gt;    &amp;lt;priority value =&amp;quot;error&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;/root&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;category name=&amp;quot;org.springframework&amp;quot; additivity=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;priority value=&amp;quot;debug&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;appender-ref ref=&amp;quot;console&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;/category&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/log4j:configuration&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In short, this tells to throw whatever is of error level from all sources, and info- and debug-level messages from anything in &lt;code&gt;org.springframework&lt;/code&gt; package in stdout.&lt;br /&gt;&lt;br /&gt;Then, add the following section to your &lt;code&gt;web.xml&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;  &amp;lt;context-param&amp;gt;&lt;br /&gt;    &amp;lt;param-name&amp;gt;log4jConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;    &amp;lt;param-value&amp;gt;/WEB-INF/log4j.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;  &amp;lt;/context-param&amp;gt;&lt;br /&gt;  &amp;lt;listener&amp;gt;&lt;br /&gt;    &amp;lt;listener-class&amp;gt;org.springframework.web.util.Log4jConfigListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;  &amp;lt;/listener&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As pointed out &lt;a href="http://cristianvrabie.blogspot.com/2008/09/spring-commonslogging-and-log4j.html"&gt;here&lt;/a&gt;, logger &lt;code&gt;Listener&lt;/code&gt; must be declared before &lt;code&gt;ContextLoaderListener&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Now, this seems to be enought, however, at this point many people (judging by the amount of complaints on Spring forums) face the problem of nothing of the described to work.&lt;br /&gt;&lt;br /&gt;This was also the case for me, and the problem was in &lt;code&gt;commons-logging.jar&lt;/code&gt;, which was sitting in %CATALINA_HOME%/lib folder. Once I removed it out of there and added commons-logging library to my web application, the System.out was full of Spring's debug messages.&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-6421115726385151447?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/6421115726385151447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=6421115726385151447' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/6421115726385151447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/6421115726385151447'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/03/configure-logging-in-spring-with-log4j.html' title='Configure Logging in Spring With Log4J'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7804057083306121028</id><published>2009-03-09T20:59:00.002+04:00</published><updated>2009-03-09T21:10:22.587+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='slf4j'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><title type='text'>Enable Debug Level For SLF4J</title><content type='html'>To my shame, I'm absolutely new to logging in Java, and so far I've gone as far as &amp;ldquo;you need to add this to enable debug-level logging in your application&amp;rdquo;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;log4j.rootLogger=DEBUG, stdout&lt;br /&gt;log4j.appender.stdout=org.apache.log4j.ConsoleAppender&lt;br /&gt;log4j.appender.stdout.layout=org.apache.log4j.PatternLayout&lt;br /&gt;log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The exact problem was that despite having that configuration, I actually didn't see any debug printouts emitted by one of the libraries I was using, just the info ones. The reason was that library used SLF4J and was bound to the SLF4J-Simple logger.&lt;br /&gt;&lt;br /&gt;Since I had no time to go ahead and read through the whole SLF4J manual, what I did was removing slf4j-simple.jar and including slf4j2log4j.jar instead.&lt;br /&gt;&lt;br /&gt;And all the debug messages were there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7804057083306121028?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7804057083306121028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7804057083306121028' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7804057083306121028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7804057083306121028'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/03/enable-debug-level-for-slf4j.html' title='Enable Debug Level For SLF4J'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-8249869855018951809</id><published>2009-01-19T16:05:00.004+04:00</published><updated>2009-01-19T16:39:58.118+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='helper'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>symfony's image_tag(): Handle With Care</title><content type='html'>Turns out, symfony's &lt;code&gt;image_tag()&lt;/code&gt; helper is a sucker for memory.&lt;br /&gt;&lt;br /&gt;It takes more than 34 megabytes of memory to render a page displaying a list of about 500 rows, each accompanied by a set of four or five icons, each icon's &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag created by &lt;code&gt;image_tag()&lt;/code&gt; helper, with additional parameters provided like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;image_tag("some_image.png", "alt=Lovely, title=Rita")&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;With those images coded explicitly, rendering takes just 8.5MB. A leak, maybe?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-8249869855018951809?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/8249869855018951809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=8249869855018951809' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8249869855018951809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8249869855018951809'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/01/symfonys-imagetag-handle-with-care.html' title='symfony&apos;s image_tag(): Handle With Care'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-419279915954353255</id><published>2009-01-09T00:02:00.010+04:00</published><updated>2009-01-09T08:08:25.204+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pidgin'/><category scheme='http://www.blogger.com/atom/ns#' term='interface'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='gnome'/><title type='text'>Pidgin's “New IM” Tray Icon</title><content type='html'>I think Pidgin is really one of the best-designed applications for GNOME. It almost looks like its interface was done by Google: nothing extra, just what you need to send and recieve messages. No bluish colours though.&lt;br /&gt;&lt;br /&gt;However, I was a bit surprised once, when changing DPI resolution of the system also changed the Pidgin's tray icon for new instant message from original &lt;img src="http://1322134.com/external/blogger/tray-new-im.png" style="margin-bottom:-6px;border:0;" /&gt; to a smiley: &lt;img src="http://1322134.com/external/blogger/tray-new-im-orig.png"  style="margin-bottom:-6px;border:0;" /&gt;. I actually connected those two events later, when I've found out that Pidgin uses four different sets of tray icons to suit the height of the tray panel.&lt;br /&gt;&lt;br /&gt;Those are stored in &lt;code&gt;/usr/share/pixmaps/pidgin/tray&lt;/code&gt; in four different folders related to the size of the icons. Turns out, the &lt;code&gt;tray-new-im.png&lt;/code&gt; icon in &lt;code&gt;22x22&lt;/code&gt; folder is different from icons in three other folders. There's actually a &lt;a href="http://developer.pidgin.im/ticket/6744"&gt;confirmed bug&lt;/a&gt; for that. But wait, it goes further.&lt;br /&gt;&lt;br /&gt;Not only the 22x22 icon has a smiley instead of an orange dialogue-box, also &amp;laquo;&lt;i&gt;&lt;a href="http://developer.pidgin.im/ticket/6744#comment:3"&gt;speech box part of tray-message.png is white&lt;/a&gt;, instead of having a bluish gradient like the others in 22&lt;/i&gt;&amp;rdquo;. That'd probably be okay with me if it was about an icon in some messy has-version-for-every-os java application like Azureus, but since we're talking about spotless purity of GNOME native app, that's truly an outrage.&lt;br /&gt;&lt;br /&gt;Luckily for everyone, Linux has a very simple way to fix this. Just save an &lt;a href="http://developer.pidgin.im/attachment/ticket/6744/tray-new-im.png"&gt;icon from the bug page&lt;/a&gt; (or you can use the one from the above, they are identical), and replace the one in &lt;code&gt;/usr/share/pixmaps/pidgin/tray/22x22&lt;/code&gt; with it.&lt;br /&gt;&lt;br /&gt;Now you're good to go (well, except for the &lt;code&gt;tray-message.png&lt;/code&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-419279915954353255?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/419279915954353255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=419279915954353255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/419279915954353255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/419279915954353255'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2009/01/pidgins-new-im-tray-icon.html' title='Pidgin&apos;s &amp;ldquo;New IM&amp;rdquo; Tray Icon'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-5126066064357959081</id><published>2008-12-29T23:51:00.003+04:00</published><updated>2008-12-30T00:05:44.315+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unicode'/><category scheme='http://www.blogger.com/atom/ns#' term='regex'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Unicode and preg_replace()</title><content type='html'>When you're dealing with PHP and finally start using unicode instead of whatever non-unicode encodings, you might find a some of your symbols being transformed into rubbish, especially when dealing with non-latin alphabet.&lt;br /&gt;&lt;br /&gt;The answer is to use a &amp;ldquo;u&amp;rdquo; flag in the expression string:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$s = preg_replace('/\s/&lt;b&gt;u&lt;/b&gt;', $s);&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-5126066064357959081?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/5126066064357959081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=5126066064357959081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5126066064357959081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5126066064357959081'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/12/unicode-and-pregreplace.html' title='Unicode and preg_replace()'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7564907776770016676</id><published>2008-12-16T13:50:00.007+04:00</published><updated>2009-03-24T22:27:17.106+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='sfguardplugin'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>sfGuardPlugin: Database Prefix</title><content type='html'>With &lt;a href="http://www.symfony-project.org/"&gt;symfony&lt;/a&gt;, it's kinda funny to search for documentation, since it's widely distributed across &lt;a href="http://trac.symfony-project.org/wiki/"&gt;wiki&lt;/a&gt;, &lt;a href="http://www.symfony-project.org/book/1_1/"&gt;book&lt;/a&gt;, and various external sources, like &lt;a href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3"&gt;Propel website&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That is why when you need something small and easy, but you don't know how to do this, it's usually faster to try that yourself first, search for an answer later. This is actually not the way I prefer to do stuff, so I will share some experiences about how to do small stuff in symfony.&lt;br /&gt;&lt;br /&gt;So, the problem is, I have a single database on my web hosting available. However, I came across a situation where I needed two separate sets of &lt;code&gt;sfGuardUser&lt;/code&gt;-s. To achieve this, I had to go the usual way — add a prefix to the tables.&lt;br /&gt;&lt;br /&gt;All I had to do was to add “prfx_” to all the tables mentioned in &lt;code&gt;&amp;lt;project-name&amp;gt;/plugins/sfGuardPlugin/config/schema.yml&lt;/code&gt; and then rebuild stuff with propel:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;symfony propel:build-all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;or, if you want to keep your existing data, rename tables in database manually, and then...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;symfony propel:build-sql&lt;/code&gt;&lt;br /&gt;&lt;code&gt;symfony propel:build-form&lt;/code&gt;&lt;br /&gt;&lt;code&gt;symfony propel:build-model&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;...and you're set.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7564907776770016676?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7564907776770016676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7564907776770016676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7564907776770016676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7564907776770016676'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/12/sfguardplugin-database-prefix.html' title='sfGuardPlugin: Database Prefix'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-8683945396977882130</id><published>2008-09-03T23:26:00.006+05:00</published><updated>2008-09-03T23:48:34.272+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='browser'/><title type='text'>Google Chrome</title><content type='html'>Ah, I just love this thing.&lt;br /&gt;&lt;br /&gt;Here're just some of the &lt;s&gt;pros&lt;/s&gt; things I really like:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cougar-fast javascript;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Interface leaves it all for the pages &amp;mdash; my normal setup of firefox only has address bar, search bar, tab bar, status bar;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It combines sweet feats from all the browsers: options menu was a lot like Firefox, expandable textareas/inputs are somewhat safarish, &amp;ldquo;most used pages&amp;rdquo; are similar to Opera, etc;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It seems smart (for instance: I don't need to install a separate 250KB extension to open links from tab in the only sane way &amp;mdash; next to parent tab);&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The only bad thing I've noticed so far is that I couldn't turn the spellchecker off. I can't wait to see this thing in Linux. Firefox is too slow, Opera is too ugly, Epiphany is too primitive. Although Chrome might also not be the cure: usually, many Google's apps work not very well in X. Like, Picasa trying to mimick Windows interface looks as ugly as Opera, Google Earth can be very unstable depending on version (probably due to 3D rendering issues). Maybe Chrome won't be following their steps on that.&lt;br /&gt;&lt;br /&gt;Also, it's kinda funny to hear all the &amp;ldquo;this is Google's way of controlling you&amp;rdquo;, &amp;ldquo;Google's way of showing you ads&amp;rdquo;, &amp;ldquo;Google's way of collecting your personal information&amp;rdquo;. In the world, where ninety-five percent of decisions about what to eat, what to wear, what music to listen, what to do after work is dictated by the monster of society, where certain agencies can obtain whatever information they need about whatever person they're interested in about one hour, it's truly sick to blather about privacy in that way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-8683945396977882130?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/8683945396977882130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=8683945396977882130' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8683945396977882130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/8683945396977882130'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/09/google-chrome.html' title='Google Chrome'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-3876764775562963031</id><published>2008-08-20T21:31:00.011+05:00</published><updated>2009-03-24T20:24:03.394+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='injection'/><category scheme='http://www.blogger.com/atom/ns#' term='jndi'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Wicket + Spring (with JDBC) Configuration</title><content type='html'>In the next several paragraphs of symbols, I'll explain how to configure Spring and Wicket frameworks to work together, and even how to use &lt;code&gt;JdbcDaoSupport&lt;/code&gt;, Spring's nice and handy JDBC tool.&lt;br /&gt;&lt;br /&gt;I prefer not to deal with automatic configurations generated by Wicket or Spring IDE plugins, but to create the application from scratch. I will be using the NetBeans IDE. In a nutshell, all we'll have to do, is download some libraries, put some of them in Tomcat's &lt;code&gt;lib&lt;/code&gt; folder, the rest in the classpath, and make a couple of modifications to &lt;code&gt;web.xml&lt;/code&gt; and &lt;code&gt;applicationContext.xml&lt;/code&gt; files.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Libraries&lt;/h3&gt;&lt;br /&gt;First of all, you will need &lt;a href="http://www.apache.org/dyn/closer.cgi/wicket/1.3.4"&gt;Wicket&lt;/a&gt; and &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=73357&amp;package_id=173644&amp;release_id=608794"&gt;Spring&lt;/a&gt; libraries. If you download Spring with all dependencies, most probably, you won't have to download anything else (except &lt;code&gt;mysql-connector&lt;/code&gt;, if you don't already have it).&lt;br /&gt;&lt;br /&gt;Specific jars are:&lt;br /&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;aspectjrt-1.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;cglib-nodep-2.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;log4j-1.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;slf4j-api-1.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;slf4j-log4j12-1.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;spring-2.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;wicket-1.3.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;wicket-ioc-1.3.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;wicket-spring-1.3.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;wicket-spring-annot-1.3.x.jar&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Those jars listed above you should add to the libraries of your NetBeans project.&lt;br /&gt;&lt;br /&gt;These three you have to put in &lt;code&gt;$CATALINA_HOME/lib&lt;/code&gt; folder. Don't put them in classpath unless you've got several hours to find out why doesn't anything work.&lt;br /&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;commons-logging-1.1.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;ehcache-1.2.x.jar&lt;/code&gt;&lt;br /&gt;&amp;mdash; &lt;code&gt;mysql-connector-java-5.1.x-bin.jar&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;context.xml&lt;/h3&gt;&lt;br /&gt;Hope you've already created a NetBeans project and selected a &amp;ldquo;Web Application&amp;rdquo; at certain point.&lt;br /&gt;&lt;br /&gt;First thing to do, is describe a database resource so we could access it via JNDI. To do this, put in the &lt;code&gt;META-INF/context.xml&lt;/code&gt; something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;Context path="/Chicago"&amp;gt;&lt;br /&gt;  &amp;lt;!-- database resource --&amp;gt;&lt;br /&gt;      &amp;lt;Resource&lt;br /&gt;        name="jdbc/Chicago"&lt;br /&gt;        auth="Container"&lt;br /&gt;        driverClassName="com.mysql.jdbc.Driver"&lt;br /&gt;        type="javax.sql.DataSource"&lt;br /&gt;&lt;br /&gt;        username="database_user"&lt;br /&gt;        password="database_pass"&lt;br /&gt;        url="jdbc:mysql://localhost/my_database"&lt;br /&gt;        &lt;br /&gt;        maxWait="10000"&lt;br /&gt;        maxActive="60"&lt;br /&gt;        minIdle = "0"&lt;br /&gt;        maxIdle="30"&lt;br /&gt;&lt;br /&gt;        removeAbandoned="true"&lt;br /&gt;        removeAbandonedTimeout="120"&lt;br /&gt;&lt;br /&gt;        testOnBorrow="false"&lt;br /&gt;        testOnReturn="false"&lt;br /&gt;        testWhileIdle="true"&lt;br /&gt;        validationQuery="SELECT 1"&lt;br /&gt;        timeBetweenEvictionRunsMillis="59000"&lt;br /&gt;        minEvictableIdleTimeMillis="58000"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;&amp;lt;/Context&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Such resource configuration will tell your servlet container (namely, Tomcat) to keep alive JDBC connections and reconnect to avoid IO exceptions when connection isn't being used for a long time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;applicationContext.xml&lt;/h3&gt;&lt;br /&gt;You will now have to create a &lt;code&gt;WEB-INF/applicationContext.xml&lt;/code&gt; file for Spring configuration.&lt;br /&gt;&lt;br /&gt;Here's what you might want to put there:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"&amp;gt;&lt;br /&gt;&amp;lt;beans&amp;gt;&lt;br /&gt;    &amp;lt;bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&amp;gt;&lt;br /&gt;        &amp;lt;property name="jndiName" value="java:comp/env/jdbc/Chicago"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;!-- Wicket WebApplication setup --&amp;gt;&lt;br /&gt;    &amp;lt;bean id="wicketApplication" class="com.mycorp.chicago.ChicagoApplication"&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;  &lt;br /&gt;    &amp;lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&amp;gt;&lt;br /&gt;            &amp;lt;property name="dataSource" ref="dataSource"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;bean id="userDaoTarget" class="com.mycorp.chicago.user.JdbcUserDao"&amp;gt;&lt;br /&gt;        &amp;lt;property name="dataSource" ref="dataSource"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;bean id="userDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&amp;gt;&lt;br /&gt;            &amp;lt;property name="transactionManager" ref="transactionManager" /&amp;gt;&lt;br /&gt;            &amp;lt;property name="proxyTargetClass" value="true"/&amp;gt;&lt;br /&gt;            &amp;lt;property name="target" ref="userDaoTarget" /&amp;gt;&lt;br /&gt;            &amp;lt;property name="transactionAttributes"&amp;gt;&lt;br /&gt;              &amp;lt;props&amp;gt;&lt;br /&gt;                &amp;lt;prop key="save"&amp;gt;PROPAGATION_REQUIRED,-Exception&amp;lt;/prop&amp;gt;&lt;br /&gt;                &amp;lt;prop key="*"&amp;gt;PROPAGATION_REQUIRED,-Exception,readOnly&amp;lt;/prop&amp;gt;&lt;br /&gt;              &amp;lt;/props&amp;gt;&lt;br /&gt;            &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What we just did there,&lt;br /&gt;&lt;br /&gt;a) configured a &lt;code&gt;dataSource&lt;/code&gt; object which is used in &lt;code&gt;JdbcDaoSupport&lt;/code&gt;, to lookup database resource via JNDI;&lt;br /&gt;&lt;br /&gt;b) told Spring to use Acegi filter on HTTP requests (Acegi is Spring's security framework, we'll deal with it in the next episode);&lt;br /&gt;&lt;br /&gt;c) created a proxy DAO bean.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;web.xml&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;We now must ask container to invoke Spring filter on certain requests. This is what we do in &lt;code&gt;WEB-INF/web.xml&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&amp;gt;&lt;br /&gt;    &amp;lt;display-name&amp;gt;Lianet Application&amp;lt;/display-name&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;context-param&amp;gt;&lt;br /&gt;        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;        &amp;lt;param-value&amp;gt;/WEB-INF/applicationContext.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;    &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;filter&amp;gt;&lt;br /&gt;        &amp;lt;filter-name&amp;gt;Spring Application Factory Filter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;        &amp;lt;filter-class&amp;gt;org.apache.wicket.protocol.http.WicketFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;        &amp;lt;init-param&amp;gt;&lt;br /&gt;            &amp;lt;param-name&amp;gt;applicationFactoryClassName&amp;lt;/param-name&amp;gt;&lt;br /&gt;            &amp;lt;param-value&amp;gt;org.apache.wicket.spring.SpringWebApplicationFactory&amp;lt;/param-value&amp;gt;&lt;br /&gt;        &amp;lt;/init-param&amp;gt;&lt;br /&gt;    &amp;lt;/filter&amp;gt;    &lt;br /&gt;&lt;br /&gt;    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;        &amp;lt;filter-name&amp;gt;Spring Application Factory Filter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;        &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;&lt;br /&gt;        &amp;lt;dispatcher&amp;gt;ERROR&amp;lt;/dispatcher&amp;gt;&lt;br /&gt;    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;UserDao.java and JdbcUserDao.java&lt;/h3&gt;&lt;br /&gt;For Spring injection to work, we create an interface of the DAO and its JDBC implementation. These I will keep in &lt;code&gt;com.mycorp.chicago.user&lt;/code&gt; package.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/*&lt;br /&gt; * &lt;b&gt;UserDao.java&lt;/b&gt;&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package com.mycorp.chicago.user;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public interface UserDao extends Serializable /* UserDetailsService */ {&lt;br /&gt;    &lt;br /&gt;    public void test();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*&lt;br /&gt; * &lt;b&gt;JdbcUserDao.java&lt;/b&gt;&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package com.mycorp.chicago.user;&lt;br /&gt;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;import org.springframework.jdbc.core.RowMapper;&lt;br /&gt;import org.springframework.jdbc.core.support.JdbcDaoSupport;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class JdbcUserDao extends JdbcDaoSupport implements UserDao {&lt;br /&gt;&lt;br /&gt;    public void test() {&lt;br /&gt;        getJdbcTemplate().query("SELECT name FROM my_table WHERE id=1", new RowMapper() {&lt;br /&gt;&lt;br /&gt;            public Object mapRow(ResultSet rs, int rowNum) throws SQLException {&lt;br /&gt;                String name = rs.getString("name");&lt;br /&gt;                System.out.println("Got object name: " + name);&lt;br /&gt;                return null;&lt;br /&gt;            }&lt;br /&gt;            &lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You probably have already got the idea that to have all the preceding work, you'll need a MySQL database &amp;ldquo;my_database&amp;rdquo; with a &amp;ldquo;my_table&amp;rdquo; table with the latter consisting of at least an integer `id` and a &lt;code&gt;varchar&lt;/code&gt; `name` fields.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;IndexPage.java&lt;/h3&gt;&lt;br /&gt;Now let's inject our brand new &lt;code&gt;UserDao&lt;/code&gt; in some Wicket component. Say, an index page of the app. I'll put it in the &lt;code&gt;com.mycorp.chicago.web.page&lt;/code&gt; package.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/*&lt;br /&gt; * Index.java&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package com.mycorp.chicago.web.page;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;import org.apache.wicket.spring.injection.annot.SpringBean;&lt;br /&gt;import com.mycorp.chicago.user.UserDao;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Main page of the application.&lt;br /&gt; */&lt;br /&gt;public class IndexPage extends WebPage {&lt;br /&gt;&lt;br /&gt;   @SpringBean(name="userDao")&lt;br /&gt;   private UserDao userDao;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    public IndexPage() {&lt;br /&gt;        add(new Label("sampleLabel", "This is a text which is also a model."));&lt;br /&gt;        userDao.test();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;IndexPage.html&lt;/h3&gt;&lt;br /&gt;By default, HTML template is stored along with the java source.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;span wicket:id="sampleLabel"&amp;gt;Sample label&amp;lt;/span&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;ChicagoApplication.java&lt;/h3&gt;&lt;br /&gt;Now all that is left is the actual &lt;code&gt;WebApplication&lt;/code&gt; of Wicket.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/*&lt;br /&gt; * ChicagoApplication.java&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;package com.mycorp.chicago;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.protocol.http.WebApplication;&lt;br /&gt;import org.apache.wicket.spring.injection.annot.SpringComponentInjector;&lt;br /&gt;import com.mycorp.chicago.web.page.IndexPage;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class ChicagoApplication extends WebApplication {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Class getHomePage() {&lt;br /&gt;        return IndexPage.class;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public void init() {&lt;br /&gt;        super.init();&lt;br /&gt;        addComponentInstantiationListener(new SpringComponentInjector(this));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Enjoy&lt;/h3&gt;&lt;br /&gt;That's it. Now all that is left is to hit &lt;i&gt;F6&lt;/i&gt; button and wait for results. If you get a &lt;code&gt;ClassNotFound&lt;/code&gt; exception, you probably forgot to add certain library. Wicket runtime exceptions are usually easy to fix since Wicket is very verbose in development mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-3876764775562963031?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/3876764775562963031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=3876764775562963031' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/3876764775562963031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/3876764775562963031'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/08/wicket-spring-with-jdbc-configuration.html' title='Wicket + Spring (with JDBC) Configuration'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7164090924857046725</id><published>2008-08-18T15:11:00.004+05:00</published><updated>2008-08-18T15:57:49.574+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jackrabbit'/><category scheme='http://www.blogger.com/atom/ns#' term='rmi'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='jndi'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Jackrabbit on JBoss with JNDI &amp; RMI</title><content type='html'>We recently decided to use &lt;a href="http://en.wikipedia.org/wiki/Content_repository_API_for_Java"&gt;JCR&lt;/a&gt;, specifically, it's Apache implementation, JackRabbit. What's already done, is a web application running on Tomcat servlet container. One of the most obvious ways to tie those two, is to deploy JackRabbit on JBoss and expose it via JNDI.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin-bottom: 0;"&gt;Configuring JBoss Server&lt;/h3&gt;&lt;br /&gt;First, you need to download &lt;a href="http://www.jboss.org/jbossas/downloads/"&gt;JBoss Application Server&lt;/a&gt;. Its installation in Ubuntu is as easy as extracting the downloaded jar/zip to the directory where you want JBoss to sit, and &lt;a href="http://www.jboss.org/file-access/default/members/jbossas/freezone/docs/Installation_Guide/beta422/html/setting_JBOSS_HOME.html"&gt;setting&lt;/a&gt; the &lt;code&gt;JBOSS_HOME&lt;/code&gt; variable to that directory in &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;To deploy JackRabbit, you need to obtain &lt;code&gt;jackrabbit-jca.rar&lt;/code&gt; and &lt;code&gt;jackrabbit-rmi.jar&lt;/code&gt; from &lt;a href="http://jackrabbit.apache.org/downloads.html"&gt;JackRabbit downloads page&lt;/a&gt; and &lt;code&gt;&lt;a href="http://jcp.org/aboutJava/communityprocess/final/jsr170/index.html"&gt;jcr-1.0.jar&lt;/a&gt;&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; The &lt;i&gt;.rar archive contains all JackRabbit dependencies&lt;/i&gt;, including &lt;code&gt;concurrent.jar&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;You will also need to download the &lt;a href="http://svn.apache.org/repos/asf/jackrabbit/branches/1.4/jackrabbit-jca/deploy/jboss/4.x/jcr-ds.xml"&gt;jcr-ds.xml&lt;/a&gt;. Edit the file so the &lt;code&gt;&amp;lt;rar-name&amp;gt;jackrabbit-jca.rar&amp;lt;/rar-name&amp;gt;&lt;/code&gt; property would contain the actual name of the rar you've downloaded (I had &lt;code&gt;jackrabbit-jca-1.4.rar&lt;/code&gt;) and the &lt;code&gt;homeDir&lt;/code&gt; property would point to the directory where you want JackRabbit to store its stuff.&lt;br /&gt;&lt;br /&gt;To complete deployment, you now need to put &lt;code&gt;jackrabbit-jca.rar&lt;/code&gt;, &lt;code&gt;jackrabbit-rmi.jar&lt;/code&gt; and &lt;code&gt;jcr-ds.xml&lt;/code&gt; files to &lt;code&gt;$JBOSS_HOME/server/default/deploy&lt;/code&gt; and &lt;code&gt;jcr-1.0.jar&lt;/code&gt; to &lt;code&gt;$JBOSS_HOME/server/default/lib&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; Apparently, you should be careful about renaming the &lt;code&gt;jcr-ds.xml&lt;/code&gt; file. I tried to name it &amp;ldquo;jcr-ds-1.4.xml&amp;rdquo; and kept getting JackRabbit deployed incompletely. Once I renamed it back to &amp;ldquo;jcr-ds.xml&amp;rdquo;, everything went smoothly.&lt;br /&gt;&lt;br /&gt;To start JBoss, do &lt;code&gt;$JBOSS_HOME/bin/run.sh&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="margin-bottom: 0;"&gt;Configuring Client&lt;/h3&gt;&lt;br /&gt;Now you might wanna check your JCR repository. You will need to create a simple function I found in the &lt;a href="http://www.mail-archive.com/users@jackrabbit.apache.org/msg02723.html"&gt;mail archive&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private static Session getJackrabbitSession() throws RepositoryException {&lt;br /&gt;    Properties env = new Properties();&lt;br /&gt;    env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");&lt;br /&gt;    env.put(Context.PROVIDER_URL, "jnp://localhost:1099");&lt;br /&gt;    env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");&lt;br /&gt;    &lt;br /&gt;    try {&lt;br /&gt;        InitialContext ctx = new InitialContext(env);&lt;br /&gt;        ClientAdapterFactory adapter = new ClientAdapterFactory();&lt;br /&gt;        RemoteRepository rr;&lt;br /&gt;        rr = (RemoteRepository) ctx.lookup("jnp://localhost:1099/jcrServer");&lt;br /&gt;        Repository repository = adapter.getRepository(rr);&lt;br /&gt;        Credentials credJBoss = new SimpleCredentials("username", "password".toCharArray());&lt;br /&gt;        return repository.login(credJBoss);&lt;br /&gt;    } catch (NamingException ex) {&lt;br /&gt;        ex.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    return null;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For that code to work, you will need &lt;code&gt;jcr-1.0.jar&lt;/code&gt;, &lt;code&gt;jackrabbit-jcr-rmi.jar&lt;/code&gt;, &lt;code&gt;jnp-client.jar&lt;/code&gt; and &lt;code&gt;jboss-common.jar&lt;/code&gt; libraries in your classpath. The latter two can be found in &lt;code&gt;$JBOSS_HOME/client&lt;/code&gt; and &lt;code&gt;$JBOSS_HOME/lib&lt;/code&gt; respectively.&lt;br /&gt;&lt;br /&gt;If you've done everything correct, and are lucky enough, the &amp;ldquo;&lt;a href="http://jackrabbit.apache.org/first-hops.html"&gt;first hops&lt;/a&gt;&amp;rdquo; from Jackrabbit introduction should work fine, with appropriate changes to obtaining &lt;code&gt;Session&lt;/code&gt; object done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7164090924857046725?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7164090924857046725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7164090924857046725' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7164090924857046725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7164090924857046725'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/08/jackrabbit-on-jboss-with-jndi-rmi.html' title='Jackrabbit on JBoss with JNDI &amp; RMI'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7878913941764823260</id><published>2008-07-29T21:56:00.004+05:00</published><updated>2008-07-29T22:19:08.535+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='unicode'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Deploying Django Project on Ubuntu Server</title><content type='html'>I've recently had to deploy a pretty simple Django application on Ubuntu server, and here're a few tips for myself in the future doing this once again.&lt;br /&gt;&lt;br /&gt;For starters, there's a &lt;a href="http://www.jeffbaier.com/2007/07/26/installing-django-on-an-ubuntu-linux-server/"&gt;Jeff Baier's tutorial&lt;/a&gt; which covers most steps. There're, however, a couple of things I had to learn the hard way.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;First&lt;/b&gt;, if you wish to use a stable version of Django, instead of dealing with subversion and compilation, just install it from repositories:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install python-django&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you do so, your admin media will be in the following directory:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;/usr/share/python-support/python-django/django/contrib/admin/media&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Second&lt;/b&gt;, in your .py files don't use relative imports. If you have a project named “project_one” and two applications, “app_one” and “app_two” applications, this will work on local django server, but won't work in production:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;import app_one.Something&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instead, you must always do&lt;br /&gt;&lt;br /&gt;&lt;code&gt;import project_one.app_one.Something&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Third&lt;/b&gt;, mind the paths to your media files. It's better to adjust them before deployment so they look the same on your development localhost and production server, otherwise you might have problems during deployment.&lt;br /&gt;&lt;br /&gt;I'm mentioning this here because django's default recommended media/admin-media url configuration is somewhat doesn't makes this easier.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finally&lt;/b&gt;, keep in mind that out-of-the-box MySQL databases are not UTF-8 which is not very good if you have any language in db besides English. Unless you won't &lt;a href="http://parand.com/say/index.php/2008/06/11/djangomysql-how-to-fix-unicode-aka-mysterious-question-marks/"&gt;unicode-enable your MySQL server&lt;/a&gt; before you create your tables structure, you will have to change encoding of all the tables after.&lt;br /&gt;&lt;br /&gt;Pretty much that is it, which actually seems really smooth deployment process to me, so another score for Django.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7878913941764823260?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7878913941764823260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7878913941764823260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7878913941764823260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7878913941764823260'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/07/deploying-django-project-on-ubuntu.html' title='Deploying Django Project on Ubuntu Server'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-6907969459390500201</id><published>2008-06-03T14:08:00.003+05:00</published><updated>2008-06-03T14:15:05.968+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='odbc'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='mssql'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>MSSQL + PHP in Ubuntu 8.04</title><content type='html'>Following comments to &lt;a href="http://pintmaster.com/20060530/how-to-compile-mssql-support-into-php-in-ubuntu-dapper-drake/"&gt;this post&lt;/a&gt;, I got MS SQL working with PHP.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ apt-get install freetds-dev tdsodbc php5-sybase&lt;/code&gt;&lt;br /&gt;&lt;code&gt;$ nano /etc/odbcinst.ini&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;[FreeTDS]&lt;br /&gt;Description = FreeTDS 0.61-5 Deb&lt;br /&gt;Driver = /usr/lib/odbc/libtdsodbc.so&lt;br /&gt;Setup = /usr/lib/odbc/libtdsS.so&lt;br /&gt;FileUsage = 1&lt;br /&gt;CPTimeout = 5&lt;br /&gt;CPReuse = 5&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ nano /etc/odbc.ini&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;[Products]&lt;br /&gt;Description = Products on The MSSQL Server&lt;br /&gt;Driver = FreeTDS&lt;br /&gt;Servername = FSData&lt;br /&gt;Database = Products&lt;br /&gt;Port = 1433&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-6907969459390500201?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/6907969459390500201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=6907969459390500201' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/6907969459390500201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/6907969459390500201'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/06/mssql-php-in-ubuntu-804.html' title='MSSQL + PHP in Ubuntu 8.04'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7285254501572098543</id><published>2008-05-21T16:29:00.003+05:00</published><updated>2008-05-21T17:30:16.820+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gimp'/><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='highlights'/><category scheme='http://www.blogger.com/atom/ns#' term='photoshop'/><title type='text'>A Lame Way To Clip Skin Highlights</title><content type='html'>I'm no professional or even advanced-amateur photographer, but sometimes people ask me to make photos. Since I do suck at that, and I don't have my own studio stuffed with lights, softboxes and stuff, I often take photos of people poorly lit with lots of highlights on their skin. There's a lame way to remove those.&lt;br /&gt;&lt;br /&gt;I'm not sure if it's possible to achieve this using just curves or levels, here's how I do it.&lt;br /&gt;&lt;br /&gt;1. Go to Levels and move the center slider to the right as far as neccessary so highlighted areas turn white and not-so-highlighted areas turn dark. Sometimes instead of moving center slider, you will need to gather black, white and center slide in the middle.&lt;br /&gt;&lt;br /&gt;2. Increase Contrast until you have a dark background with islands of white highlighted areas. Sometimes background is completely black, and you can just delete it after magic wand selection. Sometimes you need to select white by colour and delete inverted selection.&lt;br /&gt;&lt;br /&gt;3. Fill alhpa-selection of remaining areas with skin colour you can pick from not-highlighted parts. Depending on different parts of face illumination, you may want to fill highlighted areas with different colours.&lt;br /&gt;&lt;br /&gt;4. The next is up to blur and opacity tuning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7285254501572098543?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7285254501572098543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7285254501572098543' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7285254501572098543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7285254501572098543'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/05/lame-way-to-clip-skin-highlights.html' title='A Lame Way To Clip Skin Highlights'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-4606731118185082401</id><published>2008-05-01T00:49:00.008+05:00</published><updated>2008-08-18T18:28:52.563+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardy heron'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='ndiswrapper'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu 8.04 Wireless</title><content type='html'>I googled out the wireless/ndiswrapper problem. The solution, quoting Ankur Srivastava's &lt;a href="http://ankurs.com/2008/04/installing-ndiswrapper-on-ubuntu-804/"&gt;blog post&lt;/a&gt;, is as simple as this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ nano /etc/rc.local&lt;/code&gt;&lt;br /&gt;then put&lt;br /&gt;&lt;code&gt;rmmod ssb&lt;br /&gt;modprobe ndiswrapper&lt;/code&gt;&lt;br /&gt;before &lt;code&gt;exit 0&lt;/code&gt;...&lt;br /&gt;...then&lt;br /&gt;&lt;code&gt;$ shutdown -r now&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And your wireless is there.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; Apparently, these actions aren't needed if you're using kernel 2.6.24-17. After update from 8.04 original 2.6.24-16, wireless had not worked until I removed those lines from &lt;code&gt;rc.local&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-4606731118185082401?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/4606731118185082401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=4606731118185082401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/4606731118185082401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/4606731118185082401'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/05/ubuntu-saga-continued.html' title='Ubuntu 8.04 Wireless'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-887999852019584223</id><published>2008-04-24T13:27:00.006+05:00</published><updated>2008-04-24T14:23:38.811+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Last Insert Id Without Extra SELECT in Spring</title><content type='html'>If you have a table with &lt;code&gt;auto_increment&lt;/code&gt; for an &lt;code&gt;id&lt;/code&gt;, you often need to get this id immediately after a new instance has been created.&lt;br /&gt;&lt;br /&gt;The easy way to do this is to perform a &lt;code&gt;SELECT LAST_INSERT_ID()&lt;/code&gt; query. However, most of the time you want as less database requests as possible. There is a way to avoid &lt;code&gt;LAST_INSERT_ID()&lt;/code&gt; code using Spring's JDBC support.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;final String DEF_INSERT_USER_QUERY = "insert into users (username, password) values (?,?)";&lt;br /&gt;final String firstname = createdUser.getFirstname();&lt;br /&gt;final String lastname = createdUser.getLastname();&lt;br /&gt;&lt;br /&gt;KeyHolder keyHolder = new GeneratedKeyHolder();&lt;br /&gt;getJdbcTemlpate().update(new PreparedStatementCreator() {&lt;br /&gt;  public PreparedStatement createPreparedStatement(Connection connection)&lt;br /&gt;    throws SQLException {&lt;br /&gt;   PreparedStatement ps = connection.prepareStatement(DEF_INSERT_USER_QUERY,&lt;br /&gt;     new String[] {"firstname", "lastname"});&lt;br /&gt;   ps.setString(1, firstname);&lt;br /&gt;   ps.setString(2, lastname);&lt;br /&gt;   return ps;&lt;br /&gt; }&lt;br /&gt;}, keyHolder);&lt;br /&gt;&lt;br /&gt;createdUser.setId(keyHolder.getKey().intValue());&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-887999852019584223?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/887999852019584223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=887999852019584223' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/887999852019584223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/887999852019584223'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/04/last-insert-id-without-extra-select-in.html' title='Last Insert Id Without Extra SELECT in Spring'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-5422360799867044218</id><published>2008-04-16T01:27:00.003+05:00</published><updated>2008-04-16T01:36:07.531+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='j2ee'/><title type='text'>Change J2EE version of NetBeans Project</title><content type='html'>A java project I've been working was initially started as J2EE1.4 one, but finally had to be moved to J2EE5. Apparently, there's no GUI way to do this in NetBeans (nor 6 neither 5.5).&lt;br /&gt;&lt;br /&gt;When you select Project-&gt;Properties-&gt;Run, J2EE version is just displayed in a text field which value I couldn't change. Maybe this is a bug of NetBeans, maybe this is an intentional limitation.&lt;br /&gt;&lt;br /&gt;Anyway, after some painful hours spent in moving classes and configs into a newly created J2EE5 project and fighting errors popped, I just took an advice of a fellow developer, checked how things are done in &lt;code&gt;project.properties&lt;/code&gt; file and put &lt;code&gt;j2ee.version=1.5&lt;/code&gt; instead of &lt;code&gt;1.4&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-5422360799867044218?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/5422360799867044218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=5422360799867044218' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5422360799867044218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5422360799867044218'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/04/change-j2ee-version-of-netbeans-project.html' title='Change J2EE version of NetBeans Project'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-7801312299673095559</id><published>2008-04-07T04:55:00.004+05:00</published><updated>2008-04-07T05:15:30.474+05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Firefox Memory Management Mystery</title><content type='html'>Firefox's appetite for memory is a well-known problem, especially in the latest 2.0.x versions. However, I never experienced it while I was using it on Windows. The browser never ate more than one and a half hundred megabytes. &lt;br /&gt;&lt;br /&gt;I started to suffer from it only when I switched to Ubuntu a couple years ago. In fact, latest version with all the plugins (TMP+Firebug+Webdeveloper+DownThemAll) enabled, consumed up to four hundred megabytes of RAM so I even had to switch to Epiphany to be able to keep other greedy processes running.&lt;br /&gt;&lt;br /&gt;But now, on the HP laptop with the same Ubuntu 7.10 the same Firefox 2.0.0.13 acts as it did in the Windows days &amp;mdash; one and a half hundred megs no matter how many pages are opened.&lt;br /&gt;&lt;br /&gt;I guess, this mystery will never be unriddled.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-7801312299673095559?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/7801312299673095559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=7801312299673095559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7801312299673095559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/7801312299673095559'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/04/firefox-memory-management-mystery.html' title='Firefox Memory Management Mystery'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-5766634282717562562</id><published>2008-03-12T18:15:00.005+04:00</published><updated>2008-04-07T13:10:51.935+05:00</updated><title type='text'>“Not A Fish” Method Actually Works</title><content type='html'>There's this article on Wired about &lt;a href="http://blog.wired.com/wiredscience/2008/02/evolution-expla.html"&gt;how you can stop hiccups&lt;/a&gt; by &amp;ldquo;reminding yourself that you're not a fish&amp;rdquo;. I'm not sure if anyone from comments actually believed in it, but ow-emm-gee, it works perfectly.&lt;br /&gt;&lt;br /&gt;Just now I had hiccups which had stopped the second I told myself: &amp;ldquo;hey, I'm not a fish, I have no gills&amp;rdquo;. Science indeed works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-5766634282717562562?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/5766634282717562562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=5766634282717562562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5766634282717562562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5766634282717562562'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/03/fish-method-actually-works.html' title='&amp;ldquo;Not A Fish&amp;rdquo; Method Actually Works'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-339046021231985504</id><published>2008-02-28T18:07:00.008+04:00</published><updated>2008-02-28T20:59:14.355+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>100% Height Div in Firefox</title><content type='html'>It was a surprise for me to find out that this is actually a problem with tricks and hacks involved.&lt;br /&gt;&lt;br /&gt;Once I wanted to make 100% height div, I've found lots of “solutions”, all of which were either ie-only or involved render the div as a table cell or caused it to be exactly 100% of the screen height, ignoring the height of the actual content (which might be bigger), or caused scrollbar to appear even though content was fitting in one screen.&lt;br /&gt;&lt;br /&gt;Although none of the solutions was perfect, when properly combined they actually do the thing.&lt;br /&gt;&lt;br /&gt;General concepts are:&lt;br /&gt;&amp;mdash; Make &lt;i&gt;html&lt;/i&gt; and &lt;i&gt;body&lt;/i&gt; elements 100% high to allow inner blocks height setup;&lt;br /&gt;&amp;mdash; Set container's height to auto and min-height to 100% to avoid content overflow;&lt;br /&gt;&amp;mdash; Don't put content in the container itself but use it as a wrapper to allow padding without scrollbar&lt;br /&gt;&lt;br /&gt;So here it goes: &lt;a href="http://1322134.com/code/100div/"&gt;100% height div for both IE and Firefox&lt;/a&gt;.&lt;br /&gt;View source to see how it's done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-339046021231985504?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/339046021231985504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=339046021231985504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/339046021231985504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/339046021231985504'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/02/100-height-div-in-firefox.html' title='100% Height Div in Firefox'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-5857130557334638896</id><published>2008-02-27T04:46:00.002+04:00</published><updated>2008-02-29T10:27:20.319+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>«Connection is read-only» Exception</title><content type='html'>I've ran into funny exception recently. I've a function updating database table using Spring's &lt;code&gt;JdbcTemplate&lt;/code&gt; and for some reason there was this exception:&lt;br /&gt;&lt;code language="java"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed&lt;br /&gt;   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1056)&lt;br /&gt;   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)&lt;br /&gt;   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)&lt;br /&gt;   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1973)&lt;br /&gt;   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1940)&lt;br /&gt;   at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1925)&lt;br /&gt;   at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101)&lt;br /&gt;   at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:773)&lt;br /&gt;   at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:566)&lt;br /&gt;   at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:767)&lt;br /&gt;   at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:825)&lt;br /&gt;   at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:833)&lt;br /&gt;   at com.myapplication.user.JdbcUserDao.saveData(JdbcUserDao.java:511)&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There wasn't much about it on the Internet, but apparently, the problem occures when the &lt;code&gt;JdbcUserDao&lt;/code&gt; is configured as proxy bean and &lt;code&gt;saveData&lt;/code&gt; method (or any other method making updates to database) is missing its &lt;code&gt;PROPAGATION_REQUIRED&lt;/code&gt; flag in the &lt;code&gt;applicationContext.xml&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-5857130557334638896?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://th1rty7.blogspot.com/feeds/5857130557334638896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8941320698391889475&amp;postID=5857130557334638896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5857130557334638896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/5857130557334638896'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/02/connection-is-read-only-exception.html' title='«Connection is read-only» Exception'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8941320698391889475.post-3944900000120867166</id><published>2008-02-26T01:00:00.001+04:00</published><updated>2008-02-29T10:40:44.662+04:00</updated><title type='text'>***</title><content type='html'>This blog will probably mostly consist of solutions for coding problems I've faced but for which I couldn't find direct answers on the Internet. &lt;br /&gt;&lt;br /&gt;Googling the problem is the first thing I do after I can't figure it out for myself, and usually there's a blog post entitled with exact same words I used as a search query. In most cases that post solves the problem, but sometimes Google has nothing to offer (yes, even on the second page).&lt;br /&gt;&lt;br /&gt;After several hours (or minutes) of hard (or enjoyable) work, the problem is solved and I can share my explorations with people all over the world. Although most likely I'll share them with myself a couple weeks later since I'm so forgetful.&lt;br /&gt;&lt;br /&gt;Anyway, I guess it is now clear why this way of blogging looks like putting missing pieces of the puzzle in place for me.&lt;br /&gt;&lt;br /&gt;Since now I am still in the beginning of the long way of all sorts of coding, some things may seem unwise, but again, I prefer to think of this as of some sort of draft notebook used just to keep random instructions, links or thoghts in one place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8941320698391889475-3944900000120867166?l=th1rty7.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/3944900000120867166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8941320698391889475/posts/default/3944900000120867166'/><link rel='alternate' type='text/html' href='http://th1rty7.blogspot.com/2008/02/blog-post.html' title='***'/><author><name>sp</name><uri>http://www.blogger.com/profile/03114937752791835564</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
