One thing plagued me, however. Because the universal version doesn't have an actual .app file to put in your Applications directory you can't add it to the dock. While it's not a show-stopper it's clearly suboptimal.
I was certain there must be several ways I could wrap the netbeans startup shell script into an .app that I could add to my dock and maybe even set an icon for.
After some googling about I found several tutorials that did the job. Unfortunately they either involved some unnecessary steps or had information that was no longer accurate in Mac OS X 10.6. 2 Snow Leopard.
While I'm sure it may not be perfect either I decided to outline the steps I followed in the hopes that it will possibly help other Mac users trying to accomplish the same thing.
Wrapping your program in an AppleScript
The first thing we'll do is really all the meat. We'll put a three line AppleScript together that simply executes our target executable, netbeans in my case. Open up the AppleScript editor (located at /Applications/Utilities/AppleScript Editor.app in 10.6.2) and enter code similar to the following:
to run do shell script "/opt/netbeans/bin/netbeans" end run
Make sure to substitute the full path to the executable of your interest into line 2.
Now save the script into your /Applications folder but be careful to save it as an application, not as a script. I'll save mine as /Applications/run_netbeans.app.

Create an icon
Really we could stop now. You could copy the .app file to your dock and life would be merry. It would be ugly, however. We might as well give it a pretty icon while we've gone to all this trouble.
Keep in mind to follow these steps you'll need the Icon Composer which requires you to have the Apple developer tools installed.
It's quite simple, really. Just find or create a .png file of around 128x128-ish that you'd like for your application's icon.
Now fire up Icon Composer which will be located at /Developer/Applications/Utilities/Icon Composer.app. Drag your .png file into the square labeled 128 and ensure the contents that display in the square are correct. Click on the square so it's highlighted and copy it with command-c.
![]()
Using the Finder locate the .app file you created in your /Applications directory and hit command-i. Click on the icon at the top so it's highlighted then hit command-v which will paste your icon into the information window. Close out the window and, POW, you've changed the icon!
Before: ![]()
After: ![]()
Feel free to close out Icon Composer. It's up to you weather you want to save the icon or not. I recommend at least keeping the original .png artwork.
We're done!
Now you can drag your .app to the dock and enjoy!

One thing that's impressed me with Solr
is the flexibility of the Data Import Handlers
(DIHs). When I was new to Solr there were several times I thought for sure I'd
have to write my own extension of DataImportHandler. Every time that's happened
I've been wrong. A transformer or something handled my needs. Sometimes it's wonderful to be wrong! Especially when it means less code I have to write myself!
One of the aspects of DIH's that provide such great flexibility is transformers like RegexTransformer and TemplateTransformer. In this post, however, I'm going to *quickly* cover the ScriptTransformer wich allows you to employ your own custom JavaScript code in the processing of imports.
Prerequisites
Obviously you'll need a functional Solr instance. Also, ScriptTransformers require Java 6 due to JavaScript support. I'll also assume you have an understanding of how dynamicFields work.
Objective
At the office I've recently used a ScriptTransformer to build the field names of dynamicFields and I'm going to do the same in this article. The actual use-case I dealt with was very esoteric and honestly a bit proprietary so I'll substitute an example data scenario here.
Basically I'll import data about students grades for various courses from different institutions. In the resultant Solr index I'll provide a dynamicField for every course to provide easy sorting of students by their grades in the courses they took.
Consider the following MySQL schema and data and try to think beyond this sample data. Think about hundreds of schools, thousands of courses and, well, a ton of students.
create table schools (
id int auto_increment primary key,
name varchar(255)
);
insert into schools (name) values ('Pitt');
insert into schools (name) values ('Penn State');
create table students (
id int auto_increment primary key,
first_name varchar(255),
last_name varchar(255),
current_school_id int references schools(id)
);
insert into students (first_name, last_name, current_school_id) values
('John', 'Doe', 1);
insert into students (first_name, last_name, current_school_id) values
('Bill', 'Miller', 1);
insert into students (first_name, last_name, current_school_id) values
('Jane', 'Dow', 2);
insert into students (first_name, last_name, current_school_id) values
('Dennis', 'Itchison', 2);
create table courses (
id int auto_increment primary key,
school_id int references schools(id),
course_number varchar(10),
name varchar(255)
);
insert into courses (school_id, course_number, name) values
(1, 'CS1501', 'Algorithm Implementations');
insert into courses (school_id, course_number, name) values
(1, 'CS1541', 'Introduction to Computer Architecture');
insert into courses (school_id, course_number, name) values
(2, 'CMPSC465', 'Data Structures and Algorithm');
insert into courses (school_id, course_number, name) values
(2, 'CMPSC473', 'Operating Systems');
create table grades (
id int auto_increment primary key,
value FLOAT,
course_id int references courses(id),
student_id int references students (id)
);
insert into grades (value, course_id, student_id) values (4.0, 1, 1);
insert into grades (value, course_id, student_id) values (2.5, 2, 1);
insert into grades (value, course_id, student_id) values (3.0, 3, 1);
insert into grades (value, course_id, student_id) values (3.0, 1, 2);
insert into grades (value, course_id, student_id) values (3.5, 2, 2);
insert into grades (value, course_id, student_id) values (3.5, 3, 3);
insert into grades (value, course_id, student_id) values (2.5, 4, 3);
insert into grades (value, course_id, student_id) values (3.0, 3, 4);
insert into grades (value, course_id, student_id) values (2.0, 4, 4);
Keep in mind that an idea here is that there would be far too many courses to conceivably have a sparse-style column per course if we were denormalizing a list of students. A student can also have taken courses at several of the institutions despite where they're enrolled now.
Solr Schema
The data above will be transformed into the following Solr schema:
<fields> <field name="id" type="int" indexed="true" stored="true" required="true"/> <field name="first_name" type="string" indexed="true" stored="true"/> <field name="last_name" type="string" indexed="true" stored="true"/> <dynamicField name="grade_*" require="false" type="float"/> </fields>
DIH Configuration
In order to facilitate the transformation of the data into the schema defined above I'll employ the following DIH configuration:
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/school"
user="YOUR_USER"
password="YOUR_PASSWORD"/>
<script>
<![CDATA[
function pivotGrades(row) {
var courseNumber = row.get("course_number");
var gradeValue = row.get("value");
var fieldName = "grade_" + courseNumber;
row.put(fieldName, gradeValue);
return row;
}
]]>
</script>
<document name="studentGrades">
<entity name="student" query="
SELECT id, first_name, last_name
FROM students
">
<field column="id" name="id"/>
<field column="first_name" name="first_name"/>
<field column="last_name" name="last_name"/>
<entity name="grade" query="
SELECT course_number, value
FROM grades
INNER JOIN courses
ON grades.course_id = courses.id
WHERE grades.student_id = ${student.id}
" transformer="script:pivotGrades">
</entity>
</entity>
</document>
</dataConfig>
See the script tag? That's where I've defined a pivotGrades javascript function to turn the data from grade sub-entity on its side into dynamicFields. In the real world you might expect to see some more intense text manipulation here to warrant the ScriptTransformation I s'pect.
Querying
All the work I've done above was done specifically so I can easily and concisely sort students by their grades in specific courses. Here's the money:
http://localhost:8080/solr/students/select/?q=*:*&version=2.2&sort=grade_CS1541%20desc
Resulting in:
<response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="sort">grade_CS1541 desc</str> <str name="indent">on</str> <str name="q">*:*</str> <str name="version">2.2</str> </lst> </lst> <result name="response" numFound="4" start="0"> <doc> <str name="first_name">Bill</str> <float name="grade_CS1501">3.0</float> <float name="grade_CS1541">3.5</float> <int name="id">2</int> <str name="last_name">Miller</str> </doc> <doc> <str name="first_name">John</str> <float name="grade_CMPSC465">3.0</float> <float name="grade_CS1541">2.5</float> <int name="id">1</int> <str name="last_name">Doe</str> </doc> <doc> <str name="first_name">Jane</str> <float name="grade_CMPSC465">3.5</float> <float name="grade_CMPSC473">2.5</float> <int name="id">3</int> <str name="last_name">Dow</str> </doc> <doc> <str name="first_name">Dennis</str> <float name="grade_CMPSC465">3.0</float> <float name="grade_CMPSC473">2.0</float> <int name="id">4</int> <str name="last_name">Itchison</str> </doc> </result> </response>

One of the strength's of Solr is
it's ease of consumption by other platforms due to its REST API and response
writers which include XML, JSON, native Ruby and native Python code.
If you're trying to consume a Solr service from .Net you could easily use a WebClient and parse the results with .Net's System.Xml namespace and perhaps even build an object wrapper on top of it. Luckily that work's already been done with the solrnet library.
In this post I'll outline the fundamentals of solrnet usage.
Prerequisites
This article assumes you have a .Net development environment such as Visual Studio and a functional Solr install in servlet container. I'll also assume that you understand how to configure Solr's schema. If that's not the case please consult the official Solr wiki.
Sample Schema
For demonstrative purposes I'll assume the following field declarations in schema.xml.
<fields> <field name="id" type="int" indexed="true" stored="true" required="true"/> <field name="title" type="text" indexed="true" stored="true" required="true"/> <field name="content" type="text" indexed="true" stored="true" required="true"/> <field name="tag" type="string" indexed="true" stored="true" multiValued="true"/> <field name="text" type="text" indexed="true" stored="false" multiValued="true"/> </fields> <copyField source="title" dest="text"/> <copyField source="content" dest="text"/> <defaultSearchField>text</defaultSearchField> <uniqueKey>id</uniqueKey>
Project Setup
With the basic system in place now it's time to download solrnet from its project site on Google Code then add references to SolrNet.dll and Microsoft.Practices.ServiceLocation.dll (included with SolrNet) to a project.
Model
Now let's write some bloody code! Consider the following class declaration which defines the document's we'll be working with. In this case it's an article, much like a blog post, with a key, title, textual content and a list of tags.
Notice the SolrUniqueKey and SolrField attributes decorating the properties. That facilitates the mapping of the properties to field's in Solr.
using System;
using System.Collections.Generic;
using SolrNet;
using SolrNet.Attributes;
using SolrNet.Commands.Parameters;
using Microsoft.Practices.ServiceLocation;
class Article {
[SolrUniqueKey("id")]
public int ID { get; set; }
[SolrField("title")]
public string Title { get; set; }
[SolrField("content")]
public string Content { get; set; }
[SolrField("tag")]
public List<String> Tags { get; set; }
}
Writing Data
Model defined we can now connect to Solr and save some articles. The following code locates our Solr instance (running locally on port 8080 in my case), creates some documents and commits them to the index.
// find the service
Startup.Init<Article>("http://localhost:8080/solr");
ISolrOperations<Article> solr =
ServiceLocator.Current.GetInstance<ISolrOperations<Article>>();
// make some articles
solr.Add(new Article()
{
ID = 1,
Title = "my laptop",
Content = "my laptop is a portable power station",
Tags = new List<string>() {
"laptop",
"computer",
"device"
}
});
solr.Add(new Article()
{
ID = 2,
Title = "my iphone",
Content = "my iphone consumes power",
Tags = new List<string>() {
"phone",
"apple",
"device"
}
});
solr.Add(new Article()
{
ID = 3,
Title = "your blackberry",
Content = "your blackberry has an alt key",
Tags = new List<string>() {
"phone",
"rim",
"device"
}
});
// commit to the index
solr.Commit();
Basic Querying
Of course the primary purpose of Solr is performing search queries. Consider the following examples which does a general full-text search on the word "power" and a tag search for "phone":
// fulltext "power" search
Console.WriteLine("POWER ARTICLES:");
ISolrQueryResults<Article> powerArticles = solr.Query(new SolrQuery("power"));
foreach (Article article in powerArticles) {
Console.WriteLine(string.Format("{0}: {1}", article.ID, article.Title));
}
Console.WriteLine();
// tag search for "phone"
Console.WriteLine("PHONE TAGGED ARTICLES:");
ISolrQueryResults<Article> phoneTaggedArticles = solr.Query(new SolrQuery("tag:phone"));
foreach (Article article in phoneTaggedArticles)
{
Console.WriteLine(string.Format("{0}: {1}", article.ID, article.Title));
}
which produces the following output
POWER ARTICLES: 1: my laptop 2: my iphone PHONE TAGGED ARTICLES: 2: my iphone 3: your blackberry
Faceting
One of my personal favorite features of Solr is faceting which enables aggregate counts to be returned along with query results. Faceting is well supported in solrnet.
The following example displays counts per tag of articles matching the "device" tag:
Console.WriteLine("DEVICE TAGGED ARTICLES:");
ISolrQueryResults<Article> articles = solr.Query(new SolrQuery("tag:device"),
new QueryOptions() {
Facet = new FacetParameters
{
// ask solr for facets
Queries = new[] { new SolrFacetFieldQuery("tag") }
}
});
foreach (Article article in articles)
{
Console.WriteLine(string.Format("{0}: {1}", article.ID, article.Title));
}
Console.WriteLine("\nTAG COUNTS:");
foreach (var facet in articles.FacetFields["tag"])
{
Console.WriteLine("{0}: {1}", facet.Key, facet.Value);
}
with the following output:
DEVICE TAGGED ARTICLES: 1: my laptop 2: my iphone 3: your blackberry TAG COUNTS: device: 3 phone: 2 apple: 1 computer: 1 laptop: 1 rim: 1
Wrapping up
Solrnet makes consumption of a Solr service easy, but I've only covered the basic concepts here. Other features of Solr such as spell checking and match highlighting are also handled. The solrnet wiki will tell you more.

As a professional DBA I'm always interested in monitoring systems. I have to
know what's going on with my systems. Even in a world with automatic scaling
strategies and automatic tuning humans have to be in the loop. Let's face it,
sometimes automatic things don't work. Worse yet they sometimes automatically
do what you said, not what you meant:)
As I've been moving more of my read-only data out of traditional relational databases and into highly scalable, simpler document-oriented systems like Solr I've been keeping an eye out for monitoring tools. Specially for Solr I found LucidGaze by Lucid Imagination, a Lucene/Solr specialty shop.
What is LucidGaze?
LucidGaze is essentially the combination of a Solr request handler and a web application that sits in your servlet container. The request handler gathers and stores information about other handlers in the Solr instance and the web app provides the administrator with visualization capabilities.
It's downloadable free of charge from Lucid's website.
Installation
The readme enclosed with LucidGaze does a fine job of getting you up and running so I won't provide step-by-step instructions here. Suffice it to say that it's just copying some jar's into your Solr install and servlet container, then configuring the request handler in solrconfig.xml.
Configuration
After a service restart visit the gaze web application with a url like http://localhost:8080/gaze/index.html and you can configure it to provide visualization for the Solr instance you deployed LucidGaze into by entering its URL and selecting a time retention.


You can then select which handlers in the Solr instance you want to monitor.

Then sit back, relax and let LucidGaze collect metrics.
Visualization
With the configuration out of the way and some metrics collected you can view graphs of the activity in the web application.
- Overview - the main entry point is an overview of all selected handlers with
graphs in requests/sec and milliseconds/request.

- Drilldown - after clicking on a graph a detail graph is displayed that allows
you to adjust the time dimension.

A few information screens are also provided.
-
System Info - a comprehensive system info dialog is available

- Index Info - the index info dialog displays statistics about the index and its
schema

Conclusion
As I lean more and more on Solr it's becoming increasingly important that I understand the load on a given system at a moments notice. LucidGaze certainly seems to help me along the way to that goal.
Note that Lucid Imagination also has a version for LucidGaze for plain-old Lucene, and a certified Solr distribution named LucidWorks which contains LucidGaze.

* Edit 6/4/2010: Alpha 2 is now available for download at http://www.haiku-os.org/
Back in the 90's and early 2000's I played around with BeOS, an alternative
operating system developed by Be Inc. The intention of BeOS was to be a
desktop operating system that specialized in multimedia and competed with
Microsoft Windows and Mac OS. Be Inc. even attempted unsuccessfully to sell
out to Apple as the replacement for the classic Mac OS.
The proper BeOS is now long defunct but the effort is continued by way of an operating system called Haiku which is an open source continuation of BeOS.
I've been meaning to make some time to play with Haiku (which is currently in
alpha) for a few months now, but family, other projects and work have gotten in
the way. Thanks to some snow... Well, a whole lot of snow, I've had
a chance to get my feet wet with it. I'd now like to
provide some resources for those who are interested in doing the same, and I
definitely suggest that you do if you have an interest in alternative operating
systems.
What is Haiku?
As I stated above Haiku is an open source continuation of the BeOS effort, currently in the alpha phase. Right now only the x86 architecture is supported but future x64 support is likely.
One of the core design principals behind BeOS and Haiku is to keep the system simple. The belief of the designers is that operating systems like unix's and windows have had layer after layer added on over time as new needs arose. This layering resulted in inconsistency and complexity. BeOS and Haiku avoided this complexity by starting from scratch with modern needs in mind.
While it's not a unix (and sort of takes exception to unix) it is POSIX compliant, has a Bash shell and has ports of many typical open source unix-y programs. If you're familiar with unix you'll feel at home on BeOS/Haiku. If you're not familiar with unix it should still be easy enough to operate due to Haiku's user-friendly GUI.

Installation
Installation is pretty strait-forward and entirely GUI based. For most people it will be something like:
- Select your destination disk
- Click "Setup partitions..." and make a BeOS partition
- Click "Install" and watch status bar eagerly
- Click on "Write Boot Sector to <Disk Name>" button

Software
No matter how stable, fast, or easy to use an operating system is it's only as useful as the software it runs. Luckily plenty of apps exist or have been ported to BeOS. Developers are also porting new apps to Haiku all the time.
Right out of the box you'll notice familiar open source applications are included such as the nano text editor and the gcc C compiler. You'll also have the necessities like a paint program (WonderBrush), media player (MediaPlayer), PDF viewer (BePDF), web browser (BeZilla), and others.

Thus far I've relied on three main sites for additional software for Haiku:
- BeBits - A general BeOS software repository. Some apps aren't compatible with Haiku specifically but it's still a great resource due to its variety.
- Haiku Ports - A repository of open source software that's been ported to Haiku.
- HaikuWare - A vast Haiku-specific software site.
In general there's a little bit of something for everyone if you do some looking around: productivity, multimedia, software development and even games like Wolfenstein 3d.

Hardware Support
It's hard for me to speak with any authority about supported hardware but drivers do indeed seem to be supported for most popular hardware like good video cards from NVIDIA and ATI. BeBits and HaikuWare are great resources for drivers for audio, video and other devices but I suspect there will be gaps for more obscure devices.
Development
Most programmers will be pleased to know that Haiku ships with such necessities as Python and gcc. A myriad of other languages like BASIC, Ruby and Eiffel are also available from the sites outlined above as well.
The most fundamental way to write Haiku applications, however, is to use the
actual BeOS API from C++. While I'm not all that familiar with the API myself I managed
to rearrange the HelloWorld sample from the official BeOS R5 sample code into a
concise example here. It simply displays a new window with the classic
"Hello, World!" text.
Note that the code is arranged into a single unit for ease of posting. It's by no means intended to exhibit proper style.
#include <Application.h>
#include <Window.h>
#include <StringView.h>
class HelloWorldView : public BStringView {
public:
HelloWorldView(BRect rect, const char *name, const char*text):
BStringView(rect, name, text) {
SetFont(be_bold_font);
SetFontSize(24);
}
};
class HelloWorldWin : public BWindow {
public:
HelloWorldWin(BRect frame) :
BWindow(frame, "Hello", B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE) {
HelloWorldView *view;
BRect rect(Bounds());
view = new HelloWorldView(rect, "HelloWorldView", "Hello, World!");
AddChild(view);
}
virtual bool QuitRequested() {
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
};
class HelloWorldApp: public BApplication {
public:
HelloWorldApp() :
BApplication("application/x-vnd.Be-HelloWorld") {
HelloWorldWin *wnd;
BRect rect;
rect.Set(100, 80, 260, 120);
wnd = new HelloWorldWin(rect);
wnd->Show();
}
};
int main(int argc, char **argv) {
HelloWorldApp app;
app.Run();
return 0;
}
Assuming the code was placed in a source file named hello_world.cpp it could be compiled with:
~> g++ -lbe hello_world.cpp
Conclusion
Haiku is only in alpha. Pretty darn young. Be forewarned that any software beyond what's bundled may require some effort to get to work. Still, it's easy enough to use for a non-hacker, but powerful enough for a hacker.
It seems to support that which most people need to do and good bit of what they want to do. It's definitely worth a look.

Digg it
Reddit
Delicous
Facebook










