<?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-6189841530810285724</id><updated>2012-01-27T03:38:51.675-08:00</updated><category term='apache'/><category term='bpel'/><category term='hibernate'/><category term='jQuery'/><category term='proxy'/><category term='jsf'/><category term='javascript'/><category term='finance'/><category term='java'/><category term='sass'/><category term='AppleScript'/><category term='ajax'/><category term='scriptaculous'/><category term='hostgator'/><category term='bash'/><category term='sprite'/><category term='rubyonrails'/><category term='oracle'/><category term='oc4j'/><category term='rspec'/><category term='css'/><category term='struts'/><category term='git'/><category term='rails'/><category term='rails metal'/><category term='command-line'/><category term='windows'/><category term='eclipse'/><category term='capistrano'/><category term='timezones'/><category term='svn'/><title type='text'>Karl Varga's Developer Notes</title><subtitle type='html'>Giving back to the development community.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>39</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4556496800995159570</id><published>2011-05-13T14:16:00.000-07:00</published><updated>2011-05-13T14:34:07.450-07:00</updated><title type='text'>RSpec 2 matcher to test layout rendering in Rails 3</title><content type='html'>In Rails 3 there seems to be no way to determine which layout(s) were rendered.  There is &lt;span class="code"&gt;assert_template&lt;/span&gt; but it doesn't seem to accept the :layout option like the source code would suggest.  And where do you call that method anyway?  So I wrote a custom matcher along with a bit that integrates into ActionView so that we can detect when a layout is rendered and store a reference to it on the controller.
&lt;p&gt;
Not that this doesn't support multiple layout rendering.  Only the last layout rendered is stored.
&lt;p&gt;
Take a look at the Example Usage in the comments above the matcher for usage information.
&lt;p&gt;
&lt;script src="https://gist.github.com/971342.js?file=render_layout.rb"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4556496800995159570?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4556496800995159570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4556496800995159570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4556496800995159570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4556496800995159570'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2011/05/rspec-2-matcher-to-test-layout.html' title='RSpec 2 matcher to test layout rendering in Rails 3'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-1089039712322160902</id><published>2011-03-28T11:46:00.000-07:00</published><updated>2011-03-28T12:04:35.270-07:00</updated><title type='text'>[solved] installing passenger 3.0.5 apache2 module on OS X gives 'missing required architecture ppc64 in file'</title><content type='html'>I was getting odd compilation errors trying to install the Passenger 3.0.5 apache2 module on my Mac running OS X.  I worked through the problems and you just need to edit a couple of files to solve the problem.

&lt;div class="code"&gt;gem install passenger
rvmsudo passenger-install-apache2-module&lt;/div&gt;

&lt;pre class="text"&gt;mkdir -p ext/apache2/module_libboost_oxt
g++ -Iext -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -o ext/apache2/module_libboost_oxt/aggregate.o -c ext/apache2/module_libboost_oxt/aggregate.cpp
mkdir -p ext/apache2/module_libboost_oxt
rm -rf ext/apache2/module_libboost_oxt.a
ar cru ext/apache2/module_libboost_oxt.a ext/apache2/module_libboost_oxt/aggregate.o
ranlib ext/apache2/module_libboost_oxt.a
gcc -Iext -Iext/common -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -o ext/apache2/mod_passenger.o -c ext/apache2/mod_passenger.c
g++ -Iext -Iext/common -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -o ext/apache2/Configuration.o -c ext/apache2/Configuration.cpp
g++ -Iext -Iext/common -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -o ext/apache2/Bucket.o -c ext/apache2/Bucket.cpp
g++ -Iext -Iext/common -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS -o ext/apache2/Hooks.o -c ext/apache2/Hooks.cpp
g++ -flat_namespace -bundle -undefined dynamic_lookup ext/apache2/Configuration.o ext/apache2/Bucket.o ext/apache2/Hooks.o ext/apache2/mod_passenger.o -fPIC -o ext/apache2/mod_passenger.so -fPIC -fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/include/apr-1 -I/usr/include/apr-1 -I/usr/include/apache2 -arch i386 -arch ppc -arch x86_64 -arch ppc64 -D_REENTRANT -I/usr/local/include -DHASH_NAMESPACE="__gnu_cxx" -DHASH_FUN_H="&lt;ext/hash_fun.h&gt;" -DHAS_SFENCE -DHAS_LFENCE -Wall -g -DPASSENGER_DEBUG -DBOOST_DISABLE_ASSERTS ext/apache2/module_libpassenger_common.a ext/apache2/module_libboost_oxt.a -fPIC -L/usr/lib -lapr-1 -L/usr/lib -laprutil-1 -lpthread  
ld: warning: in /usr/lib/bundle1.o, missing required architecture ppc64 in file
ld: warning: in /usr/lib/libapr-1.dylib, missing required architecture ppc64 in file
ld: warning: in /usr/lib/libaprutil-1.dylib, missing required architecture ppc64 in file
ld: warning: in /usr/lib/libpthread.dylib, missing required architecture ppc64 in file
ld: warning: in /usr/lib/gcc/powerpc-apple-darwin10/4.2.1/libstdc++.dylib, missing required architecture ppc64 in file
ld: warning: in /usr/lib/libSystemStubs.a, missing required architecture ppc64 in file
ld: warning: in /usr/lib/libSystem.dylib, missing required architecture ppc64 in file
ld: symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o) for architecture ppc64
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccPTqixF.out (No such file or directory)
rake aborted!
Command failed with status (1): [g++ -flat_namespace -bundle -undefined dyn...]&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Fix the compilation errror&lt;/b&gt;&lt;/p&gt;

&lt;div class="code"&gt;cd /Users/karl/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.5
vi ./lib/phusion_passenger/platform_info/apache.rb&lt;/div&gt;

Change line 215 to:
  &lt;span class="code"&gt;architectures = ["-arch i386 -arch x86_64"]&lt;/span&gt;

Then restart Apache.  Now in your apache logs you might see the following error:

&lt;pre&gt;/Users/karl/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.5/lib/phusion_passenger/platform_info/ruby.rb:166:in `expand_path': couldn't find HOME environment -- expanding `~/.rvm' (ArgumentError)
 from /Users/karl/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.5/lib/phusion_passenger/platform_info/ruby.rb:166:in `_unmemoized_rvm_path'
 from /Users/karl/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.5/lib/phusion_passenge&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Fix the missing HOME env variable&lt;/b&gt;&lt;/p&gt;

Hard-code the path to your HOME directory.

&lt;div class="code"&gt;vi /Users/karl/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-3.0.5/lib/phusion_passenger/platform_info/ruby.rb&lt;/div&gt;

Edit #164 to 
&lt;span class="code"&gt;[ENV['rvm_path'], &amp;quot;/Users/karl/.rvm&amp;quot;, &amp;quot;/usr/local/rvm&amp;quot;].each do |path|&lt;/span&gt;

Now restart Apache with &lt;span class="code"&gt;sudo apachectl -k restart&lt;/span&gt; and everything should be working fine!
&lt;p&gt;To find the location of your gem files you can &lt;span class="code"&gt;echo $GEM_HOME&lt;/span&gt;.  Keep in mind you will need to substitute your own HOME path in the above command.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-1089039712322160902?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/1089039712322160902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=1089039712322160902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1089039712322160902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1089039712322160902'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2011/03/solved-installing-passenger-305-apache2.html' title='[solved] installing passenger 3.0.5 apache2 module on OS X gives &apos;missing required architecture ppc64 in file&apos;'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-1473069401260682454</id><published>2009-12-15T22:59:00.000-08:00</published><updated>2010-03-24T17:43:33.101-07:00</updated><title type='text'>Authenticate your Authlogic users in Rails Metal</title><content type='html'>&lt;p&gt;&lt;b&gt;Update 2010-03-17:&lt;/b&gt; Don't fail in test mode if we can't find a user&lt;/p&gt;
I haven't been able to find any information on authenticating users in Rails Metal controllers.  So I took a look at what was available in the session and worked with that.  I'm not an expert on Authlogic (I did write an Authlogic Add-On a while ago) but this seems like a good solution.  Let me know if you know of any problems with this approach.
&lt;p&gt;
I added a method to UserSession (or add it to whatever class you use for your sessions) that takes the Metal &lt;span class="code"&gt;env&lt;/span&gt; and checks the authentication parameters and returns the user record.  I don't bother with updating the user's &lt;span class="code"&gt;last_request_at&lt;/span&gt; attributes or anything.  I had to bypass the Authlogic session entirely because Authlogic needs to be activated with a controller before you can use the session stuff.  I considered dummying the controller by including &lt;span class="code"&gt;authlogic/test_case&lt;/span&gt; but I don't know enough about what the dummy controller does regarding authentication to go this route.
&lt;p&gt;
And the code...
&lt;script src="http://gist.github.com/343024.js?file=user_session.rb"&gt;&lt;/script&gt;
&lt;p&gt;
Here's the Metal "controller":
&lt;script src="http://gist.github.com/343024.js?file=token_request.rb"&gt;&lt;/script&gt;&lt;p&gt;
A couple neat things in the Metal controller are the use of &lt;span class="code"&gt;ActionController::Request.new(env)&lt;/span&gt; so we have access to &lt;span class="code"&gt;request.remote_ip&lt;/span&gt; and other helper methods this class provides.
&lt;p&gt;
The part where I validate the user is:
&lt;script src="http://gist.github.com/343024.js?file=Authenticating+the+user"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-1473069401260682454?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/1473069401260682454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=1473069401260682454' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1473069401260682454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1473069401260682454'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/authenticate-your-authlogic-users-in.html' title='Authenticate your Authlogic users in Rails Metal'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-8252245155814256148</id><published>2009-12-08T04:47:00.000-08:00</published><updated>2009-12-08T05:00:05.736-08:00</updated><title type='text'>Silence the Rails logger as well as the SQL logs</title><content type='html'>It's one thing to turn off logging in Rails, it's another to prevent SQL statements from appearing in your logs.
&lt;p&gt;
I've written a Rake helper to silence both.  You can adapt it for other uses, but I think it's mostly relevant in Rake tasks.
&lt;p&gt;
&lt;pre name="code" class="ruby"&gt;
# lib/rake_helpers.rb
module Rake
  module Helpers
    # Silence the Rails logger as well as the SQL logger
    # Call with a block e.g
    # silent { my block code }
    def silent
      ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
        alias_method :original_log_info, :log_info
        def silent_log_info(*args); end
        alias_method :log_info, :silent_log_info
      end
      @@old_logger = ActiveRecord::Base.logger
      ActiveRecord::Base.logger = Class.new { def method_missing(*args); end; }.new
      yield
      ActiveRecord::Base.logger = @@old_logger
      ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
        alias_method :log_info, :original_log_info
      end 
    end
  end
end
&lt;/pre&gt;
And sample usage:
&lt;pre name="code" class="ruby"&gt;
# lib/tasks/db.rake
require &amp;#039;rake_helpers&amp;#039;
include Rake::Helpers

namespace :db do
  namespace :update do

    desc &amp;quot;Update counter caches&amp;quot;
    task :counters =&amp;gt; :environment do
      silent do
        ActiveRecord::Base.transaction do
          [Artist, Album].each do |model| 
            model.find_in_batches(:batch_size =&amp;gt; 5000) do |batch|
              batch.each { |record| record.update_counts }
            end
          end
        end
      end
    end
  end
end
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-8252245155814256148?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/8252245155814256148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=8252245155814256148' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8252245155814256148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8252245155814256148'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/silence-rails-logger-as-well-as-sql.html' title='Silence the Rails logger as well as the SQL logs'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-7263454244672398095</id><published>2009-12-04T02:46:00.001-08:00</published><updated>2009-12-04T03:02:42.809-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rspec'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='rails metal'/><title type='text'>Rails Metal real-world example with RSpec integration test</title><content type='html'>There's not that much information out there about Rails Metal, and even less about how to test Metal classes using RSpec.  If I had time I would create a new RSpec ExampleGroup with a lot of the goodness of the ControllerExampleGroup, but alas I don't.
&lt;p&gt;
So integration tests will have to do.  I had problems with using &lt;span class="code"&gt;response.should be_success&lt;/span&gt;.  The docs say it exists, but it doesn't for me.  YMMV.
&lt;p&gt;
Anyways, here is my Metal class along with the integration test:
&lt;p&gt;
&lt;script src="http://gist.github.com/248981.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-7263454244672398095?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/7263454244672398095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=7263454244672398095' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7263454244672398095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7263454244672398095'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/rails-metal-real-world-example-with.html' title='Rails Metal real-world example with RSpec integration test'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-5464677958954817881</id><published>2009-12-03T20:57:00.000-08:00</published><updated>2009-12-03T21:29:55.302-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Bash script to easily check and switch between Rails environments.  Usage: renv [p|d|t|s]</title><content type='html'>When I'm on our deployment server I'm constantly checking the &lt;span class="code"&gt;RAILS_ENV&lt;/span&gt; environment variable to make sure that I don't accidentally do something on the production database when I meant to do it on the staging database.  (Incidentally I’ve added some stuff to the Rakefile to guard against such a thing: &lt;a href="http://kjvarga.blogspot.com/2009/12/rakefile-mods-prevent-destructive-rake.html"&gt;Rakefile: Prevent destructive rake tasks in the production environment.&lt;/a&gt;). So I created this handy Bash function to check and switch between your Rails environments easily.
&lt;p&gt;
Sample usage:
&lt;pre name="code" class="bash"&gt;
$ renv
RAILS_ENV is unset
$ renv p
RAILS_ENV set to production
$ renv d
RAILS_ENV set to development
$ renv s
RAILS_ENV set to staging
$ renv t
RAILS_ENV set to test
$ renv
RAILS_ENV is test
&lt;/pre&gt;
&lt;p&gt;
And the code:
&lt;pre name="code" class="bash"&gt;
# Put this in your ~/.profile
function renv() {
  rails_env_p=&amp;quot;production&amp;quot; 
  rails_env_d=&amp;quot;development&amp;quot; 
  rails_env_s=&amp;quot;staging&amp;quot; 
  rails_env_t=&amp;quot;test&amp;quot; 

  if [ $1 ];then
    eval &amp;#039;rails_env=${rails_env_&amp;#039;&amp;quot;${1}&amp;quot;&amp;#039;}&amp;#039; 
    export RAILS_ENV=$rails_env
    echo &amp;quot;RAILS_ENV set to $RAILS_ENV&amp;quot; 
  elif [ $RAILS_ENV ];then
    echo &amp;quot;RAILS_ENV is $RAILS_ENV&amp;quot; 
  else
    echo &amp;quot;RAILS_ENV is unset&amp;quot; 
  fi
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-5464677958954817881?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/5464677958954817881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=5464677958954817881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5464677958954817881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5464677958954817881'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/when-im-on-our-deployment-server-im.html' title='Bash script to easily check and switch between Rails environments.  Usage: renv [p|d|t|s]'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2682066999563120400</id><published>2009-12-03T20:15:00.000-08:00</published><updated>2009-12-03T21:29:31.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='capistrano'/><title type='text'>Rakefile: Prevent destructive rake tasks in the production environment.</title><content type='html'>We are using the same server for our staging and production deploys.  The problem is that the default RAILS_ENV is set to production so when I go to the staging app and start messing about with &lt;span class="code"&gt;rake db:seed&lt;/span&gt; (or worse, &lt;span class="code"&gt;rake db:reset&lt;/span&gt;) I am almost always a hair's breadth away from imminent death.
&lt;p&gt;
(Here's a handy bash script I wrote to &lt;a href="http://kjvarga.blogspot.com/2009/12/when-im-on-our-deployment-server-im.html"&gt;easily switch between your Rails environments&lt;/a&gt;.)
&lt;p&gt; 
So I decided to do something about it and protect destructive or database altering rake tasks from being run in the production environment.  I really like this approach and I think I'll use it in future projects regardless of the setup.  The fact is you only do a &lt;span class="code"&gt;rake db:reset&lt;/span&gt; in production once, during the cold deploy of your app.  It allows &lt;span class="code"&gt;rake db:migrate&lt;/span&gt; and its variants, but not &lt;span class="code"&gt;rake db:migrate:reset&lt;/span&gt;.  Look at the code for the full list of restricted rake tasks.  The tasks in &lt;span class="code"&gt;PROTECT_SOME&lt;/span&gt; are matched explicitly, &lt;span class="code"&gt;PROTECT_ALL&lt;/span&gt; restricts all variants of that task. 
&lt;p&gt;
This shows the warning message and confirmation that appear.  If you know what you are doing, or you want to automate things with Capistrano and need to run one of the protected tasks just pass &lt;span class="code"&gt;FORCE=true&lt;/span&gt; to the task.
&lt;pre name="code" class="bash"&gt;
[deployer@rails1 ~/rails_apps/rails1.creagency.com.au/current] echo $RAILS_ENV
production
[deployer@rails1 ~/rails_apps/rails1.creagency.com.au/current] rake db:reset
(in /www/rails_apps/rails1.creagency.com.au/releases/20091204033227)
****************************************************************************
* WARNING! You are in the PRODUCTION environment and are running a Rake task 
* that will DESTROY your PRODUCTION database!
* 
* If you know what you are doing you can run this task with FORCE=true to
* prevent this message appearing.
****************************************************************************

Are you sure? (Yes|No) [No]

Quitting.
[deployer@rails1 ~/rails_apps/rails1.creagency.com.au/current] 
&lt;/pre&gt;
And here is the code.  Just add it to the bottom of your application's &lt;span class="code"&gt;Rakefile&lt;/span&gt;:
&lt;p&gt;
&lt;script src="http://gist.github.com/248819.js?file=Protect+destructive+rake+tasks+in+the+production+environment.rb"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2682066999563120400?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2682066999563120400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2682066999563120400' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2682066999563120400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2682066999563120400'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/rakefile-mods-prevent-destructive-rake.html' title='Rakefile: Prevent destructive rake tasks in the production environment.'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-1498719175855551324</id><published>2009-12-03T19:32:00.000-08:00</published><updated>2009-12-03T20:10:41.443-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='capistrano'/><title type='text'>Solved: Capistro deploy fails with 'Permission denied (publickey).' but you know you have your permissions setup correctly</title><content type='html'>I spent a couple hours scratching me head one day when I couldn't deploy to the production server, but I could a little while ago.
&lt;p&gt;
The Capistrano deployment recipe had been changed to forward the ssh agent (which means that my local ssh key is the one that will be used by the deployment server to checkout the updated code from Git):
&lt;pre class="code"&gt;
  ssh_options[:forward_agent] = true
&lt;/pre&gt;
Capistrano was complaining:
&lt;pre name="code" class="xml"&gt;
    servers: [&amp;quot;10.5.23.203&amp;quot;]
    [10.5.23.203] executing command
 ** [10.5.23.203 :: out] Permission denied (publickey).
 ** [10.5.23.203 :: out] fatal: The remote end hung up unexpectedly
&lt;/pre&gt;
The solution was just to add my SSH key to my local SSH agent:
&lt;pre class="code"&gt;
$ ssh-add
&lt;/pre&gt;
Simple enough.  Turns out you have to do that every time you restart your machine tho, which is a bit annoying.  Any way to avoid that?
&lt;p&gt;
Cheers,
Karl&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-1498719175855551324?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/1498719175855551324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=1498719175855551324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1498719175855551324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1498719175855551324'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/solved-capistro-deploy-fails-with.html' title='Solved: Capistro deploy fails with &apos;Permission denied (publickey).&apos; but you know you have your permissions setup correctly'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-6300572865329164585</id><published>2009-12-02T00:10:00.000-08:00</published><updated>2009-12-02T00:23:21.122-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Git: how to keep the master branch tidy, even if you've been working on it</title><content type='html'>In order to keep the master branch clean we want to avoid merges and "noisy" commits.
&lt;p&gt;
As you probably know, the best thing to do is to &lt;b&gt;develop in a branch&lt;/b&gt; and &lt;b&gt;rebase against master&lt;/b&gt; often (never rebase a remote branch).  This ensures that your changes are always the latest changes applied to the index.  And because they're applied on top of the index, when you merge them into the master branch and push, it's just a fast-forward update and you will never have to do a merge.
&lt;p&gt;
But what happens if you've been working on the master branch for a while?  Is it too late?  I just encountered this myself, and here's how you can keep the master merge-free in this situation.

&lt;h3&gt;On master&lt;/h3&gt;

&lt;pre&gt;git fetch # have there been changes to master since you last fetched/pulled?  if not, you can just commit and push, otherwise...

git commit -a -m "awesome message here" # commit your changes
git branch wip           # create a new branch with your changes
git reset --hard HEAD~1  # reset the master branch to before your commit(s)
git checkout wip
continue working...
git fetch origin master
git rebase origin/master # rebase your changes on top of master often
all done...
git rebase -i origin/master # preferably squash your commits
git checkout master
git pull                 # make sure master has the latest code
git merge wip            # apply your fast-forward changes to the index
git push                 # quick before someone else does!&lt;/pre&gt;
&lt;p&gt;
Can this process be shortened?  Let me know if you have ideas.
&lt;p&gt;
Here are some excellent articles explaining some Git best-practices.  There is some excellent info here, even from Linus himself!
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html"&gt;A Git Workflow for Agile Teams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lwn.net/Articles/328436/"&gt;Rebasing and merging: some git best practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lwn.net/Articles/328438/"&gt;Linus' explanation of what clean history means and when merging/rebasing best-practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Let me know if you have good Git articles.  I'm still learning about Git, but now that I'm getting my head around it, it's getting better and better!
&lt;p&gt;
Karl&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-6300572865329164585?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/6300572865329164585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=6300572865329164585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6300572865329164585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6300572865329164585'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/12/git-how-to-keep-master-branch-tidy.html' title='Git: how to keep the master branch tidy, even if you&apos;ve been working on it'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4015061010951644738</id><published>2009-11-15T04:48:00.001-08:00</published><updated>2009-11-15T08:16:17.509-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sass'/><category scheme='http://www.blogger.com/atom/ns#' term='sprite'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Sass sprite mixin: making sprites super easy to use!</title><content type='html'>If you're like me, you love &lt;a href="http://haml-lang.com/"&gt;Haml&lt;/a&gt; and &lt;a href="http://sass-lang.com/"&gt;Sass&lt;/a&gt;!.  And if you're a serious web developer trying to squeeze every last bit of performance out of your web application (let's pretend :), then you are already using &lt;a href="http://www.fiftyfoureleven.com/weblog/web-development/css/css-sprites-images-optimization" title="CSS, Image Sprites, Background Images and Website Optimization"&gt;image sprites&lt;/a&gt;, right?
&lt;p/&gt;
I won't go into the benefits of using sprites, but apart from the obvious, I kinda like how they keep things organized.  I don't need to worry about adding another small image to my application because it's not going to be yet another resource to bog things down, it goes in the sprite and probably only takes 1K.  So that's nice.  But they're just not as easy to use as a simple image...until now!
&lt;p/&gt;
With my Sass mixin you can use a sprite image with just two lines of Sass.  
&lt;h2&gt;The mixin:&lt;/h2&gt;
&lt;pre name="code" class="xml"&gt;// Add styles to an element to show the image in *image* at the given *x_pos* and *y_pos*.
// If the optional *x_size* or *y_size* arguments are passed in, the width and/or height 
// is set to that value.
=sprite(!image, !x_pos, !y_pos, !x_size=0, !y_size=0)
  :background-image = url(!image)
  :background-position = !x_pos !y_pos
  @if !x_size &amp;gt; 0
    :width = !x_size
  @if !y_size &amp;gt; 0
    :height = !y_size  
&lt;/pre&gt;
I'd recommend wrapping the mixin for your sprite image, because you're going to use it a lot.  For example:
&lt;pre name="code" class="xml"&gt;=player_sprite(!x_pos, !y_pos, !x_size=0, !y_size=0)
  +sprite(&amp;quot;/images/player-sprite.png&amp;quot;, !x_pos, !y_pos, !x_size, !y_size)
  
// Now define some styles using the player sprite
.playlists-icon
  +player_sprite(-600px, 0, 18px, 18px)
.recently-played-icon
  +player_sprite(-700px, 0, 18px, 18px)
.playing-now-icon
  +player_sprite(-800px, 0, 18px, 18px)
&lt;/pre&gt;
This will generate the following CSS
&lt;pre name="code" class="css"&gt;.playlists-icon {
  background-image: url(&amp;#039;/images/player-sprite.png&amp;#039;);
  background-position: -600px 0;
  width: 18px;
  height: 18px; }

.recently-played-icon {
  background-image: url(&amp;#039;/images/player-sprite.png&amp;#039;);
  background-position: -700px 0;
  width: 18px;
  height: 18px; }

.playing-now-icon {
  background-image: url(&amp;#039;/images/player-sprite.png&amp;#039;);
  background-position: -800px 0;
  width: 18px;
  height: 18px; }  
&lt;/pre&gt; 
And your Haml to display the divs with the images is as simple as:
&lt;pre name="code" class="xml"&gt;.playlists-icon
.recently-played-icon
.playing-now-icon
&lt;/pre&gt;
Awesome!  Now that's easy!
&lt;p/&gt;
If you found this useful, let me know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4015061010951644738?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4015061010951644738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4015061010951644738' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4015061010951644738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4015061010951644738'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/11/sass-sprite-mixin-making-sprites-super.html' title='Sass sprite mixin: making sprites super easy to use!'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2277082811531565157</id><published>2009-06-04T23:03:00.000-07:00</published><updated>2009-11-15T04:47:14.818-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>jQuery plugin to escape CSS selectors</title><content type='html'>Sometimes in jQuery you need to find an element(s) using a selector that contains special characters, for instance &lt;span class="code"&gt;#&lt;/span&gt;, or &lt;span class="code"&gt;.&lt;/span&gt;.  I'm quite baffled that jQuery doesn't include a CSS selector escape function.  Not that you should use special characters in your class/id attributes, but hey, sometimes you don't have control over the content.
&lt;p/&gt;
My escape function uses a couple of neat JavaScript techniques like closures (very, very useful once you get the hang of 'em!) and regular expressions.  I use &lt;a href="http://simonwillison.net"&gt;Simon Willison's&lt;/a&gt; &lt;a href="http://simonwillison.net/2006/Jan/20/escape/"&gt;Escaping regular expression characters in JavaScript&lt;/a&gt; Regex extension a lot.  For more on closures check out &lt;a href="http://novemberborn.net"&gt;Mark Wubben&lt;/a&gt;'s &lt;a href="http://novemberborn.net/javascript/scopes-and-closures-funk"&gt;Getting Funky With Scopes and Closures&lt;/a&gt;.
&lt;p/&gt;
As an extreme example, say we have something as crazy as:
&lt;div class="code"&gt;  &amp;lt;div id=&amp;#039;#;&amp;amp;,.+*~&amp;quot;:!^$[]()=&amp;gt;|/&amp;#039;&amp;gt;
    Hello World!
  &amp;lt;/div&amp;gt;
&lt;/div&gt;
We can match that with this jQuery:
&lt;div class="code"&gt;  $(&amp;#039;#&amp;#039; + jQuery.escapeSelector(&amp;#039;#;&amp;amp;,.+*~&amp;quot;:!^$[]()=&amp;gt;|/&amp;#039;))
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
function findIt() {
  return $('#' + jQuery.escapeSelector('#;&amp;,.+*~":!^$[]()=&gt;|/'));
};
&lt;/script&gt;
&lt;div style="display: none;" id='#;&amp;,.+*~":!^$[]()=&gt;|/'&gt;Hello World!&lt;/div&gt;
&lt;p/&gt;
Try it out: &lt;input type="button" onclick="alert(findIt().html());" value="Find it!"/&gt;
&lt;p/&gt;
&lt;h2&gt;Here's the code&lt;/h2&gt;
&lt;pre name="code" class="javascript"&gt;
/**
 * jQuery static function extensions.
 */
 
jQuery.extend(jQuery, {
  /**
   * Escape all special jQuery CSS selector characters in *selector*.
   * Useful when you have a class or id which contains special characters
   * which you need to include in a selector.
   */
  escapeSelector: (function() {
    var specials = [
      '#', '&amp;', '~', '=', '&gt;', 
      "'", ':', '"', '!', ';', ','
    ];
    var regexSpecials = [
      '.', '*', '+', '|', '[', ']', '(', ')', '/', '^', '$'
    ];
    var sRE = new RegExp(
      '(' + specials.join('|') + '|\\' + regexSpecials.join('|\\') + ')', 'g'
    );

    return function(selector) {
      return selector.replace(sRE, '\\$1');
    }
  })()
});
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2277082811531565157?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2277082811531565157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2277082811531565157' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2277082811531565157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2277082811531565157'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/06/jquery-plugin-to-escape-css-selector.html' title='jQuery plugin to escape CSS selectors'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-8696059929333376851</id><published>2009-05-24T03:38:00.000-07:00</published><updated>2009-05-30T06:50:07.977-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>How to setup an ad-blocking proxy in 10 minutes and block ads in all your favorite browsers!</title><content type='html'>&lt;style type="text/css"&gt;

h4.subtitle {
  font-size: 120%;
  margin-top: 4px;
  margin-bottom: 10px;
}

h5.subtitle {
  font-size: 120%;
  margin-top: 4px;
  margin-bottom: 10px;
  font-style: italic;
}

h3.subtitle {
  color: #669922;
  font-size: 140%;
  margin-top: 5px;
  margin-bottom: 10px;
}

.captioned-image div { 
  font-size: 80%;
  font-family: Verdana, Arial, sans-serif;
  text-align: center; 
  color: black;
}

.captioned-image.right {
  float: right;
  margin: 0 0 5px 10px;
}

.captioned-image.left {
  float: left;
  margin: 0 10px 5px 0;
}

.captioned-image img {
  cursor: pointer;
  cursor: hand; 
}

.quicklinks {
  width: 200px;
  font-size: 90%;
  border: 1px solid #669922;
  float: right;
  background: white;
  z-index: 10;
  margin: 0 10px 10px 15px;
}

.quicklinks div {
  font-size: 1em;
  background-color: #669922;
  color: white;
  padding-left: 10px;
  font-weight: bold;
  padding: 2px;
}

.quicklinks a {
  text-decoration: none;
  color: #669922; /*#555544;*/
  font-weight: normal;
}

.quicklinks ol, .quicklinks ul {
  padding-left: 30px;
}

&lt;/style&gt;


&lt;div class="quicklinks"&gt;
  &lt;div&gt;Quick links&lt;/div&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href="#benefits"&gt;Benefits&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#getting-started"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#setup-apache"&gt;Setup Apache&lt;/a&gt;&lt;/li&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;a href="http://varzyfamily.com/links/blog/ad-blocker.zip"&gt;Download ad-blocker.zip&lt;/a&gt;
      &lt;li&gt;&lt;a href="#configure-virtual-host"&gt;Configure the virtual host&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href="#start-apache"&gt;Start Apache&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;  
    &lt;li&gt;&lt;a href="#configure-browsers"&gt;Configure your browsers&lt;/a&gt;&lt;/li&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;a href="#firefox"&gt;Firefox&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href="#opera"&gt;Opera&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href="#safari"&gt;Safari&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
    &lt;li&gt;&lt;a href="#the-pac-file"&gt;Technical: The PAC file&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

For a long time now I've been content using Opera's built-in ad blocker, an example of which you can see below.  This approach has worked for me for a while, but has some major shortcomings: I can't use expressions to filter multiple URLs from the same server, and obviously all my hard work blocking ads in Opera doesn't do anything for me in Firefox or Safari.
&lt;p&gt;
&lt;!-- Opera ad blocker --&gt;
&lt;div class="captioned-image left"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_LjUDvSJPqv4/Sh3Yy5mkXbI/AAAAAAAAACM/xARcfs2wfEo/s1600-h/Opera+ad+blocker-2.jpg"&gt;&lt;img style="width: 320px; height: 217px;" src="http://3.bp.blogspot.com/_LjUDvSJPqv4/Sh3Yy5mkXbI/AAAAAAAAACM/xARcfs2wfEo/s320/Opera+ad+blocker-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340663102098922930" /&gt;&lt;/a&gt;
&lt;div&gt;Opera's Ad Blocker&lt;/div&gt;
&lt;/div&gt;
&lt;p style="clear: right;"&gt;
The best solution to these problems lies in setting up a proxy to filter requests by URL.  I had read about doing something like this a couple years ago, but couldn't be bothered to figure out all the details of setting it up.  It turns out the be remarkably easy, as I'll show you!  With my setup files and instructions you can be browsing ad-free in 10 minutes.  And trust me, it's worth it!
&lt;/p&gt;
&lt;p&gt;
  &lt;br /&gt;
&lt;a name="benefits"&gt;&lt;/a&gt;
&lt;h3 class="subtitle" style="clear: both;"&gt;The benefits of the proxy approach&lt;/h3&gt;
&lt;img style="float: left; margin-right: 0px;" src="http://varzyfamily.com/links/blog/images/firefox.png" /&gt;
&lt;img style="float: left; clear: left; margin-right: 0px;" src="http://varzyfamily.com/links/blog/images/opera.gif" /&gt;
&lt;img style="float: left; clear: left; margin-right: 0px;" src="http://varzyfamily.com/links/blog/images/safari.jpg" /&gt;

&lt;ul style="margin-left: 50px;"&gt;
&lt;li&gt;&lt;b&gt;Block ads in every browser with a single configuration file.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Filter URLs using Regular Expressions&lt;/b&gt; (I've added some methods so you don't have to).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Configuration files are in JavaScript for easy scripting&lt;/b&gt; and customization.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Blocks HTML ads, image ads, flash ads, you name it.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Faster browsing because you don't wait for ads to load&lt;/b&gt; (and ads are usually given first priority in the loading sequence when you visit commercial websites, so your pages render faster).
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
You're going to need to be running a webserver that will serve a blank page for the blocked ads.  Without this your browser will report a 404 error because it can't access the blocked pages, and your webpages will have 404 errors rendered where the ads used to be - not so pretty to look at.  If you're on Mac, you've already got Apache installed and ready to go.  If you're on Windows, you're going to have to set that up and then come back here when you're done.
&lt;p&gt;
[ Aside: I've been thinking that you don't really need to run a local webserver at all, if you have access to one on the web. That would allow any number of people on any network to benefit from a single filter file. ]
&lt;p style="clear: both;"&gt;
&lt;a name="getting-started"&gt;&lt;/a&gt;
&lt;h3 class="subtitle"&gt;Getting started&lt;/h3&gt;

&lt;!-- Page with ads --&gt;
&lt;div class="captioned-image left" style="margin-right: 20px;"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_LjUDvSJPqv4/Sh3ZOIiLq8I/AAAAAAAAACU/2fDbvtFJErI/s1600-h/Webpage+with+ads-2.jpg"&gt;&lt;img style="width: 320px; height: 251px;" src="http://3.bp.blogspot.com/_LjUDvSJPqv4/Sh3ZOIiLq8I/AAAAAAAAACU/2fDbvtFJErI/s320/Webpage+with+ads-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340663569963527106" /&gt;&lt;/a&gt;
&lt;div&gt;Webpage with Ads&lt;/div&gt;
&lt;/div&gt;

&lt;!-- Page without ads --&gt;
&lt;div class="captioned-image left" style="margin-right: 20px;"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_LjUDvSJPqv4/Sh3ZbSQzCII/AAAAAAAAACc/9JPiC1UiPAc/s1600-h/Webpage+without+ads-2.jpg"&gt;&lt;img style="width: 320px; height: 252px;" src="http://4.bp.blogspot.com/_LjUDvSJPqv4/Sh3ZbSQzCII/AAAAAAAAACc/9JPiC1UiPAc/s320/Webpage+without+ads-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340663795913263234" /&gt;&lt;/a&gt;
&lt;div&gt;Webpage without Ads&lt;/div&gt;
&lt;/div&gt;

First off, here's a little taste of how your new browsing experience will look.  On the left is a regular webpage followed by the same page minus the ads.  Ad free goodness!
&lt;p&gt;
The setup is simple.
&lt;ol&gt;
  &lt;li&gt;You have an Apache virtual host listening on a non-standard port, say 61111.  The virtual host does only one thing: it rewrites all requests to point to an empty HTML file, which I have named &lt;span class="code"&gt;response.html&lt;/span&gt;.&lt;/li&gt;
  &lt;li&gt;You also have a proxy configuration file, or PAC, which you configure your browser to use.  All requests from the browser are sent to this PAC file.  The PAC file examines the request and if it looks like it's  an advertisement it sends the request to our apache virtual host (which will render a blank page...so no ad will display).  Otherwise the request is served by the browser in the normal fashion.&lt;/li&gt;
&lt;/ol&gt;

&lt;a name="setup-apache"&gt;&lt;/a&gt;
&lt;h4 class="subtitle" style="clear: both;"&gt;Setup Apache&lt;/h4&gt;
&lt;em&gt;You're going to need to modify the paths according to where you put these files, and the setup of your machine.  These instructions are particular to Mac OS X, but the Windows setup is analagous.&lt;/em&gt;
&lt;p&gt;
On Mac, I think the easiest place to put our PAC file and the response.html file is in your &lt;span class="code"&gt;Public/&lt;/span&gt; directory which is under your home directory.  Extract &lt;a href="http://varzyfamily.com/links/blog/ad-blocker.zip"&gt;this archive (ad-blocker.zip)&lt;/a&gt; which contains four files: &lt;span class="code"&gt;favicon.ico&lt;/span&gt;, &lt;span class="code"&gt;proxy.conf&lt;/span&gt;, &lt;span class="code"&gt;response.html&lt;/span&gt; as well as a copy of &lt;span class="code"&gt;ad-blocker.conf&lt;/span&gt; (the Apache virtual host configuration file).
&lt;p&gt;
  
&lt;a name="configure-virtual-host"&gt;&lt;/a&gt;
&lt;h5 class="subtitle" style="clear: both;"&gt;Configure the virtual host&lt;/h5&gt;
You should have a directory under &lt;span class="code"&gt;/etc/apache2/&lt;/span&gt; called &lt;span class="code"&gt;other/&lt;/span&gt;.  You can define virtual hosts in their own conf files here and they will be read by Apache on startup.
&lt;p&gt;
In &lt;span class="code"&gt;/etc/apache2/other/&lt;/span&gt; create a file called &lt;span class="code"&gt;ad-blocker.conf&lt;/span&gt; with the following contents (this file is also contained in &lt;span class="code"&gt;ad-blocker.zip&lt;/span&gt;):
&lt;pre name="code" class="xml"&gt;
  ## Use Listen directives and not Port directive if server will handle
  ## requests from multiple ports.
  Listen 127.0.0.1:61111

  &amp;lt;VirtualHost *:61111&amp;gt;
  DocumentRoot &amp;quot;/Users/Karl/Public/ad-blocker&amp;quot;
  &amp;lt;directory &amp;quot;/Users/Karl/Public/ad-blocker&amp;quot;&amp;gt;
    Order allow,deny
    Allow from all
    Options +Indexes
  &amp;lt;/directory&amp;gt;
  ErrorLog /var/log/apache2/error_log_ads
  SetEnvIf Request_URI .* no-access-log
  CustomLog /dev/null common env=!no-access-log
  RewriteEngine on
  RewriteRule ^(.*) /Users/Karl/Public/ad-blocker/response.html
  &amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;
Now modify the &lt;span class="code"&gt;DocumentRoot&lt;/span&gt; and  &lt;span class="code"&gt;&amp;lt;directory ...&amp;gt;&lt;/span&gt; with the full path to the ad-blocker directory you added to Public, and modify the &lt;span class="code"&gt;RewriteRule&lt;/span&gt; directive to point to the &lt;span class="code"&gt;response.html&lt;/span&gt; file.
&lt;p&gt;
  
&lt;a name="start-apache"&gt;&lt;/a&gt;
&lt;h5 class="subtitle" style="clear: both;"&gt;Start Apache&lt;/h5&gt;

&lt;!-- Enable Web Sharing --&gt;
&lt;div class="captioned-image left"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_LjUDvSJPqv4/Sh3jos8cQ0I/AAAAAAAAACk/as6qZ7yONOk/s1600-h/Enable+Web+Sharing.jpg"&gt;&lt;img style="width: 320px; height: 266px;" src="http://2.bp.blogspot.com/_LjUDvSJPqv4/Sh3jos8cQ0I/AAAAAAAAACk/as6qZ7yONOk/s320/Enable+Web+Sharing.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340675021530219330" /&gt;&lt;/a&gt;
&lt;div&gt;Mac OSX: Enable Web Sharing&lt;/div&gt;
&lt;/div&gt;

On Mac, just enable &lt;b&gt;Web Sharing&lt;/b&gt; under &lt;b&gt;System Preferences -&gt; Sharing&lt;/b&gt;.  Apache will start, and if you visit &lt;a href="http://127.0.0.1:61111"&gt;http://127.0.0.1:61111&lt;/a&gt; you should see a blank page (with no errors or anything else).  If you get an error like &lt;span class="code" style="white-space: normal;"&gt;You don't have permissions to access / on this server&lt;/span&gt; you may permissions problems on your &lt;span class="code"&gt;ad-blocker&lt;/span&gt; directory, you may have messed up your &lt;span class="code"&gt;&amp;lt;directory ...&amp;gt;&lt;/span&gt; directive path, or you may need to enable File Sharing on the directory and give permissions to Everyone to Read.

&lt;p&gt;Apache should be up and running and ready to serve ads.
&lt;p&gt;Now the easy part.
&lt;br/&gt;
&lt;a name="configure-browsers"&gt;&lt;/a&gt;
&lt;h3 class="subtitle" style="clear: both;"&gt;Configure your browsers&lt;/h3&gt;
We need to configure the browser to use our proxy configuration file (PAC file).  For each browser, open your Preferences and configure the path to the &lt;span class="code"&gt;proxy.conf&lt;/span&gt; file for your machine using my screenshots as a guide.
&lt;p&gt;

&lt;div style="clear: both;"&gt;&lt;/div&gt;
&lt;a name="firefox"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;img style="float: left; clear: both; margin-right: 10px;" src="http://varzyfamily.com/links/blog/images/firefox.png" /&gt;
&lt;h5 class="subtitle"&gt;Firefox&lt;/h5&gt;

&lt;!-- Firefox advanced settings --&gt;
&lt;div  style="clear: both; margin-bottom: 15px;" class="captioned-image left"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_LjUDvSJPqv4/Sh3mR6srzJI/AAAAAAAAACs/J-Y4eN0tPfs/s1600-h/Firefox+Advanced+Settings-2.jpg"&gt;&lt;img style="width: 400px; height: 343px;" src="http://2.bp.blogspot.com/_LjUDvSJPqv4/Sh3mR6srzJI/AAAAAAAAACs/J-Y4eN0tPfs/s400/Firefox+Advanced+Settings-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340677928620117138" /&gt;&lt;/a&gt;
&lt;div style="margin-top: -20px;"&gt;&lt;em&gt;Open Preferences-&gt;Advanced-&gt;Network.  Then under Connection, click 'Settings...'&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;!-- Firefox proxy settings --&gt;
&lt;div  style="clear: both;" class="captioned-image left"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_LjUDvSJPqv4/Sh3mbHuQRHI/AAAAAAAAAC0/noUryYmyuA8/s1600-h/Firefox+Proxy+Settings-2.jpg"&gt;&lt;img style="width: 400px; height: 378px;" src="http://4.bp.blogspot.com/_LjUDvSJPqv4/Sh3mbHuQRHI/AAAAAAAAAC0/noUryYmyuA8/s400/Firefox+Proxy+Settings-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5340678086735185010" /&gt;&lt;/a&gt;
&lt;div&gt;&lt;em&gt;Select 'Automatic proxy configuration URL' and enter the path to the proxy.conf file&lt;/em&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div style="clear: both;"&gt;&lt;/div&gt;
&lt;a name="opera"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;img style="float: left; margin-right: 10px;" src="http://varzyfamily.com/links/blog/images/opera.gif" /&gt;
&lt;h5 class="subtitle"&gt;Opera&lt;/h5&gt;

&lt;div  style="clear: both; margin-bottom: 15px;" class="captioned-image left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_LjUDvSJPqv4/SiD1cX66raI/AAAAAAAAAC8/IBCJHKBc6IM/s1600-h/Opera+Advanced+Preferences-2.jpg"&gt;&lt;img style="width: 400px; height: 302px;" src="http://2.bp.blogspot.com/_LjUDvSJPqv4/SiD1cX66raI/AAAAAAAAAC8/IBCJHKBc6IM/s400/Opera+Advanced+Preferences-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341539025867681186" /&gt;&lt;/a&gt;
  &lt;div  style="margin-top: -20px;"&gt;&lt;em&gt;Open Preferences-&gt;Advanced-&gt;Network and click on 'Proxy Servers'&lt;/em&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;br/&gt;
  &lt;div  style="clear: both;" class="captioned-image left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LjUDvSJPqv4/SiD1ciCwbwI/AAAAAAAAADE/pAozxC-R1TE/s1600-h/Opera+Proxy+Servers-2.jpg"&gt;&lt;img style="width: 392px; height: 400px;" src="http://1.bp.blogspot.com/_LjUDvSJPqv4/SiD1ciCwbwI/AAAAAAAAADE/pAozxC-R1TE/s400/Opera+Proxy+Servers-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341539028584918786" /&gt;&lt;/a&gt;
    &lt;div  style="margin-top: -20px;"&gt;Select 'Use automatic proxy configuration' and enter the path to the proxy.conf file&lt;/div&gt;
    &lt;/div&gt;
      


&lt;div style="clear: both;"&gt;&lt;/div&gt;
&lt;a name="safari"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;img style="float: left; margin-right: 10px;" src="http://varzyfamily.com/links/blog/images/safari.jpg" /&gt;
&lt;h5 class="subtitle"&gt;Safari&lt;/h5&gt;

&lt;div  style="clear: both;  margin-bottom: 15px;" class="captioned-image left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_LjUDvSJPqv4/SiD1c6ietdI/AAAAAAAAADM/SQFDiVBrAVU/s1600-h/Safari+Advanced+Settings-2.jpg"&gt;&lt;img style="width: 400px; height: 276px;" src="http://4.bp.blogspot.com/_LjUDvSJPqv4/SiD1c6ietdI/AAAAAAAAADM/SQFDiVBrAVU/s400/Safari+Advanced+Settings-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341539035160425938" /&gt;&lt;/a&gt;
  &lt;div style="margin-top: -20px;"&gt;&lt;em&gt;Open Preferences-&gt;Advanced and click 'Proxies: Change Settings...'&lt;/em&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;br/&gt;    
    &lt;div  style="clear: both; width: 500px;  margin-bottom: 15px;" class="captioned-image left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_LjUDvSJPqv4/SiD1dLU4W0I/AAAAAAAAADc/lFkQZug4v9s/s1600-h/System+Proxy+Settings-2.jpg"&gt;&lt;img style="width: 400px; height: 292px;" src="http://3.bp.blogspot.com/_LjUDvSJPqv4/SiD1dLU4W0I/AAAAAAAAADc/lFkQZug4v9s/s400/System+Proxy+Settings-2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341539039666789186" /&gt;&lt;/a&gt;
      &lt;div&gt;&lt;em&gt;This should bring up your OS X Network-&gt;Proxies settings.  Select 'Configure Proxies: Using a PAC file' and enter the path to the proxy.conf file&lt;/em&gt;&lt;/div&gt;
      &lt;/div&gt;
&lt;br/&gt;      
  &lt;div  style="clear: both; width: 500px;" class="captioned-image left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_LjUDvSJPqv4/SiD1dO5pQHI/AAAAAAAAADU/TBbuNn2lKb8/s1600-h/Network+Settings-3.jpg"&gt;&lt;img style="width: 400px; height: 324px;" src="http://4.bp.blogspot.com/_LjUDvSJPqv4/SiD1dO5pQHI/AAAAAAAAADU/TBbuNn2lKb8/s400/Network+Settings-3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341539040626294898" /&gt;&lt;/a&gt;
    &lt;div style="margin: 5px 0;"&gt;&lt;em&gt;Alternatively you can get there from OS X System Preferences-&gt;Network click on 'Advanced' then 'Proxies'&lt;/em&gt;&lt;/div&gt;
    &lt;/div&gt;

&lt;div style="clear: both;"&gt;&lt;/div&gt; 
&lt;a name="the-pac-file"&gt;&lt;/a&gt;&lt;br /&gt;   
&lt;h3 class="subtitle"&gt;The PAC file&lt;/h3&gt;
Here's the proxy configuration (PAC) file if you just want to have a look at how it's setup.  I've modified the original file that I reference in the comments by adding two really useful JavaScript functions, &lt;span class="code"&gt;domainMatch()&lt;/span&gt; and &lt;span class="code"&gt;subdomainMatch()&lt;/span&gt;.  These perform regular expression matching on the URL and can filter URLs by domain e.g. &lt;span class="code"&gt;domainMatch('doubleclick.net')&lt;/span&gt; or by subdomain e.g. &lt;span class="code"&gt;subdomainMatch('ads')&lt;/span&gt;.  This makes it much cleaner and more powerful than calling &lt;span class="code"&gt;shExpMatch(host, ...)&lt;/span&gt; every time and using sub-par pattern matching.
&lt;p&gt;
Here's the code...
&lt;pre name="code" class="javascript"&gt;
  /**
   * Proxy configuration file to block ads.
   * 
   * From &amp;lt;http://hydra.nac.uci.edu/indiv/ehood/gems/ad-blocking.html&amp;gt;
   * Host matching adapted from hostname list at
   *    &amp;lt;http://www.ecst.csuchico.edu/~atman/spam/adblock.shtml&amp;gt;
   * Regular-expression matching functions added by Karl Varga
   *    &amp;lt;kjvarga.blogspot.com&amp;gt;
   *
   * The proxy is assumed to be listening on 127.0.0.1:61111.  Change
   * the return &amp;quot;PROXY ...&amp;quot; statement near the end of the file to
   * suit your local configuration.
   */



  /**
   * Add an escape function to the RegExp object.
   * 
   * @see http://simonwillison.net/2006/Jan/20/escape/
   */
  RegExp.escape = function(text) {
    if (!arguments.callee.sRE) {
      var specials = [
        '/', '.', '*', '+', '?', '|',
        '(', ')', '[', ']', '{', '}', '\\'
      ];
      arguments.callee.sRE = new RegExp(
        '(\\' + specials.join('|\\') + ')', 'g'
      );
    }
    return text.replace(arguments.callee.sRE, '\\$1');
  }

  /**
   * A domain is matched if it is preceeded by one or more subdomains,
   * or no subdomains.  A domain does not match a similar domain with text
   * prepended.
   */
  function domainMatch(host, domain) {
    var regex = new RegExp('^([^.]+\\.)*' + RegExp.escape(domain) + '$', 'i');
    return regex.test(host);
  }

  /**
   * Match any subdomain.
   */
  function subdomainMatch(host, subdomain) {
    var regex = new RegExp('^.*[.]' + RegExp.escape(subdomain) 
        + '[.].*$|^' + RegExp.escape(subdomain) + '[.].*$', 'i');
    return regex.test(host);
  }

  /**
   * Called by the browser to determine whether to proxy the request or not.
   */
  function FindProxyForURL(url, host) {

    if (

      /**
       * Domains.
       */
      domainMatch(host, &amp;quot;PostMasterBannerNet.com&amp;quot;) ||
      domainMatch(host, &amp;quot;adbureau.net&amp;quot;) ||
      domainMatch(host, &amp;quot;admaximize.com&amp;quot;) ||
      domainMatch(host, &amp;quot;admex.com&amp;quot;) ||
      domainMatch(host, &amp;quot;alladvantage.com&amp;quot;) ||
      domainMatch(host, &amp;quot;avenuea.com&amp;quot;) ||
      domainMatch(host, &amp;quot;bizservers.com&amp;quot;) ||
      domainMatch(host, &amp;quot;burstnet.com&amp;quot;) ||
      domainMatch(host, &amp;quot;click2net.com&amp;quot;) ||
      domainMatch(host, &amp;quot;clicktrade.com&amp;quot;) ||
      domainMatch(host, &amp;quot;commision-junction.com&amp;quot;) ||
      domainMatch(host, &amp;quot;digitalriver.com&amp;quot;) ||
      domainMatch(host, &amp;quot;doubleclick.net&amp;quot;) ||
      domainMatch(host, &amp;quot;eads.com&amp;quot;) ||
      domainMatch(host, &amp;quot;extreme-dm.com&amp;quot;) ||
      domainMatch(host, &amp;quot;flycast.com&amp;quot;) ||
      domainMatch(host, &amp;quot;focalink.com&amp;quot;) ||
      domainMatch(host, &amp;quot;freestats.com&amp;quot;) ||
      domainMatch(host, &amp;quot;hitbox.com&amp;quot;) ||
      domainMatch(host, &amp;quot;iadnet.com&amp;quot;) ||
      domainMatch(host, &amp;quot;imaginemedia.com&amp;quot;) ||
      domainMatch(host, &amp;quot;imgis.com&amp;quot;) ||
      domainMatch(host, &amp;quot;link4ads.com&amp;quot;) ||
      domainMatch(host, &amp;quot;mediaplex.com&amp;quot;) ||
      domainMatch(host, &amp;quot;netdirect.nl&amp;quot;) ||
      domainMatch(host, &amp;quot;ngadcenter.net&amp;quot;) ||
      domainMatch(host, &amp;quot;oneandonlynetwork.com&amp;quot;) ||
      domainMatch(host, &amp;quot;preferences.com&amp;quot;) ||
      domainMatch(host, &amp;quot;targetshop.com&amp;quot;) ||
      domainMatch(host, &amp;quot;teknosurf2.com&amp;quot;) ||
      domainMatch(host, &amp;quot;teknosurf3.com&amp;quot;) ||
      domainMatch(host, &amp;quot;trix.net&amp;quot;) ||
      domainMatch(host, &amp;quot;valueclick.com&amp;quot;) ||
      domainMatch(host, &amp;quot;websitefinancing.com&amp;quot;) ||
      domainMatch(host, &amp;quot;2mdn.net&amp;quot;) ||
      domainMatch(host, &amp;quot;brandreachsys.com&amp;quot;) ||
      domainMatch(host, &amp;quot;fastclick.net&amp;quot;) ||
      domainMatch(host, &amp;quot;eyewonder.com&amp;quot;) ||
      domainMatch(host, &amp;quot;clicktorrent.info&amp;quot;) ||
      // domainMatch(host, &amp;quot;yimg.com&amp;quot;) ||
      domainMatch(host, &amp;quot;pop6.com&amp;quot;) ||
      domainMatch(host, &amp;quot;adinterax.com&amp;quot;) ||
      domainMatch(host, &amp;quot;atdmt.com&amp;quot;) ||
      domainMatch(host, &amp;quot;fling.com&amp;quot;) ||
      domainMatch(host, &amp;quot;serving-sys.com&amp;quot;) ||
      domainMatch(host, &amp;quot;fuelbuck.com&amp;quot;) ||
      domainMatch(host, &amp;quot;blogads.com&amp;quot;) ||
      domainMatch(host, &amp;quot;doublepimp.com&amp;quot;) ||
      domainMatch(host, &amp;quot;etology.com&amp;quot;) ||
      domainMatch(host, &amp;quot;adshuffle.com&amp;quot;) ||
      domainMatch(host, &amp;quot;awempire.com&amp;quot;) ||
      domainMatch(host, &amp;quot;adjuggler.com&amp;quot;) ||
      domainMatch(host, &amp;quot;atdmt.com&amp;quot;) ||
      domainMatch(host, &amp;quot;edgesuite.net&amp;quot;) ||

      /**
       * Subdomains
       */
      subdomainMatch(host, &amp;quot;ads&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads0&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads1&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads2&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads3&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads4&amp;quot;) ||
      subdomainMatch(host, &amp;quot;ads5&amp;quot;) ||
      subdomainMatch(host, &amp;quot;banners&amp;quot;) ||
      subdomainMatch(host, &amp;quot;banner&amp;quot;) ||
      subdomainMatch(host, &amp;quot;adcontroller&amp;quot;) ||
      subdomainMatch(host, &amp;quot;click&amp;quot;) ||

      /**
       * Hostname Patterns
       */
      shExpMatch(host, &amp;quot;*-ad.*&amp;quot;) ||
      shExpMatch(host, &amp;quot;*adlink.*&amp;quot;) ||
      shExpMatch(host, &amp;quot;ad-*.com&amp;quot;) ||
      shExpMatch(host, &amp;quot;ad.*&amp;quot;) ||
      shExpMatch(host, &amp;quot;ad0*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adcontroller*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adcreatives*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adex*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adforce*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adfu.*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adimage*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adimg*&amp;quot;) ||
      shExpMatch(host, &amp;quot;admedia*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adpick*&amp;quot;) ||
      shExpMatch(host, &amp;quot;adremote*&amp;quot;) ||
      shExpMatch(host, &amp;quot;ngads*&amp;quot;) ||
      shExpMatch(host, &amp;quot;nsads*&amp;quot;) ||
      shExpMatch(host, &amp;quot;ph-ad*&amp;quot;) ||
      shExpMatch(host, &amp;quot;realads*&amp;quot;) ||

      /**
       * URLs
       */
      shExpMatch(url, &amp;quot;*.weather.com/*/ads/*&amp;quot;) ||
      shExpMatch(url, &amp;quot;*/adimages/*&amp;quot;) ||
      shExpMatch(url, &amp;quot;*/adsmanager/*&amp;quot;) ||

      false   
    ) {

      // Proxy the request
      return &amp;quot;PROXY 127.0.0.1:61111&amp;quot;;

    }

    // Let the browser handle it
    return &amp;quot;DIRECT&amp;quot;;
  }  
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-8696059929333376851?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/8696059929333376851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=8696059929333376851' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8696059929333376851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8696059929333376851'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/05/how-to-setup-ad-blocking-proxy-in-10.html' title='How to setup an ad-blocking proxy in 10 minutes and block ads in all your favorite browsers!'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_LjUDvSJPqv4/Sh3Yy5mkXbI/AAAAAAAAACM/xARcfs2wfEo/s72-c/Opera+ad+blocker-2.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-7958410845256452887</id><published>2009-05-22T00:03:00.000-07:00</published><updated>2009-05-27T17:07:55.890-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>makePositioned: A jQuery extension function to dynamically position an element near another element</title><content type='html'>I've recently been working on a dynamic select/auto-complete list (which I'll post about soon) and I had to position the dynamically-created div under the input when the user enters some text.  jQuery makes it quite easy to position elements in this manner because you have access to elements position and size, but who wants to go to the hassle every time?
&lt;p&gt;
So I've created a jQuery extension function called &lt;span class="code"&gt;makePositioned&lt;/span&gt; which is called on the element you want to position and accepts two arguments: the alignment position (either &lt;span class="code"&gt;top&lt;/span&gt;, &lt;span class="code"&gt;right&lt;/span&gt;, &lt;span class="code"&gt;bottom&lt;/span&gt; or &lt;span class="code"&gt;left&lt;/span&gt;) and the element to position it against.  You would usually use this for positioning dynamically created content, for instance help popups beside form input fields, ajax feedback icons etc.
&lt;p&gt;
Let me know if you find this useful, or if you add support for more alignment options.  &lt;span class="code"&gt;top&lt;/span&gt; aligns above left, &lt;span class="code"&gt;right&lt;/span&gt; aligns top right, &lt;span class="code"&gt;bottom&lt;/span&gt; aligns bottom left, and &lt;span class="code"&gt;left&lt;/span&gt; aligns top left.  It doesn't do any fancy checking to see if there is room in the viewport below the element, but that would be a nice feature to add.
&lt;p&gt;
Here's a demo.  Check out &lt;a href="#the-code"&gt;the code&lt;/a&gt; below.
&lt;p&gt;
&lt;div id="demo" style="margin: 0 auto; width: 400px; height: 200px; position: relative;"&gt;
  &lt;div id="makePositioned" style="width: 150px; padding: 10px; background: #88BB22 url(http://www.blogblog.com/moto_son/headbotborder.gif) repeat-x scroll left bottom; height: 50px; position: absolute; left: 125px; top: 50px; color: white; font-size: 1.2em; z-index: 1000;"&gt;
    Click the buttons to position this div.
  &lt;/div&gt;
  &lt;input type="button" style="position: absolute; left: 0; top: 0; padding: 10px;" 
      value="Align Bottom"  name="bottom"/&gt;
  &lt;input type="button" style="position: absolute; right: 0; top: 0; padding: 10px;" 
      value="Align Left" name="left"/&gt;
  &lt;input type="button" style="position: absolute; bottom: 0; left: 0; padding: 10px;" 
      value="Align Top"  name="top"/&gt;
  &lt;input type="button" style="position: absolute; bottom: 0; right: 0px; padding: 10px;" 
      value="Align Right"  name="right"/&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;
  $(function() {
    $('#demo input').click(function() {
      // Do this because otherwise when we align right it is hidden by the overflow: hidden
      if ($('#makePositioned').parent('#demo').length) {
        $('body').append($('#makePositioned').hide());
      }
      $('#makePositioned').makePositioned($(this).attr('name'), $(this)).show();
    });
  });
&lt;/script&gt;

&lt;h2&gt;The Code&lt;/h2&gt;
&lt;a name="the-code"&gt;&lt;/a&gt;
&lt;pre name="code" class="javascript"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
/** 
 * Extend jQuery.
 *
 */
jQuery.fn.extend({

  /**
   * Position the first element in the jQuery list near another element 
   * using absolute positioning. The element should already have the 
   * proper z-Index set.
   * 
   * @param string align &amp;#039;bottom&amp;#039; for bottom left, or &amp;#039;right&amp;#039; for top right,
   *    &amp;#039;left&amp;#039; for top left, &amp;#039;top&amp;#039; for above left.
   */
  makePositioned: function(align, element) {
    var first = this.eq(0);
    var pos, height, width, left, top, thisHeight, thisWidth;
    pos = element.offset();
    height = element.outerHeight(), width = element.outerWidth();
    left = pos.left, top = pos.top;
    thisHeight = first.outerHeight(), thisWidth = first.outerWidth();
    
    switch (align) { 
      case &amp;#039;bottom&amp;#039;:
        top += height;
      break;
      case &amp;#039;right&amp;#039;:
        left += width;
      break;
      case &amp;#039;left&amp;#039;:
        left = left - thisWidth;
      break;
      case &amp;#039;top&amp;#039;:
        top = top - thisHeight;
      break;
    }

    first.css({ 
      top: parseInt(top)+&amp;#039;px&amp;#039;, 
      left: parseInt(left)+&amp;#039;px&amp;#039;,
      position: &amp;#039;absolute&amp;#039;
    });
    
    return this;
  }

});
&amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-7958410845256452887?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/7958410845256452887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=7958410845256452887' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7958410845256452887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7958410845256452887'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/05/makepositioned-jquery-extension.html' title='makePositioned: A jQuery extension function to dynamically position an element near another element'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4424114151135295415</id><published>2009-05-06T17:42:00.000-07:00</published><updated>2009-05-06T17:50:41.540-07:00</updated><title type='text'>Keep using TextMate unregistered, indefinitely (forever, aka eternity)</title><content type='html'>Ok, this one is real easy.  I didn't come up with it, but I often forget where the file is that I'm supposed to delete so I thought I'd put a note here and never forget again...until next month :)
&lt;p&gt;
This is a one-step process.  Not two, not three.  Just one.  Delete the following file:
&lt;div class="code"&gt;
~/Library/Preferences/com.macromates.textmate.plist
&lt;/div&gt;
Done already?  You'll lose your preferences, but if you're too skint to buy this stuff then you don't deserve to have preferences.
&lt;p&gt;
If you're wondering what will happen next, you'll get 30 more days to evaluate TextMate.  See you in 30 days :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4424114151135295415?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4424114151135295415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4424114151135295415' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4424114151135295415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4424114151135295415'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/05/keep-using-textmate-unregistered.html' title='Keep using TextMate unregistered, indefinitely (forever, aka eternity)'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-808504204408648478</id><published>2009-04-29T01:50:00.000-07:00</published><updated>2009-05-21T21:53:36.322-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery extensions to support highlight effects on hidden elements</title><content type='html'>I was disappointed with the lack of support for show, hide, fade and highlight effects on hidden elements in &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.  By hidden I mean that they have &lt;span class="code"&gt;visibility: hidden&lt;/span&gt; and not &lt;span class="code"&gt;display: none&lt;/span&gt; (so they still take up space in the DOM but are not "visible").  Almost all of jQuery's functions to hide and show elements toggle their states between &lt;span class="code"&gt;display: block;&lt;/span&gt; and &lt;span class="code"&gt;display: none;&lt;/span&gt;.  This is alright in some cases, but sometimes you want the element to still take up DOM space.
&lt;p /&gt;
Even the &lt;span class="code"&gt;:hidden&lt;/span&gt; selector doesn't work on &lt;span class="code"&gt;visibility: hidden&lt;/span&gt; elements.  So I've added an extension function called hidden() which returns a jQuery list of elements with &lt;span class="code"&gt;visibility: hidden&lt;/span&gt;.  So if you want to test if something is hidden you can do &lt;span class="code"&gt;if ($('#element').hidden().length) { ... }&lt;/span&gt;, as well as call regular jQuery methods on the result like so &lt;span class="code"&gt;$('#table td:hidden').show();&lt;/span&gt;.
&lt;p /&gt;
Because most of the time I want to highlight elements when I show/hide, the extension functions I have written use the &lt;a href="http://jqueryui.com/docs/effect/"&gt;jQuery Highlight effect&lt;/a&gt;.  So you will need that to run this code.  You will also need the UI Core (required for all effects) and of course the &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; library.
&lt;p /&gt;
Another annoying thing is that the jQuery UI highlight effects don't work on table rows.  I suspect it's because table rows have a display mode of &lt;span class="code"&gt;display: table-row;&lt;/span&gt; as opposed to the usual &lt;span class="code"&gt;display: none;&lt;/span&gt;.  Because I often need to highlight show/hide table rows, I've added support for them in my extension functions.
&lt;p /&gt;
There are four highlight methods:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;highlightShow&lt;/strong&gt;: highlight and fade in (show) an element or elements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;highlightFade&lt;/strong&gt;: highlight and fade out (to visibility: hidden) an element or elements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;highlightHide&lt;/strong&gt;: highlight, fade out and hide (display: none) an element or elements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;highlightRemove&lt;/strong&gt;: highlight, fade out and remove from the DOM an element or elements.&lt;/li&gt;
&lt;/ul&gt;

Let me know if you've found this useful!  Enjoy the slick JavaSripty goodness!

&lt;h2&gt;The Demo&lt;/h2&gt;
&lt;div class="demo"&gt;
&lt;script type="text/javascript"&gt;

$().ready(function() {

  $('#demo-table').listen('click', 'input.remove', function(e) {
    $(this).closest('tr').highlightRemove(2000); 
  });
  
  $('#demo-table').listen('click', 'input.fade', function(e) {
    $(this).closest('tr').highlightFade(2000); 
  });
  
  $('#add-row').click(function() {
    var hidden = $('#demo-table tr:hidden'); 
    var clone = hidden.clone(); 
    hidden.after(clone.show()); 
    clone.highlightShow(2000); 
  });
  
});

&lt;/script&gt;
&lt;style type="text/css"&gt;
#demo-text {
  border: 1px solid #006699;
  background-color: #aaeeff;
  font-size: 15px;
  line-height: 30px;
  height: 30px;
  margin: 0 auto;
  padding: 0 15px;
}
#demo-table {
  border: 1px solid #006699;
  background-color: #aaeeff;
}
&lt;/style&gt;

&lt;strong&gt;A Regular DIV&lt;/strong&gt;
&lt;p&gt;
&lt;table id="demo-text-wrapper" style="border: 4px solid #eee;"&gt;
&lt;caption&gt;Wrapper&lt;/caption&gt;
&lt;tr&gt;&lt;td&gt;
  &lt;div id="demo-text"&gt;This is the text we will fade in and out.&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;input type="button" value="Highlight Hide" onclick="javascript: $('#demo-text').highlightHide(2000);" /&gt;
&lt;input type="button" value="Highlight Show" onclick="javascript: $('#demo-text').highlightShow(2000);"/&gt;
&lt;input type="button" value="Highlight Fade" onclick="javascript: $('#demo-text').highlightFade(2000);"/&gt;
&lt;input type="button" value="Highlight Remove" onclick="javascript: $('#demo-text').highlightRemove(2000);" /&gt;
&lt;input type="button" value="Reset" onclick="javascript: $('#demo-text-wrapper td').html('&amp;lt;div id=&amp;quot;demo-text&amp;quot;&amp;gt;This is the text we will fade in and out.&amp;lt;/div&amp;gt;').highlightShow(2000);" /&gt;
&lt;p style="margin-top: 20px" /&gt;
&lt;strong&gt;A Table&lt;/strong&gt;
&lt;p&gt;
&lt;table id="demo-table" border="0" cellspacing="0" cellpadding="3"&gt;
  &lt;tr&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Occupation&lt;/th&gt;&lt;th&gt;Height&lt;/th&gt;&lt;td&gt;Remove&lt;/td&gt;&lt;td&gt;Fade&lt;/td&gt;&lt;/tr&gt;
  &lt;tr style="display: none;"&gt;&lt;td&gt;Karl Varga&lt;/td&gt;&lt;td&gt;Programmer&lt;/td&gt;&lt;td&gt;6'&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="remove" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="fade"/&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Karl Varga&lt;/td&gt;&lt;td&gt;Programmer&lt;/td&gt;&lt;td&gt;6'&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="remove" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="fade"/&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;John Edward&lt;/td&gt;&lt;td&gt;Student&lt;/td&gt;&lt;td&gt;10' 5"&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="remove"/&gt;&lt;/td&gt;&lt;td&gt;&lt;input type="checkbox" class="fade"/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;input type="button" id="add-row" value="Add Row" /&gt;
&lt;p /&gt;
The JavaScript code for the table effects uses &lt;a href="http://www.cherny.com/webdev/70/javascript-event-delegation-and-event-hanlders"&gt;event delegation&lt;/a&gt; to bind events to the checkboxes.  This means that you can bind an event handler to a top-level element.  When sub-elements receive events they bubble up the DOM to the parent, which handles it.  This way, I just have to write a handler for the remove and fade events on the table and when I add new rows to the table those new rows will also support the remove and fade events because the handler is not bound to each individual checkbox, but rather to the parent table.  Neat!
&lt;p&gt;
It uses the &lt;a href="http://plugins.jquery.com/project/Listen"&gt;jQuery Listen plugin&lt;/a&gt; and here is the JavaScript snippet:
&lt;pre name="code" class="javascript"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;

$().ready(function() {

  $('#demo-table').listen('click', 'input.remove', function(e) {
    $(this).closest('tr').highlightRemove(2000); 
  });
  
  $('#demo-table').listen('click', 'input.fade', function(e) {
    $(this).closest('tr').highlightFade(2000); 
  });
  
  $('#add-row').click(function() {
    var hidden = $('#demo-table tr:hidden'); 
    var clone = hidden.clone(); 
    hidden.after(clone); 
    clone.highlightShow(2000); 
  });
  
});
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;h2&gt;The Code&lt;/h2&gt;

Here are my jQuery extensions.  If you are using jQuery in &lt;em&gt;no conflict&lt;/em&gt; mode you will have to include this JavaScript before your &lt;em&gt;noConflict&lt;/em&gt; call, or do a search-and-replace on the &lt;span class="code"&gt;$&lt;/span&gt; function.&lt;p /&gt;

&lt;pre name="code" class="javascript"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;

jQuery.fn.extend({
  
  /**
   * Highlight and fade out an element to visibility: hidden so that it still takes up DOM space.
   * Works for table rows (which use display: table-row as opposed to the usual display: block).
   *
   */
  highlightFade: function(speed) {
    this.each(function() { 
    $(this).effect('highlight', { mode: 'hide' }, speed, function() {
      // retore the elements visibility and display type
      this.style.visibility = &amp;quot;hidden&amp;quot;;
      if ($(this).is('tr')) {
        this.style.display = 'table-row';
      } else {
        this.style.display = 'block';
      }
    });
  });
  return this;
  },

  /**
   * Highlight and fade out an element to display: none.  Just a wrapper for effect('highlight', ...)
   * for completeness.  Use highlightFade() to highlight and fade but still maintain visibility.
   */
  highlightHide: function(speed) {
    this.effect('highlight', { mode: 'hide' }, speed);
  return this;
  },

  /**
   * Highlight and fade in an element.  Works for visibility: hidden elements as well 
   * as elements with display: none.  jQuery highlight doesn't work on table rows, so
   * we apply the effect to the row cells.
   */
  highlightShow: function(speed) {
    this.each(function() {
    if ($(this).hidden().length) {
      this.style.display = &amp;quot;none&amp;quot;;         // highlight only works when display is none
      this.style.visibility = &amp;quot;visible&amp;quot;;
    }
    var apply_to = $(this);
    if ($(this).is('tr')) {
      apply_to = apply_to.find('td');
    }
    apply_to.effect('highlight', {}, speed);
  });
  return this;
  },

  /**
   * Highlight fade out and remove.  jQuery highlight doesn't work on table rows, so
   * we apply the effect to the row cells.
   */
  highlightRemove: function(speed, callback) {
  this.each(function() {
    var original_target = $(this);
    var apply_to = original_target;
    if ($(this).is('tr')) {
      apply_to = apply_to.find('td');
    }
    apply_to.effect(&amp;quot;highlight&amp;quot;, {mode: 'hide'}, speed, function() { 
      original_target.remove();
      if (callback != undefined) {
        callback.call(this);
      }
    });
  });
  return this;
  },

  /**
   * Return elements which have visibility: hidden.
   * The jQuery :hidden selector only matches elements with display: none.
   */
  hidden: function() {
  var hidden = [];
  this.each(function() {
    if (this.style.visibility == 'hidden') {
      hidden.push(this);
    }
  });
  return $(hidden);
  }
});'

&amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-808504204408648478?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/808504204408648478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=808504204408648478' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/808504204408648478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/808504204408648478'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/04/jquery-extensions-to-support-highlight.html' title='jQuery extensions to support highlight effects on hidden elements'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-7835889368989371609</id><published>2009-04-22T00:28:00.000-07:00</published><updated>2009-05-03T19:00:47.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Output JavaScript date in human-readable format (Day Month DD YYYY HH:MM:SS PM)</title><content type='html'>You often need to display the user's current date and time on a website in a custom format.  Unfortunately JavaScript doesn't have (many) date formatting functions built-in so you either have to use someone else's JS date formatting "library" or roll your own.
&lt;p&gt;
&lt;script language="JavaScript" type="text/javascript"&gt;

/**
 * Format a date as Day Month DD YYYY HH:MM:SS PM
 */
formatDate = function(date) {
 var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
 var months = ["January", "February", "March", "April", "May", 
   "June", "July", "August", "September", "October", "November", "December"];
  var pad = function(str) { str = String(str); return (str.length &lt; 2) ? "0" + str : str; }

 var meridian = (parseInt(date.getHours() / 12) == 1) ? 'PM' : 'AM';
 var hours = date.getHours() &gt; 12 ? date.getHours() - 12 : date.getHours();
 return days[date.getDay()] + ' ' + months[date.getMonth()] + ' ' + date.getDate() + ' ' 
   + date.getFullYear() + ' ' + hours + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds())
   + ' ' + meridian;
}
&lt;/script&gt;
For simplicity I rolled my own.  And since this is common thing that we all need to do from time to time I thought I would share my code in case you find it useful.
&lt;h2&gt;The Demo&lt;/h2&gt;
(The format the date appears in is &lt;b&gt;Day Month DD YYYY HH:MM:SS PM&lt;/b&gt;.)
&lt;p&gt;
The date and time right now is
&lt;div style="font-size: 15px; color: #666; margin-left: 20px; margin-top: 10px;" id="format-date"&gt;&lt;/div&gt;
  &lt;script type="text/javascript"&gt; 
    document.getElementById('format-date').innerHTML = formatDate(new Date());
  &lt;/script&gt;
&lt;h2&gt;The Code&lt;/h2&gt;
&lt;pre name="code" class="javascript"&gt;&lt;script language="JavaScript" type="text/javascript"&gt;
/**
 * Format a date as Day Month DD YYYY HH:MM:SS PM
 */
formatDate = function(date) {
 var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
 var months = ["January", "February", "March", "April", "May", 
   "June", "July", "August", "September", "October", "November", "December"];
  var pad = function(str) { str = String(str); return (str.length &lt; 2) ? "0" + str : str; }

 var meridian = (parseInt(date.getHours() / 12) == 1) ? 'PM' : 'AM';
 var hours = date.getHours() &gt; 12 ? date.getHours() - 12 : date.getHours();
 return days[date.getDay()] + ' ' + months[date.getMonth()] + ' ' + date.getDate() + ' ' 
     + date.getFullYear() + ' ' + hours + ':' + pad(date.getMinutes()) + ':' 
     + pad(date.getSeconds()) + ' ' + meridian;
}
&lt;/script&gt;
&lt;div id="format-date"&gt;&lt;!-- The date goes in here --&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt; 
  document.getElementById('format-date').innerHTML = formatDate(new Date());
&lt;/script&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-7835889368989371609?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/7835889368989371609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=7835889368989371609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7835889368989371609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7835889368989371609'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/04/output-javascript-date-in-human.html' title='Output JavaScript date in human-readable format (Day Month DD YYYY HH:MM:SS PM)'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-6811454641557044107</id><published>2009-04-21T23:36:00.000-07:00</published><updated>2009-05-03T19:00:59.077-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Simple JavaScript expanding text input</title><content type='html'>Today my colleague had a requirement for a simple expanding text input on a website form.  By expanding I don't mean that it gets bigger as you type, just that when you click/focus into the text input it appears to grow giving you a larger multi-line textarea in which to post a comment. Unfortunately I couldn't whip out &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; (which is my new favourity JS library after using &lt;a href="http://prototypejs.org"&gt;Prototype&lt;/a&gt; for some time) because we just needed this one bit of DHTML.
&lt;p&gt;
Requirements
&lt;ul&gt;
&lt;li&gt;When user clicks/focuses on the input show a larger textarea.&lt;/li&gt;
&lt;li&gt;The textarea must appear above the other form elements but leave some of the submit button showing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Demo&lt;/h2&gt;
&lt;script language="JavaScript" type="text/javascript"&gt;
/**
 * Expand an input when the user clicks into it.
 */
var expandingInput = {
 focusSmallInput: function(input) {
  input.style.visibility = 'hidden';
  var largeInput = document.getElementById('largeInput'); 
  largeInput.style.display = 'block'; 
  largeInput.focus(); 
  largeInput.style.position = 'absolute';
 },
 
 blurLargeInput: function(input) {
  input.style.display = 'none';
  var smallInput = document.getElementById('smallInput'); 
  smallInput.style.visibility = 'visible'; 
  smallInput.value = input.value; // Copy the value over
 }
};

&lt;/script&gt;
&lt;style type="text/css"&gt;

/**
 * Styles for the expanding / contracting input
 */
div.container {
 margin: 0 auto; 
 background-color: #eee; 
 width: 350px; 
 padding: 10px;
 line-height: 25px;
 font-size: 15px;
 color: #666;
}
div.container input, div.container textarea { font-size: 15px; color: #666; }

#smallInput {
 height: 30px;
 width: 250px;
 overflow: hidden;

}
#largeInput {
 display: none;
 height: 80px;
 width: 350px;
 overflow-x: hidden;
 overflow-y: auto;
 word-wrap: break-word;
 z-index: 1000;
}

&lt;/style&gt;
&lt;div class="container"&gt;
&lt;div&gt;Click in the input to see it grow.&lt;/div&gt;
&lt;br/&gt;
&lt;!-- The textarea must come before the div.  Use DIVs, not BReaks to put them on their own lines
  because the break messes up the overlapping. --&gt;
&lt;div&gt;
 &lt;textarea id="largeInput" onblur="javascript: expandingInput.blurLargeInput(this);"&gt;&lt;/textarea&gt;
&lt;/div&gt;
&lt;div&gt;
 &lt;input type="text" id="smallInput" onfocus="javascript: expandingInput.focusSmallInput(this);" value="" /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;input type="button" name="submit" value="Submit" style="margin-top: 30px; width: 100px; height: 30px;"/&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2&gt;The Code&lt;/h2&gt;
&lt;pre name="code" class="html"&gt;&lt;script language="JavaScript" type="text/javascript"&gt;

/**
 * Expand an input when the user clicks into it.
 */
var expandingInput = {
 focusSmallInput: function(input) {
  input.style.visibility = 'hidden';
  var largeInput = document.getElementById('largeInput'); 
  largeInput.style.display = 'block'; 
  largeInput.focus(); 
  largeInput.style.position = 'absolute';
 },
 
 blurLargeInput: function(input) {
  input.style.display = 'none';
  var smallInput = document.getElementById('smallInput'); 
  smallInput.style.visibility = 'visible'; 
  smallInput.value = input.value; // Copy the value over
 }
};

&lt;/script&gt;

&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;

/**
 * Styles for the expanding / contracting input
 */

#smallInput {
 height: 30px;
 width: 250px;
 overflow: hidden;

}
#largeInput {
 display: none;
 height: 80px;
 width: 350px;
 overflow-x: hidden;
 overflow-y: auto;
 word-wrap: break-word;
 z-index: 1000;
}

&amp;lt;/style&amp;gt;

&lt;!-- The textarea must come before the div.  Use DIVs, not BReaks to put them on their own lines
  because the break messes up the overlapping. --&gt;
&lt;div&gt;
 &lt;textarea id="largeInput" onblur="javascript: expandingInput.blurLargeInput(this);"&gt;&lt;/textarea&gt;
&lt;/div&gt;
&lt;div&gt;
 &lt;input type="text" id="smallInput" onfocus="javascript: expandingInput.focusSmallInput(this);" /&gt;
&lt;/div&gt;
&lt;div&gt;
 &lt;input type="button" name="submit" value="Submit" style="margin-top: 30px;"/&gt;
&lt;/div&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-6811454641557044107?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/6811454641557044107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=6811454641557044107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6811454641557044107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6811454641557044107'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/04/simple-javascript-expanding-text-input.html' title='Simple JavaScript expanding text input'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-9221959977486117830</id><published>2009-03-24T05:49:00.000-07:00</published><updated>2009-05-03T19:01:26.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AppleScript'/><title type='text'>AppleScript / Automator: Import AVI video to iTunes as a TV Show or Movie</title><content type='html'>This is a sweet AppleScript / Automator Workflow that I created which totally automates the task of importing an AVI video into iTunes.
&lt;ul&gt;
&lt;li&gt;Select one or more video files to import.  Works on AVI as well as other formats like M4V.&lt;/li&gt;
&lt;li&gt;Adds metadata to the AVI files to make them iTunes compatible.&lt;/li&gt;
&lt;li&gt;Prompts if you would like to import into Movies or TV Shows.&lt;/li&gt;
&lt;li&gt;Sets iTunes metadata to identify the video as Movie or TV Show depending on your choice.&lt;/li&gt;
&lt;/ul&gt;

Here is a screenshot of my workflow and &lt;a href="http://varzyfamily.com/links/blog/import-to-itunes.workflow.tar"&gt;here is the workflow file&lt;/a&gt; (in a tarball...workflows actually are directories it seems...).
&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_LjUDvSJPqv4/SclwueoxK3I/AAAAAAAAABg/JgivhZ4tIuY/s1600-h/Import+to+iTunes.jpg"&gt;&lt;img style="float:left; margin:0 20px 10px 0;cursor:pointer; cursor:hand;width: 260px; height: 320px;" src="http://2.bp.blogspot.com/_LjUDvSJPqv4/SclwueoxK3I/AAAAAAAAABg/JgivhZ4tIuY/s320/Import+to+iTunes.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5316904778887932786" /&gt;&lt;/a&gt;
&lt;p&gt;
&lt;h3&gt;Installing&lt;/h3&gt;
&lt;ol&gt;&lt;li&gt;
To install as a Finder plugin (so you can select files in Finder then secondary-click / control-click and choose Automator -&gt; Import to iTunes), open the .workflow file in Automator and choose Save As Plug-in, then in Plug-in for select Finder and Save.&lt;/li&gt;
&lt;li&gt;
To install as an application so you can drag and drop files onto the application, open the .workflow file in Automator and choose File -&gt; Save As and in File Format choose Application.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The AppleScript code is here if you want to copy and paste it:
&lt;pre name="code" class="xml"&gt;
on run {input, parameters}
 set videoType to button returned of (display dialog ("What type of video are you importing?") buttons {"Movie", "TV Show"} default button {"TV Show"})
 repeat with i in input
  try
   tell application "Finder" to set file type of file i to "MooV"
  end try
  tell application "iTunes"
   set newAddition to (add (i as alias))
   if videoType = "TV Show" then
    tell newAddition to set video kind to TV show
   end if
  end tell
 end repeat
 return input
end run
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-9221959977486117830?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/9221959977486117830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=9221959977486117830' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/9221959977486117830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/9221959977486117830'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/03/applescript-automator-import-avi-video.html' title='AppleScript / Automator: Import AVI video to iTunes as a TV Show or Movie'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_LjUDvSJPqv4/SclwueoxK3I/AAAAAAAAABg/JgivhZ4tIuY/s72-c/Import+to+iTunes.jpg' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-5340063513904253666</id><published>2009-03-23T23:18:00.000-07:00</published><updated>2009-03-24T02:51:07.682-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><title type='text'>Recursive chmod on files or directories</title><content type='html'>This is useful when, for example, you need to set execute permissions on every PHP or Ruby file in all directories below your current directory.
&lt;p&gt;
Just replace the '*.php' with the name pattern you want to match.  Works on Mac OS X 10.5.6.
&lt;pre name="code" class="xml"&gt;
find . -type f -name '*.php' -exec chmod 755 {} \;
&lt;/pre&gt;
&lt;p&gt;
To see which files will be changed use:
&lt;pre name="code" class="xml"&gt;
find . -type f -name '*.php' -exec echo {} \;
&lt;/pre&gt;
&lt;p&gt;
The &lt;span class="code"&gt;{}&lt;/span&gt; braces are replaced with each filename as find finds each file that matches your pattern.  To find directories use &lt;span class="code"&gt;-type d&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-5340063513904253666?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/5340063513904253666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=5340063513904253666' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5340063513904253666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5340063513904253666'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2009/03/recursive-chmod-on-php-or-ruby-files.html' title='Recursive chmod on files or directories'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4588707344976598189</id><published>2008-12-19T14:19:00.000-08:00</published><updated>2008-12-19T14:34:13.898-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Using iText to convert TIFF to PDF and to combine multiple PDFs into one PDF</title><content type='html'>We recently had the requirement to take a Microsoft Excel file as well as one or more PDF "attachments" and 1) convert the Excel file to PDF, and 2) combine all the PDFs into a single PDF.
&lt;p&gt;
Unfortunately we were unable to find an open source Java solution for converting the Excel file to PDF. &amp;nbsp;If you want to extract information from the Excel file you can do so using &lt;a href="http://poi.apache.org/"&gt;Apache POI&lt;/a&gt;. &amp;nbsp;You can then generate a PDF file from this data using &lt;a href="http://www.lowagie.com/iText/"&gt;iText&lt;/a&gt;. &amp;nbsp;This wasn't an appropriate solution for us. &amp;nbsp;An alternative solution in the interim was to print the Excel file to TIFF using the Microsoft Document Image Writer and then convert the TIFF to PDF using iText. &amp;nbsp;The results look alright, not ideal, but workable.
&lt;p&gt;
Here are two Java methods to do it. &amp;nbsp;Let me know if you find a free Java solution to converting Excel to PDF.
&lt;p&gt;
&lt;pre name="code" class="java"&gt;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.PRAcroForm;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.SimpleBookmark;

public class FileConversions {

    /**
     * Convert a TIFF file to a PDF.
     * 
     * @param tiffFile
     * @return
     * @throws DocumentException
     * @throws MalformedURLException
     * @throws IOException
     */
    public static byte[] convertTiffToPdf(byte[] tiffFile) 
            throws DocumentException, MalformedURLException, IOException {

        ByteArrayOutputStream outfile = new ByteArrayOutputStream();
        Document document = new Document(PageSize.A4.rotate());
        PdfWriter writer = PdfWriter.getInstance(document, outfile);
        writer.setStrictImageSequence(true);
        document.open();
        Image tiff = Image.getInstance(tiffFile);
        tiff.scaleToFit(800, 600);
        document.add(tiff);
        document.close();
        outfile.flush();
        return outfile.toByteArray();
    }

    /**
     * Combine multiple PDFs into a single PDF.
     *
     * @param pdfs
     * @param combinedPdfFile TODO
     * @throws IOException
     * @see http://itext.ugent.be/library/com/lowagie/examples/general/copystamp/Concatenate.java
     */
    public static void combinePdfFiles(List&amp;lt;byte[]&amp;gt; pdfs, File combinedPdfFile) throws Exception {

        PdfReader reader = null;
        Document document = null;
        PdfCopy  writer = null;
        ArrayList master = new ArrayList();
        int pageOffset = 0;

        for (byte[] pdf : pdfs) {
            int size = pdf.length;
            reader = new PdfReader(pdf);
            reader.consolidateNamedDestinations();
            int n = reader.getNumberOfPages();
            List bookmarks = SimpleBookmark.getBookmark(reader);
            if (bookmarks != null) {
                if (pageOffset != 0) {
                    SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null);
                }
                master.addAll(bookmarks);
            }
            pageOffset += n;

            if (document == null) {
                // step 1: creation of a document-object
                document = new Document(reader.getPageSizeWithRotation(1));
                // step 2: we create a writer that listens to the document
                writer = new PdfCopy(document, new FileOutputStream(combinedPdfFile));
                // step 3: we open the document
                document.open();
            }
            // step 4: we add content
            PdfImportedPage page;
            for (int i = 0; i &lt; n; ) {
                ++i;
                page = writer.getImportedPage(reader, i);
                writer.addPage(page);
            }
            PRAcroForm form = reader.getAcroForm();
            if (form != null) {
                writer.copyAcroForm(reader);
            }
        }
        if (!master.isEmpty()) {
            writer.setOutlines(master);
        }
        if (document != null) {
            document.close();
        }
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4588707344976598189?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4588707344976598189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4588707344976598189' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4588707344976598189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4588707344976598189'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/12/using-itext-to-convert-tiff-to-pdf-and.html' title='Using iText to convert TIFF to PDF and to combine multiple PDFs into one PDF'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4543389702015869951</id><published>2008-12-18T13:23:00.000-08:00</published><updated>2009-03-24T02:51:44.767-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='rubyonrails'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Simple request benchmarking of a Ruby on Rails application using ApacheBenchmarker</title><content type='html'>You can use &lt;span style="font-weight:bold;"&gt;ApacheBenchmarker&lt;/span&gt; which comes with your default Apache install.  You can find the &lt;span style="font-family:courier new;"&gt;ab.exe&lt;/span&gt; executable in &lt;span style="font-family:courier new;"&gt;C:\Program Files\Apache Group\Apache2\bin&lt;/span&gt; on Windows.
&lt;p&gt;
&lt;pre&gt;
Usage: ab [options] [http://]hostname[:port]/path
Options are:
  -n requests     Number of requests to perform
  -c concurrency  Number of multiple requests to make
  -t timelimit    Seconds to max. wait for responses
  -p postfile     File containing data to POST
  -T content-type Content-type header for POSTing
  -v verbosity    How much troubleshooting info to print
  -w              Print out results in HTML tables
  -i              Use HEAD instead of GET
  -x attributes   String to insert as table attributes
  -y attributes   String to insert as tr attributes
  -z attributes   String to insert as td or th attributes
  -C attribute    Add cookie, eg. 'Apache=1234. (repeatable)
  -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                  Inserted after all normal header lines. (repeatable)
  -A attribute    Add Basic WWW Authentication, the attributes
                  are a colon separated username and password.
  -P attribute    Add Basic Proxy Authentication, the attributes
                  are a colon separated username and password.
  -X proxy:port   Proxyserver and port number to use
  -V              Print version number and exit
  -k              Use HTTP KeepAlive feature
  -d              Do not show percentiles served table.
  -S              Do not show confidence estimators and warnings.
  -g filename     Output collected data to gnuplot format file.
  -e filename     Output CSV file with percentages served
  -h              Display usage information (this message)
&lt;/pre&gt;
&lt;p&gt;
My simple benchmarking tests for &lt;a href="http://new.varzyfamily.com/"&gt;my Ruby on Rails website&lt;/a&gt;.  I wanted to compare the performance of RoR over CGI with a new server instance created on each request versus requests over CGI proxied to a single long-running mongrel_rails server.  These tests do 10 individual requests, then 100 requests, 5 concurrently.  Results are output in HTML.
&lt;p&gt;
&lt;div class="code"&gt;ab -n 10 -c 1 -w http://new.varzyfamily.com/ &gt; 10-requests.html
ab -n 100 -c 5 -w http://new.varzyfamily.com/ &gt; 100-5-concurrent-requests.html&lt;/div&gt;
&lt;p&gt;
For your information I'm running my mongrel_rails using God on port 3000 and I am proxying requests using the standard RoR .htaccess file as follows:
&lt;p&gt;
&lt;div class="code"&gt;RewriteEngine On
RewriteCond %{HTTP_HOST} ^new.varzyfamily.com$
RewriteRule ^(.*)$ http://127.0.0.1:3000%{REQUEST_URI} [P,QSA,L]&lt;/div&gt;
&lt;p&gt;
I have to adopt such an arcane setup because my host &lt;a href="http://hostgator.com/"&gt;HostGator&lt;/a&gt; only supports RoR over CGI, which is not very performant.
&lt;p&gt;
The test results basically tell me what I already: never, ever run a RoR app over CGI where you're starting the server on every request!  Holy smokes!  For 100 requests (5 concurrent) over CGI average total request time was &lt;span style="font-weight:bold;"&gt;16437 ms&lt;/span&gt; (ouch!!!) serving &lt;span style="font-weight:bold;"&gt;0.3 reqs/sec&lt;/span&gt;.  Talking to a proxied mongrel server fared much better with average total request time being &lt;span style="font-weight:bold;"&gt;565 ms&lt;/span&gt; serving &lt;span style="font-weight:bold;"&gt;8.61 reqs/sec&lt;/span&gt;.
&lt;p&gt;
Here is the output from the latter test.
&lt;hr /&gt;
&lt;p&gt;
This is ApacheBench, Version 2.0.41-dev &lt;i&gt;&amp;lt;$Revision: 1.121.2.12 $&amp;gt;&lt;/i&gt; apache-2.0

Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/

&lt;/p&gt;
&lt;p&gt;
..done
&lt;table&gt;
&lt;tbody&gt;&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Server Software:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;Mongrel&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Server Hostname:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;new.varzyfamily.com&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Server Port:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;80&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Document Path:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;/&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Document Length:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;4174 bytes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Concurrency Level:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Time taken for tests:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;0.11609 seconds&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Complete requests:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Failed requests:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Total transferred:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;457200 bytes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;HTML transferred:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;417400 bytes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Requests per second:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;8.61&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th colspan="2" bgcolor="white"&gt;Transfer rate:&lt;/th&gt;&lt;td colspan="2" bgcolor="white"&gt;39.38 kb/s received&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th bgcolor="white" colspan="4"&gt;Connnection Times (ms)&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th bgcolor="white"&gt; &lt;/th&gt;&lt;th bgcolor="white"&gt;min&lt;/th&gt;&lt;th bgcolor="white"&gt;avg&lt;/th&gt;&lt;th bgcolor="white"&gt;max&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th bgcolor="white"&gt;Connect:&lt;/th&gt;&lt;td bgcolor="white"&gt;   62&lt;/td&gt;&lt;td bgcolor="white"&gt;  107&lt;/td&gt;&lt;td bgcolor="white"&gt; 3062&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th bgcolor="white"&gt;Processing:&lt;/th&gt;&lt;td bgcolor="white"&gt;  188&lt;/td&gt;&lt;td bgcolor="white"&gt;  458&lt;/td&gt;&lt;td bgcolor="white"&gt;  703&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th bgcolor="white"&gt;Total:&lt;/th&gt;&lt;td bgcolor="white"&gt;  250&lt;/td&gt;&lt;td bgcolor="white"&gt;  565&lt;/td&gt;&lt;td bgcolor="white"&gt; 3765&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4543389702015869951?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4543389702015869951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4543389702015869951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4543389702015869951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4543389702015869951'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/12/simple-request-benchmarking.html' title='Simple request benchmarking of a Ruby on Rails application using ApacheBenchmarker'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-515290246844584945</id><published>2008-12-15T16:23:00.000-08:00</published><updated>2008-12-19T14:34:58.464-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><title type='text'>Starting tomcat from Eclipse gives error "Can't load server.xml"</title><content type='html'>I am using Eclipse Gannymede and I am trying to start a Tomcat 5.5 and/or Tomcat 6.0 server.
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;Problem:&lt;/span&gt; When trying to start the Tomcat server from within Eclipse you get an error stating that Eclipse cannot load the &lt;span style="font-family:courier new;"&gt;server.xml&lt;/span&gt; file: 
&lt;pre name="code" class="xml"&gt;WARNING: Can't load server.xml from C:\projects\workspace-gannymede\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\server.xml&lt;br /&gt;Dec 15, 2008 3:52:51 PM org.apache.catalina.startup.Catalina load&lt;br /&gt;WARNING: Can't load server.xml from C:\projects\workspace-gannymede\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\server.xml&lt;br /&gt;Dec 15, 2008 3:52:51 PM org.apache.catalina.startup.Catalina start&lt;br /&gt;INFO: Server startup in 0 ms&lt;br /&gt;java.lang.reflect.InvocationTargetException&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:585)&lt;br /&gt; at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)&lt;br /&gt; at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)&lt;br /&gt;Caused by: java.lang.NullPointerException&lt;br /&gt; at org.apache.catalina.startup.Catalina.await(Catalina.java:616)&lt;br /&gt; at org.apache.catalina.startup.Catalina.start(Catalina.java:576)&lt;br /&gt; ... 6 more&lt;/pre&gt;
&lt;p&gt;
If I try to look at the &lt;span style="font-family:courier new;"&gt;server.xml&lt;/span&gt; file that Eclipse is trying to read, it does not exist on the filesystem.
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;Solution: &lt;/span&gt;I tried a number of things such as deleting all my server configurations as well as the contents of the .metadata\.plugins\org.eclipse.wst.server.core\ directory.  Nothing worked.  The solution is to create a new Server Runtime Environment (Window -&gt; Preferences -&gt; Server -&gt; Runtime Environments).  Then in your Servers view (Window -&gt; Show View -&gt; Servers) add a new server configuration (right-click and select New -&gt; Server) but DO NOT ADD ANY PROJECTS TO IT.  Double click the new server configuration to bring up the Server Overview page which looks like this:&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_LjUDvSJPqv4/SUb5E6xaSDI/AAAAAAAAABI/veU4fLruMLA/s1600-h/server-overview.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 263px;" src="http://2.bp.blogspot.com/_LjUDvSJPqv4/SUb5E6xaSDI/AAAAAAAAABI/veU4fLruMLA/s320/server-overview.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5280181476029777970" /&gt;&lt;/a&gt;
&lt;p&gt;
Under &lt;em&gt;Server Locations&lt;/em&gt; select &lt;em&gt;Use Tomcat installation&lt;/em&gt;.  Save.  You should be able to start your server now (assuming you can start it fine from the command line).  Now add your project to the server and you're ready to go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-515290246844584945?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/515290246844584945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=515290246844584945' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/515290246844584945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/515290246844584945'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/12/starting-tomcat-from-eclipse-gives.html' title='Starting tomcat from Eclipse gives error &quot;Can&apos;t load server.xml&quot;'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_LjUDvSJPqv4/SUb5E6xaSDI/AAAAAAAAABI/veU4fLruMLA/s72-c/server-overview.jpg' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2479384143389387007</id><published>2008-12-12T11:54:00.000-08:00</published><updated>2008-12-12T12:06:43.208-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oc4j'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>OC4J 10.1.3.* does not support JSF 1.2</title><content type='html'>I spent a very frustrating day wading through the version soup that is JavaServer Faces and trying to deploy a JSF 1.2 app on on OC4J 10.1.3 container. &amp;nbsp;To save you a lot of time, &lt;em&gt;OC4J DOES NOT SUPPORT JSF 1.2&lt;/em&gt;.
&lt;p&gt;
&lt;a href="http://www.oracle.com/technology/tech/java/oc4j/1013/whitepapers/OC4J-FOV-10131.pdf"&gt;This technical paper&lt;/a&gt; explains that OC4J 10.1.3 (all versions) supports &lt;span style="font-weight:bold;"&gt;Servlet 2.4&lt;/span&gt;, &lt;span style="font-weight:bold;"&gt;JSP 2.0&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;JSF 1.1&lt;/span&gt;.
&lt;p&gt;
&lt;a href="http://www.roseindia.net/jsf/jsf-versions.shtml"&gt;And this handy webpage&lt;/a&gt; explains that &lt;span style="font-style:italic;"&gt;"JSF  1.2 is the latest release and it works with servlet 2.5 and jsp 2.1"&lt;/span&gt;.  So obviously it's not compatible. &amp;nbsp;It also details all the versions of Java technologies that each JSF version relies upon.
&lt;p&gt;
So don't waste your time like I did.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2479384143389387007?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2479384143389387007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2479384143389387007' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2479384143389387007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2479384143389387007'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/12/oc4j-1013-does-not-support-jsf-12.html' title='OC4J 10.1.3.* does not support JSF 1.2'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-9014916073929063060</id><published>2008-11-26T23:01:00.000-08:00</published><updated>2008-12-19T14:35:30.428-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scriptaculous'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>Custom Scriptaculous Ajax InPlaceEditor</title><content type='html'>The following code demonstrates how to customize the Scriptaculous library's InPlaceEditor to make it look and feel exctly how you want.&amp;nbsp; It also demonstrates the general techniques that can be used to extend any of the Scriptaculous Event classes as well as the Prototype base classes (as I will demonstrate in a later post).&amp;nbsp; All of my customizations are controlled by options passed in when creating your IPE instance and do not alter the original behaviour of the IPE classes.
&lt;p&gt;
My intention here is to isolate my customizations so that the libraries can be updated at will and my modifications will continue to work.
&lt;p&gt;
I will post a sample of the code in action and describe what I am doing here at a later time.  For now, here's the code.
&lt;p&gt;
&lt;pre name="code" class="javascript"&gt;// Custom controls.  Must be loaded after prototype &amp; scriptaculous.

Object.extend(Ajax.InPlaceEditor.DefaultOptions, {
  showHighlight: true,  // false/true
  showSaving: true,     // false/true
  lockoutOnSave: true   // false/true
});

/**
 * The following fixes are from http://www.mail-archive.com/rubyonrails-spinoffs@googlegroups.com/msg11429.html  
 * They fix the cancelling/escape issues with the IPE.
 *
 */

/**
 * Removed the checkForEscapeOrReturn binding on keydown because it doesn't
 * do anything attached to the span element.
 */
Ajax.InPlaceEditor.Listeners = {
  click: 'enterEditMode',
  mouseover: 'enterHover',
  mouseout: 'leaveHover'
};
 
Ajax.InPlaceEditor.prototype.initialize = Ajax.InPlaceEditor.prototype.initialize.wrap( function(){
  var args = $A(arguments), proceed = args.shift();
  //proceed(args[0], args[1], args[2] ? args[2] : null);
  proceed.apply(null, args);
  this._boundKeyListener = this.checkForEscapeOrReturn.bindAsEventListener(this);
});

Ajax.InPlaceEditor.prototype.enterEditMode = Ajax.InPlaceEditor.prototype.enterEditMode.wrap( function(){
  var args = $A(arguments), proceed = args.shift();
  var e = args[0] ? args[0] : null;
  //proceed(); // args[0] ? args[0] : null 
  proceed.apply(null, args);
  // The form won't exist if we are saving, so check before setting the key listener
  if (this._controls.editor) {
    this._controls.editor.observe('keydown', this._boundKeyListener);
    if (e.rangeOffset != undefined) {
      setCaretTo(this._controls.editor, e.rangeOffset);
    }
    
  }
});

Ajax.InPlaceEditor.prototype.removeForm = Ajax.InPlaceEditor.prototype.removeForm.wrap( function(){
  var args = $A(arguments), proceed = args.shift();
  if (this._controls.editor) {
    this._controls.editor.stopObserving('keydown', this._boundKeyListener);
  }
  proceed.apply(null, args);
});

/**
 * Don't submit the form if nothing has changed.
 *
 */
 
Ajax.InPlaceEditor.prototype.handleFormSubmission = Ajax.InPlaceEditor.prototype.handleFormSubmission.wrap( function() {
  var args = $A(arguments), proceed = args.shift();
  var e = args[0] ? args[0] : null;
  //proceed(e);
  //return;
  //alert($A(arguments));
  var value = $F(this._controls.editor);
  var original_value = this.getText();
  //alert("Original value is: " + original_value + ", new value is " + value + ", values are equal? " + (original_value == value));
  if (original_value == value) {
    alert("nothing changed");
    // Stop the event and return.  Prepare submission removes the form and does
    // some cleanup that we need to do.
    this.prepareSubmission();
    if (e) Event.stop(e);
    return;
  } else {
    alert("submitting ajax request");
    proceed.apply(null, args);
  }
});

/**
 * Don't prevent the user from editing the field while the value is being saved.
 */

Ajax.InPlaceEditor.prototype.prepareSubmission = Ajax.InPlaceEditor.prototype.prepareSubmission.wrap( function() {
  var args = $A(arguments), proceed = args.shift();
  proceed.apply(null, args);
  if (!this.options.lockoutOnSave) {
    this._saving = false;
  }
});


/**
 * Don't show "Saving..." if showSaving is turned off.
 */

Ajax.InPlaceEditor.prototype.showSaving = Ajax.InPlaceEditor.prototype.showSaving.wrap(function() {
  if (!this.options.showSaving) {
    this._boundWrapperHandler();
    return;
  } else {
    var args = $A(arguments), proceed = args.shift();
    proceed.apply(null, args);
  }
});
  
/**
 * Don't highlight if highlighting is turned off.
 */
 
var checkIfHighlighting = function() {
  //alert("check if highlighting: " + this.options.hoverClassName);
  if (!this.options.showHighlight) return;
  var args = $A(arguments), proceed = args.shift();
  proceed.apply(null, args);
};&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-9014916073929063060?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/9014916073929063060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=9014916073929063060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/9014916073929063060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/9014916073929063060'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/11/custom-scriptaculous-ajax-inplaceeditor.html' title='Custom Scriptaculous Ajax InPlaceEditor'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-7695939902747089324</id><published>2008-11-26T17:18:00.000-08:00</published><updated>2008-12-19T14:36:00.233-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='oc4j'/><title type='text'>Debugging applications running in OC4J in Eclipse</title><content type='html'>&lt;p&gt;Being able to breakpoint your Java code and step through it in Eclipse is essential for timely development.   But every time I go to create a new OC4J debugger instance in Eclipse I don't know where to start!  And nothing on the web helped me out.   So here are my settings which work for me.   Hopefully they will work for you too.
&lt;/p&gt;
&lt;p&gt;
A note on versions.  I am using Eclipse 3.3.2 and OC4J 10.1.3.2.0 which I have installed at C:\appservers\oc4j10.1.3.2.0.   My Java version is 1.5.0_11.
&lt;/p&gt;
&lt;p&gt;
Click &lt;span style="font-family:courier new;"&gt;Run -&gt; Open Debug Dialog&lt;/span&gt;.  Create a new &lt;span style="font-family:courier new;"&gt;Java Application&lt;/span&gt; and give it a name.   Now configure each tab according to the screenshots.   The project I'm debugging is called &lt;span style="font-family:courier new;"&gt;regis&lt;/span&gt;.  I don't know if you have to supply the project or not, but obviously whereever you see  &lt;span style="font-family:courier new;"&gt;regis &lt;/span&gt;you'll want to replace that with your own project.
&lt;/p&gt;
&lt;i&gt;(Click on the screenshots to see a larger version.)&lt;/i&gt;
&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33lNnJZdI/AAAAAAAAAAY/POk8cHtliV4/s1600-h/oc4j1.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 264px;" src="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33lNnJZdI/AAAAAAAAAAY/POk8cHtliV4/s400/oc4j1.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5273142957401794002" /&gt;&lt;/a&gt;
&lt;p&gt;
Some of the arguments here are optional.  &lt;span style="font-family:courier new;"&gt;-Xmx512M&lt;/span&gt; just gives more memory to the process.
&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_LjUDvSJPqv4/SS33vu0JsDI/AAAAAAAAAAg/axkcEZ2JWg4/s1600-h/oc4j2.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 208px;" src="http://3.bp.blogspot.com/_LjUDvSJPqv4/SS33vu0JsDI/AAAAAAAAAAg/axkcEZ2JWg4/s320/oc4j2.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5273143138113400882" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33v_ZKgzI/AAAAAAAAAAo/5WAf4t5Qd18/s1600-h/oc4j3.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 208px;" src="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33v_ZKgzI/AAAAAAAAAAo/5WAf4t5Qd18/s320/oc4j3.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5273143142563611442" /&gt;&lt;/a&gt;
&lt;p&gt;
The libraries I have on the &lt;span style="font-family:courier new;"&gt;Source&lt;/span&gt; tab are also optional.   They're useful though when you want to step into Struts method calls etc.
&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_LjUDvSJPqv4/SS33wWgTgkI/AAAAAAAAAAw/urIYFCkG7LE/s1600-h/oc4j4.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://4.bp.blogspot.com/_LjUDvSJPqv4/SS33wWgTgkI/AAAAAAAAAAw/urIYFCkG7LE/s320/oc4j4.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5273143148767576642" /&gt;&lt;/a&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33wksPs4I/AAAAAAAAAA4/2NMZBVCr3To/s1600-h/oc4j5.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33wksPs4I/AAAAAAAAAA4/2NMZBVCr3To/s320/oc4j5.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5273143152575755138" /&gt;&lt;/a&gt;
Hopefully after duplicating my settings you are now ready to debug!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-7695939902747089324?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/7695939902747089324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=7695939902747089324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7695939902747089324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/7695939902747089324'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/11/debugging-applications-running-on-oc4j.html' title='Debugging applications running in OC4J in Eclipse'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_LjUDvSJPqv4/SS33lNnJZdI/AAAAAAAAAAY/POk8cHtliV4/s72-c/oc4j1.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-1538972487956315136</id><published>2008-10-29T18:03:00.000-07:00</published><updated>2009-03-24T02:52:17.746-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>SVN tips</title><content type='html'>I'm going to keep track of some SVN tips here.  For instance I always get confused about when I'm supposed to use a URL and when I'm supposed to use a path with SVN.  And I always have to recreate those annoying trunk/ branch/ and tag/ directories every time I want to import a project and sometimes if you do it wrong you're truly screwed.  Hopefully this will help you (and me) out in future.
&lt;p&gt;
&lt;h2&gt;Create a repository and import a project&lt;/h2&gt;

&lt;div class="code"&gt;svnadmin create --fs-type fsfs /home/kjvarga/svnroot
svn import newproject file:///home/kjvarga/svnroot/newproject/&lt;/div&gt;

&lt;em&gt;Some things to notice&lt;/em&gt;
&lt;ul&gt;&lt;li&gt;The triple slash on the local file URL.&lt;/li&gt;
&lt;li&gt;Specifying the file store type as fsfs.  I'm on a shared host and apparently it's really not a good idea to use the BerkleyDB in this scenario.  I found out the hard way when after about 4 months of no problems I was suddenly unable to access my repository (something about a BDB version mismatch).&lt;/li&gt;
&lt;li&gt;In this scenario newproject has the structure newproject/trunk tags branches.&lt;/li&gt;
&lt;li&gt;Don't forget to append the directory name to the SVNROOT in the import.  Otherwise the contents of newproject/ will be imported to the root of your SVNROOT, which isn't very useful.&lt;/li&gt;
&lt;/ul&gt;

Verify your import with &lt;span class="code"&gt;svn list file:///home/kjvarga/svnroot/newproject/&lt;/span&gt;

&lt;h2&gt;Checkout your import&lt;/h2&gt;

The next logical step is to checkout the project you just checked in.

&lt;div class="code"&gt;svn checkout file:///home/kjvarga/svnroot/newproject/trunk svnproject&lt;/div&gt;
&lt;p&gt;
Don't forget that you're checking out the trunk/ directory!
&lt;p&gt;
If you're not checking out the project locally you will need to supply a URL pointing to the repository resource.
&lt;p&gt;
I'm on a shared host which doesn't allow any direct access to SVN so I have to connect using &lt;span style="font-family:courier new;"&gt;ssh+svn&lt;/span&gt;.  In taht case your checkout would look something like this:

&lt;div class="code"&gt;svn checkout svn+ssh://kjvarga@varzyfamily.com/home/kjvarga/svnroot/newproject/trunk newproject&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-1538972487956315136?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/1538972487956315136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=1538972487956315136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1538972487956315136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/1538972487956315136'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/10/svn-tips.html' title='SVN tips'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-332776502377636763</id><published>2008-10-17T13:14:00.001-07:00</published><updated>2008-12-19T14:36:20.474-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>CSS Tips and Tricks</title><content type='html'>Every time I get back into CSS I forget some of the basic rules about inline and block level elements, positioning and box models.  I'm not a fan of browser hacks, so you won't find any of those here.
&lt;p&gt;
&lt;h2&gt;Inline Elements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Can have &lt;span style="font-family:courier new;"&gt;width&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;padding-left&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;padding-right&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;margin-left&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;margin-right&lt;/span&gt; applied.  However &lt;span style="font-family:courier new;"&gt;height&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;padding-top&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;padding-bottom&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;margin-top&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;margin-bottom&lt;/span&gt; are not applied.&lt;li&gt;To set the &lt;font face="'Courier New',Courier,monospace"&gt;height &lt;/font&gt;you can use the&lt;font face="'Courier New',Courier,monospace"&gt; line-height &lt;/font&gt;property.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;Vertically Centered Text&lt;/h2&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;An easy way center text vertically within an element is to use the &lt;font face="'Courier New',Courier,monospace"&gt;line-height &lt;/font&gt;property.  If the line-height is greater than the font size, the extra space is distributed evenly above and below the text.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;Horzontally Centered Elements&lt;/h2&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Set a &lt;font face="'Courier New',Courier,monospace"&gt;width&lt;/font&gt; and &lt;font face="'Courier New',Courier,monospace"&gt;margin: 0 auto;&lt;/font&gt; on an element to have it horizontally centered.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;Clearing Floats&lt;/h2&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Clearing floats with &lt;font face="'Courier New',Courier,monospace"&gt;clear: left;&lt;/font&gt; &lt;font face="'Courier New',Courier,monospace"&gt;clear: right;&lt;/font&gt; or &lt;font face="'Courier New',Courier,monospace"&gt;clear: both;&lt;/font&gt; will clear all floats that precede the element in the document model.  So use floats wisely because you will probably end up clearing floats on other parts of the page which you did not intent to clear.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;Absolute vs Relative Positioned Elements&lt;/h2&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;A relatively positioned element's margins will collapse (the margin will be the maximum of the two adjacent element's margins).  However an absolutely positioned element will start a new block formatting context and its margins will not collapse with adjoining elements.&lt;/li&gt;
&lt;li&gt;An absolutely positioned element is taken out of the document flow and positioned &lt;span style="font-style:italic;"&gt;relative to the first positioned (rel or abs) ancestor&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;h2&gt;100% Height Divs&lt;/h2&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Assigning &lt;span style="font-style:italic;"&gt;height: 100%&lt;/span&gt; to a div will have no effect without a height defined on the parent.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-332776502377636763?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/332776502377636763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=332776502377636763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/332776502377636763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/332776502377636763'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/10/css-tips-and-tricks.html' title='CSS Tips and Tricks'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-5958943485638800156</id><published>2008-10-07T17:06:00.000-07:00</published><updated>2008-10-07T17:11:22.300-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='finance'/><title type='text'>How to determine your hourly rate as a contractor</title><content type='html'>This is a useful bit of information I pulled off of &lt;a href="http://salary.com"&gt;salary.com&lt;/a&gt; about &lt;a href="http://www.salary.com/advice/layouthtmls/advl_display_Cat14_Ser67_Par150.html"&gt;how to derive your hourly rate as a contractor&lt;/a&gt; based on your current salary:
&lt;p&gt;
&lt;blockquote&gt;Independent contractor fees. If you work as an independent contractor without going through an agency, you have some leeway in establishing your professional fees, but you should charge close to market. To calculate this rate, start with the prevailing full-time salary for that job. Then divide by 2080, the number of work hours in a year (2080 = 52 X 40). This is the hourly rate for your job if benefits are being paid for by the employer.
&lt;p&gt;
But as a contractor, you need to pay for your own benefits, as well as additional Social Security contributions, so the number needs to be higher. Salary.com uses an adjustment factor of 30 percent to convert an hourly wage for a salaried employee to an hourly wage for a contract employee. Multiply your unadjusted hourly rate by (1 + 0.3) to get your adjusted hourly rate. For example, if your unadjusted hourly rate comes out to $20 per hour, your contract rate should be $20 * (1.3) = $26.
&lt;p&gt;
An example shows how this works for a senior-level web designer in Kansas City. A Web designer III working in Kansas City makes $66,244. The unadjusted hourly rate for this position is $66,244/2,080, or $31.85. Adjusted by 30 percent, the contract rate comes to $41.40.
&lt;p&gt;
Contract fee for a Web designer III in Kansas City
&lt;table&gt;&lt;tr&gt;&lt;td&gt;Salary&lt;/td&gt;&lt;td&gt;$66,244&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Hourly rate, unadjusted&lt;/td&gt;&lt;td&gt;$31.85&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Adjustment factor&lt;/td&gt;&lt;td&gt;30%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Hourly rate, adjusted&lt;/td&gt;&lt;td&gt;$41.40&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;em&gt;Source: Salary.com, May 2002.&lt;/em&gt;
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-5958943485638800156?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/5958943485638800156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=5958943485638800156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5958943485638800156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5958943485638800156'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/10/contractors-arriving-at-hourly-rate.html' title='How to determine your hourly rate as a contractor'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2805828712928578175</id><published>2008-08-12T14:39:00.000-07:00</published><updated>2008-11-26T22:49:59.271-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bpel'/><title type='text'>BPEL fails with WSIF exception on multiple simultaneous requests</title><content type='html'>Occasionally we run into what appear to be concurrency issues with BPEL whereby WSIF calls to our EJB are failing sporadically, reporting that the method we are trying to call cannot be found.  Which is obviously incorrect because the deployed EJB has not been modified, and subsequent BPEL processes are not faulted.  Usually we get this error when we are processing multiple records simultaneously.
&lt;p&gt;
Today I discovered the conditions that manifest the problem.  If one of the BPEL processes is modfied and deployed and then - without refreshing the WSDL cache - two requests are processed concurrently, the first will always fail.  If the WSDL cache is cleared, both are processed without problems.
&lt;p&gt;
So it appears to be a problem related to caching that only comes up if 
multiple requests are processed concurrently.  So always refresh your WSDL cache after deploying BPEL processes to avoid any such issues.

&lt;pre name="code" class="xml"&gt;&amp;lt;2008-08-12 13:19:50,125&amp;gt; &amp;lt;DEBUG&amp;gt; &amp;lt;default.collaxa.cube.ws&amp;gt; &amp;lt;WSIFInvocationHandler::invoke&amp;gt; Fault happened
org.collaxa.thirdparty.apache.wsif.WSIFException: No method named &amp;#039;findSearchFile&amp;#039; found that match the parts specified
 at com.collaxa.cube.ws.wsif.providers.ejb.WSIFOperation_EJB.executeRequestResponseOperation(WSIFOperation_EJB.java:938)
 at com.collaxa.cube.ws.WSIFInvocationHandler.invoke(WSIFInvocationHandler.java:435)
 at com.collaxa.cube.ws.WSInvocationManager.invoke2(WSInvocationManager.java:443)
 at com.collaxa.cube.ws.WSInvocationManager.invoke(WSInvocationManager.java:251)
 at com.collaxa.cube.engine.ext.wmp.BPELInvokeWMP.__invoke(BPELInvokeWMP.java:727)
 at com.collaxa.cube.engine.ext.wmp.BPELInvokeWMP.__executeStatements(BPELInvokeWMP.java:366)
 at com.collaxa.cube.engine.ext.wmp.BPELActivityWMP.perform(BPELActivityWMP.java:195)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2805828712928578175?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2805828712928578175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2805828712928578175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2805828712928578175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2805828712928578175'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/08/bpel-fails-with-wsif-exception-on.html' title='BPEL fails with WSIF exception on multiple simultaneous requests'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-8672537428650615485</id><published>2008-08-01T13:32:00.000-07:00</published><updated>2008-11-26T22:36:55.734-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><title type='text'>Extract the original entity from a (Hibernate) CGLIB proxy class</title><content type='html'>&lt;em&gt;Ed: this is a &lt;a href="http://kjvarga.blogspot.com/2008/07/access-target-object-from-hibernate.html"&gt;rewrite of another post&lt;/a&gt; that deals with the same problem but with a less technical description.&lt;/em&gt;
&lt;p&gt;
If you have a polymorphic class structure then when Hibernate instantiates instances of your sub-classes and wraps them in a proxy class, the proxy is actually an instance of the &lt;em&gt;root&lt;/em&gt; class in the hierarchy.  This introduces some problems because you can no longer rely on &lt;i&gt;instanceof&lt;/i&gt; and class casts because they will not work.  You can implement a &lt;a href="http://www.hibernate.org/280.html"&gt;visitor pattern&lt;/a&gt; to work around these shortcomings.
&lt;p&gt;
The following code shows you how to retrieve the persisted concrete instance of your sub-class from the proxy class.  This is useful for those occasions when you want access to the concrete instance, but don't want to implement a full visitor pattern:
&lt;pre name="code" class="java"&gt;if (proxy instanceof HibernateProxy){ 
   return ((HibernateProxy)proxy).getHibernateLazyInitializer().getImplementation(); 
}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-8672537428650615485?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/8672537428650615485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=8672537428650615485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8672537428650615485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8672537428650615485'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/08/extract-original-entity-from-hibernate.html' title='Extract the original entity from a (Hibernate) CGLIB proxy class'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-3078469343018362426</id><published>2008-07-29T18:40:00.001-07:00</published><updated>2008-11-26T22:35:51.327-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><title type='text'>Access the target object from a Hibernate CGLIB proxy</title><content type='html'>Sometimes in Hibernate when you have Lazy Loaded lists of objects you will end up interacting with a proxied instance of the object rather than the object itself, even if you access members of the object so that you know it's been loaded from the database.
&lt;p&gt;
This situation can be tricky because your object walks like a duck and talks like a duck...but it's a proxy.  You want the duck!  You can do something like the following to lure it out:
&lt;pre name="code" class="java"&gt;if (asset instanceof org.hibernate.proxy.HibernateProxy) {
    BankAccount ss = (BankAccount) ((HibernateProxy)asset).getHibernateLazyInitializer().getImplementation();
    String desc = asset.getDescriptionTxt();
}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-3078469343018362426?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/3078469343018362426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=3078469343018362426' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/3078469343018362426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/3078469343018362426'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/07/access-target-object-from-hibernate.html' title='Access the target object from a Hibernate CGLIB proxy'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-5331367674775672487</id><published>2008-07-25T13:59:00.000-07:00</published><updated>2008-11-26T22:53:09.019-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='struts'/><title type='text'>Pass an encoded message resource in a redirect URL</title><content type='html'>Often you need to display a message/error on a JSP page but you want to redirect to the page so that it can be refreshed without reposting the form. &amp;nbsp;If you simply set &lt;i&gt;redirect="true"&lt;/i&gt; in your &lt;i&gt;struts-config.xml&lt;/i&gt; action forward you end up losing the request-scoped message when struts issues the redirect.
&lt;p&gt;
So what you need to do is 1) construct the message from a resource file, 2) encode the message, 3) issue a redirect and 4) display the message in the target JSP.
&lt;h3&gt;Access the MessageResources.properties bundle&lt;/h3&gt;
&lt;pre name="code" class="java"&gt;org.apache.struts.util.MessageResources mr = getResources(request);
String message = mr.getMessage("the.message.key", optionalInterpolationArgument);&lt;/pre&gt;
&lt;h3&gt;URL encode the message and issue a redirect&lt;/h3&gt;
&lt;pre name="code" class="java"&gt;message = "message=" + java.net.URLEncoder.encode(message, "UTF-8");
response.sendRedirect(request.getContextPath() + "/targetAction.do?" + message);&lt;/pre&gt;
&lt;h3&gt;Display the message&lt;/h3&gt;
Note the use of &lt;i&gt;&amp;lt;c:out /&amp;gt;&lt;/i&gt; here.  If you just write out the message without doing any HTML escaping on it you open yourself up to an HTML-injection attack.
&lt;pre name="code" class="xml"&gt;&amp;lt;c:if test=&amp;quot;${!empty param.message}&amp;quot;&amp;gt;
  &amp;lt;c:out value=&amp;quot;${param.message}&amp;quot; /&amp;gt;
&amp;lt;/c:if&amp;gt;&lt;/pre&gt;
&lt;h3&gt;Lookup message resources in a JSP file&lt;/h3&gt;
Sometimes it may be better to just pass the message key itself and have the target JSP lookup the message and display it.  The following snippet shows you how to lookup a message key:
&lt;pre name="code" class="xml"&gt;&amp;lt;bean:message key=&amp;quot;simple.message.key&amp;quot;/&amp;gt;
&amp;lt;bean:message key=&amp;quot;interpolated.message.key&amp;quot; arg0=&amp;quot;argument.value&amp;quot;/&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-5331367674775672487?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/5331367674775672487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=5331367674775672487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5331367674775672487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5331367674775672487'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/07/looking-up-message-keys-in-java-and.html' title='Pass an encoded message resource in a redirect URL'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-6372847775338016693</id><published>2008-07-22T18:16:00.000-07:00</published><updated>2009-03-24T02:53:38.043-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Installing MySQL and Apache as Windows services</title><content type='html'>&lt;h3&gt;To install Apache as a service&lt;/h3&gt;
From the Apache bin directory (usually C:\Program Files\Apache Group\Apache2\bin):
&lt;div class="code"&gt;C:\Program Files\Apache Group\Apache2\bin&gt;Apache.exe -k install -n "This is the service name"&lt;/div&gt;
Other options are&lt;br&gt;
&lt;span class="code"&gt;-k uninstall&lt;/span&gt; to uninstall the service,&lt;br&gt;
&lt;span class="code"&gt;-k start&lt;/span&gt;,&lt;br&gt;
&lt;span class="code"&gt;-k stop&lt;/span&gt; and&lt;br&gt;
&lt;span class="code"&gt;-k restart&lt;/span&gt; to control the apache server.
&lt;p&gt;
&lt;h3&gt;To install MySQL as a service&lt;/h3&gt;
From the MySQL bin directory (usually C:\Program Files\MySQL\MySQL Server 5.0\bin):
&lt;div class="code"&gt;C:\Program Files\MySQL\MySQL Server 5.0\bin&gt;mysqld --install "This is the service name" --defaults-file=C:/custom/path/to/my.ini&lt;/div&gt;
The example above sets the --defaults-file option which allows you to specify a non-standard options file location.  The server will read options from the [mysqld] group.
&lt;p&gt;
To control the server you can use &lt;span class="code"&gt;mysqladmin --port=3306 -u root shutdown&lt;/span&gt; to shutdown the server.  3306 is the default port.  I put in the --port option as an example for when you need to specify a non-standard port.  &lt;span class="code"&gt;mysqld --remove&lt;/span&gt; removes the service.  There are many other useful commands, to see them use the --help option.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-6372847775338016693?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/6372847775338016693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=6372847775338016693' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6372847775338016693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6372847775338016693'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/07/installing-mysql-and-apache-as-windows.html' title='Installing MySQL and Apache as Windows services'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-5975975098669780079</id><published>2008-07-22T14:37:00.000-07:00</published><updated>2009-03-24T02:54:23.997-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Shut down Windows XP from the command line</title><content type='html'>You can use following built-in utility to shutdown Windows and then the machine itself:
&lt;div class="code"&gt;C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /POWERDOWN /DELAY:&lt;i&gt;secs&lt;/i&gt;&lt;/div&gt;
&lt;p&gt;
To reboot use the following option:
&lt;div class="code"&gt;C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /REBOOT /DELAY:&lt;i&gt;secs&lt;/i&gt;&lt;/div&gt;
&lt;p&gt;
To see a list of command options type &lt;span class="code"&gt;tsshutdn /?&lt;/span&gt;
&lt;p&gt;&lt;i&gt;DELAY&lt;/i&gt; is in seconds.
&lt;ul&gt;&lt;li&gt;30 minutes = 1800 seconds
&lt;li&gt;1 hour = 3600 seconds
&lt;li&gt;2 hours = 7200 seconds
&lt;li&gt;3 hours = 10800 seconds&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-5975975098669780079?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/5975975098669780079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=5975975098669780079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5975975098669780079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/5975975098669780079'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/07/shut-down-windows-xp-from-command-line.html' title='Shut down Windows XP from the command line'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-4686912383481334377</id><published>2008-05-28T20:30:00.000-07:00</published><updated>2008-09-23T14:26:31.282-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Disable Windows Update restart reminders</title><content type='html'>So you don't think getting automatic updates is a bad thing, but you don't want that damn annoying dialogue popping up every 5 minutes telling you to restart?  Follow these simple steps:
&lt;div class="code"&gt;Start / Run / gpedit.msc / Local Computer Policy / Computer Configuration / Administrative Templates / Windows Components / Windows Update / Re-prompt for restart with scheduled installations

Set to Disabled.&lt;/div&gt;
Then you need to disable the Windows Update service for this session with the following command.
&lt;div class="code"&gt;sc stop wuauserv&lt;/div&gt;
Your changes will take effect on reboot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-4686912383481334377?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/4686912383481334377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=4686912383481334377' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4686912383481334377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/4686912383481334377'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/05/disable-windows-update-restart.html' title='Disable Windows Update restart reminders'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-8840047991375080854</id><published>2008-05-22T14:22:00.000-07:00</published><updated>2009-08-04T21:21:48.199-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Debugging javascript errors in IE7 on WinXP</title><content type='html'>As you may have noticed, the built-in Script Debugger in WinXP cannot be used to debug javascipt errors in Internet Explorer 7.   It used to work in IE6, but doesn't work with IE7 because it can no longer bind to the browser process.
&lt;p&gt;
But fear not, it is possible!  You have to download &lt;a href="http://msdn.microsoft.com/vstudio/express/vwd/"&gt;Microsoft's Visual Web Developer 2008 Express Edition&lt;/a&gt; which is freely available.  Then you create a new project and select &lt;i&gt;Debug-&gt; Start Debugger&lt;/i&gt;.  This will open a new IE7 window with the debugger attached.  You can now access the site or pages that you want to debug, and because the debugger is attached, when the (ridiculously unhelpful) Error dialog pops up you can select 'Yes' to debug and you will be taken to the VWD debugger.
&lt;p&gt;
Check out this &lt;a href="http://www.berniecode.com/blog/2007/03/08/how-to-debug-javascript-with-visual-web-developer-express/"&gt;blog&lt;/a&gt; for a step-by-step guide.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-8840047991375080854?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/8840047991375080854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=8840047991375080854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8840047991375080854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/8840047991375080854'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/05/debugging-javascript-errors-in-ie7-on.html' title='Debugging javascript errors in IE7 on WinXP'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-6250151760770735941</id><published>2008-04-30T15:58:00.000-07:00</published><updated>2009-03-24T02:55:20.502-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='hostgator'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Accessing a HostGator SVN repository via SVN+SSH on Windows</title><content type='html'>This information should be helpful to anyone trying to access an svn repository stored on a remote (shared) server which does not expose an svn server.
&lt;p&gt;
My host is &lt;a href="hostgator.com"&gt;HostGator&lt;/a&gt; (good speeds, reliable ssh, cgi-only, MyISAM-only, decent support, non-existent knowledgebase).  HostGator runs SSH over port 2222 which presents a few problems when trying to use traditional methods to connect to an SVN repository via SSH.
&lt;p&gt;
For these steps you will need &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html"&gt;Putty&lt;/a&gt;.  Just get the whole suite.
&lt;ol&gt;
&lt;li&gt;Generate an RSA key using PuttyGen&lt;/li&gt;

&lt;li&gt;Copy the public key into your &lt;span class="filename"&gt;~/.ssh/authorized_keys&lt;/span&gt; file on the server.&lt;/li&gt;

&lt;li&gt;Prepend your key with (so it's all on one line):

&lt;div class="code"&gt;command="/usr/bin/svnserve -t"&lt;/div&gt;
&lt;p&gt;This sets up svnserve to run in tunnel mode.  The ramification of this is that you can no longer use this RSA key to auto-login on the shell.  There is some information out there about creating an svn.mydomain.com subdomain and only having this rule apply to that subdomain, which solves that problem.  On *nix machines this involves adding a simple rule to your SSH keystore that says "use key X when connecting to svn.mydomain.com and key Y when connecting to mydomain.com".  Then you would have two entries in your &lt;span class="filename"&gt;authorized_keys&lt;/span&gt; file, one with the &lt;span class="filename"&gt;svnserve&lt;/span&gt; command for connections to svn.mydomain.com using key X and one without for key Y.&lt;/li&gt;
&lt;p&gt;
&lt;li&gt;Now load your private key into Pageant&lt;/li&gt;

&lt;li&gt;Create a new Putty connection called mydomain.com.
&lt;p&gt;    
    &lt;ul&gt;
    &lt;li&gt; Set the the Auto-login username.&lt;/li&gt;
    &lt;li&gt; Ensure that SSH-&gt;Auth-&gt;Attempt authentication using Pageant is checked.&lt;/li&gt;
    &lt;li&gt; Create an SSH tunnel which forwards LOCAL port 22 to mydomain.com port 2222.&lt;/li&gt;
    &lt;/ul&gt;
&lt;p&gt;
SAVE the connection and then test it by opening it.  You should be logged in without having to provide a password.
&lt;p&gt;
SVN should now be working when you use TortoiseSVN (or a similar client I assume).  However, svn from the command line will not work and will report "Can't create tunnel..."
&lt;p&gt;
Now to get SVN working from the command line.
&lt;/li&gt;
&lt;li&gt;Create an SVN_SSH environment variable with value (keep the quotes and use forward slashes):

&lt;div class="code"&gt;"C:/Program Files/PuTTY/plink.exe"&lt;/div&gt;
&lt;p&gt;
SVN will now use plink to try to connect to the svn repository.  This will only work if the domain of your svn root's URL is named the same as the Putty connection you created i.e. mydomain.com.&lt;/li&gt;
&lt;/ol&gt;
If you find that you are getting errors when running "svn info" on a URL I found that
version 1.4.2 works for Windows but 1.4.6 does not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-6250151760770735941?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/6250151760770735941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=6250151760770735941' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6250151760770735941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/6250151760770735941'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/04/accessing-hostgator-svn-repository-via.html' title='Accessing a HostGator SVN repository via SVN+SSH on Windows'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2513359599542643372</id><published>2008-04-25T14:39:00.000-07:00</published><updated>2008-11-26T22:59:56.202-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='timezones'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle 10g timezones and setting the Java timezone</title><content type='html'>To see your session and database timezones:
&lt;pre name="code" class="sql"&gt;SELECT sessiontimezone, dbtimezone FROM dual;&lt;/pre&gt;
To set them:
&lt;pre name="code" class="sql"&gt;ALTER database SET TIME_ZONE = '-07:00';
ALTER session SET TIME_ZONE = '-07:00';&lt;/pre&gt;
Alternatively you can set it by supplying a region which exists in the following list:
&lt;pre name="code" class="sql"&gt;SELECT tzname, tzabbrev FROM V$TIMEZONE_NAMES;&lt;/pre&gt;
To set the JVM timezone append the following option when calling java:
&lt;div class="code"&gt;-Duser.timezone=Asia/Japan&lt;/div&gt;
Java stores the supported timezones in files located at:
&lt;div class="code"&gt;c:\path\to\jdk1.5.0_12\jre\lib\zi\&lt;/div&gt;
To set the timezone within your code, which is sometimes neccessary because OC4J seems to ignore my -Duser.timezone option:
&lt;pre name="code" class="java"&gt;java.util.TimeZone tz = java.util.TimeZone.getTimeZone("America/Vancouver");
java.util.TimeZone.setDefault(tz);&lt;/pre&gt;
&lt;p&gt;
Here is a JSP page to display some time and timezone related information:
&lt;pre name="code" class="xml"&gt;&amp;lt;%@ page language=\&amp;quot;java\&amp;quot; contentType=\&amp;quot;text/html; charset=ISO-8859-1\&amp;quot;
    pageEncoding=\&amp;quot;ISO-8859-1\&amp;quot;%&amp;gt;
&amp;lt;%@ page import=\&amp;quot;
  java.util.*,
  java.text.DateFormat\&amp;quot; %&amp;gt;
&amp;lt;!DOCTYPE html PUBLIC \&amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN\&amp;quot; \&amp;quot;http://www.w3.org/TR/html4/loose.dtd\&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=\&amp;quot;Content-Type\&amp;quot; content=\&amp;quot;text/html; charset=ISO-8859-1\&amp;quot;&amp;gt;
&amp;lt;title&amp;gt;TimeZone Test&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
Your current timezone is: &amp;lt;%= java.util.TimeZone.getDefault().toString() %&amp;gt;
&amp;lt;p&amp;gt;
The current time is: &amp;lt;%= (new java.util.Date()).toString() %&amp;gt;
&amp;lt;p&amp;gt;
The value of the user.timezone property is: &amp;lt;%= System.getProperty(\&amp;quot;user.timezone\&amp;quot;) %&amp;gt;
&amp;lt;p&amp;gt;
The date using DateFormat is: &amp;lt;%= DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()) %&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2513359599542643372?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2513359599542643372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2513359599542643372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2513359599542643372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2513359599542643372'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/04/oracle-10g-timezones-and-setting-java.html' title='Oracle 10g timezones and setting the Java timezone'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6189841530810285724.post-2978654254809975019</id><published>2008-04-16T19:52:00.000-07:00</published><updated>2008-11-26T22:57:35.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oc4j'/><title type='text'>oc4j 10.1.3.2.0 is missing a required rmi class PropagatedIdentity</title><content type='html'>Today I was getting an error on the console which I have included below.  The error prevents the BPEL server from calling our application server via rmi, which results in some BPEL processes not being executed.
&lt;p&gt;
Oc4j10.1.3.2.0 is missing the &lt;span class="monospace light"&gt;oracle.oc4j.rmi.interceptors.PropagatedIdentity&lt;/span&gt; class which should be in &lt;span class="monospace light"&gt;C:/appservers/oc4j10.1.3.2.0/j2ee/home/lib/oc4j-internal.jar&lt;/span&gt;.
&lt;p&gt;
The required class was found in &lt;span class="monospace light"&gt;C:\appservers\famsbpel1013\j2ee\home\oc4jclient.jar&lt;/span&gt;.  I copied the oracle.oc4j.rmi.interceptors class folder from &lt;span class="monospace light"&gt;oc4jclient.jar&lt;/span&gt; to &lt;span class="monospace light"&gt;oc4j-internal.jar&lt;/span&gt; and everything worked fine with no errors.
&lt;p&gt;
If everything is running 10.1.3.3.0 you should be ok.
&lt;p&gt;
Here's the error:
&lt;pre name="code" class="plain"&gt;08/04/16 18:24:20 SEVERE: RMIInterceptorManagerImpl.readInterceptorContexts unable to recover remote context:

         Missing class: oracle.oc4j.rmi.interceptors.PropagatedIdentity
       Dependent class: com.evermind.io.ClassLoaderObjectInputStream
                Loader: oc4j:10.1.3
           Code-Source: /C:/appservers/oc4j10.1.3.2.0/j2ee/home/lib/oc4j-internal.jar
         Configuration: &amp;lt;code-source&amp;gt; in META-INF/boot.xml in C:\appservers\oc4j10.1.3.2.0\j2ee\home\oc4j.jar

This load was initiated at fams.root:0.0.0 using the Class.forName() method.

The missing class is not available from any code-source or loader in the system.

08/04/16 18:24:20 SEVERE: RMIInterceptorManagerImpl.readInterceptorContexts unable to recover remote context:

         Missing class: oracle.oc4j.rmi.interceptors.PropagatedIdentity
       Dependent class: com.evermind.io.ClassLoaderObjectInputStream
                Loader: oc4j:10.1.3
           Code-Source: /C:/appservers/oc4j10.1.3.2.0/j2ee/home/lib/oc4j-internal.jar
         Configuration: &amp;lt;code-source&amp;gt; in META-INF/boot.xml in C:\appservers\oc4j10.1.3.2.0\j2ee\home\oc4j.jar

This load was initiated at fams.root:0.0.0 using the Class.forName() method.

The missing class is not available from any code-source or loader in the system.

08/04/16 18:24:20 SEVERE: RMIInterceptorManagerImpl.readInterceptorContexts unable to recover remote context:

         Missing class: oracle.oc4j.rmi.interceptors.PropagatedIdentity
       Dependent class: com.evermind.io.ClassLoaderObjectInputStream
                Loader: oc4j:10.1.3
           Code-Source: /C:/appservers/oc4j10.1.3.2.0/j2ee/home/lib/oc4j-internal.jar
         Configuration: &amp;lt;code-source&amp;gt; in META-INF/boot.xml in C:\appservers\oc4j10.1.3.2.0\j2ee\home\oc4j.jar

This load was initiated at fams.root:0.0.0 using the Class.forName() method.
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6189841530810285724-2978654254809975019?l=kjvarga.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kjvarga.blogspot.com/feeds/2978654254809975019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6189841530810285724&amp;postID=2978654254809975019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2978654254809975019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6189841530810285724/posts/default/2978654254809975019'/><link rel='alternate' type='text/html' href='http://kjvarga.blogspot.com/2008/04/oc4j-101320-is-missing-required-rmi.html' title='oc4j 10.1.3.2.0 is missing a required rmi class PropagatedIdentity'/><author><name>Karl Varga</name><uri>http://www.blogger.com/profile/10861233326760747414</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_LjUDvSJPqv4/SIo9lFTDVTI/AAAAAAAAAAM/F5-S91lMZZg/S220/sitka-summer-shindig-043---.jpg'/></author><thr:total>0</thr:total></entry></feed>
