Archive for March 2008

Blue screen of the death on a Mac

2008/03/29

Here it comes, first occurence: one of my VM’s BSOD-ed on me yesterday.

picture-35.png

To be completely fair, I did have experienced an occurrence of something similar twice in last moths: after wake up from sleep, the screen was collection of the color pixels, completely unreadable. After reboot, everything was normal.

I found out that the issue may be related to the “safesleep” mode. For now, I disabled the mode by

sudo pmset -a hibernatemode 0

To re-enable SafeSleep, the command is:
sudo pmset -a hibernatemode 3

So far, everything works – but I am still investigating. Thanks to this thread (in German) for the hint.

Finally over 16 :-)

2008/03/26

I did not even notice that the visit counter left the 16 bit domain sometimes during last few days. Now it shows about 67 000 visits. Honestly, I am pleasantly surprised how many people found this blog worthy their time :-). Thanks to you all …

Next boundary is of course 128K, 256K, 512K hits and finally a “Megahit”. But that’s far far away.

Rails 2 – really good tutorial

2008/03/25

Akita published two part tutorial that leads you through building the famous 15 minute blog application in Rails 2.0. Read the parts one and two – or follow the screencast by the same author.

Thanks a lot, Akita – very nicely done !

The meaning of ORA-29907 error and the fix

2008/03/19

I have first time encountered the error:

ORA-29907: found duplicate labels in primary invocations

after testing the change request we have implemented recently. The error message was not very helpful – I was not exactly sure which labels and which invocations ๐Ÿ˜‰ – and as Oracle guru who actually does understand fine details of Oracle Text was visiting sunny India, I was on my own.

The change addressed an issue in repository search: users were asking for more flexible processing of full text search phrases: instead of e.g. searching for “unit test” search for document that contains both unit AND test. The text was parsed in Java and the SQL generator produced instead of something like


SELECT * FROM DOCUMENT d1 WHERE ROWNUM  5)


SELECT * FROM DOCUMENT d1 WHERE ROWNUM  5)
AND ( CONTAINS(d1.document,'unit',1) > 5)

I am still unsure what primary invocation is, but the above mentioned ‘label’ was the number one. After changing the generator to issue sequence numbers in the CONTAINS, everything worked OK:


SELECT * FROM DOCUMENT d1 WHERE ROWNUM  5)
AND ( CONTAINS(d1.document,'unit',2) > 5)

Starting Ruby on Rails 2 with Netbeans and AWDWR book

2008/03/17

After some break, I got back to Rails land. The return is not as smooth as I hoped: since Rails 2.0, many things work differently and quite a few steps learned from “The Book” do not work any more. The issues are more often than not quite easy to fix, but there is quite a few of them.

All the following is related to NetbeansRuby build 6327 from Jan 26th with JRuby 1.1RC1

After installing NetbeansRuby and updating the Gems (Tools->Ruby Gems), the attempt to generate Rails application fails:


/Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:379:in `report_activate_error': Could not find RubyGem activeresource (= 2.0.2) (Gem::LoadError)

        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:311:in `activate'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:337:in `activate'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `each'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `activate'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `active_gem_with_options'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:50:in `gem'
        from /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/rails:18

Looks like the gem updater somehow missed activeresource – maybe a problem with dependencies ?To fix this, manually install activeresource 2.0.2 – Tools -> Ruby Gems, New Gems, search for resource, install. This is list of the installed gems:

  • actionmailer (2.0.2, 1.3.5)
  • actionpack (2.0.2, 1.13.5)
  • actionwebservice (1.2.6, 1.2.5)
  • activerecord (2.0.2, 1.15.5)
  • activerecord-jdbc-adapter (0.7.2, 0.7)
  • activeresource (2.0.2)
  • activesupport (2.0.2, 1.4.4)
  • jruby-openssl (0.1.1)
  • rails (2.0.2, 1.2.5)
  • rake (0.8.1, 0.7.3)
  • rspec (1.1.3, 1.1.1)
  • sources (0.0.1)

By default, the Rails 2 selects Sqlite3 database. This is great choice if you use C-Ruby, but not so great for JRuby – see this post. After few frustrated attempts to find workaround, I decided to go with Ruby 1.8.6, updated (again) the Gems in system installation (the first updated upgraded JRuby gems) and decided to try out the Depot sample – just have something that works, rather than fighting with issues of both Rails 2 and my own bugs. To keep with the book, I stayed with MySQL (quietly running in VMWare virtual machine).

By the book I have generated Product model and Admin controller, but instead of seeing familiar screen, Rails responded with error:


Routing Error

No route matches "/admin" with {:method=>:get}

This can be fixed by addingmap.connect ‘:controller/:action’to routes.rb, but this is probably bad idea because it goes against REST design principles which Rails 2 tries to promote. But to go ahead with the example, I hacked it ๐Ÿ™‚ and added scaffolding. Next error I got was:


 NoMethodError in AdminController#index

undefined method `scaffold' for AdminController:Class

RAILS_ROOT: /Users/miro/Projects/RAILS2/Depot
Application Trace | Framework Trace | Full Trace

app/controllers/admin_controller.rb:2
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_file'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in `load_file'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in `require_or_load'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in `load_missing_constant'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in `const_missing'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in `const_missing'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/inflector.rb:257:in `constantize'
/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/string/inflections.rb:148:in `constantize'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/routing.rb:1426:in `recognize'

Scaffolding is one of the parts removed in Rails 2. :-(. I tried to install ‘scaffolding’, which led to another error:


NoMethodError in AdminController#index

undefined method `paginate' for #

RAILS_ROOT: /Users/miro/Projects/RAILS2/Depot
Application Trace | Framework Trace | Full Trace

vendor/plugins/scaffolding/lib/scaffolding.rb:107:in `list'
vendor/plugins/scaffolding/lib/scaffolding.rb:95:in `index'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `send'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `perform_action_without_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in `call_filters'

Based on this post, I installed classic_pagination, which resulted in another error when trying to enter new Product


 ActionController::InvalidAuthenticityToken in AdminController#create

ActionController::InvalidAuthenticityToken

RAILS_ROOT: /Users/miro/Projects/RAILS2/Depot
Application Trace | Framework Trace | Full Trace

/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:469:in `send!'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:469:in `call'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:441:in `run'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:716:in `run_before_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:695:in `call_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in `perform_action_without_benchmark'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in `perform_action_without_caching'

I backtracked, and tried to go with generated scaffold, rather with dynamic. The generated views were named edit.html.erb, rather than edit.rhtml and the generator did not allow to enter controller (second argument). This lead to error


Error:

Template is missing

Missing template admin/index.html.erb in view path /Users/miro/Projects/RAILS2/Depot/app/views

At this point I gave up and decided to:

  • read the Rails 2.0 documentation (after everything else failed, read the manual …)
  • reconsider using AWDWR as the guide – obviously, it needs to be updated to be useful with Rails 2. If you purchased the PDF from Pargmatic Programmers, there is an update available on their website, but it is not an update for Rails 2 …

I was not the only person to try AWDWR with Rails 2. The best resource I found was Ruby Plus website with series of screencasts, starting with this. The author – Bala Paranj did great job in putting together very useful collection of Rails screencasts. If you want to use the AWDWR with Rails 2.0, listen to them first – unless you are very experienced Rails developer.

Showstopper issue with JRuby ?

2008/03/16

After some break, I dusted off the Ruby to try out one interesting idea Peter presented yesterday that literally ASKS for Rails. So I grabbed the latest and greatest RubyNetBeans from Ruby Hudson. For some reason it stopped updates on January 26th so the latest version I have got was build 6327. It is bundled with JRuby 1.1RC1 and the Rails version that comes preinstalled is 1.2.6. Using the menu Tools -> Ruby Gems, they can be easily upgraded to latest and greatest 2.0.2.

The trouble begins when you want to install database connectivity gems such as sqlite3-ruby. The installer fails with the message:


trying to install

INFO:  `gem install -y` is now default and will be removed
INFO:  use --ignore-dependencies to install only the gems you list
Building native extensions.  This could take a while...
extconf.rb:1: no such file to load -- mkmf (LoadError)
ERROR:  Error installing sqlite3-ruby:
    ERROR: Failed to build gem native extension.

/Users/miro/Applications/<a href="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/jruby" class="linkification-ext" title="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/jruby">RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/jruby</a> extconf.rb install sqlite3-ruby --no-rdoc --no-ri --include-dependencies --version &gt; 0

Gem files will remain installed in /Users/miro/Applications/<a href="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1" class="linkification-ext" title="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1">RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1</a> for inspection.
Results logged to /Users/miro/Applications/<a href="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1/ext/sqlite3_api/gem_make.out" class="linkification-ext" title="http://RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1/ext/sqlite3_api/gem_make.out">RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1/ext/sqlite3_api/gem_make.out</a>

The missing file mkmf.rb is indeed missing from the JRuby distribution. This is entered as a bug in JIRA 1306 with resolution ‘Won’t fix’. Tough luck.

I understand the reasons and motivation for this decision – the JRuby team decided not to support native extensions in Gems, to keep the platform Java only. I also understand that in this particular case, there are workarounds – using ActiveRecord-DBC gem and JDBC drivers for the database will most likely work. Unfortunately, this decision makes choice of JRuby as platform very questionable.

I really liked JRuby for the comfort of having platform that is portable and safely wrapped within boundaries of the good old trusted JVM. I feel much more comfortable maintaining possibly several different versions of JRuby and corresponding Gems sets than maintaining same several configurations on the OS level and sudo-ing just to install Gems. I was more that happy to trade the lack of speed for this security.

The two main attractions of Ruby (from my point of view) are elegant, powerful language with beautiful syntax as well as sheer amount of code available as Gems to be reused. With the bug 1306, many of this code may not be available for JRuby – unless Gem authors make specific provisions for Java version of the Gem. I cannot think how this is a good idea and certainly not a good news for the future of the language.

One way out is use native Ruby interpreter, of course and make sure you do not mess up your installation by trying out new things. This does not allow the easy way into enterprise that JRuby was promising – by being basically ‘just another jar’ and running on Tomcat.
The other way out is to reconsider the Groovy. I still do not enjoy the syntax anywhere close to Ruby, but every Groovy class is Java class, there is no need for artificial bridges. It has own clone of Rails – GRails – that seems to provide lots of Rails magic and goodies and is based on Spring which I am very familiar and quite happy with. I still do not know whether the amount of “gems” in Groovy world is in the same league as Ruby (which is still limited compared to Python or even CPAN Perl bonanza) – but as long as I can find that what I need, it may be just enough.

For now, I will revert back to Ruby (no time to start learning Groovy+Grails), but I definitely will look at it later on.

On White Stuff and Other Disasters

2008/03/13

Guess what are three most useful tools without which no proper Ottawa household can exist ? Snow shovel, snow pusher and car window ice scratcher. If the number was 4, the next would be snowblower. Up to yesterday, our family was in safe position being equipped with several shovels, four or five scratchers and one pusher.

Then disaster stroke: my son broke the pusher while moving away few cube meters of snow we removed from the roof. In case you do not understand – removing snow from roof is another favorite winter leisure time activity in Ottawa: almost everybody is doing it. Not that it would be so much fun, but because of the dreadful consequences – avoid it and you may end up like this guy.

Especially in year rich on snow, like this one. And this winter – despite beig warm and cosy, only few days of -25 and below – it is snow-wise very likely a record year. The previous record winter happened (fortunately) long before I set foot on this continent: in 1970-71, we had 444 cm of snow during winter. Right now, it is about 415. The weather forecast for next week mentions possibility of another 50 cm. Ouch.

picture-19.pngThe shoveling is no fun at all. The back garden is full of snow, with top of the snowhill well over 3 m high. Another mountain in front of the house. I can hardly imagine where we do put another 50 cm, and most importantly HOW. Because the darn pusher is broken.
Now if you think that in modern market economy it is just a matter of driving to next store and buying one, think again. This is what I did today, just to discover that full Garden and Outdoor section is filled with barbecues, rakes, seeds, lawn movers and other completely ridiculous tools :-). No pushers at all. Only small pack of deserted shovels set aside. I bought one to make the trip worth the time ….

I guess I will have to BORROW a pusher from neighbor :-(. What a shame to admit I am pusher-less …

Out of desperation, I have decided to share my experience with the public in the following book:
Snow Shovelling

Couple of Objective-C and Cocoa links

2008/03/12

Lured by the iPhone platform, this is what I read in the evenings. Feels kind of funny: after 10+ years of Java/C# and almost as many yearsย  of C++ beforehand, I mostly lost my C instincts and C habits. Fortunately, I have also mostly lost my C++ bad habits as well.

The Apple site is definitive starting point – put the http://developer.apple.com/referencelibrary/index.html into your bookmarks. From non-Apple sources, very bookmarking-worthy is the Cocoa Literature and Cocoa Devcentral.

Theocacao has a nice example highlighting diferences between Objective C 1.0 and 2.0. There are many tutorials available, with various depth and quality, e.g. here, and here. Wikipedia page is also quite useful.

From books – I have browsed few in Chapters and on Safari Books, the best still seems to be Hillegass’s book. There is an updated version (for Objective C 2.0) coming out in June 2008.

From list of links, try this.

Versioning with Spring and Ant

2008/03/10

This is post is NOT about version control in the sense of source code control. It addresses the issue how to easily tell which version of the Web application is running as well make sure that the same version is reflected in the snapshots performed by Ant. We have used this approach on several applications and found it quite useful.

The version I talk about is not the automatically generated version from VCS system (such as SVN revision). The version number is set manually.

In every project, we include property file named application.properties, placed at the root of the classpath (next to ‘com’ directory in the source tree). The content can look like this


app.name = MyApp
app.version = 0.5.4
app.info = User authentication implemented

This property file will be available to Java code because of its location in classpath. Our build.xml file ususally starts with few includes like this



    
    ...
    

We try to load first the property files named after the computer. This way we can easily address differences in e.g. Tomcat locations, pathnames to libraries etc. This is very useful if not all team members have identical development environment – which is almost always the case, as I am on Mac and the others mostly on Windows :-). The environment variable COMPUTERNAME is automatically set for you if you are on Windows, for Mac/Linux users all you need is an export in your .bashrc file.

The second include loads the application properties and makes the ‘app.version’, ‘app.name’ available for Ant tasks. Externalizing the app.name allows reusing same Ant script for multiple project. Here is an example of the task that creates and archive of current source code snapshot using this information:



      
            
            
            
            
            
            
            
            
            
      
    

The DSTAMP and TSTAMP are set in prepare task:



        
            
        
        
    

To access the information from application.properties, we simply add it to the list of message sources:

    
        
            
                messages
                application
            
        
    

This allows to easily display the version number and information as part of e.g. JSP page:


 -
            

For production, I usually still leave the version in the JSP, only include it in HTML comments, so that it does not interfere with the UI but is still accessible by viewing page source.

I usually set version number and info string manually, but it possible to automatically write information about e.g. build date and time of the application and make it a part of the version info. To do that, use the Ant task:



    
        
    
    File test.properties updated at ${DSTAMP} ${TSTAMP}
  

In this case, the value of property app.stamp will be overwritten every time the ‘set_version’ task executes.

iBatis, Date null values and Oracle

2008/03/07

I better blog this before I forget what was the issue :-).

During daily run of unit tests, I started to receive this (very well explained) exception:

org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [17004];
--- The error occurred while applying a parameter map.
--- Check the APPROVAL_TASK.insert-InlineParameterMap.
--- Check the parameter mapping for the 'scheduledDate' property.
--- Cause: java.sql.SQLException: Invalid column type; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred while applying a parameter map.
--- Check the APPROVAL_TASK.insert-InlineParameterMap.
--- Check the parameter mapping for the 'scheduledDate' property.
--- Cause: java.sql.SQLException: Invalid column type
	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:121)
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)
	at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
	at org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:397)
... 

Now the problem was that scheduledDate was null. Here is partial SQL map used:


    insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)
    values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:DATETIME#)


The createDate time jdbcType DATETIME was actually one of my changes. What Abator generated originally was this:


    insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)
    values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:DATE#)
</pre>
<pre>

This map does not suffer by the Null value problem, but unfortunately does not store the time portion of the date – which was the main reason why I used DATETIME, unaware of the Null sensitivity.

There are three ways how to fix this. First is obvious – do use DATETIME and make sure that the field has value. This may be good enough as long as you do not need to save null values.

Second solution is to keep DATETIME and use iBatis magic with conditionals in map definition:

</pre>
<pre>
    insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)
    values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#,
                
			null
		
		
			#createDate:DATETIME#
		   )
</pre>
<pre>

This deals with the null value differently and avoids “guessing” the column type, which caused the problem.Third solution may not work on other databases, but on Oracle works prefectly. The data type TIMESTAMP does both store the time portion as well as handles Null values without any problems. This is what I used at the end.

Final map:

</pre>
<pre>
    insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)
    values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:TIMESTAMP#)
</pre>
<pre>