<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Brian Leonard&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/" />
<modified>2008-06-25T21:20:03Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, bleonard</copyright>
<entry>
<title>Introducing The Observatory</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/06/introducing_the.html" />
<modified>2008-06-25T21:20:03Z</modified>
<issued>2008-06-25T21:19:53Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.10030</id>
<created>2008-06-25T21:19:53Z</created>
<summary type="text/plain">Yesterday Gregg Sporar, Roman Strobl and I launched The Observatory, a blog dedicated to those learning to use OpenSolaris.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>Yesterday <a href="http://blogs.sun.com/gregg/entry/the_observatory">Gregg Sporar</a>, <a href="http://blogs.sun.com/roumen/entry/my_new_role_at_sun">Roman Strobl</a> and I launched <a href="http://blogs.sun.com/observatory/entry/the_first_sighting">The Observatory</a>, a blog dedicated to those learning to use OpenSolaris. The last couple of my blog entries have been about OpenSolaris and I've been waiting for someone to ask: &quot;Dude, what are you doing talking about OpenSolaris on a Java site?&quot; Plus, this blog also feeds into <a href="http://www.planetnetbeans.org/">Planet NetBeans</a> and I don't necessarily want to piss off that community either.</p>
<p>In many respects, my role does not change, as I'm still going to talk about NetBeans and other technologies I've come to love like Rails. The difference is that I will be showing off the advantages of doing those things from OpenSolaris. ]]>

</content>
</entry>
<entry>
<title>OpenSolaris 2008.05: Installing MySQL 5</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/06/opensolaris_200_3.html" />
<modified>2008-06-23T20:27:36Z</modified>
<issued>2008-06-23T20:25:55Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.10010</id>
<created>2008-06-23T20:25:55Z</created>
<summary type="text/plain">Looking at the MySQL web site, the instructions for Installing MySQL Community Server seem more complicated then they need to be. Maybe that&apos;s because there are no instructions for OpenSolaris (yet - I hope). Here are the easy steps that got me up and running.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>Looking at the MySQL web site, the instructions for <a href="http://dev.mysql.com/doc/refman/5.0/en/installing-cs.html">Installing MySQL Community Server</a> seem more complicated then they need to be. Maybe that's because there are no instructions for OpenSolaris (yet - I hope). Here are the easy steps that got me up and running.</p>
<h3>Install MySQL</h3>
<ul>
  <li>Open the Package Manager: System &gt; Administration &gt; Package Manager (give it a couple of seconds to load the package information):<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Package Manager - revision 1.png" width="826" height="652" /><br />
    <br />
  </li>
  <li>Enter <strong>mysql5</strong> in the Search text box .The list will filter as you type.<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Package Manager - revision 1-1.png" width="826" height="652" /><br />
    <br />
  </li>
  <li>Select the check box for SUNWmysql5 and click the Install/Update button in the toolbar;<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Package Manager - revision 1-2.png" width="826" height="652" /><br />
    <br />
  </li>
  <li>Wait while package dependencies are checked and then click Next on the Install / Update Confirmation dialog:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Install - Update Confirmation.png" width="403" height="411" /><br />
    <br />
  </li>
  <li>Wait while the packages are downloaded and installed:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Downloading Packages.png" width="376" height="197" /><br />
    <br />
  </li>
  <li>After which, the Package Manager will show MySQL as installed:<br />
    <br />
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Package Manager - revision 1-3.png" width="826" height="652" /></li>
</ul>
<h3>Start the MySQL Service</h3>
<ul>
  <li>Open System &gt; Administration &gt; Services and scroll down to MySQL RDBMS in the list:<br />
      <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Services settings.png" width="454" height="439" /><br />
        <br />
  </li>
  <li>Click the check box to enable the MySQL RDBMS:<br />
      <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/Screenshot-Services settings-1.png" width="454" height="439" /><br />
  </li>
</ul>
<h3>Verify the Installation</h3>
<p><br />
  Note, the MySQL documentation's <a href="http://dev.mysql.com/doc/refman/5.0/en/installation-layouts.html">Installation Layouts</a> page does not cover OpenSolaris, but you'll find the binaries in <span class="style1">/usr/mysql/bin</span> and the databases in <span class="style1">/var/mysql/data</span>.<br />
</p>
<ul>
  <li>
    <p>Open a terminal and start the MySQL client:<br />  
      <br />    
      bleonard@opensolaris:~$ <strong>/usr/mysql/bin/mysql -u root</strong><br />
      Welcome to the MySQL monitor.  Commands end with ; or \g.<br />
      Your MySQL connection id is 4<br />
    Server version: 5.0.45 Source distribution</p>
    <p>Type 'help;' or '\h' for help. Type '\c' to clear the buffer.</p>
    <p>mysql&gt; <strong>show databases;</strong><br />
        +--------------------+<br />
        | Database           |<br />
        +--------------------+<br />
        | information_schema | <br />
        | mysql              | <br />
        | test               | <br />
        +--------------------+<br />
        3 rows in set (0.00 sec)<br />
      <br />
</p>
  </li>
  <li>
    <p>If you have <a href="http://weblogs.java.net/blog/bleonard/archive/2008/06/opensolaris_200_1.html">NetBeans 6.1 installed</a> it will also show you your MySQL databases in the services tab:<br />
        <br />
        <img src="http://weblogs.java.net/blog/bleonard/archive/2008/06/mysql5_opensolaris/NetBeans_Services.png" width="514" height="140" /></p>
    <br />
  </li>
</ul>]]>

</content>
</entry>
<entry>
<title>OpenSolaris 2008.05: Installing NetBeans 6.1</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/06/opensolaris_200_1.html" />
<modified>2008-06-19T18:56:06Z</modified>
<issued>2008-06-19T18:56:00Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9993</id>
<created>2008-06-19T18:56:00Z</created>
<summary type="text/plain">Unfortunately, NetBeans 6.1 has not yet made it into the package repository for OpenSolaris 2008.05 yet. Here&apos;s how to install it.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>Unfortunately, NetBeans 6.1 has not yet made it into the package repository for OpenSolaris 2008.05 yet. Here's how to install it.</p>
<h3>Step 1: Install the JDK</h3>
<p>OpenSolaris 2008.05 does not ship with the JDK, so if you haven't already done so, it needs to be installed first.</p>
<ul>
  <li><a href="http://java.sun.com/javase/downloads/index.jsp">Download</a>  JDK 6 Update 6 (or newer)</li>
  <li>For the Platform select Solaris x86. Even if you're running in 64-bit mode you need to install the x86 version first:  <br />
    <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/netbeans61_opensolaris/JDK_Download.png" width="604" height="270" /><br />
      <br />
  </li>
  <li>Download the <strong>Solaris x86 packages -tar.Z</strong>. You can use the Sun Download Manager, but I just clicked the file name and saved it to a JDK folder I created on my Desktop (I created a folder so the extracted files would be easier to clean up):  <br />
    <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/netbeans61_opensolaris/JDK_Download2.png" width="604" height="523" /><br />
        <br />
  </li>
  <li>Extract the tar file. Open a terminal and enter:<br />
      <br />
        <span class="style3">cd Desktop/JDK<br />
    zcat jdk-6u6-solaris-i586.tar.Z | tar -xf - </span><br />
    <br />
  </li>
  <li>Install the JDK (OpenSolaris 2008.05 ships with the JRE, so there's no need to install that package):    <br />
    <br />
    <span class="style1">bleonard@opensolaris:~/Desktop/JDK$ <strong>pfexec pkgadd -d . SUNWj6dev SUNWj6cfg SUNWj6man SUNWj6dmo</strong>
    </p>
    </span>  </li>
</ul>

  <blockquote>
    <p class="style1">Processing package instance &lt;SUNWj6dev&gt; from &lt;/export/home/bleonard/Desktop/JDK&gt;</p>
  <p class="style1">JDK 6.0 Dev. Tools (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03<br />
    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.<br />
    Use is subject to license terms.<br />
    Using &lt;/usr&gt; as the package base directory.<br />
    ## Processing package information.<br />
    ## Processing system information.<br />
    4 package pathnames are already properly installed.<br />
    ## Verifying package dependencies.<br />
    WARNING:<br />
    The &lt;SUNWmfrun&gt; package &quot;Motif RunTime Kit&quot; is a<br />
    prerequisite package and should be installed.</p>
  <p class="style1">Do you want to continue with the installation of &lt;SUNWj6dev&gt; [y,n,?]      
  <p>  <br />
  	The Motif RunTime Kit (SUNWmfrun) isn't included with OpenSolaris 2008.05, so I'm just going to ignore this warning and continue...<br />
  	<br />
  	<span class="style1">Do you want to continue with the installation of &lt;SUNWj6dev&gt; [y,n,?] <strong>y</strong></span></p>
  <p class="style1">Installing JDK 6.0 Dev. Tools (1.6.0_06) as &lt;SUNWj6dev&gt;</p>
  <p class="style1">## Installing part 1 of 1.<br />
    /usr/jdk/instances/jdk1.6.0/LICENSE<br />
    /usr/jdk/instances/jdk1.6.0/README.html<br />
    ...</p>
  <p class="style1">/usr/jdk/instances/jdk1.6.0/lib/tools.jar<br />
    /usr/jdk/instances/jdk1.6.0/src.zip<br />
    [ verifying class &lt;none&gt; ]<br />
    ## Executing postinstall script.</p>
  <p class="style1">Installation of &lt;SUNWj6dev&gt; was successful.</p>
  <p class="style1">Processing package instance &lt;SUNWj6cfg&gt; from &lt;/export/home/bleonard/Desktop/JDK&gt;</p>
  <p class="style1">JDK 6.0 Host Config. (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03<br />
    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.<br />
    Use is subject to license terms.<br />
    Using &lt;/&gt; as the package base directory.<br />
    ## Processing package information.<br />
    ## Processing system information.<br />
    1 package pathname is already properly installed.<br />
    ## Verifying package dependencies.<br />
    WARNING:<br />
    The &lt;SUNWmfrun&gt; package &quot;Motif RunTime Kit&quot; is a<br />
    prerequisite package and should be installed.</p>
  <p class="style1">Do you want to continue with the installation of &lt;SUNWj6cfg&gt; [y,n,?] </p>
  <p>You get the same warning with the Dev. Tools package. Again, continue...<br />
      <br />
    <span class="style1">Do you want to continue with the installation of &lt;SUNWj6cfg&gt; [y,n,?] <strong>y</strong><br />
      ## Verifying disk space requirements.<br />
      ## Checking for conflicts with packages already installed.<br />
    ## Checking for setuid/setgid programs.</span></p>
  <p class="style1">This package contains scripts which will be executed with super-user<br />
    permission during the process of installing this package.</p>
  <p class="style1">Do you want to continue with the installation of &lt;SUNWj6cfg&gt; [y,n,?] <strong>y</strong></p>
  <p class="style1">Installing JDK 6.0 Host Config. (1.6.0_06) as &lt;SUNWj6cfg&gt;</p>
  <p class="style1">## Installing part 1 of 1.<br />
    [ verifying class &lt;none&gt; ]<br />
    [ verifying class &lt;preserve&gt; ]<br />
    ## Executing postinstall script.</p>
  <p class="style1">Installation of &lt;SUNWj6cfg&gt; was successful.</p>
  <p class="style1">Processing package instance &lt;SUNWj6man&gt; from &lt;/export/home/bleonard/Desktop/JDK&gt;</p>
  <p class="style1">JDK 6.0 Man Pages (1.6.0_06)(i386) 1.6.0,REV=2006.12.07.16.42<br />
    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.<br />
    Use is subject to license terms.<br />
    Using &lt;/usr&gt; as the package base directory.<br />
    ## Processing package information.<br />
    ## Processing system information.<br />
    3 package pathnames are already properly installed.<br />
    ## Verifying package dependencies.<br />
    ## Verifying disk space requirements.<br />
    ## Checking for conflicts with packages already installed.<br />
    ## Checking for setuid/setgid programs.</p>
  <p class="style1">Installing JDK 6.0 Man Pages (1.6.0_06) as &lt;SUNWj6man&gt;</p>
  <p class="style1">## Installing part 1 of 1.<br />
    /usr/jdk/instances/jdk1.6.0/man/man1/appletviewer.1<br />
    /usr/jdk/instances/jdk1.6.0/man/man1/apt.1<br />
    ...</p>
  <p class="style1">/usr/jdk/instances/jdk1.6.0/man/man1/wsimport.1<br />
    /usr/jdk/instances/jdk1.6.0/man/man1/xjc.1<br />
    [ verifying class &lt;none&gt; ]</p>
  <p class="style1">Installation of &lt;SUNWj6man&gt; was successful.</p>
  <p class="style1">Processing package instance &lt;SUNWj6dmo&gt; from &lt;/export/home/bleonard/Desktop/JDK&gt;</p>
  <p class="style1">JDK 6.0 Demo Programs (1.6.0_06)(i386) 1.6.0,REV=2006.11.29.05.03<br />
    Copyright 2007 Sun Microsystems, Inc.  All rights reserved.<br />
    Use is subject to license terms.<br />
    Using &lt;/usr&gt; as the package base directory.<br />
    ## Processing package information.<br />
    ## Processing system information.<br />
    3 package pathnames are already properly installed.<br />
    ## Verifying package dependencies.<br />
    WARNING:<br />
    The &lt;SUNWmfrun&gt; package &quot;Motif RunTime Kit&quot; is a<br />
    prerequisite package and should be installed.</p>
  <p class="style1">Do you want to continue with the installation of &lt;SUNWj6dmo&gt; [y,n,?] </p>
  <p>And one final warning with the Demo Programs package...<br />
      <br />
    <span class="style1">Do you want to continue with the installation of &lt;SUNWj6dmo&gt; [y,n,?] <strong>y</strong></span></p>
  <p class="style1">/usr/jdk/instances/jdk1.6.0/sample/webservices/EbayServer/src/ebay/server/Main.java<br />
    [ verifying class &lt;none&gt; ]</p>
  <p class="style1">Installation of &lt;SUNWj6dmo&gt; was successful.<br />
    bleonard@opensolaris:~/Desktop/JDK$ </p>
  </blockquote>
  <ul>
    <li>      Delete the JDK directory<br />
      <br />
      <span class="style3">cd ..<br />
    rm -r JDK</span><br />
    <br />
    </li>
    <li>If you're running in 64-bit mode, you can now optionally <a href="http://java.sun.com/javase/6/webnotes/install/jdk/install-solaris-64.html">install the 64-bit version of the JDK</a>. To check, run:<br />
      <br />
      <span class="style3">isainfo -b</span><br />
      <br />
    The output will either be 32 or 64.</li>
  </ul>
      <h3>Step 2: Download NetBeans 6.1</h3>
<ul>
  <li><a href="http://download.netbeans.org/netbeans/6.1/final/">Download</a> NetBeans 6.1. Personally I'm choosing the &quot;All&quot; packs configuration, but any of the bundles should work with these instructions. Save the NetBeans installer to your Desktop (which is the default location if you haven't configured Firefox otherwise).</li>
</ul>
<h3>Step 3: Install NetBeans 6.1</h3>
<ul>
  <li> Make the installer executable. Open a terminal and run: <br />
    <br />
  <span class="style1">chmod +x Desktop/netbeans-6.1-ml-solaris-x86.sh</span>  <br />
  <br />
  </li>
  <li>Run the installer:<br />
      <br />
      <span class="style1">./netbeans-6.1-ml-solaris-x86.sh</span><br />
    <br />
    You'll see the following as the installer GUI starts...<br />
    <br />
    <span class="style1">bleonard@opensolaris:~/Desktop$ <strong>./netbeans-6.1-ml-solaris-x86.sh</strong> <br />
  Configuring the installer...<br />
  Searching for JVM on the system...<br />
  Extracting installation data...<br />
  Running the installer wizard...</span><br />
  <br />
  Followed by the welcome screen where you can continue with the installation:<br />
  <br />
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/netbeans61_opensolaris/Screenshot-NetBeans IDE Installer.png" width="718" height="542" /><br />
  </li>
</ul>
<h3>Step 4: Launching NetBeans</h3>
<ul>
  <li>Once NetBeans is Installed you'll find an icon on your desktop:<br />
    <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/netbeans61_opensolaris/NetBeans_Desktop_Icon.png" width="236" height="151" /><br />
        <br />
  </li>
  <li>As well as a menu item under Applications &gt; Developer Tools:<br />
      <br />
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/netbeans61_opensolaris/NetBeans_Menu.png" width="339" height="274" /><br />  
    <br />
  </li>
</ul>
<h3>Resources</h3>
<ul>
  <li><a href="http://java.sun.com/javase/6/webnotes/install/jdk/install-solaris.html">JDK Installation Instructions (32-bit)</a></li>
  <li><a href="http://java.sun.com/javase/6/webnotes/install/jdk/install-solaris-64.html">JDK Installation Instructions (64-bit)</a></li>
  <li><a href="http://www.netbeans.org/community/releases/61/install.html">NetBeans 6.1 Installation Instructions</a></li>
</ul>
]]>

</content>
</entry>
<entry>
<title>OpenSolaris 2008.05: Configuring an External Monitor</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris_200.html" />
<modified>2008-05-29T17:06:05Z</modified>
<issued>2008-05-29T17:06:00Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9877</id>
<created>2008-05-29T17:06:00Z</created>
<summary type="text/plain">OpenSolaris 2008.05 has a sweet NVIDIA settings utility, but using it isn&apos;t as easy as it should be.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>If you have an NVIDIA graphics card, OpenSolaris 2008.05 comes with a sweet NVIDIA utility for working with their cards. The only problem is that is seems pretty worthless w/out an existing xorg.conf file and the proper permissions to write to it:<br />
  <br />
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-nvidia-settings.png" width="354" height="174" />  <br />
</p>
<p>These are the steps I took to configure my external display.</p>
<h3>Step 1: Generate an xorg.conf File</h3>
<p>Open a terminal and run: <span class="style1"> pfexec nvidia-xconfig</span></p>
<p class="style1">bleonard@opensolaris:~$ <b>pfexec nvidia-xconfig</b></p>
<p class="style1">WARNING: Unable to locate/open X configuration file.</p>
<p class="style1">sh: line 1: pkg-config: not found<br />
  sh: line 1: pkg-config: not found<br />
  New X configuration file written to '/etc/X11/xorg.conf'</p>
<p class="style1">bleonard@opensolaris:~$ </p>
<h3>Step 2: Configure NVIDIA Settings To Run with the Proper Privileges</h3>
Launching the NVIDIA X Server Settings GUI from the Applications &gt; System Tools menu seems fairly worthless, as it doesn't have the proper privileges to make changes to xorg.conf: <br />
<br />
<img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-nvidia-settings-1.png" width="356" height="174" />
<p>&nbsp;</p>
<p>NVIDIA Settings can be run from the command line using: <span class="style1">pfexec nvidia-settings</span></p>
<p>But let's fix the menu so it's not so worthless:</p>
<ul>
  <li>From the terminal run: <span class="style1">pfexec vi /usr/share/applications/nvidia-settings.desktop</span> </li>
  <li>Prefix the Exec command with pfexec. The complete line should look as follows:<br />
    <br />
    <span class="style1">Exec=pfexec /usr/bin/nvidia-settings</span><br />
    <br />
  </li>
  <li>Save the changes (:wq)</li>
</ul>
<h3>Step 3: Configure You External Monitor</h3>
<ul>
  <li>Run Applications &gt; System Tools &gt; NVIDIA X Server Settings</li>
  <li>Select X Server Display Configuration:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-NVIDIA X Server Settings.png" width="742" height="590" /><br />
    <br />
  </li>
  <li>Select your external monitor (mine's a Sun) and click Configure:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-Configure Display Device.png" width="371" height="212" /><br />
    <br />
  </li>
  <li>If necessary, you can change screen positions by dragging the screens, or by selecting the X Screen tab and setting the screen's Position:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-NVIDIA X Server Settings-1.png" width="750" height="590" /><br />
    <br />
  </li>
  <li> Click Save to X Configuration File:<br />
    <br />
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris-nvidia/Screenshot-Save X Configuration.png" width="415" height="199" /></li>
  <li>If you selected Separate X screen, log out and back in to restart the X server:<br />
</li>
</ul>
<p>There are still some oddities. I use the Sun 24&quot; monitor as my primary. Every now and then while working from the Sun display, a window opens on the laptop display. Also, for some reason, I cannot drag an open window from one display to the other, although my mouse moves easily between them and I can easily drag desktop icons across the displays.<br />
</p>
]]>

</content>
</entry>
<entry>
<title> OpenSolaris 2008.05 Meet the MacBook Pro</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/_opensolaris_20.html" />
<modified>2008-05-28T00:07:27Z</modified>
<issued>2008-05-28T00:07:17Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9871</id>
<created>2008-05-28T00:07:17Z</created>
<summary type="text/plain">Interested in trying out OpenSolaris 2008.05 on your MacBook? In the blog entry I walk you through the steps I took to get there.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p id="pgca10">
    Okay, so I'm not the first to document this configuration <sup id="hwno0">(<a href="#resources">1</a>)</sup>. However, I wasn't successful with any of the other approaches I discovered. Maybe this was because it most cases they were using a pre-release build of OpenSolaris 2008.05. So, for what it's worth, here are the steps that led me to success...
</p>
  
  
<h3 id="pgca14">
    What I've Got
</h3>
  
<ul id="ds-z0">
    
<li id="ds-z1">
      MacBook Pro w/ a 2.4 GHz Intel Core 2 Duo processor (model A1226) running OS X 10.5.1. I believe these steps would work for any MacBook w/ an Intel Core 2 Duo processor.<br id="fo7k0">
  </li>
</ul>
  
<h3 id="pgca14">
    What You'll Need
</h3>
  
<ul id="g9vc0" style="text-align: left;">
    

<li ><a href="http://www.opensolaris.com/get/" target="_blank" title="OpenSolaris 2008.05" style="color: rgb(85, 26, 139);">OpenSolaris 2008.05</a></li>
<li id="g9vc1">A blank writable CD (to burn OpenSolaris 2008.05)<br id="zr3m0">
</li>
<li id="g9vc1">
      Your OS X Installation DVD
  </li>
    
<li id="g9vc1">
      <a href="http://refit.sourceforge.net/" target="_blank" title="rEFIt">rEFIt</a> - a boot menu for <a title="EFI" target="_blank" href="http://www.intel.com/technology/efi/">EFI</a>-based machines like the Intel Mac.</li>
<li id="g9vc1">A USB thumb drive (for the network drivers)</li>
<li id="g9vc1">A USB mouse (Solaris doesn't support ctrl-click :-()<br id="di450">
</li>
</ul>
  
<h3 id="pgca14">What You Should Know</h3>
<p>I still haven't gotten the audio to work :-(.<br id="c7gk0">
</p>
<h3 id="pgca14">What I Did</h3>

<h4 id="pgca14">Step 1: Burn the OpenSolaris 2008.05 Live CD</h4>
<p id="m_q10">OpenSolaris comes as a live bootable CD, that once loaded provides you the option to install the OS.<br class="webkit-block-placeholder" id="eu6g0">
</p>
<ul id="true" style="margin-top: 0px; margin-bottom: 0px;">
<li id="q4fc2" style="margin-top: 0px; margin-bottom: 0px;"><a href="http://www.opensolaris.com/get/" target="_blank" title="Download" style="color: rgb(85, 26, 139);">Download</a> OpenSolaris 2008.05.</li>
<li id="q4fc2" style="margin-top: 0px; margin-bottom: 0px;">Start Disk Utility.</li>
<li id="q4fc2" style="margin-top: 0px; margin-bottom: 0px;">Select the os200805.iso and the click Burn in the toolbar.<br>
    <br>
        <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/os200805-iso.png" width="820" height="721"><br>
  </li>
</ul>
<h4 id="pgca14">Step 2: Put the Ethernet Drivers on a USB Stick</h4>
<p id="jn8y0">Unfortunately, the drivers for the Ethernet adapter are not included on the Live CD. Save <a title="yukonxsol_x64v8.19.2.3.tar.Z" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/yukonxsol_x64v8.19.2.3.tar.Z">yukonxsol_x64v8.19.2.3.tar.Z</a> to a USB thumb drive (you could also burn it to a CD if you don't have  a USB drive handy).</p>

  
<h4 id="pgca14">Step 3: Create a Partition for OpenSolaris 2008.05
</h4>
   First I tried to  create a partition from my existing Mac OS installation using "diskutil resizeVolume", but this kept failing on me because of insufficient disk space. Now my MacBook's about 9 months old and has been through an upgrade to Leopard, so I imagine the disk was pretty fragmented. Luckily I'm using Time Machine so I just decided to start from scratch.

  
<ul id="true">
    
<li id="mdqr1">
      Insert your OS X installation DVD. When it loads, click Install Mac OS X:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Mac_OS_X_Install_DVD.png" width="605" height="504"><br id="wgcu0"></li>
</ul>
  
    

<ul id="true">
        
<li id="zk.21">
          Then click the Restart button to launch the installer:
            <br>
            <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Install_Mac_OS_X.png" width="780" height="602"></li>
</ul>
      

  
<ul id="h87z0">
<li id="h87z1">When you get to the Welcome screen, select Disk Utility from the Utilities menu.</li>
<li id="h87z1">When Disk Utility starts, select the MacBook's hard drive. Mine is a "149.1 GB FUJITSU MHW2160BHPL Media". Then select the Partition tab on the right panel.</li>
<li id="h87z1">Change the Volume Scheme to 2 Partitions.</li>
<li id="h87z1">Select the Untitled Partition 1 and set the following</li>
<ul id="ty2:0">
<li id="h87z1">Name: OPENSOLARIS</li>
<li id="h87z1">Format: MS-DOS FAT</li>
<li id="h87z1">Size: 55.00 GB</li>
</ul>
<li id="h87z1">Select the Untitled Partition 2 and set the following</li>
<ul id="sl_y0">
<li id="h87z1">Name: MacOS</li>
<li id="h87z1">Format: Mac OS Extended (Journaled)</li>
<li id="h87z1">Size: (whatever's remaining - for me this was 94.05 GB)</li>
</ul>
</ul>
<ul id="h87z0">
<li id="h87z1">Click the Options button and verify GUID Partition Table is selected as the partition scheme (we'll have to change this later as the OpenSolaris installer does not recognize GUID Partition Tables).<br id="be5p0">
</li>
<li id="h87z1">Click Apply and then Partition when the
Partition Disk dialog appears. It only takes a couple of seconds for
the new partition map to be created. This is what my disk looks like
after the disk is repartitioned:<br>
<br>
<img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Disk_Utility_After_Partition.png" width="820" height="721"></li>
</ul>
<ul id="h87z5">
  <li id="h87z7">Quit Disk Utility<br id="usms4">
  </li>
</ul>

<h4 id="pgca14">
    Step 4: Install OS X</h4>

<ul id="fo7v0">
<li id="fo7v1">You should now be back at the installer's Welcome screen. Click Continue to proceed with the installation of OS X.</li>
<li id="fo7v1">Select the MacOS partition on the Select a Destination screen.</li>
<li id="fo7v1">Select Install on the Install Summary screen and go do something else for a couple of hours as OS X installs.<br id="mstg0">
</li>
<li id="fo7v1">Once the install is complete you'll be presented with the Welcome screen where you'll select your country, keyboard and then the option to restore from a Time Machine backup. Restoring from Time Machine took several more hours, so this time around I'm going to skip this step (I can always do a restore later) and just complete the vanilla installation (selecting Do not transfer my information now).</li>
<li id="fo7v1">Complete the installation entering your Apple ID, Registration Information, etc.<br id="iu1.3">
</li>
</ul>

<h4 id="pgca14">Step 5: Install rEFIt</h4>
rEFIt is a boot menu that will allow you to choose between Mac OS and OpenSolaris at system start up.

<ul id="true">
<li id="lg921"><a id="ghz_" href="http://refit.sourceforge.net/" target="_blank" title="Download">Download</a> and install rEFIt using the Mac disk image.<br>
  <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/rEFIt_installer.png" width="700" height="520"></li>
</ul>


<ul id="true">
<li id="k2880">To ensure that rEFIt is always enabled, open a Terminal and enter the the following command:<br>
  <br>
$ <b style="font-family: Courier New;" id="kbpk0">sudo /efi/refit/enable-always.sh</b> <br>
  <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/enable-always.png" width="759" height="293"><br>
</li>
</ul>
        
<ul id="true">
<li id="v__20">After OpenSolaris is installed, the rEFIt boot menu is going to display the Linux penguin for OpenSolaris. While we're in Mac OS and have access to the EFI partition, let's replace the Linux icons with OpenSolaris icons:</li>
<ul id="true">
<li id="wd_b0"><a title="os_linux.icns" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/os_linux.icns" >os_linux.icns</a> </li>
<li id="wd_b1"><a title="boot_linux.icns" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/boot_linux.icns" >boot_linux.icns</a> <br>
  <br id="zfu.1">
</li>
</ul>
<li id="wd_b2">Save these files to your <span id="ekid0" style="font-family: Courier New;">/efi/refit/icons</span> directory. Rename the original files if you don't want to loose them.</li>
</ul>




<h4>Step 6: Change the EFI partition ID
</h4>

<br id="pg543">
If you attempted to install OpenSolaris now, it would not recognize the new partition that was just created, only giving you the option to install over the entire disk. In this step we change the partition ID for the EFI partition from 'EE' to 'AF'.
<br id="t6c-0">
<ul id="f2y40">
<li id="f2y41">Open a Terminal and run diskUtil list:<br id="ew9x0">
<br id="ew9x1">
<div id="ew9x2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x3">william-leonards-macbook-pro:~ brianleonard$ <b id="joci0">diskUtil list</b></span></div>
<div id="ew9x4"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x5">/dev/disk0</span></div>
<div id="ew9x6"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x7">   #:                       TYPE NAME                    SIZE       IDENTIFIER</span></div>
<div id="ew9x8"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x9">   0:      GUID_partition_scheme                        *149.1 Gi   disk0</span></div>
<div id="ew9x10"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x11">   1:                        EFI                         200.0 Mi   disk0s1</span></div>
<div id="ew9x12"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x13">   2:       Microsoft Basic Data OPENSOLARIS             55.0 Gi    disk0s2</span></div>
<div id="ew9x14"><span class="Apple-style-span" style="font-family: 'Courier New';" id="ew9x15">   3:                  Apple_HFS MacOS                   93.7 Gi    disk0s3</span></div>
<div id="ew9x16"><br class="webkit-block-placeholder" id="ew9x17">
</div>
      Your internal hard drive should show up as /dev/disk0. You'll also see disks for the OS X installation DVD and your Time Machine drive.

      <br>
      <br>
</li>


<li id="ponl1">Next we will alter partition 1, the EFI partition. Run:<br id="tx9o0">
<br id="tx9o1">
<div id="a.0y0"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv90">william-leonards-macbook-pro:~ brianleonard$ <b id="joci1">sudo fdisk -e /dev/disk0</b></span></div>
<div id="a.0y1"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv91">Password:</span></div>
<div id="a.0y2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv92">fdisk: could not open MBR file /usr/standalone/i386/boot0: No such file or directory</span></div>
<div id="a.0y3"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv93">Enter 'help' for information</span></div>
<div id="a.0y4"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv94">fdisk: 1&gt; </span></div>
<div id="a.0y5"><br id="ws.w0">
</div>
</li>
<li id="ponl1">At the fdisk prompt, type <span id="fys90" style="font-family: Courier New;">p</span> to print the partition table:<br id="u0cq0">
<br id="u0cq1">
<div id="q:j90"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv95">fdisk: 1&gt; <b id="h12g0">p</b></span></div>
<div id="q:j91"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv96">Disk: /dev/disk0</span>	<span class="Apple-style-span" style="font-family: 'Courier New';" id="elv98">geometry: 19457/255/63 [312581808 sectors]</span></div>
<div id="q:j93"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv99">Offset: 0</span>	<span class="Apple-style-span" style="font-family: 'Courier New';" id="elv911">Signature: 0xAA55</span></div>
<div id="q:j95"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv912">         Starting       Ending</span></div>
<div id="q:j96"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv913"> #: id  cyl  hd sec -  cyl  hd sec [     start -       size]</span></div>
<div id="q:j97"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv914">------------------------------------------------------------------------</span></div>
<div id="q:j98"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv915"> 1: EE 1023 254  63 - 1023 254  63 [         1 -     409639] &lt;Unknown ID&gt;</span></div>
<div id="q:j99"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv916"> 2: 0B 1023 254  63 - 1023 254  63 [    409640 -  115344664] Win95 FAT-32</span></div>
<div id="q:j910"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv917"> 3: AF 1023 254  63 - 1023 254  63 [ 115754304 -  196565320] HFS+        </span></div>
<div id="q:j911"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv918"> 4: 00    0   0   0 -    0   0   0 [         0 -          0] unused      </span></div>
<div id="q:j912"><span class="Apple-style-span" style="font-family: 'Courier New';" id="elv919">fdisk: 1&gt;</span> </div>
<div id="q:j913"><br id="l5:-0">
</div>
</li>
</ul>
<blockquote class="webkit-indent-blockquote" style="border: medium none ; margin: 0pt 0pt 0pt 40px; padding: 0px;" id="l5:-1">You'll see that partition 1 is of type EE &lt;Unknown ID&gt;. Let's change it to AF HFS+:</blockquote>
<blockquote class="webkit-indent-blockquote" style="border: medium none ; margin: 0pt 0pt 0pt 40px; padding: 0px;" id="l5:-1"><br class="webkit-block-placeholder" id="qhap0">
</blockquote>
<ul id="true">
<li id="ko_t0">At the prompt type: <span id="fys91" style="font-family: Courier New;">setpid 1</span><br id="m_6f0">
<br id="m_6f1">
<div id="m_6f2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f3">fdisk: 1&gt; <b id="h12g1">setpid 1</b></span></div>
<div id="m_6f4"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f5">         Starting       Ending</span></div>
<div id="m_6f6"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f7"> #: id  cyl  hd sec -  cyl  hd sec [     start -       size]</span></div>
<div id="m_6f8"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f9">------------------------------------------------------------------------</span></div>
<div id="m_6f10"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f11"> 1: EE 1023 254  63 - 1023 254  63 [         1 -     409639] &lt;Unknown ID&gt;</span></div>
<div id="m_6f12"><span class="Apple-style-span" style="font-family: 'Courier New';" id="m_6f13">Partition id ('0' to disable)  [0 - FF]: [EE] (? for help) </span></div>
<div id="m_6f14"><br class="webkit-block-placeholder" id="m_6f15">
</div>
</li>
<li id="k4nb0">Enter <span id="fys92" style="font-family: Courier New;">AF<span id="fys93" style="font-family: Verdana;">:</span></span><br id="a_xy0">
<br id="a_xy1">
<div id="a_xy2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="bob40">Partition id ('0' to disable)  [0 - FF]: [EE] (? for help) <b id="akaj0">AF</b></span></div>
<div id="a_xy3"><span class="Apple-style-span" style="font-family: 'Courier New';" id="bob41">fdisk:*1&gt; </span></div>
<div id="a_xy4"><br class="webkit-block-placeholder" id="a_xy5">
</div>
</li>
<li id="oi660">Then <span id="e36s0" style="font-family: Courier New;">write</span>:<br id="oi661">
<br id="oi662">
<div id="oi663"><span class="Apple-style-span" style="font-family: 'Courier New';" id="dkfx0">fdisk:*1&gt; <b id="it1m0">write</b></span></div>
<div id="oi664"><span class="Apple-style-span" style="font-family: 'Courier New';" id="dkfx1">Device could not be accessed exclusively.</span></div>
<div id="oi665"><span class="Apple-style-span" style="font-family: 'Courier New';" id="dkfx2">A reboot will be needed for changes to take effect. OK? [n] </span></div>
<div id="oi666"><br class="webkit-block-placeholder" id="oi667">
</div>
</li>
<li id="z9f_0">Then <span id="e36s1" style="font-family: Courier New;">y</span>:<br id="yadv0">
<br id="yadv1">
<div id="yadv2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="yadv3">A reboot will be needed for changes to take effect. OK? [n] <b id="it1m1">y</b></span></div>
<div id="yadv4"><span class="Apple-style-span" style="font-family: 'Courier New';" id="yadv5">Writing MBR at offset 0.</span></div>
<div id="yadv6"><span class="Apple-style-span" style="font-family: 'Courier New';" id="yadv7">fdisk: 1&gt;   <br id="it1m2">
<br id="it1m3">
</span></div>
</li>
<li id="yadv8">Then <span id="qs1l0" style="font-family: Courier New;">quit</span>:<br id="yadv9">
<br id="yadv10">
<div id="kt0e0"><span class="Apple-style-span" style="font-family: 'Courier New';" id="kt0e1">fdisk: 1&gt; <b id="it1m4">quit</b></span></div>
<div id="kt0e2"><span class="Apple-style-span" style="font-family: 'Courier New';" id="kt0e3">william-leonards-macbook-pro:~ brianleonard$ </span></div>
<div id="kt0e4"><br class="webkit-block-placeholder" id="kt0e5">
</div>
</li>
</ul>
<ul id="true">
<li id="rktq3">Eject the OS X Installation DVD and insert the OpenSolaris 2008.05 Live CD.</li>
<li id="rktq3">Restart</li>
<li id="rktq3">From the rEFIt menu, select the option to "Boot Legacy OS from CD"</li>
<li id="rktq3">As the Live CD boots, select your keyboard layout and desktop language and then wait for the desktop to load.</li>
<li id="rktq3">Close the license.<br id="qsiu1">
</li>
<li id="rktq3">Click the Install OpenSolaris icon on the desktop:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Desktop.png" width="895" height="528"><br>
      <br id="qvxl0">
</li>
<li id="rktq3">Once the Welcome screen loads click Next to get to the Disk screen:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerWelcome.png" width="916" height="736"><br>
      <br id="h:5m0">
</li>
<li id="rktq3">On the Disk screen you'll notice that OpenSolaris recognizes the newly created Win95 FAT32 partition:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerDiskFat32.png" width="916" height="736"><br>
      <br id="ocn60">
</li>
<li id="rktq3">Change the Partition Type to Solaris:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerDiskSolaris.png" width="916" height="736"><br>
      <br id="ocn62">
</li>
<li id="rktq3">Click Next to select your Time Zone, Date and Time. Note, you can use the Map to select your region:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerTime.png" width="916" height="736"><br>
      <br id="el501">
</li>
<li id="rktq3">Select your Locale:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerLocale.png" width="916" height="736"><br id="wd7k0">
    <br id="wd7k1">
</li>
<li id="rktq3">Set up your users:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerUsers.png" width="916" height="736"><br>
      <br id="v-gl1">
</li>
<li id="rktq3">Review the Installation summary and then Install:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerSummary.png" width="916" height="736"><br id="tzro1">
    <br id="pka82">
</li>
<li id="rktq3">It takes about 30 minutes for the installer to complete:<br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerInstalling.png" width="916" height="736"><br>
      <br id="vuhe0">
</li>
<li id="rktq3">Once complete, select Reboot:<br>
      <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/OpenSolarisInstallerFinished.png" width="916" height="736"></li>
</ul>

<h4>Step 8: Start OpenSolaris and Install the Wired Ethernet Driver <br id="lh_g0">
</h4>
<ul id="true">
<li id="aprd2">If you installed the OpenSolaris icons, you'll see them now in the rEFIt menu. <br id="i-4b0">
</li>
<li id="aprd2">Insert your USB mouse.<br id="i-4b1">
</li>
<li id="aprd2">Open System &gt; Administration &gt; Device Driver Utility. You see that both the wired and wireless network drivers are missing. Select the Marvel Technology Group Ethernet Controller and write down the Vendor ID and Device ID. In my case these are 11ab and 436a respectively:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Screenshot-Device Driver Utility.png" width="826" height="646"><br id="u2.v0">
    <br id="u2.v1">
</li>
<li id="aprd2">Copy <span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: 12px;" id="gc:x0"><a title="yukonxsol_x64v8.19.2.3.tar.Z" href="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/yukonxsol_x64v8.19.2.3.tar.Z">yukonxsol_x64v8.19.2.3.tar.Z</a> </span>from the USB drive to the desktop.</li>
<li id="aprd2">Open Applications &gt; System Tools &gt; Terminal.</li>
<li id="aprd2">You should be in your home directory. CD into the Desktop directory:<br id="y9t30">
<br id="ua-b0">
<span id="y9t31" style="font-family: Courier New;">bleonard@opensolaris:~$ <b id="v4az0">cd Desktop</b></span><br id="y9t32" style="font-family: Courier New;">
<span id="y9t33" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="bpve1">
<br id="y9t34">
</li>
<li id="aprd2">Unzip the archive:<br id="i9yo0">
<br id="i9yo1">
<span id="z.y-0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="aj:j0">gunzip yukonxsol_x64v8.19.2.3.tar.Z</b> </span><br style="font-family: Courier New;" id="i9yo2">
<span id="z.y-1" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$</span><br id="i9yo3">
<br id="i9yo4">
</li>
<li id="aprd2">Untar the archive:<br id="r_nf0">
<br id="r_nf1">
<span id="z.y-2" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="aj:j1">tar -xvf yukonxsol_x64v8.19.2.3.tar </b></span><br style="font-family: Courier New;" id="r_nf2">
<span id="z.y-3" style="font-family: Courier New;">YUKONXsolx/</span><br style="font-family: Courier New;" id="r_nf3">
<span id="z.y-4" style="font-family: Courier New;">YUKONXsolx/pkgmap</span><br style="font-family: Courier New;" id="r_nf4">
<span id="z.y-5" style="font-family: Courier New;">...</span><br style="font-family: Courier New;" id="r_nf5">
<span id="z.y-6" style="font-family: Courier New;">YUKONXsolx/install/yukonx.txt</span><br style="font-family: Courier New;" id="r_nf6">
<span id="z.y-7" style="font-family: Courier New;">yukonx.txt</span><br style="font-family: Courier New;" id="r_nf7">
<span id="z.y-8" style="font-family: Courier New;">yukonx.htm</span><br style="font-family: Courier New;" id="r_nf8">
<span id="z.y-9" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="r_nf9">
<br id="z.y-10">
</li>
<li id="aprd2">Install the package:<br id="lnc:0">
<br id="lnc:1">
<span id="lnc:2" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="aj:j2">pfexec pkgadd -d . YUKONXsolx</b></span><br id="lnc:3" style="font-family: Courier New;">
<br id="lnc:4" style="font-family: Courier New;">
<span id="lnc:5" style="font-family: Courier New;">Processing package instance &lt;YUKONXsolx&gt; from &lt;/export/home/bleonard/Desktop&gt;</span><br id="lnc:6" style="font-family: Courier New;">
<br id="lnc:7" style="font-family: Courier New;">
<span id="lnc:8" style="font-family: Courier New;">Marvell Yukon Ethernet Controller 64 bit driver(i386) 8.19.2.3</span><br id="lnc:9" style="font-family: Courier New;">
<span id="lnc:10" style="font-family: Courier New;">Marvell</span><br id="lnc:11" style="font-family: Courier New;">
<br id="lnc:12" style="font-family: Courier New;">
<span id="lnc:13" style="font-family: Courier New;">----------------------</span><br id="lnc:14" style="font-family: Courier New;">
<span id="lnc:15" style="font-family: Courier New;">   IP configuration   </span><br id="lnc:16" style="font-family: Courier New;">
<span id="lnc:17" style="font-family: Courier New;">printf: ----------------------\n\n: unknown option</span><br id="lnc:18" style="font-family: Courier New;">
<span id="lnc:19" style="font-family: Courier New;">Usage: printf [ options ] format [string ...]</span><br id="lnc:20" style="font-family: Courier New;">
<span id="lnc:21" style="font-family: Courier New;">Do you want to configure the IP interfaces now (y/n)?  </span><br id="lnc:22">
<br id="lnc:23">
</li>
<li id="aprd2">Yes, configure the IP interfaces now...<br id="n72m0">
<br id="a4tr0" style="font-family: Courier New;">
<span id="a4tr1" style="font-family: Courier New;">Do you want to configure the IP interfaces now (y/n)? <b id="se-q0">y</b></span><br id="a4tr2" style="font-family: Courier New;">
<br id="a4tr3" style="font-family: Courier New;">
<span id="a4tr4" style="font-family: Courier New;">Configuring Marvell Gigabit Ethernet interface 0</span><br id="a4tr5" style="font-family: Courier New;">
<br id="a4tr6" style="font-family: Courier New;">
<span id="a4tr7" style="font-family: Courier New;">NOTE: If you want to configure the driver for the use of VLANs,</span><br id="a4tr8" style="font-family: Courier New;">
<span id="a4tr9" style="font-family: Courier New;">      you should use the script /usr/sbin/yukonx_vlan_config.</span><br id="a4tr10" style="font-family: Courier New;">
<span id="a4tr11" style="font-family: Courier New;">      You have to do this after driver installation is finished.</span><br id="a4tr12" style="font-family: Courier New;">
<br id="a4tr13" style="font-family: Courier New;">
<span id="a4tr14" style="font-family: Courier New;">Please enter a hostname for the Marvell Gigabit Ethernet interface.</span><br id="a4tr15" style="font-family: Courier New;">
<span id="a4tr16" style="font-family: Courier New;">It should be different from all existing hostnames in</span><br id="a4tr17" style="font-family: Courier New;">
<span id="a4tr18" style="font-family: Courier New;">your system (see /etc/hostname.*).</span><br id="a4tr19" style="font-family: Courier New;">
<br id="a4tr20" style="font-family: Courier New;">
<span id="a4tr21" style="font-family: Courier New;">Hostname [yukonx0]:</span><br id="a4tr22" style="font-family: Courier New;">
 <br id="a4tr23">
</li>
<li id="aprd2">Select the default Hostname 'yukonx0'...<br id="h2fe0">
<br id="h2fe1">
<span id="h2fe2" style="font-family: Courier New;">Hostname [yukonx0]: </span><br id="h2fe3" style="font-family: Courier New;">
<br id="h2fe4">
</li>
<li id="aprd2">DHCP will ultimately set the IP address, so for now I just enter 127.0.0.1...<br id="h2fe5">
<br id="h2fe6">
<span id="ofkp0" style="font-family: Courier New;">Enter the IP address for 'yukonx0' []: <b id="hr.s0">127.0.0.1</b></span><br style="font-family: Courier New;" id="h2fe7">
<br style="font-family: Courier New;" id="h2fe8">
<span id="ofkp1" style="font-family: Courier New;">WARNING: The selected IP address has been found in</span><br style="font-family: Courier New;" id="h2fe9">
<span id="ofkp2" style="font-family: Courier New;">         /etc/hosts:</span><br style="font-family: Courier New;" id="h2fe10">
<br style="font-family: Courier New;" id="h2fe11">
<span id="ofkp3" style="font-family: Courier New;">         127.0.0.1    opensolaris opensolaris.local localhost loghost</span><br style="font-family: Courier New;" id="h2fe12">
<br style="font-family: Courier New;" id="h2fe13">
<span id="ofkp4" style="font-family: Courier New;">         This can cause problems, but it</span><br style="font-family: Courier New;" id="h2fe14">
<span id="ofkp5" style="font-family: Courier New;">         might be intentional in this case.</span><br style="font-family: Courier New;" id="h2fe15">
<br style="font-family: Courier New;" id="h2fe16">
<span id="ofkp6" style="font-family: Courier New;">Enter the IP netmask for 'yukonx0' []: </span><br id="c2w70">
<br id="c2w71">
</li>
<li id="aprd2">Enter the IP netmask, I used 255.255.255.0, and review the settings...<br id="ofkp7">
<br id="ofkp8">
<span id="hulm0" style="font-family: Courier New;">Enter the IP netmask for 'yukonx0' []: <b id="hr.s1">255.255.255.0</b></span><br style="font-family: Courier New;" id="ofkp9">
<br style="font-family: Courier New;" id="ofkp10">
<span id="hulm1" style="font-family: Courier New;">Settings for Marvell Gigabit Ethernet interface 0:</span><br style="font-family: Courier New;" id="ofkp11">
<span id="hulm2" style="font-family: Courier New;">hostname    : yukonx0</span><br style="font-family: Courier New;" id="ofkp12">
<span id="hulm3" style="font-family: Courier New;">IP-address  : 127.0.0.1</span><br style="font-family: Courier New;" id="ofkp13">
<span id="hulm4" style="font-family: Courier New;">IP-netmask  : 255.255.255.0</span><br style="font-family: Courier New;" id="ofkp14">
<span id="hulm5" style="font-family: Courier New;">IP-netnumber: 127.0.0.0</span><br style="font-family: Courier New;" id="ofkp15">
<br style="font-family: Courier New;" id="ofkp16">
<span id="hulm6" style="font-family: Courier New;">NOTE: If the netmask does not consist of '255's and '0's only,</span><br style="font-family: Courier New;" id="ofkp17">
<span id="hulm7" style="font-family: Courier New;">      the netnumber in /etc/netmasks will require manual correction</span><br style="font-family: Courier New;" id="ofkp18">
<br style="font-family: Courier New;" id="ofkp19">
<span id="hulm8" style="font-family: Courier New;">Are these settings OK (y/n)? </span><br id="ofkp20">
<br id="ofkp21">
</li>
<li id="aprd2">Answer yes to confirm the settings and then no to configure another adapter...<br id="hs3j0">
<br id="hs3j1">
<span id="hs3j2" style="font-family: Courier New;">Are these settings OK (y/n)? <b id="eup30">y</b></span><br id="hs3j3" style="font-family: Courier New;">
<br id="hs3j4" style="font-family: Courier New;">
<span id="hs3j5" style="font-family: Courier New;">Do you have more Marvell Gigabit Ethernet adapters installed (y/n)? <b id="r8j.0">n</b></span><br id="hs3j6" style="font-family: Courier New;">
<span id="hs3j7" style="font-family: Courier New;">Using &lt;/&gt; as the package base directory.</span><br id="hs3j8" style="font-family: Courier New;">
<span id="hs3j9" style="font-family: Courier New;">## Processing package information.</span><br id="hs3j10" style="font-family: Courier New;">
<span id="hs3j11" style="font-family: Courier New;">## Processing system information.</span><br id="hs3j12" style="font-family: Courier New;">
<span id="hs3j13" style="font-family: Courier New;">   10 package pathnames are already properly installed.</span><br id="hs3j14" style="font-family: Courier New;">
<span id="hs3j15" style="font-family: Courier New;">## Verifying disk space requirements.</span><br id="hs3j16" style="font-family: Courier New;">
<span id="hs3j17" style="font-family: Courier New;">## Checking for conflicts with packages already installed.</span><br id="hs3j18" style="font-family: Courier New;">
<span id="hs3j19" style="font-family: Courier New;">## Checking for setuid/setgid programs.</span><br id="hs3j20" style="font-family: Courier New;">
<br id="hs3j21" style="font-family: Courier New;">
<span id="hs3j22" style="font-family: Courier New;">This package contains scripts which will be executed with super-user</span><br id="hs3j23" style="font-family: Courier New;">
<span id="hs3j24" style="font-family: Courier New;">permission during the process of installing this package.</span><br id="hs3j25" style="font-family: Courier New;">
<br id="hs3j26" style="font-family: Courier New;">
<span id="hs3j27" style="font-family: Courier New;">Do you want to continue with the installation of &lt;YUKONXsolx&gt; [y,n,?] </span><br id="hs3j28" style="font-family: Courier New;">
<br id="hs3j29">
</li>
<li id="aprd2">Answer yes to continue with the installation of the package...<br id="hs3j30">
<br id="hs3j31">
<span class="style1">Do you want to continue with the installation of &lt;YUKONXsolx&gt; [y,n,?] <b id="r8j.1">y</b><br id="fy820">
<br id="fy821">
Installing Marvell Yukon Ethernet Controller 64 bit driver as &lt;YUKONXsolx&gt;</span><br id="fy822">
<br id="fy823">
<span id="fy824" style="font-family: Courier New;">## Executing preinstall script.</span><br id="fy825" style="font-family: Courier New;">
<span id="fy826" style="font-family: Courier New;">## Installing part 1 of 1.</span><br id="fy827" style="font-family: Courier New;">
<span id="fy828" style="font-family: Courier New;">/etc/rcS.d/S50yukonx</span><br id="fy829" style="font-family: Courier New;">
<span id="fy8210" style="font-family: Courier New;">/kernel/drv/amd64/yukonx</span><br id="fy8211" style="font-family: Courier New;">
<span id="fy8212" style="font-family: Courier New;">/kernel/drv/yukonx.conf</span><br id="fy8213" style="font-family: Courier New;">
<span id="fy8214" style="font-family: Courier New;">/usr/sbin/yukonx_vlan_config</span><br id="fy8215" style="font-family: Courier New;">
<span id="fy8216" style="font-family: Courier New;">/usr/share/man/man7d/yukonx.7d</span><br id="fy8217" style="font-family: Courier New;">
<span id="fy8218" style="font-family: Courier New;">[ verifying class &lt;none&gt; ]</span><br id="fy8219" style="font-family: Courier New;">
<span id="fy8220" style="font-family: Courier New;">[ verifying class &lt;master&gt; ]</span><br id="fy8221" style="font-family: Courier New;">
<span id="fy8222" style="font-family: Courier New;">## Executing postinstall script.</span><br id="fy8223" style="font-family: Courier New;">
<span id="fy8224" style="font-family: Courier New;">/var/sadm/pkg/YUKONXsolx/install/postinstall[14]: /usr/ucb/echo: not found [No such file or directory]</span><br id="fy8225" style="font-family: Courier New;">
<span id="fy8226" style="font-family: Courier New;">devfsadm: driver failed to attach: yukonx</span><br id="fy8227" style="font-family: Courier New;">
<span id="fy8228" style="font-family: Courier New;">Warning: Driver (yukonx) successfully added to system but failed to attach</span><br id="fy8229" style="font-family: Courier New;">
<span id="fy8230" style="font-family: Courier New;">/var/sadm/pkg/YUKONXsolx/install/postinstall[113]: /usr/ucb/echo: not found [No such file or directory]</span><br id="fy8231" style="font-family: Courier New;">
<span id="fy8232" style="font-family: Courier New;">pkgadd: ERROR: postinstall script did not complete successfully</span><br id="fy8233" style="font-family: Courier New;">
<br id="fy8234" style="font-family: Courier New;">
<span id="fy8235" style="font-family: Courier New;">Installation of &lt;YUKONXsolx&gt; partially failed.</span><br id="fy8236" style="font-family: Courier New;">
<span id="fy8237" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="fy8238">
<br id="n72m1">
</li>
<li id="aprd2">Don't worry about the failure, we'll update the driver next...<br id="vlf20">
<br id="vlf21">
<span id="tanh0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="hgiv0">pfexec update_drv -a -i '"pci11ab,436a"' yukonx</b></span><br id="tanh1" style="font-family: Courier New;">
<span id="tanh2" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="tanh3">
<br id="tanh4">
</li>
<li id="aprd2">Then plumb the interface...<br id="z0q.0">
<br id="z0q.1">
<span id="z0q.2" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="hgiv1">pfexec ifconfig yukonx0 plumb</b></span><br id="z0q.3" style="font-family: Courier New;">
<span id="z0q.4" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="z0q.5" style="font-family: Courier New;">
<br id="z0q.6">
</li>
<li id="aprd2">Then in a couple of seconds you should see the interface come up:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Screenshot-Information.png" width="463" height="174"><br>
    <br id="tanh6">
</li>
<li id="aprd2">
Test the connection:<br id="uv3.2">
<br id="vgbs0">
<span id="qha20" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="hgiv2">ping www.google.com</b></span><br style="font-family: Courier New;" id="vgbs1">
<span id="qha21" style="font-family: Courier New;">www.google.com is alive</span><br>
<br id="vgbs3">
</li>
<li id="aprd2">
Confirm that all is well (at least for the Marvell card) in the Device Driver Utility:<br>
<br>
<img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Screenshot-Device Driver Utility-1.png" width="826" height="646"><br id="c.881">
</li>
</ul>


<h4 id="pgca14">Step 9: Install the Wireless Adapter Driver</h4>
<p id="t_cv0">Now that we're connected to the Internet, the world is at your fingertips. However, let's do one more thing (for now) and install the wireless adapter driver.<br id="w7vt0">
<br id="w7vt1">
</p>
<ul id="aeq20">
<li id="aeq21">Select the Atheros Communications Wireless PCI Express Adapter in the Device Driver Utility. Write down the
Vendor ID and Device ID. In my case these are 168c and 24
respectively:<br>
<br>
<img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Screenshot-Device Driver Utility-2.png" width="826" height="646"><br id="ijz11">
<br id="ijz12">
</li>
<li id="aeq21"><a title="Download" href="http://www.opensolaris.org/os/community/laptop/downloads/ath-0.7.2-pkg.tar.gz">Download</a> the SUNWatheros 0.7.2 package and save it to your desktop.</li>
<li id="aeq21">Return to the Terminal and gunzip and untar the package.</li>
<li id="aeq21">Install the package:<br id="om:.2">
<br id="om:.3">
<span id="dzcr0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="f13g0">pfexec pkgadd -d SUNWatheros </b></span><br style="font-family: Courier New;" id="aeas0">
<br style="font-family: Courier New;" id="aeas1">
<span id="dzcr1" style="font-family: Courier New;">The following packages are available:</span><br style="font-family: Courier New;" id="aeas2">
<span id="dzcr2" style="font-family: Courier New;">  1  SUNWatheros     Atheros 802.11b/g Wireless NIC Driver</span><br style="font-family: Courier New;" id="aeas3">
<span id="dzcr3" style="font-family: Courier New;">                     (i386) 11.11,REV=2007.12.18.15.35</span><br style="font-family: Courier New;" id="aeas4">
<br style="font-family: Courier New;" id="aeas5">
<span id="dzcr4" style="font-family: Courier New;">Select package(s) you wish to process (or 'all' to process</span><br style="font-family: Courier New;" id="aeas6">
<span id="dzcr5" style="font-family: Courier New;">all packages). (default: all) [?,??,q]: </span><br id="aeas7">
<br id="aeas8">
</li>
<li id="aeq21">Press enter to select the default - all...<br id="up410">
<br id="b8s40">
<span id="b8s41" style="font-family: Courier New;">Select package(s) you wish to process (or 'all' to process</span><br id="b8s42" style="font-family: Courier New;">
<span id="b8s43" style="font-family: Courier New;">all packages). (default: all) [?,??,q]: </span><br id="b8s44" style="font-family: Courier New;">
<br id="b8s45" style="font-family: Courier New;">
<span id="b8s46" style="font-family: Courier New;">Processing package instance &lt;SUNWatheros&gt; from &lt;/export/home/bleonard/Desktop/SUNWatheros&gt;</span><br id="b8s47" style="font-family: Courier New;">
<br id="b8s48" style="font-family: Courier New;">
<span id="b8s49" style="font-family: Courier New;">Atheros 802.11b/g Wireless NIC Driver(i386) 11.11,REV=2007.12.18.15.35</span><br id="b8s410" style="font-family: Courier New;">
<span id="b8s411" style="font-family: Courier New;"># ident    "@(#)LICENSE    1.1    05/11/28 SMI"</span><br id="b8s412" style="font-family: Courier New;">
<br id="b8s413" style="font-family: Courier New;">
<span id="b8s414" style="font-family: Courier New;">SOLARIS WIRELESS DRIVER FOR THE ATHEROS 52XX CHIPSET (ATH)</span><br id="b8s415" style="font-family: Courier New;">
<br id="b8s416" style="font-family: Courier New;">
<span id="b8s417" style="font-family: Courier New;">LICENSE AGREEMENT</span><br id="b8s418" style="font-family: Courier New;">
<br id="b8s419" style="font-family: Courier New;">
<span id="b8s420" style="font-family: Courier New;">...<br id="jff_0">
<br id="jff_1">
</span><span id="b8s4143" style="font-family: Courier New;">Using &lt;/&gt; as the package base directory.</span><br id="b8s4144" style="font-family: Courier New;">
<span id="b8s4145" style="font-family: Courier New;">## Processing package information.</span><br id="b8s4146" style="font-family: Courier New;">
<span id="b8s4147" style="font-family: Courier New;">## Processing system information.</span><br id="b8s4148" style="font-family: Courier New;">
<span id="b8s4149" style="font-family: Courier New;">   5 package pathnames are already properly installed.</span><br id="b8s4150" style="font-family: Courier New;">
<span id="b8s4151" style="font-family: Courier New;">## Verifying package dependencies.</span><br id="b8s4152" style="font-family: Courier New;">
<span id="b8s4153" style="font-family: Courier New;">## Verifying disk space requirements.</span><br id="b8s4154" style="font-family: Courier New;">
<span id="b8s4155" style="font-family: Courier New;">## Checking for conflicts with packages already installed.</span><br id="b8s4156" style="font-family: Courier New;">
<br id="b8s4157" style="font-family: Courier New;">
<span id="b8s4158" style="font-family: Courier New;">The following files are already installed on the system and are being</span><br id="b8s4159" style="font-family: Courier New;">
<span id="b8s4160" style="font-family: Courier New;">used by another package:</span><br id="b8s4161" style="font-family: Courier New;">
<span id="b8s4162" style="font-family: Courier New;">* /kernel/drv/amd64/ath</span><br id="b8s4163" style="font-family: Courier New;">
<span id="b8s4164" style="font-family: Courier New;">* /kernel/drv/ath</span><br id="b8s4165" style="font-family: Courier New;">
<span id="b8s4166" style="font-family: Courier New;">* /kernel/misc/amd64/net80211</span><br id="b8s4167" style="font-family: Courier New;">
<span id="b8s4168" style="font-family: Courier New;">* /kernel/misc/net80211</span><br id="b8s4169" style="font-family: Courier New;">
<br id="b8s4170" style="font-family: Courier New;">
<span id="b8s4171" style="font-family: Courier New;">* - conflict with a file which does not belong to any package.</span><br id="b8s4172" style="font-family: Courier New;">
<br id="b8s4173" style="font-family: Courier New;">
<span id="b8s4174" style="font-family: Courier New;">Do you want to install these conflicting files [y,n,?,q] </span><br id="b8s4175">
<br id="b8s4177">
</li>
<li id="aeq21">Answer yes to install the conflicting files and yes to continue with the installation...<br id="ky3s0">
<br id="ky3s1">
<span id="gfa50" style="font-family: Courier New;">Do you want to install these conflicting files [y,n,?,q] <b id="f13g1">y</b></span><br style="font-family: Courier New;" id="z5j70">
<span id="gfa51" style="font-family: Courier New;">## Checking for setuid/setgid programs.</span><br style="font-family: Courier New;" id="z5j71">
<br style="font-family: Courier New;" id="z5j72">
<span id="gfa52" style="font-family: Courier New;">This package contains scripts which will be executed with super-user</span><br style="font-family: Courier New;" id="z5j73">
<span id="gfa53" style="font-family: Courier New;">permission during the process of installing this package.</span><br style="font-family: Courier New;" id="z5j74">
<br style="font-family: Courier New;" id="z5j75">
<span id="gfa54" style="font-family: Courier New;">Do you want to continue with the installation of &lt;SUNWatheros.2&gt; [y,n,?] <b id="w4wz0">y</b></span><br style="font-family: Courier New;" id="z5j76">
<br style="font-family: Courier New;" id="z5j77">
<span id="gfa55" style="font-family: Courier New;">Installing Atheros 802.11b/g Wireless NIC Driver as &lt;SUNWatheros.2&gt;</span><br style="font-family: Courier New;" id="z5j78">
<br style="font-family: Courier New;" id="z5j79">
<span id="gfa56" style="font-family: Courier New;">## Installing part 1 of 1.</span><br style="font-family: Courier New;" id="z5j710">
<span id="gfa57" style="font-family: Courier New;">/kernel/drv/amd64/ath</span><br style="font-family: Courier New;" id="z5j711">
<span id="gfa58" style="font-family: Courier New;">/kernel/drv/ath</span><br style="font-family: Courier New;" id="z5j712">
<span id="gfa59" style="font-family: Courier New;">/kernel/misc/amd64/net80211</span><br style="font-family: Courier New;" id="z5j713">
<span id="gfa510" style="font-family: Courier New;">/kernel/misc/net80211</span><br style="font-family: Courier New;" id="z5j714">
<span id="gfa511" style="font-family: Courier New;">[ verifying class &lt;none&gt; ]</span><br style="font-family: Courier New;" id="z5j715">
<span id="gfa512" style="font-family: Courier New;">## Executing postinstall script.</span><br style="font-family: Courier New;" id="z5j716">
<br style="font-family: Courier New;" id="z5j717">
<span id="gfa513" style="font-family: Courier New;">Installation of &lt;SUNWatheros.2&gt; was successful.</span><br style="font-family: Courier New;" id="z5j718">
<span id="gfa514" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ </span><br id="z5j719">
<br id="gfa515">
</li>
<li id="aeq21">Remove and reinstall the driver...<br id="vgq30">
<br id="vgq31">
<span id="f77e0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="qtkr0">pfexec rem_drv ath</b></span><br id="f77e1" style="font-family: Courier New;">
<span id="f77e2" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="qtkr1">pfexec add_drv -i '"pci168c,24"' ath</b></span><br id="f77e3" style="font-family: Courier New;">
<br id="f77e4">
</li>
<li id="aeq21">Plumb the interface...<br id="ky3s2">
<br id="f77e5">
<span class="style1">bleonard@opensolaris:~/Desktop$ <b id="qtkr2">pfexec ifconfig ath0 plumb</b></span><br id="sn4_0">
<br id="sn4_1">
</li>
<li id="aeq21">Configure the interface for DHCP:<br id="drmc0">
<br id="gdfs0">
<span id="gdfs1" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="l58m0">pfexec ifconfig ath0 dhcp</b></span><br id="gdfs2" style="font-family: Courier New;">
<br id="gdfs3">
</li>
<li id="aeq21">Wired connections take precedence over wireless. Unplug the wired connection to test the wireless...<br id="g_ei0">
<br id="g_ei1">
</li>
<li id="aeq21">Scan for available networks:<br id="f3ju0">
<br id="f3ju1">
<span id="ar_d0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="ysek0">wificonfig scan</b></span><br id="ar_d1" style="font-family: Courier New;">
<span id="ar_d2" style="font-family: Courier New;">essid        bssid          type        encryption    signallevel</span><br id="ar_d3" style="font-family: Courier New;">
<span id="ar_d4" style="font-family: Courier New;">CowPlanet    00:1e:52:7a:26:e5 access point    none        15</span><br id="ar_d5">
<br id="ar_d6">
</li>
<li id="aeq21">And connect:<br id="ar_d7">
<br style="font-family: Courier New;" id="ar_d8">
<span id="tw1e0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="ysek1">wificonfig connect 'CowPlanet'</b></span><br id="tw1e1" style="font-family: Courier New;">
<span id="tw1e2" style="font-family: Courier New;">wificonfig: connecting to essid 'CowPlanet'</span><br id="tw1e3" style="font-family: Courier New;">
<span id="tw1e4" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <br id="g_ei2">
<br id="g_ei3">
</span></li>
<li id="aeq21">See it's status:<br id="vk7a0">
<br id="fs.30" style="font-family: Courier New;">
<span id="fs.31" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="ysek2">wificonfig showstatus</b></span><br id="fs.32" style="font-family: Courier New;">
<span id="fs.33" style="font-family: Courier New;">    linkstatus: connected</span><br id="fs.34" style="font-family: Courier New;">
<span id="fs.35" style="font-family: Courier New;">    active profile: none</span><br id="fs.36" style="font-family: Courier New;">
<span id="fs.37" style="font-family: Courier New;">    essid: CowPlanet</span><br id="fs.38" style="font-family: Courier New;">
<span id="fs.39" style="font-family: Courier New;">    bssid: 00:1e:52:7a:26:e5</span><br id="fs.310" style="font-family: Courier New;">
<span id="fs.311" style="font-family: Courier New;">    encryption: none</span><br id="fs.312" style="font-family: Courier New;">
<span id="fs.313" style="font-family: Courier New;">    signal strength: strong(15)</span><br id="fs.314">
<br id="fs.315">
</li>
<li id="aeq21">And test:<br id="fs.316">
<br id="fs.317">
<span id="b.lk0" style="font-family: Courier New;">bleonard@opensolaris:~/Desktop$ <b id="ysek3">ping www.google.com</b></span><br style="font-family: Courier New;" id="fs.318">
<span id="b.lk1" style="font-family: Courier New;">www.google.com is alive</span><br id="ps7j0">
<br id="ps7j1">
</li>
<li id="aeq21">Confirm that the network driver issues are now resolved in the Device Driver Utility:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/05/opensolaris/Screenshot-Device Driver Utility-3.png" width="826" height="646"><br id="ajhz0">
</li>
</ul>
<br id="bjwg0">
<h3 id="resources">
    Resources</h3>
Everything I've summarized here I was able to learn from these various resources:
<br id="kh031">
  
  
<ul id="hlb40">
    
<li id="hlb41" style="text-align: left;">
      <a href="http://www.genunix.org/wiki/index.php/OpenSolaris_Dual_Boot" id="q2_0" target="_blank" title="OpenSolaris Dual Boot">OpenSolaris Dual Boot</a> - I found no reason to use GParted.<br id="hlb42">
  </li>
    
<li id="hlb43">
      <a href="http://blogs.sun.com/paulm/entry/dual_partitioning_a_macbook_pro" id="h34h" target="_blank" title="How to Dual Partition a MacBook Pro with MacOS and Solaris">How to Dual Partition a MacBook Pro with MacOS and Solaris</a> - Over 1 year old, and many of the steps are no longer necessary, but I prefer Paul's approach to changing the EFI partition ID (instead of using GParted).
  </li>
    
<li id="hlb43">
      <a target="_blank" href="http://omsarti.wordpress.com/2007/11/13/solaris-on-a-macbook/" id="d9vj" title="Solaris on a MacBook">Solaris on a MacBook</a> - Helped me with the Network configuration
  </li>
    
<li id="hlb43" style="text-align: left;">
      <a target="_blank" href="http://www.sun.com/bigadmin/hcl/data/systems/details/2985.html" id="c05r" title="BigAdmin - HCL: Apple MacBook Pro A1150">BigAdmin - HCL: Apple MacBook Pro A1150</a> - The Hardware Compatibility List - not an exact match, but close enough.
  </li>
</ul>
  <br id="hlb45">
  
<h3 id="pgca14"><br id="jy4c0">
</h3>

]]>

</content>
</entry>
<entry>
<title>Drag &amp; Drop with Rails</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/04/drag_drop_with.html" />
<modified>2008-04-18T19:45:41Z</modified>
<issued>2008-04-18T19:45:27Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9567</id>
<created>2008-04-18T19:45:27Z</created>
<summary type="text/plain">The ability to drag and drop has been a staple of desktop applications for years. With the advent of Ajax, the ability to drag and drop has now found its way to web applications. In this entry I spice up the blogging application we&apos;ve been building with the ability to drag comments to the trash. </summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>The ability to drag and drop has been a staple of desktop applications for years. With the advent of Ajax, the ability to drag and drop has now found its way to web applications. In this entry I spice up the blogging application we've been building with the ability to drag comments to the trash. This is an appropriate feature to add as our own blogs here on java.net have been prone to spam attacks via the comments which require cleanup.</p>
<h3>Setting Things Up </h3>
<p>I'm going to continue from where the tutorial <a href="http://www.netbeans.org/kb/60/ruby/ajax.html">Using Ajax with Ruby on Rails</a> leaves off. However, I'll be using NetBeans 6.1 and Rails 2.0, so you may want to start with this updated version of the <a href="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_drag_drop/rubyweblog.zip">rubyweblog</a> project which has been updated to Rails 2.0 (the entire tutorial series is in the process of being updated).</p>
<p></p>
<h3>Test the Existing rubyweblog Project </h3>
<ol>
  <li>Open the rubyweblog project.</li>
  <li>Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database (Run Rake Task &gt; db &gt; create) and run the migrations. </li>
  <li>Run the project and browse to <a href="http://localhost:3000/posts">http://localhost:3000/posts</a> to verify that it works. Add at least one blog entry with a couple of comments.</li>
</ol>
<h3>The Plan</h3>
<p>Currently, the application does not provide the means to delete a comment. Now, I know this application is severely lacking any sort of user model or administrative interface, but my intent is to show how to do cool things with Rails, not create a replacement for <a href="http://rollerweblogger.org/project/">roller</a>, so I squeeze the features in where I can. In this case, I'm going to add a trash can icon to the page and allow users to drag comments to the trash for deletion.<br>
<br>
<ul>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_drag_drop/dragtrash.png" width="631" height="678"><br></ul>
<h3>Step 1: Make the Comments Draggable</h3>
<p>Here we'll employ the <a href="http://railsapi.org/actionview-helpers-scriptaculoushelper-draggable_element">draggable_element</a> helper, a Rails wrapper around the Scriptaculous <a href="http://script.aculo.us/docs/Draggable.html">Draggable </a>object, to make the comments draggable.</p>
<ol>
  <li>Open _comment.html.erb, which is the partial for displaying a single comment, and make it draggable by adding the draggable element helper to the bottom of the file as shown in bold below:<br>
    <br>
  <pre><strong>&lt;% comment_id = &quot;comment_#{comment.id}&quot; %&gt;</strong><br>&lt;li id=&lt;%= <strong>comment_id</strong> %&gt; &gt;<br>  &lt;%= h comment.comment %&gt;&lt;br&gt;<br>  &lt;div style=&quot;color: #999; font-size: 8pt&quot;&gt;<br>      Posted on &lt;%= comment.created_at.strftime(&quot;%B %d, %Y at %I:%M %p&quot;) %&gt;<br>  &lt;/div&gt;<br>&lt;/li&gt;<br><strong>&lt;%= draggable_element(comment_id, :revert=&gt;true) %&gt;</strong></pre>
  <br>
  Note, since <tt>comment_id</tt> is used twice, I pulled it out into a local variable to keep the code a bit cleaner. Revert returns the comment to its original location if we drop it anywhere but on the trash can (which we haven't added yet).<br>
  <br>
  </li>
  <li>Add a visual indicator that the comments are draggable. Open scaffold.css (Public &gt; stylesheets) and add the following style:<br>
      <br>
    <pre>#comments {<br>    cursor: -moz-grab;<br>}</pre><br>
    <br>
  </li>
  <li>Test your changes. The comments are now draggable, but we haven't specified anywhere to drop them yet.</li>
</ol>
<h3>Step 2: Add the Trash Icon</h3>
<ol>
  <li>Save <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_drag_drop/trash.jpg" width="91" height="91" align="middle"> (trashfull.jpg) to the <tt>public/images</tt> directory of your rubyweblob project directory.<br>
    <br>
  </li>
  <li>Open <tt>show.html.erb</tt> and add the following <tt>&lt;image_tag&gt;</tt> after the <tt>&lt;text_area&gt;</tt>:<br>
      <br>
    <pre>&lt;%= text_area 'comment', 'comment' %&gt;<br><strong>&lt;%= image_tag &quot;trash.jpg&quot;, :id=&gt;'trash'%&gt;</strong></pre>
    <br>
  </li>
</ol>
<h3>Step 3: Make the Trash Icon a Drop Receiver</h3>
<p>Here we'll use the <a href="http://railsapi.org/actionview-helpers-scriptaculoushelper-drop_receiving_element">drop_receiving_element</a> helper, a Rails wrapper around the Scriptaculous <a href="http://script.aculo.us/docs/Droppables.add.html">Droppables.add</a> method to give the comment a drop destination and call the action to delete the comment.</p>
<ol>
  <li>Open show.html.erb and add the drop_receiving_element to the bottom of the file as show below:<br>
      <br>
    <pre>&lt;%= drop_receiving_element('trash',                             # The id of the receiving element<br>  :accept =&gt; &quot;comment&quot;,                                         # The CSS class of the dropped element<br>  :with   =&gt; &quot;'comment=' + (element.id.split('_').last())&quot;,     # The query string parameters<br>  :url    =&gt; {:action=&gt;:trash_comment}                          # The action to call<br>)%&gt;</pre>
    <br>
    Note the <tt>:with</tt> parameter - this is a piece of JavaScript code that extracts the comment ID form the DOM ID, which if you recall from above is something like &quot;comment_123&quot;. We also still have some work to do: first, we don't have anything with a CCS class named &quot;comment&quot; and second we need to code the <tt>trash_comment</tt> action.<br>
      <br>
  </li>
  <li>Open <tt>_comment.html.erb</tt> and add <strong><tt>class=&quot;comment&quot;</tt></strong> to the <tt>&lt;li&gt; tag</tt>:<br>
      <br><pre>&lt;li <strong>class=&quot;comment&quot;</strong> id=&lt;%= comment_id %&gt; &gt;</pre>
    <br>  
    </li>
  <li>Open <tt>posts_controller.rb</tt> and add the following <tt>trash_comment</tt> action:<br>
      <br>
    <pre>  def trash_comment<br>    comment_id = params[:comment]<br>    Comment.delete(comment_id)<br>    <br>    render :update do |page|<br>      page.replace_html &quot;comment_#{comment_id}&quot;, &quot;&quot; <br>    end          <br>  end</pre>
    <br>
  </li>
  <li>Test your changes. Dragging a comment to the trash can should delete it and clear it from the list, although the bullet still remains. That's because the <tt>replace_html</tt> method above is replacing the html <em>inside</em> of the bulleted list item. Wrapping the bulleted list items in a <tt>&lt;div&gt;</tt> solves this problem.<br>
    <br>
  </li>
  <li>Open <tt>_comment.html.erb</tt> and wrap the <tt>&lt;li&gt;</tt> in a <tt>&lt;div&gt;</tt>, also moving the <tt>class</tt> and <tt>id</tt> properties to the <tt>&lt;div&gt;</tt>:<br>
    <br><pre>&lt;% comment_id = &quot;comment_#{comment.id}&quot; %&gt;<br><strong>&lt;div class=&quot;comment&quot; id=&lt;%= comment_id %&gt; &gt;</strong> <br>  &lt;li&gt;<br>    &lt;%= h comment.comment %&gt;&lt;br&gt;<br>    &lt;div style=&quot;color: #999; font-size: 8pt&quot;&gt;<br>       Posted on &lt;%= comment.created_at.strftime(&quot;%B %d, %Y at %I:%M %p&quot;) %&gt;<br>    &lt;/div&gt;<br> &lt;/li&gt;<br><strong>&lt;/div&gt;</strong><br>&lt;%= draggable_element(comment_id, :revert=&gt;true) %&gt;</pre>
      <br>
  </li>
  <li>Now the comments should delete completely.<br>
    <br>
  </li>
</ol>
<h3>Step 4: Adding Visual Clues That Something's Happening<br>
</h3>
<ol>
  <li>Save <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_drag_drop/trashfull.jpg" width="91" height="91" align="middle"> (trashfull.jpg) to the <tt>public/images</tt> directory of your rubyweblob project directory.<br>
    <br>
  </li>
  <li>Add a couple of JavaScript methods to <tt>show.html.erb</tt> to swap the source of the trash image from empty to full and back:<br>
      <br>
    <pre>&lt;script&gt;    <br>    function fill_trash() {<br>        $('trash').src = &quot;/images/trashfull.jpg&quot;;<br>    }       <br>  <br>    function empty_trash() {<br>        $('trash').src = &quot;/images/trash.jpg&quot;;<br>    }     <br>&lt;/script&gt;</pre><br>
  </li>
  <li>Add a couple of properties to the <tt>drop_receiving_element</tt> method, <tt>:onHover</tt> and <tt>:complete:</tt><br>
      <br>
    <pre>&lt;%= drop_receiving_element('trash',                             # The id of the receiving element<br>  :accept =&gt; &quot;comment&quot;,                                         # The CSS class of the dropped element<br>  :with   =&gt; &quot;'comment=' + (element.id.split('_').last())&quot;,     # The query string parameters<br>  :url    =&gt; {:action=&gt;:trash_comment},                         # The action to call<br>  <strong>:onHover =&gt; &quot;function() {fill_trash()}&quot;,                      <br>  :complete =&gt; &quot;empty_trash()&quot;</strong><br>)%&gt;</pre><br>
  Note, I can't tell you why <tt>:onHover</tt> requires a function definition while <tt>:complete</tt> takes any arbitrary JavaScript, but that's the way it works.<br>
  <br>
<li>Test your changes. You should now see a full garbage can when you drag a comment over it and then empty again once the delete completes.<br>
  <br>
  </li>
  <li>There's still one minor problem - if you drag a comment over the trash but don't actually drop it, your trash can remains full. We can fix this using the <tt>onMouseOut</tt> event. Add it to the image_tag as follows:<br>
    <br><pre>&lt;%= image_tag &quot;trash.jpg&quot;, :id=&gt;'trash', <strong>:onMouseOut=&gt;&quot;empty_trash()&quot;</strong>%&gt;</pre>
  And that should pretty much complete the drag and drop functionality. Remember to refresh the browser to pick up changes to Javascript. Also, <a href="https://addons.mozilla.org/firefox/addon/1843">Firebug</a> is your friend whenever you're working with Ajax and not seeing what you're expecting.<br>
  </li>
</ol>
<h3>The Completed Application </h3>
<p><a href="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_drag_drop/RubyWeblogDND.zip">RubyWeblogDND.zip<br>
]]>

</content>
</entry>
<entry>
<title>Autovalidation with Rails</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/04/autovalidation.html" />
<modified>2008-04-16T20:31:53Z</modified>
<issued>2008-04-16T20:31:44Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9551</id>
<created>2008-04-16T20:31:44Z</created>
<summary type="text/plain">A common question following my Ruby on Rails lectures is how to validate against a database. In this blog entry I do just that, but with the added bonus of incorporating Ajax to avoid the page submit.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[Actually, I don't know what this feature is called, but I love it when a web application gives me instant feedback on the validity of my entry. For example:<br>
  <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/taken.png" width="406" height="114"><br>
  <br> 
  This is especially true when I'm registering a new user account - submitting the page over and over again because the username I've selected is already taken or the password doesn't meet the requirements is always a drag. 
So I started looked for examples on how to do this in Rails and couldn't really find anything (possibly because I don't actually know what to call it) - I guess it's most similar to <a href="http://demo.script.aculo.us/ajax/autocompleter">autocompletion</a>, so I'm going with autovalidation. And here are the steps I've put together to get it to work...</p>
<h3>Setting Things Up </h3>
<ol>
  <li><a href="http://dev.mysql.com/downloads/mysql/5.0.html#downloads">Download</a> and install MySQL.</li>
  <li><a href="http://download.netbeans.org/netbeans/6.1/rc/">Download</a> and install NetBeans 6.1 RC1 or later.</li>
</ol>
<h3>Creating the Rails Project</h3>
<ol>
  <li>Create a new Ruby on Rails Application named<strong> autovalidation</strong>. You can select Finish after the first page of the New Ruby on Rails Application dialog:  
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/newapplication.png" width="853" height="513"></li>
  <li>Right-click the project and select <tt>Run Rake Task &gt; db &gt; create</tt>:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/dbcreate.png" width="689" height="187"><br>
    <br>
    </li>
  <li>Right-click the project and select <tt>Generate</tt>. Generate a scaffold with the Model Name <strong>User</strong> and the Attribute Pairs <strong>username:string</strong>:  <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/generatescaffold.png" width="891" height="624"></li>
  <li>Right-click the project and select <tt>Migrate Database &gt; To Current Version</tt>.<br>
    <br>
  </li>
  <li>Open <tt>user.rb</tt> and type the following:<br>
      <br>
    <pre>vu[tab]</pre> 
    - this will expand to:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/vu.png" width="305" height="17"><br>
    <br>
    type <strong>username</strong> over the attribute and press enter.<br>
    <br>
  </li>
  <li>On the next line in <tt>user.rb</tt> type the following:<br>
      <br>
    <pre>vl[tab]</pre> this will expand to:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/vl.png" width="412" height="23"><br>
    <br>
    type <strong>username</strong> over the attribute and press enter. Type <strong>5..10</strong> over the 3..20 and press enter. The completed code should look as follows:<br>
    <br>
    <pre>class User < ActiveRecord::Base
  validates_uniqueness_of :username
  validates_length_of :username, :within => 5..10
end</pre>
  </li>
</ol>
<h3>Traditional Server Side Validation</h3>
<ol>
  <li>Run the project and browse to <a href="http://localhost:3000/users">http://localhost:3000/users</a>. Try to create a new user such as <strong>bill</strong>:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/serverbill.png" width="531" height="381"><br>
        <br>
  </li>
  <li>Okay, create <strong>william</strong>.<br>
    <br>
  </li>
  <li>Try to create <strong>william</strong> again:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/williamserver.png" width="531" height="378"><br>
        <br>
    Let's enhance this application with  more user friendly &quot;autovalidation&quot;...<br>
  </li>
</ol>
<h3>Lets Autovalidate</h3>
<p>In addition to the server side validation that's being performed, we're going to add some client side validation using Ajax. We'll do this by displaying a message to the right of the field on the validity of what's been entered. Since we're validating against the database, we will need to make an XMLHTTPRequest back to the server. We can use Rails' <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html#M000966">observe_field</a> helper method for this task.</p>
<ol>
  <li>First we need to create a named placeholder for the message. Open <tt>new.html.erb</tt> and add a <tt>&lt;span&gt;</tt> tag after the text field as follows:<br>
      <br>
    <pre>&lt;%= f.text_field :username %&gt;<strong>&lt;span id=&quot;message&quot;&gt;&lt;/span&gt;</strong></pre>
  </li>
  <li>Now we'll use Rails' observe_field method to watch changes to that field. Add the following before the closing <tt>&lt;% end %&gt;</tt> tag:<br>
      <br><pre>    &lt;%= observe_field   :user_username,                         # The field to observe <br>                        :with       =&gt; &quot;username&quot;,              # The input to validate<br>                        :frequency  =&gt; 0.25,                    # The frequency in seconds to watch for changes<br>                        :url        =&gt; {:action =&gt; :validate }, # The action to call when changes occur<br>                        :update     =&gt; :message                 # The DOM ID to update<br>                      %&gt;</pre>
    <br>
  </li>
  <li>Create the <tt>validate</tt> action. Open <tt>users_controller.rb</tt> and add the following:<br>
      <br>
    <pre>  def validate<br>    color = 'red'<br>    username = params[:username]<br>    if username.length &lt; 5<br>      message = 'Too short'<br>    elsif username.length &gt; 10<br>      message = 'Too long'<br>    else<br>      user = User.find_all_by_username(username)      <br>      if user.size &gt; 0        <br>        message = 'Taken'     <br>      else<br>        message = 'Available'<br>        color = 'green'<br>      end<br>    end<br>    @message = &quot;&lt;b style='color:#{color}'&gt;#{message}&lt;/b&gt;&quot;<br>    render :partial=&gt;'message'<br>  end</pre>
    <br>
    You'll notice in the last line of the validate action above we're rendering a partial. This partial, which we'll create next, will be dynamically rendered inside the <tt>span</tt> tag we defined in step 1 above.<br>
    <br>
  </li>
  <li>Create a new ERB file named <strong>_message</strong> in Views &gt; users. Replace its contents with the following:<br>
      <br>
    <pre>&lt;%= @message %&gt;</pre>
    <br>
  </li>
  <li>Open <tt>users.html.erb</tt> and add the following before the closing <tt>&lt;/head&gt;</tt> tag:<br>
    <br>
      <pre>&lt;%= javascript_include_tag 'prototype'  %&gt;</pre>
      All Rails applications come with the <a href="http://www.prototypejs.org/">prototype</a> and <a href="http://script.aculo.us/">scriptaculous</a> libraries ready to use, but you do need to tell the application that you want to use them.<br>
    <br>
  </li>
</ol>
<h3>Run with Autovalidate</h3>
<ol>
  <li>    Switch to the browser and start creating a new user (you'll need to refresh the browser once to load the prototype JavaScript libraries):<br>  
    <br>    
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/ajaxwill.png" width="527" height="225"><br>  
    <br>  
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/ajaxwilliam.png" width="527" height="220"><br>  
    <br>  
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/ajaxwilliaml.png" width="529" height="222"><br>  
    <br>  
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/ajaxwilliamleon.png" width="526" height="219"><br>
  </li>
</ol>
<h3>Troubleshooting</h3>
  <p><a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> is your friend for troubleshooting Rails applications. With Firebug enabled, you can see the requests as you type:  
    <br>  
<blockquote> 
    <p><img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/firebugresponse.png" width="530" height="414">
  </p>
      <br>
    </p>
</blockquote>
  <h4>A couple of things that tripped me up</h4>
  <blockquote>
    <p>Forgetting to include the Prototype libraries:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/firebugformnotdefined.png" width="529" height="319"><br>
    </p>
    <p>Misspelling the field to observe:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/firebugelementnoproperties.png" width="529" height="380"></p>
</blockquote>
  <p>&nbsp;  </p>
  <h3>The Completed Application </h3>
<p><a href="http://weblogs.java.net/blog/bleonard/archive/2008/04/rails_auto_validate/autovalidation.zip">autovalidation.zip</a><br>
]]>

</content>
</entry>
<entry>
<title>Blogging for Dollars (and T-Shirts)</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/03/blogging_for_do.html" />
<modified>2008-03-18T19:37:55Z</modified>
<issued>2008-03-18T19:37:49Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9385</id>
<created>2008-03-18T19:37:49Z</created>
<summary type="text/plain">The NetBeans team has started a blogging contest. Simply download the NetBeans 6.1 Beta and tell us your thoughts. What, you&apos;re not a blogger? Well then, I list some places for you to get started.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<img alt="61blog-contest-logo-trans.gif" src="http://weblogs.java.net/blog/bleonard/archive/2008/03/blog_contest/61blog-contest-logo-trans.gif" width="330" height="183" /></p>
<p>The NetBeans team has started a blogging contest. Simply <a href="http://download.netbeans.org/netbeans/6.1/beta/">download</a> the NetBeans 6.1 Beta and tell us your thoughts. What, you're not a blogger? Well, here are some places to get started:</p>
<ul>
  <li><a href="https://www.blogger.com/start">Blogger</a></li>
  <li><a href="http://www.jroller.com/">JRoller</a></li>
  <li><a href="http://wordpress.org/">WordPress</a></li>
</ul>
<p>See the <a href="http://www.netbeans.org/competition/blog-contest.html">blogging contest</a> web site for details on how to enter, ideas for your blog, rules and deadlines.</p>
]]>

</content>
</entry>
<entry>
<title>Hello Grails!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails_1.html" />
<modified>2008-01-31T13:14:20Z</modified>
<issued>2008-01-31T02:37:20Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.9099</id>
<created>2008-01-31T02:37:20Z</created>
<summary type="text/plain">The recently released NetBeans 6.1 M1 brings with is the beginnings of support for Groovy and Grails. In this post I create a Grails implementation of the basic web log we&apos;ve been using for our Rails tutorials.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>NetBeans 6.1 M1 was just released, and with it comes rudimentary support for the Groovy language and the Grails framework. I say rudimentary because this is M1, but there's a lot of work in progress as you can see from this <a href="http://wiki.netbeans.org/Groovygrails">task list</a>.</p>
<p>So, of course I'm anxious to compare Grails to Rails. What better way to do than by creating the same <a href="http://www.netbeans.org/kb/60/ruby/rapid-ruby-weblog.html">blog application</a> I've been blogging about with Rails?</p>
<h3>Setting Things Up </h3>
<p>Unlike with Rails, the NetBeans Groovy plugin does not come bundled with Groovy and the Grails framework - these must be pre-installed on your system (don't worry, it's easy):</p>
<ol>
  <li><a href="http://groovy.codehaus.org/Download">Download</a>  and <a href="http://groovy.codehaus.org/Installing+Groovy">install</a> Groovy</li>
  <li><a href="http://grails.codehaus.org/Installation">Download</a> and <a href="http://grails.codehaus.org/Installation">install</a> Grails</li>
  <li><a href="http://bits.netbeans.org/download/6.1/m1/latest/">Download</a> and install NetBeans 6.1 M1.</li>
  <li>Install the Groovy and Grails plugin (Tools &gt; Plugins &gt; Available Plugins)</li>
  <li>Open the NetBeans Options dialog and select the Groovy category. Set the Groovy and Grails home directories.</li>
</ol>
<h3>Creating the Grails Project</h3>
<ol>
  <li>Choose File &gt; New Project to create a new Grails Application named <strong>GroovyWebLog</strong>. Your new Grails application will appear in the IDE:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/new_grails_project.png" width="217" height="285"><br>
  </li>
</ol>
<h3>Creating the Model</h3>
<p>Or as Grails prefers to call them, Domain classes.</p>
<ol>
  <li>Right-click the Domain classes node and select &quot;Create new Domain Class&quot;:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/create_new_domain_class.png" width="345" height="121"><br>
      <br>
  </li>
  <li>Name the class <strong>Post</strong>.</li>
  <li>When  Post.groovy  opens in the editor, add a single field, title:<br>
      <br>
    <pre>class Post {

    String title

}</pre>
  </li>
</ol>
<h3>Creating the Controller</h3>
<ol>
  <li>Right-click the Controllers node and select &quot;Create new controller&quot;</li>
  <li>Name the controller <strong>Blog</strong>.</li>
  <li>For now, we'll use dynamic <a href="http://grails.codehaus.org/Scaffolding">scaffolding</a> to create the application views at runtime. Replace the default contents of BlogController with the following:<br>
    <br>
  <pre>class BlogController {
    def scaffold = Post
}<br></pre>
  Note, if our controller named matched the domain class name, we could then use <span class="style1">def scaffolding = true</span>. I kept the model and controller names different to match what we did with Rails.<br>
  </li>
</ol>
<h3>Run the Application</h3>
<ol>
  <li>Right-click the GrailsWebLog project and select Grails &gt; Run Application.</li>
  <li>If all goes well, NetBeans will start the Jetty server that comes bundled with Grails and launch your browser where you will see the Grails welcome page:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/grails_welcome_page.png" width="822" height="237"><br>
  </li>
  <li>Click the BlogController link:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/blog_controller.png" width="553" height="270"><br>
        <br>
  </li>
  <li>Create a New Post:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/new_post.png" width="562" height="285"><br>
      <br>
    It's not immediately obvious, but the Id is a link which you can use to view the post details. From the detail page you can then edit and/or delete the post:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/edit_post.png" width="580" height="318"><br>
    <br>
  </li>
</ol>
<h3>Adding Another Field</h3>
<p>Our blog needs a body field.</p>
<ol>
  <li>Edit Post.groovy and add a body field:<br>
    <br>
  <pre>class Post {

    String title
    String body

}<br></pre>
  </li>
  <li>Return to the browser and depending on what you do, you may get an error. By default Grails is configured to drop and create the database every time a change is made, so if you tried to edit the existing record you were viewing, you got a NullPointerException. However, if you navigate back to the list, you will see that the body field has been detected and you can add a new record again:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/with_body.png" width="572" height="331"><br>
    <br>
  </li>
</ol>
<h3>A Friendlier Database Configuration</h3>
<p>Surprisingly, we haven't had to talk about databases yet as the Grails framework magically took care of this for us. The Grails framework includes HSQLDB and all of the necessary configuration was setup for us in DataSource.groovy, which you'll find under the Configuration node:</p>
<blockquote>
  <p><img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/datasource_groovy.png" width="786" height="510"></p><br>
You can also see from this configuration file that Grails supports the same three environments as Rails: development, test and production. It's also easy to switch to another database, just set the driver class name, jdbc url and copy the JDBC driver to the project's lib directory.
</blockquote>
<p>Do the following:</p>
<ol>
  <li>Change the dbCreate property from &quot;create-drop&quot; to &quot;update&quot;.</li>
  <li>Right-click the GrailsWebLog project and choose Grails &gt; Stop Application.</li>
  <li>Richt-click the project again and choose Grails &gt; Run Application.</li>
  <li>Now experiment with adding and/or deleting fields - you'll notice that the behavior is much more &quot;Railsesque&quot;.</li>
</ol>
<h3>Validating Input</h3>
<p>Like Rails, <a href="http://grails.codehaus.org/Validation">validation</a> in Grails is very straightforward.</p>
<ol>
  <li>Open Post.groovy and add the following constraints:<br>
    <br>
  <pre>class Post {

    String title
    String body
    
    static constraints = {
        title(blank:false)
        body(blank:false)
    }

}</pre>
  </li>
  <li>Attempt to add a new Post without entering any data:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/validation.png" width="583" height="387"><br>
    <br>
  </li>
</ol>
<h3>Customizing the View</h3>
<p>Okay, enough with this dynamic scaffolding. Let's generate our controller and view code. Unfortunately, for this step I haven't found the menu option in NetBeans yet, so we'll resort to the command line for now.</p>
<ol>
  <li>Open your command prompt and navigate to the GrailsWebLog project directory. If you've forgotten where this is, you can find it in the project's Properties dialog.</li>
  <li>Run the command <span class="style1">grails generate-all Post</span>:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/generate_all.png" width="689" height="263"><br>
      <br>
  </li>
  <li>Now this created a new controller named PostController. I don't see a way to specify a controller name when using <a href="http://grails.codehaus.org/doc/1.0.x/ref/Command Line/generate-all.html">generate-all</a> (or <a href="http://grails.codehaus.org/doc/1.0.x/ref/Command%20Line/generate-controller.html">generate-controller</a>). That's fine - I'll leave BlogController to do the dynamic scaffolding and use PostController for my customizations.</li>
  <li>Also created were a set of GSP (Groovy Server Pages) for managing the view for the PostController:<br>
      <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/views_and_layouts.png" width="168" height="181"><br>
        <br>
  </li>
  <li>Open list.gsp and delete everything from from the &lt;h1&gt;Post List&lt;h1&gt; to the &lt;/div&gt; following the pagination buttons. In its place put the following:<br>
  </li>
  <pre>&lt;h1&gt;The Groovy Blog&lt;/h1&gt;
 
&lt;g:each in=&quot;${postList}&quot; var=&quot;post&quot;&gt;
  &lt;h2&gt;${post.title}&lt;/h2&gt;
  &lt;p&gt;${post.body}&lt;/p&gt;
  &lt;small&gt;&lt;g:link action=&quot;show&quot; id=&quot;${post.id}&quot;&gt;permalink&lt;/g:link&gt;&lt;/small&gt;
  &lt;hr&gt;
&lt;/g:each&gt;</pre>
  <li>Return to the browser and refresh the list page:<br>
      <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/listing_posts.png" width="549" height="313"><br>
      <br>
  </li>
  <li>To display the blog with the most recent entry first, add .reverse() to the end of postList in list.gsp:<br>
      <br>
    <pre>&lt;g:each in=&quot;${postList.reverse()}&quot; var=&quot;post&quot;&gt;</pre>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/listing_posts_reversed.png" width="562" height="312"><br>
      <br>
    <br>
  </li>
</ol>
<h3>The Completed Application </h3>
<p><a href="http://weblogs.java.net/blog/bleonard/archive/2008/01/hello_grails/GrailsWebLog.zip">GrailsWebLog.zip</a><br>
]]>

</content>
</entry>
<entry>
<title>Testing Rails Applications</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2008/01/testing_rails_a.html" />
<modified>2008-01-04T23:30:43Z</modified>
<issued>2008-01-04T19:04:35Z</issued>
<id>tag:weblogs.java.net,2008:/blog/bleonard/222.8924</id>
<created>2008-01-04T19:04:35Z</created>
<summary type="text/plain">All Rails applications include unit, functional and integration test facilities. In this entry I address all three of these test types as I put the Ruby Weblog application to the test.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[<p>All well developed applications are supported by tests. In this entry I extend the web log I've been building to include some unit, functional and integration tests.</p>
<h3>Setting Things Up </h3>
<p>I'm going to begin from where I left off in my previous post: <a href="http://weblogs.java.net/blog/bleonard/archive/2007/12/an_introduction_3.html">An Introduction to using AJAX with Rails: Take 2</a>. Alternatively, you can start from <a href="http://weblogs.java.net/blog/bleonard/archive/2007/12/rails_ajax2/RubyWeblogAJAX.zip">RubyWeblogAJAX.zip</a>, which is the completed project from that post. </p>
<h3>Test the RubyWeblog Project </h3>
<ol>
  <li>Open the rubyweblog project.</li>
  <li>Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database and run the migrations. </li>
  <li>Run the project and browse to <a href="http://localhost:3000/blog">http://localhost:3000/blog</a> to verify that it works. </li>
</ol>
<h3>The Plan</h3>
<p>We're going to look at the facilities Rails provides for testing our model classes, controller classes and entire application.</p>
<h3>Model Testing (Unit Tests)</h3>
<p>The Rails framework uses unit tests for testing of the model classes. Back when we first created the Post model class, a couple of test files were created for us, test/unit/post_test.rb and test/fixtures/post.yml:<br>
  <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/generate_model.png" width="391" height="143"></p>
<p>The post.yml file contains test data that's made available to the unit test and reloaded in the database every time the test is run. Don't worry, this isn't going to affect your  development database, but rather the test database that's configured in database.yml, which we haven't created yet:<br>
    <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/database_yml.png" width="548" height="137"></p>
<h4>Create the rubyweblog_test Database</h4>
<ol>
  <li>Switch to the Services window and expand the Databases node. We'll use an existing MySQL connection to create the test database. If you don't already have an existing MySQL database connection, create one for the development database.
    <ol>
      <li>Expand the Drivers node, right-click the MySQL driver and choose Connect Using</li>
      <li>Set the Database URL to: <strong>jdbc:mysql://localhost/rubyweblog_development</strong></li>
      <li>Set the User Name to: <strong>root</strong></li>
      <li>Leave the Password blank</li>
      <li>Click OK to establish the connection</li>
    </ol>
  </li>
  <li>Right-click an existing MySQL connection (connect first if not already) and select Execute Command.</li>
  <li>Enter <strong>create database rubyweblog_test</strong>  </li>
  <li>Right-click the commend and select Run Statement</li>
</ol>
<h4>Prepare the Database<br>
</h4>
<p>We need to run the migrations against the test database. This is done using the rake task db:test:prepare</p>
<ol>
  <li>Right-click the rubyweblog project and choose Run Rake Task &gt; db &gt; test &gt; prepare<br>
</li>
</ol>
<h4>Run the Default Unit Test</h4>
<p>The default unit test that was created for us when the model was generated is very basic and really only servers to prove our test environment is properly configured.</p>
<ol>
  <li>Open post_test.rb</li>
  <li>Right-click the file and select Run File. <br>
    <br>
      <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/post_test_output.png" width="559" height="148"><br>
        <br>
  If for some reason the test fails to run, the error messages are generally descriptive enough to alert you to the problem, like &quot;Unknown database 'rubyweblog_test' if you forgot to create the test database first.</li>
</ol>
<h4>Test the Validations</h4>
<p>The post model is pretty simple and doesn't offer a lot to test, but it does have a couple of validations when can test, so therefore, we can assert that an empty model is invalid:</p>
<pre>
  def test_invalid_with_empty_attributes
    post = Post.new
    assert !post.valid?                  # An empty Post model will be invalid
    assert post.errors.invalid?(:title)  # The title field will have validation errors
    assert post.errors.invalid?(:body)   # The body field will have validation errors
  end</pre>
<h4>Using Fixture Data</h4>
<p>To give us something more to test, let's require blog titles be unique. </p>
<ol>
  <li>Navigate to the tested class (Navigate &gt; Go to Tested Class)</li>
  <li>Add <pre>validates_uniqueness_of :title</pre></li>
  <li>Open fixtures/post.yml and add the following:
    <pre>first:
  id: 1
  title: George Jetson
  body: Was a man ahead of his time
</pre>
  </li>
<li>Navigate back to the post_test.rb and add the following test method:<pre>  def test_unique_title
    post = Post.new(:title  => posts(:first).title, # Pull the title from the fixture 
                    :body   => "Whatever")
    assert !post.save
    assert_equal "has already been taken", post.errors.on(:title) 
  end</pre>
  </li>
  </ol>
      <h4>Run the Tests</h4>
      <p>There are several way to run the test:</p>
      <ol>
        <li>From the test file, right-click the file and choose Run File or Test File, as both do the same when executed from a test file.</li>
        <li>From the tested class, right-click the file and choose Test File.<br>
          <br>
      <p><img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/post_test_output2.png" width="564" height="147"> </p>
        </li>
      </ol>
      <h3>Controller Testing (Functional Tests)</h3>
      <p>When the scaffolding  was generated, Rails also generated a functional test stub in the test/functional directory, which has 8 tests for the actions created by the generator (index, list, show, new, create, edit, update, destroy). </p>
      <ol>
        <li>Open test/functional/blog_controller_test.rb.</li>
        <li>Right-click the file and choose Run File. You should see one failure:<br>
            <br>
          <img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/blog_controller_test_output.png" width="818" height="143"><br>
            <br>
          This failure is caused by the validations we've added to the Post model as this line from the test_create method doesn't pass any arguments in with the post:
          <pre>    post :create, :post => {}</pre>
          (Note, the first &quot;post&quot; in the line above refers to the HTTP Post method, while &quot;:post&quot; refers to the Post model).<br>
          <br>
        </li>
        <li>Add required parameters to the empty :post hash:<pre>    post :create, :post => { :title => "Astro", 
                             :body  => "Was loved by George" }   </pre>
          All 8 tests and 25 assertions should now pass.<br>
        </li>
      </ol>
      <h4>Testing the post_comment Action</h4>
      <p>The default tests provide excellent examples on how to create tests for other controller actions. I'll create a new test for the additional controller action we've created since the controller was generated, post_comment:
      <pre>  def test_post_comment
    xhr :post,                                            # Simulate xml_http_request 
      :post_comment,                                      # the action to call  
      { :comment => { :comment => "What about Jane?" }},  # the parameters to post
      nil,                                                # session variables expected by the action
      { :post_id => 100 }                                 # flash variables expected by the action
              
    assert_response :success
    assert_template '_comment'
    assert_equal 'Comment was successfully added.', flash[:notice]
    assert_equal 'What about Jane?', Comment.find_by_post_id(100).comment
  end  </pre>
      <h4>Application Testing (Integration Tests)</h4>
      <p>Integration tests are used for testing application flow and generally test a scenario of events. The blog application is very simple, but we can still create a test scenario such as creating an entry, viewing the entry, editing the entry and adding a comment.</p>
<p>Integration tests are very much like functional tests, but since they can span multiple controllers  you have to pass the controller as well as the action to the HTTP method (e.g., get &quot;/blog/index&quot;). Also, the Rails framework has not created a default integration test file for us, one must first be generated.</p>
<ol>
  <li>Generate an Integration Test named <strong>ApplicationUsage</strong>.</li>
  <li>Add the following test method:<pre>  def test_creating_a_post
    
    # Clear the database tables
    Comment.delete_all  
    Post.delete_all  
    
    # Load the home page
    get "/blog/index"
    assert_response :success
    assert_template "list"
    
    # Load the New post page
    get "/blog/new"
    assert_response :success
    assert_template "new"
    
    # Create a new blog post
    post "/blog/create", :post => { :title => "Integration Test Title", 
                                    :body => "Integration Test Body"}
    assert_response :redirect
    
    # Get the post variable from the controller so we can fetch the generated id
    # which we'll use to get the record.
    post_id = @controller.instance_variable_get(:@post).attributes['id']
    
    # Show the newly created post
    get "/blog/show/#{post_id}"
    assert_response :success
    assert_template "show"
    
    # Edit the post    
    get "/blog/edit/#{post_id}"
    assert_response :success
    assert_template "edit"
    
    # Post the edits    
    post "/blog/update/#{post_id}", :post => { :title => "Integration Test Title Updated", 
                                               :body => "Integration Test Body Updated"}
    assert_response :redirect
    
    # Verify the post exists
    posts = Post.find(:all)
    assert_equal 1, posts.size
    
    # Confirm it's contents
    post = posts[0]    
    assert_equal  "Integration Test Title Updated", post.title
    assert_equal  "Integration Test Body Updated",  post.body
  end</pre></li>
  <li>Run the file to execute the test.</li>
</ol>
<p>You may have noticed that the test above does not test adding a comment. This is because I couldn't figure out how to set the flash from an integration test. Here's the signature for the <a href="http://api.rubyonrails.org/classes/ActionController/TestProcess.html#M000191">xhr</a> method I used from the functional test:
<pre>xhr(request_method, action, parameters = nil, session = nil, flash = nil)</pre>
<p>and here's the signature for the <a href="http://api.rubyonrails.org/classes/ActionController/Integration/Session.html#M000250">xhr</a> method for integration testing:
<pre>xhr(request_method, path, parameters = nil, headers = nil)</pre><p>And I just don't see a way to set the flash. If anyone knows, please let me know.</p>
<h3>Running All Tests</h3>
<p>You can run the entire suite of tests by selecting Run &gt; Test &quot;rubyweblog&quot; or right-clicking the project and selecting Test. You'll also see a nice summary at the bottom of the editor window (this summary is there for every test run - it's just more useful in this case because it shows the aggregate of all test runs).<br>
  <br>
<img src="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/test_summary.png" width="505" height="21"></p>
<h3>The Completed Application </h3>
<p><a href="http://weblogs.java.net/blog/bleonard/archive/2008/01/rails_test/RubyWeblogTested.zip">RubyWebLogTested.zip</a></p>
<h3>References</h3>
<ul>
  <li>
    <a href="http://www.pragprog.com/titles/rails2">Agile Web Development with Rails</a></li>
</ul>]]>

</content>
</entry>
<entry>
<title>An Introduction to using AJAX with Rails: Take 2</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2007/12/an_introduction_3.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-12-05T00:25:49Z</issued>
<id>tag:weblogs.java.net,2007:/blog/bleonard/222.8758</id>
<created>2007-12-05T00:25:49Z</created>
<summary type="text/plain">In this entry I apply lessons learned to present a better alternative to the AJAX implementation of the Ruby Web Log sample application. No longer is the entire list of comments refreshed. Rather, our new comment is efficiently inserted into the bottom of the list.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[In my <a href="http://weblogs.java.net/blog/bleonard/archive/2007/07/an_introduction.html">first take</a> on introducing AJAX with Rails, when a new comment is posted to an entry, the entire set of existing comments is replaced with a new set containing the new comment. Although the  request is asynchronous, it's still inefficient, especially if the list of comments grows large. Ideally I would just insert the new comment to the bottom of the existing list, and that's what I show here.</p>
<h3>Setting Things Up </h3>
<p>I'm going to begin where the <a href="http://www.netbeans.org/kb/60/ruby/model.html">Building Relationships Between Rails Models</a> tutorial leaves off. Alternatively, you can start from <a href="http://weblogs.java.net/blog/bleonard/archive/2007/12/rails_ajax2/RubyWeblogComments.zip">RubyWeblogComments.zip</a>, which is the completed project from that tutorial.</p>
<h3>Test the rubyweblog Project </h3>
<ol>
  <li>Open the rubyweblog project.</li>
  <li>Note, if you are starting with the provided rubyweblog project, you will also need to create the rubyweblog_development database and run the migrations. </li>
  <li>Run the project and browse to <a href="http://localhost:3000/blog">http://localhost:3000/blog</a> to verify that it works. </li>
</ol>
<h3>The Plan</h3>
<p>Currently, when a new comment is added, the entire page - blog entry and comments - are reloaded. Instead, we'll use AJAX to just insert the new comment to the bottom of the list. Just for fun,  I will also show you how to apply a visual effect to highlight the most recently added comment. </p>
<h3>Preparation</h3>
<p>First we're going to move the fragment of rhtml that we want to dynamically insert, that being a single comment, into a <a href="http://api.rubyonrails.com/classes/ActionView/Partials.html">partial template</a>.</p>
<ol>
  <li>Open show.rhtml<br>
    <br>
  </li>
  <li>Cut the following block of code from show.rhtml<br>
    <br>
    <br>
    <pre>
&lt;li&gt;&lt;%= h comment.comment %&gt;&lt;br&gt;
  &lt;div style=&quot;color: #999; font-size: 8pt&quot;&gt;
    Posted on &lt;%= comment.created_at.strftime(&quot;%B %d, %Y at %I:%M %p&quot;) %&gt;
  &lt;/div&gt;
&lt;/li&gt;    </pre>
    <br>
  </li>
  <li>Create a new RHTML file named <strong>_comment</strong> and place it in the <strong>app\views\blog</strong> folder. <br>
    <br>
  </li>
  <li>Paste in the code you cut above, replacing all existing content in _comment.rhtml.<br>
    <br>
  </li>
  <li>Return to show.rhtml and insert a call to the partial from where you cut the code. Also, place a &lt;div&gt; tag with the id of &quot;comments&quot; inside the &lt;ul&gt; elements. We'll use this div to refer to this block of HTML when we insert the new comment. The new chunk of code in show.html should now look as follows:<br>
      <br>
      <pre>&lt;ul&gt;
  &lt;div id=&quot;comments&quot;&gt;
    &lt;% @post_comments.each do |comment| %&gt;
      &lt;%= render :partial=&gt;&quot;comment&quot;, :object =&gt; comment %&gt;
    &lt;% end %&gt;
  &lt;/div&gt;
&lt;/ul&gt;
</pre>
      <br>
  </li>
  <li>Test your changes. The application should behave as it did before.</li>
</ol>
<h3>Change the POST to an XMLHTTPRequest</h3>
<ol>
  <li>First, let's make sure the JavaScript libraries we're going to use are included in our application. Open blog.rhtml and add the following line below the stylesheet_link_tag:<br>
    <br>
    <pre> <span class="ST4">&lt;%=</span> <span class="ruby">javascript_include_tag</span> <span class="ST6">:</span><span class="ST6">defaults</span>  <span class="ST4">%&gt;</span></pre>
    We're passing <strong>:defaults</strong> as the source because we're going to be using the Prototype and Scriptaculous libraries that come bundled with Rails. <br>
    <br> 
  </li>
  <li>In show.rhtml, change the form_tag, which performs a HTTP POST, to a form_remote_tag, which performs an XMLHTTPRequest, as follows:<br>
    <br>
    <pre><span class="ST0">&lt;%</span> <span class="ruby">form_remote_tag</span> <span class="ST6">:</span><span class="ST6">url</span> <span class="ruby">=&gt;</span> <span class="ruby">{</span><span class="ST6">:</span><span class="ST6">action</span> <span class="ruby">=&gt;</span> <span class="ST5">"</span><span class="ST5">post_comment</span><span class="ST5">"</span><span class="ruby">}</span> <span class="ST1">do</span> <span class="ST0">%&gt;</span></pre>
    <br>
  </li>
  <li>Test. The entire page is no longer reloaded on submit. This is because submit is now performing an XMLHTTPRequest rather that a POST. As a matter of fact, it appears as though nothing has happened. However, if you refresh the browser at this point, you will see the comments are indeed being added.<br>
    <br>
  </li>
  <li>Open blog_controller.rb and navigate to the post_comment action. <br>
    <br>
  </li>
  <li>Replace the existing redirect_to method with the following render method:<br>
      <br>
<pre>render :update do |page|
  page.insert_html :bottom, 'comments', :partial =&gt; 'comment'
  page[:comment_comment].clear
  flash.keep(:post_id)
end</pre>
<br>
The code above is dynamically inserting the _comment.rhtml partial into the bottom of the &quot;comments&quot; &lt;div&gt; we defined above. It's important to keep the post_id in the flash, otherwise, any additional comments the user decides to insert will have a nil post_id, and will therefore be orphaned (there's no referential integrity defined on the comments table).
    <br>
    <br>
  </li>
  <li>Test  and our comment should now be dynamically inserted into the bottom of the list.</li>
</ol>
<h3>Apply Visual Effects</h3>
<p>The Scriptaculous library comes with a bunch of <a href="http://wiki.script.aculo.us/scriptaculous/show/VisualEffects">visual effects</a>. I'm going to apply the <a href="http://wiki.script.aculo.us/scriptaculous/show/Effect.Highlight">highlight effect</a> to the comment just posted. Once in place, you can easily swap in and try out any of the other effects.</p>
<ol>
  <li>Like we did above for the entire comments section, we need to label the comment to which we want to apply the visual effect. We'll do this by adding a unique, deterministic id to each comment - what better than the comment id itself? Open _comment.rhtml and add the following id property to the &lt;li&gt; element:<br>
    <br>
    <pre>&lt;li id=&lt;%= &quot;comment_#{comment.id}&quot; %&gt;&gt;</pre>
    <br>
  </li>
  <li>Then switch to blog_controller.rb and add the following to the block provided by render :update:<br>
      <br>
    <pre>page[&quot;comment_#{@comment.id}&quot;].visual_effect :highlight, :duration =&gt; 3.5</pre>
    <br>
  </li>
  <li>Test the end result:<br>
    <br>
  <img src="http://weblogs.java.net/blog/bleonard/archive/2007/12/rails_ajax2/highlight_effect.png" width="422" height="239"> <br>
  <br>
  The highlight will appear for 3 1/2 seconds and then fade away. </li>
</ol>
<h3>Troubleshooting</h3>
<p>Working with AJAX can be frustrating because when things go wrong you often don't get a notification in the browser (or if you do, it's a bunch of confusing JavaScript). In such cases I found the server output invaluable. For example, if you misspell the partial &quot;comment&quot; above when inserting the html, nothing happens when you click Post to add the comment. However, looking at the server's output shows the following helpful message:<br>
    <br>
    <img src="http://weblogs.java.net/blog/bleonard/archive/2007/12/rails_ajax2/server_output.png" width="780" height="104"><br>
  <br>
</p>
<p>&nbsp;</p>
<h3>The Completed Application </h3>
<p><a href="http://weblogs.java.net/blog/bleonard/archive/2007/12/rails_ajax2/RubyWeblogAJAX.zip">RubyWeblogAJAX.zip</a>]]>

</content>
</entry>
<entry>
<title>Rails and JPA (Instead of ActiveRecord)</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/bleonard/archive/2007/09/rails_and_jpa_i.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-09-26T16:30:52Z</issued>
<id>tag:weblogs.java.net,2007:/blog/bleonard/222.8321</id>
<created>2007-09-26T16:30:52Z</created>
<summary type="text/plain">Out of sheer morbid curiosity, I wondered what it would take to replace ActiveRecord with JPA in the classic blog demo. After discussing the concept with a developer I met at RailsConf last week, I decided to go ahead and publish my results.</summary>
<author>
<name>bleonard</name>

<email>bleonard@netbeans.org</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/bleonard/">
<![CDATA[Out of sheer morbid curiosity, I wondered what it would take to replace ActiveRecord with JPA in the classic blog demo. <a href="http://www.workingwithrails.com/person/5514-jeroen-zwartepoorte">Jeroen Zwartepoorte</a>, a developer I met last week at RailsConf, convinced me to go ahead and publish my results.</p><p>
<p>In almost all cases, I tried to keep the view and controller code similar to what you would expect from generated scaffolding, so all of the JPA code is isolated in the model class. I also refrained from making any changes to the Java e