<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>mikwat code</title>
	<atom:link href="http://code.mikwat.com/feed" rel="self" type="application/rss+xml" />
	<link>http://code.mikwat.com</link>
	<description>A coder's daily explorations through PHP, Java, CSS, JavaScript, Linux, OS X, Apache, Tomcat, and everything else.</description>
	<pubDate>Wed, 20 Feb 2008 22:14:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>SSH Tunnel in OS X</title>
		<link>http://code.mikwat.com/archives/26</link>
		<comments>http://code.mikwat.com/archives/26#comments</comments>
		<pubDate>Wed, 20 Feb 2008 22:13:28 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/26</guid>
		<description><![CDATA[Open tunnel:

$ ssh -L 8080:remote-host:80 -f -C -q -N me@myserver.com

Close tunnel:

$ ps -aux &#124; grep ssh
$ kill {pid}

]]></description>
			<content:encoded><![CDATA[<p>Open tunnel:<br />
<code><br />
$ ssh -L 8080:remote-host:80 -f -C -q -N me@myserver.com<br />
</code></p>
<p>Close tunnel:<br />
<code><br />
$ ps -aux | grep ssh<br />
$ kill {pid}<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/26/feed</wfw:commentRss>
		</item>
		<item>
		<title>Quartz + Spring + Hibernate with JDBC Job Store</title>
		<link>http://code.mikwat.com/archives/24</link>
		<comments>http://code.mikwat.com/archives/24#comments</comments>
		<pubDate>Thu, 04 Oct 2007 23:25:15 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[hibernate]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[quartz]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/24</guid>
		<description><![CDATA[Here is how I configured Quartz to work with Spring and Hibernate.  I&#8217;m using the Quartz JDBC Job Store which stores and retrieves the job settings from a database instead of a static configuration.
I use the SchedulerFactoryBean to manager the Quartz Scheduler lifecycle.
spring-servlet.xml

...
	&#60;!-- Quartz --&#62;
	&#60;bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&#62;
		&#60;property name="applicationContextSchedulerContextKey" value="applicationContext"/&#62;
		&#60;property name="configLocation" value="classpath:quartz.properties"/&#62;
	&#60;/bean&#62;
...

The Quartz settings are [...]]]></description>
			<content:encoded><![CDATA[<p>Here is how I configured Quartz to work with Spring and Hibernate.  I&#8217;m using the Quartz JDBC Job Store which stores and retrieves the job settings from a database instead of a static configuration.</p>
<p>I use the <a href="http://static.springframework.org/spring/docs/1.2.x/api/index.html?org/springframework/orm/hibernate3/HibernateTransactionManager.html">SchedulerFactoryBean</a> to manager the Quartz Scheduler lifecycle.</p>
<p><b>spring-servlet.xml</b></p>
<pre>
...
	&lt;!-- Quartz --&gt;
	&lt;bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;
		&lt;property name="applicationContextSchedulerContextKey" value="applicationContext"/&gt;
		&lt;property name="configLocation" value="classpath:quartz.properties"/&gt;
	&lt;/bean&gt;
...
</pre>
<p>The Quartz settings are stored in a quartz.properties file so that they can be unique to each instance of the web application.  This setup requires that quartz.properties be on the classpath.  This file defines the JDBC connection for Quartz to use.</p>
<p><b>quartz.properties</b></p>
<pre>
...
org.quartz.dataSource.myDS.jndiURL=java:comp/env/jdbc/MyDS
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=JB_
org.quartz.jobStore.useProperties=true
</pre>
<p><b>MyBaseJob</b></p>
<pre>
public abstract class MyBaseJob extends QuartzJobBean
{
    private transient ApplicationContext applicationContext = null;

    public ApplicationContext getApplicationContext()
    {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext)
    {
        this.applicationContext = applicationContext;
    }
}
</pre>
<p>Each of my job classes extend MyBaseJob, overriding <code>executeInternal</code>.  The jobs can use the <code>applicationContext</code> to lookup Spring service beans.  In my environment these service beans extend <code>HibernateDaoSupport</code>.</p>
<pre>
    protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException
    {
        MyServiceManager sm = applicationContext.getBean("myServiceManager"); // lookup Spring service bean
        ...
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/24/feed</wfw:commentRss>
		</item>
		<item>
		<title>Find and Replace String in Multiple Files</title>
		<link>http://code.mikwat.com/archives/23</link>
		<comments>http://code.mikwat.com/archives/23#comments</comments>
		<pubDate>Mon, 01 Oct 2007 22:53:11 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/23</guid>
		<description><![CDATA[Periodically I need to replace a string in multiple files on Linux.  I find myself looking up this command or a variant every time.
grep -rl OLDSTRING *.FILEEXTENSION &#124; xargs perl -pi~ -e 's/OLDSTRING/NEWSTRING/'
]]></description>
			<content:encoded><![CDATA[<p>Periodically I need to replace a string in multiple files on Linux.  I find myself looking up this command or a variant every time.</p>
<p><code>grep -rl OLDSTRING *.FILEEXTENSION | xargs perl -pi~ -e 's/OLDSTRING/NEWSTRING/'</code></p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/23/feed</wfw:commentRss>
		</item>
		<item>
		<title>SSL + gzip Compression with Apache and Tomcat</title>
		<link>http://code.mikwat.com/archives/21</link>
		<comments>http://code.mikwat.com/archives/21#comments</comments>
		<pubDate>Mon, 27 Aug 2007 16:28:25 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/21</guid>
		<description><![CDATA[My setup is a single Fedora Core 6 server running Apache 2.2.4 (with mod_ssl and mod_proxy) and Tomcat 5.
With mod_ssl the following virtualhost is setup using an SSL certificate from GoDaddy.  Notice the SSLCertificateChainFile /etc/httpd/conf/ssl.crt/gd_intermediate_bundle.crt reference.  This intermediate certificate comes from GoDaddy and is required.  I didn&#8217;t catch this at first and [...]]]></description>
			<content:encoded><![CDATA[<p>My setup is a single Fedora Core 6 server running <a href="/archives/category/apache">Apache</a> 2.2.4 (with mod_ssl and mod_proxy) and <a href="/archives/category/tomcat">Tomcat</a> 5.</p>
<p>With <strong>mod_ssl</strong> the following virtualhost is setup using an SSL certificate from GoDaddy.  Notice the <strong>SSLCertificateChainFile /etc/httpd/conf/ssl.crt/gd_intermediate_bundle.crt</strong> reference.  This intermediate certificate comes from GoDaddy and is required.  I didn&#8217;t catch this at first and couldn&#8217;t understand what my web browser was unhappy about.  When I called GoDaddy support they told me my certificate was setup correctly and worked in all of there &#8220;off-site&#8221; test browsers.  They were no help, so I continued to dig around and finally found the answer.</p>
<p>The <strong>mod_proxy</strong> lines pass all requests to the <a href="/archives/category/tomcat">Tomcat</a> instance listening on port 9014.</p>
<p><b>/etc/httpd/conf.d/ssl.conf</b></p>
<pre>
&lt;virtualhost&gt;
DocumentRoot  /var/www/html/
ServerName    myserver.com:433</virtualhost>  SSLEngine on
SSLCertificateFile /etc/httpd/conf/ssl.crt/myserver.crt
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/myserver.key
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/gd_intermediate_bundle.crt
SetEnvIf User-Agent ".*MSIE.*"
         nokeepalive ssl-unclean-shutdown
         downgrade-1.0 force-response-1.0
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
CustomLog logs/ssl_request_log
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

ProxyPreserveHost On
ProxyPass / http://localhost:9014/
ProxyPassReverse / http://localhost:9014/
SetEnv proxy-nokeepalive 1
&lt;/virtualserver&gt;
</pre>
<p>For the <a href="/archives/category/tomcat">Tomcat</a> setup, a proxy connector is configured to listen on port 9014 and to proxy port 443 requests (SSL).  The communication between <a href="/archives/category/apache">Apache</a> and <a href="/archives/category/tomcat">Tomcat</a> is not secure, but this is not a concern since this communication is local to the server.  Finally, compression is turned on for several common mime-types.</p>
<p><b>server.xml</b></p>
<pre>
  ...
  &lt;Connector acceptCount="100" connectionTimeout="60000" disableUploadTimeout="true" port="9014" redirectPort="8944"
  scheme="https" proxyPort="443" compression="on" compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript"/&gt;
  ...
</pre>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/21/feed</wfw:commentRss>
		</item>
		<item>
		<title>Problems using Digester in custom Struts Plugin</title>
		<link>http://code.mikwat.com/archives/18</link>
		<comments>http://code.mikwat.com/archives/18#comments</comments>
		<pubDate>Tue, 24 Jul 2007 21:49:22 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/18</guid>
		<description><![CDATA[In migrating from Tomcat 5.0 to Tomcat 5.5, one of my custom Struts plugins started failing on startup with the following exception:

org.apache.commons.digester.Digester startElement
SEVERE: Begin event threw exception
java.lang.ClassNotFoundException: com.mikwat.struts.config.AuthorizationActionConfig
The root of the problems appears to be that the Digester defaults to using the same ClassLoader that loaded it and whichever ClassLoader this is, it doesn&#8217;t have [...]]]></description>
			<content:encoded><![CDATA[<p>In migrating from <a href="/archives/category/tomcat">Tomcat</a> 5.0 to <a href="/archives/category/tomcat">Tomcat </a>5.5, one of my custom Struts plugins started failing on startup with the following exception:</p>
<pre>
org.apache.commons.digester.Digester startElement
SEVERE: Begin event threw exception
java.lang.ClassNotFoundException: com.mikwat.struts.config.AuthorizationActionConfig</pre>
<p>The root of the problems appears to be that the Digester defaults to using the same ClassLoader that loaded it and whichever ClassLoader this is, it doesn&#8217;t have access to my webapp class <code>com.mikwat.struts.config.AuthorizationActionConfig</code>.</p>
<p>After Googling around, I eventually came across this post regarding a similar problem loading the Quartz plugin: <a href="http://mail-archives.apache.org/mod_mbox/struts-user/200305.mbox/%3CB40B3D4758FBFD4AA8C4F3A015DE4446011DF774@sTamExchange1.paymentech.us%3E">Mailing list archives</a>.</p>
<p>The solution is to call setUseContextClassLoader(true) on the Digester object which forces it to use the ClassLoader found by calling <code>Thread.currentThread().getContextClassLoader()</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/18/feed</wfw:commentRss>
		</item>
		<item>
		<title>Importing Existing Email into Gmail</title>
		<link>http://code.mikwat.com/archives/17</link>
		<comments>http://code.mikwat.com/archives/17#comments</comments>
		<pubDate>Fri, 20 Apr 2007 15:29:50 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/17</guid>
		<description><![CDATA[We recently switched to Google Apps at work and I have been looking for a way to import my existing email, which was stored on an IMAP server, into Gmail.  The answer became clear when I came across Mark Lyon&#8217;s GMail Loader (GML), but it was much simpler than I thought.  Rather than [...]]]></description>
			<content:encoded><![CDATA[<p>We recently switched to Google Apps at work and I have been looking for a way to import my existing email, which was stored on an IMAP server, into Gmail.  The answer became clear when I came across <a href="http://marklyon.org/gmail/">Mark Lyon&#8217;s GMail Loader (GML)</a>, but it was much simpler than I thought.  Rather than use GML, all I had to do was move my email from their IMAP folders into the Inbox.  Then, I configured Gmail to <strong>Get mail from other accounts</strong> under <strong>Settings » Accounts</strong>.</p>
<p>This only works for POP3, which was available on my old mail server, but requires that all email be moved to the Inbox.  Gmail downloads 200 messages at a time and checks for mail every hour, so the process can take a long time.  Filters, SPAM, and virus checks are performed on each message, so check your <strong>Spam </strong>folder periodically for misdirected messages.   There are several settings that allow you to automatically Archive and label incoming messages.  See <a href="http://mail.google.com/support/bin/answer.py?answer=21289&amp;topic=1577">Google&#8217;s Help Center</a> for more information.</p>
<p>So, although GML looks interesting and powerful, using Gmail&#8217;s built-in POP3 fetcher was the best solution for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/17/feed</wfw:commentRss>
		</item>
		<item>
		<title>Internationalize PHP Applications</title>
		<link>http://code.mikwat.com/archives/16</link>
		<comments>http://code.mikwat.com/archives/16#comments</comments>
		<pubDate>Thu, 19 Apr 2007 17:36:13 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/16</guid>
		<description><![CDATA[The other day it dawned on me that my hobby website, My Cycling Log, has a large international audience and that I should cater more to them.  My Cycling Log is basically exactly what its name suggests: an online cycling log.  It&#8217;s a place for cyclists to log their rides, share their achievements [...]]]></description>
			<content:encoded><![CDATA[<p>The other day it dawned on me that my hobby website, <a href="http://www.mycyclinglog.com">My Cycling Log</a>, has a large international audience and that I should cater more to them.  My Cycling Log is basically exactly what its name suggests: an online cycling log.  It&#8217;s a place for cyclists to log their rides, share their achievements with their friends and the world, and organize themselves into groups.  The site is constantly evolving largely driven by user feedback.</p>
<p>My first step in making My Cycling Log friendlier for international users was to implement user-specific timezones.  This is a no brainer.  PHP handles timezones quite elegantly using the <a href="http://us2.php.net/manual/en/function.date-default-timezone-set.php"><code>date_default_timezone_set</code></a> function.</p>
<p>The second step is to internationalize the text.  An article on IBM&#8217;s website lays it out very clearly: <a href="http://www-128.ibm.com/developerworks/library/os-php-intl/index.html">How to internationalize PHP apps</a>.  I&#8217;m still looking for translators, but I will update this post once I begin the process.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/16/feed</wfw:commentRss>
		</item>
		<item>
		<title>MSSQL Transaction Log Full</title>
		<link>http://code.mikwat.com/archives/14</link>
		<comments>http://code.mikwat.com/archives/14#comments</comments>
		<pubDate>Mon, 09 Apr 2007 01:13:34 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[mssql]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/14</guid>
		<description><![CDATA[Problem: Occasionally I get the following JDBC error from MSSQL:
The log file for database 'db_example' is full. Back up the transaction log for the database to free up some log space.
Solution:
BACKUP LOG db_example WITH TRUNCATE_ONLY
DBCC SHRINKFILE(db_example_log, 2)
If &#8216;db_example_log&#8217; is not the logical name of the logfile, the 2nd command will fail.  The correct logical [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Problem:</strong> Occasionally I get the following JDBC error from <a href="/archives/category/mssql">MSSQL</a>:</p>
<p><code>The log file for database 'db_example' is full. Back up the transaction log for the database to free up some log space.</code></p>
<p><strong>Solution:</strong></p>
<p><code>BACKUP LOG db_example WITH TRUNCATE_ONLY<br />
DBCC SHRINKFILE(db_example_log, 2)</code></p>
<p>If &#8216;db_example_log&#8217; is not the logical name of the logfile, the 2nd command will fail.  The correct logical name can be found by running the following statements:</p>
<p><code> USE db_example;<br />
SELECT * FROM sysfiles;<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/14/feed</wfw:commentRss>
		</item>
		<item>
		<title>Oracle ADF Cache Files</title>
		<link>http://code.mikwat.com/archives/13</link>
		<comments>http://code.mikwat.com/archives/13#comments</comments>
		<pubDate>Thu, 05 Apr 2007 20:26:23 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[java]]></category>

		<category><![CDATA[oracle]]></category>

		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/13</guid>
		<description><![CDATA[Problem: I have a web application running under Tomcat using the Oracle ADF framework.  When the application is installed as a service under Windows, it outputs cache files in mass to \WINDOWS\system32\  Needless to say, this doesn&#8217;t make the system administrators happy.
 Solution Under Linux:  This problem is avoided by starting the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Problem:</strong> I have a web application running under <a href="/archives/category/tomcat">Tomcat</a> using the <a href="/archives/category/oracle">Oracle</a> ADF framework.  When the application is installed as a service under Windows, it outputs cache files in mass to \WINDOWS\system32\  Needless to say, this doesn&#8217;t make the system administrators happy.</p>
<p><strong> Solution Under <a href="/archives/category/linux">Linux</a>:</strong>  This problem is avoided by starting the application with a working directory of &lt;application.root&gt;\temp  Then, these ADF cache files get dumped there.  The following snip-it does the trick:</p>
<p><code>pushd "$CATALINA_BASE"/temp &gt; /dev/null<br />
exec "$EXECUTABLE" start "$@"<br />
popd &gt; /dev/null<br />
</code></p>
<p>CATALINA_BASE: &lt;application.root&gt;</p>
<p>EXECUTABLE: &lt;tomcat.home&gt;/bin/catalina.sh</p>
<p><strong> Solution Under Windows:</strong>  Unknown at this point, please provide feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/13/feed</wfw:commentRss>
		</item>
		<item>
		<title>Site Monitoring</title>
		<link>http://code.mikwat.com/archives/7</link>
		<comments>http://code.mikwat.com/archives/7#comments</comments>
		<pubDate>Sun, 01 Apr 2007 21:20:41 +0000</pubDate>
		<dc:creator>mikwat</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<guid isPermaLink="false">http://code.mikwat.com/archives/7</guid>
		<description><![CDATA[After having some site performance and availability problems, I began investigating ways to monitor web servers. There are lots of sites offering various services, here&#8217;s what I&#8217;ve settled on.
1. Broadband Reports offers both free and paid services.  Their Line Monitoring tool provides a continuous response time graph shown below by sending out pings every [...]]]></description>
			<content:encoded><![CDATA[<p>After having some site performance and availability problems, I began investigating ways to monitor web servers. There are lots of sites offering various services, here&#8217;s what I&#8217;ve settled on.</p>
<p>1. <a href="http://www.dslreports.com">Broadband Reports</a> offers both free and paid services.  Their <strong>Line Monitoring</strong> tool provides a continuous response time graph shown below by sending out pings every 10 minutes.  The Line Monitoring tool costs approximately $1 per week.  It also provide the ability to setup a HTTP ping to a specific URL.</p>
<p><img src="http://code.mikwat.com/wp-content/uploads/2007/04/line-monitor-ping1.gif" alt="Line Monitor - Ping" /></p>
<p><img src="http://code.mikwat.com/wp-content/uploads/2007/04/line-monitor-http-ping.gif" alt="Line Monitor - HTTP Ping" /></p>
<p>2. <a href="http://mon.itor.us/">mon.itor.us</a> is a free web site monitor tool.  As far as simplicity in setup, mon.itor.us couldn&#8217;t be easier.  Their website serves as a dashboard with drag-and-drop modules for each of your sites.  These modules can also be included in your OS X dashboard, Google Personal, Netvibes, etc.  Another nice feature is the ability to be notified when your sites are unavailable.  Alerts can be sent to an email address, IM account, or cellphone.  The main problem with mon.itor.us is in its ping frequency, which is currently between 30-45 minutes.  According to their parent site <a href="http://www.monitis.com/">Monitis</a> they are rolling out a Bronze plan ($10 per month) that will ping every 5 minutes and provide some advanced features.</p>
<p><img src="http://code.mikwat.com/wp-content/uploads/2007/04/mon-itor-us.gif" alt="Mon.itor.us - Ping" /></p>
]]></content:encoded>
			<wfw:commentRss>http://code.mikwat.com/archives/7/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
