The Blog of Maxim Porges

Posts Tagged ‘Coding’

  • Using AppleScript to Position iChat Windows

    We use instant messaging quite a bit at Highwinds. I bounce back and forth between using my laptop by itself, and using it with a secondary 22″ display. Regardless of how I’m using my laptop, I like my iChat windows to fill the laptop screen with about a 3-pixel gap between each of them. This means that when I’m on my laptop alone, its screen gets filled when I Apple-Tab to iChat, and when I’m on a two-monitor setup, the larger attached monitor display is free of chat windows and they are all present on my laptop screen so I can work while watching for chats.

    My AIM and GMail buddy lists are about the same length, so I like to stack them on top of each other with half of the screen height given to each. My Highwinds buddy list is the longest, so that gets a full column to itself to the right of my AIM/GMail lists. Finally, I have my chat window occupying the rest of the right-hand side of the display. You can see this in the image below (some screen names have been obscured to protect the innocent).

    My iChat Layout

    Unfortunately, Apple hasn’t programmed OS X to remember the position of windows between laptop-only and display-attached configurations, which means I always have to manually move my chat windows back to the second display after I reconnect it to my laptop. This is a pain in the ass. I finally got a few minutes to write an AppleScript to do this for me automatically, presented below.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    -- Get display area
    tell application "Finder"
    	set displayAreaDimensions to bounds of window of desktop
    	set widthOfDisplayArea to item 3 of displayAreaDimensions
    	set heightOfDisplayArea to item 4 of displayAreaDimensions
    end tell
     
    tell application "System Events" to tell process "Dock"
    	set dockDimensions to size in list 1
    	set heightOfDock to item 2 of dockDimensions
    end tell
     
    -- Set up desired coordinates when running iChat on the laptop monitor at 1440x900
    set maximumChatWindowHeight to (heightOfDisplayArea - heightOfDock)
    set chatWindowWidth to 275
    set padding to 3
    set heightOfMenuBar to 22
    set laptopPhysicalDisplayWidth to 1440
     
    set aimCoordinates to [0, 0, chatWindowWidth, (maximumChatWindowHeight / 2) - heightOfMenuBar]
    set gmailCoordinates to [0, (item 4 of aimCoordinates) + (heightOfMenuBar + padding), chatWindowWidth, maximumChatWindowHeight]
    set highwindsCoordinates to [chatWindowWidth + padding, 0, (chatWindowWidth * 2) + padding, maximumChatWindowHeight]
    set chatWindowCoordinates to [(chatWindowWidth * 2) + (padding * 2), 0, laptopPhysicalDisplayWidth, maximumChatWindowHeight]
     
    -- Shift everything over by laptop display width if using a second monitor
    if widthOfDisplayArea is greater than laptopPhysicalDisplayWidth then
    	set widthOfSecondaryDisplay to (widthOfDisplayArea - laptopPhysicalDisplayWidth)
    	repeat with currentDimensions in [aimCoordinates, gmailCoordinates, highwindsCoordinates, chatWindowCoordinates]
    		repeat with itemPosition in [1, 3]
    			set item itemPosition of currentDimensions to ((item itemPosition of currentDimensions) + widthOfSecondaryDisplay)
    		end repeat
    	end repeat
    end if
     
    -- Position chat windows
    tell application "iChat"
    	set bounds of window "AIM Buddy List" to aimCoordinates
    	set bounds of window "myGoogleTalkAddress@gmail.com" to gmailCoordinates
    	set bounds of window "myWorkEmailAddress@highwinds.com" to highwindsCoordinates
    	set bounds of windows whose name contains "Chats" to chatWindowCoordinates
    end tell

    The script is pretty simple. It grabs the screen and dock dimensions, and sets up some global variables. Then, for each of my buddy lists (AIM, GMail, and Highwinds) it sets up 4-coordinate position arrays describing the [top left x, top left y, bottom right x, bottom right y] coordinates that I want each window to end up in. Next, it checks the total display area: if the area is greater than the width of my physical laptop display, it bumps all the X coordinates over by the width of the secondary display so that the windows end up on my laptop display (since I position my laptop to the right of my secondary display). Finally, it tells iChat to position the windows, referencing each by their title bar. I group all my chats in to a single window, so the title of this window is something like “18 Chats”; as a result, I use a query-like expression to reference this window’s title.

    Rather than dynamically setting the position of your chat windows, if you would prefer to move your chat windows to the positions that you want them in and have your Mac tell you what the coordinates are, you can use the script below. You can then hard-code these coordinates in to the coordinate arrays in the script above.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    tell application "iChat"
    	activate
    	set allChatWindows to every window
    	repeat with currentWindow in allChatWindows
    		set windowBounds to the bounds of currentWindow
    		set allBounds to ""
    		repeat with bound in windowBounds
    			set allBounds to (allBounds & bound & ",")
    		end repeat
    		display dialog (name of currentWindow & ": " & allBounds)
    	end repeat
    end tell

    2010.01.25 / 2 responses / Category: Uncategorized

  • An Objective-C Tutorial for Enterprise Java Programmers

    As a programmer, the lingua franca for computers and I is mainly Java. And although I have no real work-related purpose for it, I’ve always had a hankering to learn Objective-C and OS X development.

    And so, over the years, I’ve acquired a handful of really nice books on Objective-C and OS X programming that generous relatives have bought for me as gifts from my Amazon wish list, including Aaron Hillegass’s Cocoa Programming for Mac OS X and Beginning Mac OS X Programming from Wiley. But after a handful of evening coding sessions, I’ve never been able to stick with it long enough to learn it, and every time I return to an old project I find that I’ve forgotten most of what I learned and have to start over at the early chapters again.

    Last night, I finally figured out why this is the case when I decided to give OS X development another try. All the books I have dive in and say: “Let’s build a program with a GUI!” And then I’m bouncing around between Xcode and Interface Builder, and I’m doing drag-and-drop UI building, and I’m hooking up selectors to class methods, and it’s totally alien from anything I’ve ever done before.

    The reason this is so alien to me is that I’m an enterprise Java programmer with years of experience writing web and desktop apps through code, with the IDE as a participant rather than the full-blown means. The last time I used a drag-and-drop editor to build a GUI was when I was forced to take a VB6 class in college; even in my programming salad days, I thought that a “program that builds a program” was way too far from the metal. I’ve got a solid foundation in ground-up MVC principles, and I never, ever start building an application GUI-first nor use drag-and-drop GUI builders.

    When building something in Java, what I do is code the core business logic of the app, write unit tests, and then hook the GUI in to it last once I know everything at the core is working perfectly. If I could just apply this pattern to development of an Objective-C project, I knew I would have a chance of actually retaining what I had learned. I know that the way things are done with OS X is to use Interface Builder and hook up the GUI to the classes visually (and that this is one of the things that makes it a rapid development environment), but for me it was just the wrong place to start.

    So, I decided to try building a test-only GUI-less app last night, and I had some success. I’d like to share what I did with other Java developers in case it can help them too. This won’t be a tutorial as much as a post with a bunch of links to other tutorials that helped me accomplish my goal along with notes about using Objective-C and Xcode that were helpful to somebody familiar with Eclipse. If you like, you can download the project that I put together for reference.

    Getting Started

    I’ll assume that if you are reading this, you (a) have a Mac and (b) have installed Xcode. If not, go and do these things now. Go ahead, I’ll wait.

    As I usually advise programmers learning JUnit to build the world’s simplest calculator application, I decided to apply this same principle to what I was doing. So that’s what I’ll be telling you about; riveting, I know…

    Making Xcode Livable

    Having worked in Eclipse so long, I’m used to having code completion on by default, all my editing happening in a single window, strong support for custom code formatting, and many other things that just seem like good plain common sense.

    Xcode in its default state appears to have none of this, and is really frustrating to use when you first dive in if you are familiar with Eclipse. Have no fear, though – these features are mostly there and just need to be turned on. before you do anything with Xcode, I suggest that you open the preference pane and set up the following options. Note that I am using Xcode 3.0 on Leopard so you may see the options under different headings depending on the version you are using.

    General Tab

    • “Layout”: set this to “All-In-One” to prevent tons of new windows from opening whenever you do anything at all.
    • Check “Open counterparts in same editor” to prevent Apple-Option-Up (used to switch between header and implementation files) from causing the files to open in a new window.
    • Check “Automatically open/close attached editor” to cause the in-window editor to be used when you select code files.
    • Check “Automatically clear log” to clear out the log between runs, a la Eclipse.

    Code Sense Tab
    For some reason, code sense is not on by default from what I could see, which just seems plain silly to me. The options for turning it on in this tab are self-explanatory .

    Debugging Tab
    Launching an app in debug mode doesn’t show the debug “perspective” in Xcode by default. I changed the “On Start” option to “Show Console & Debugger” to make this happen, since I am used to switching to debug mode in Eclipse when I launch an app to see what it’s doing. Press Apple-0 in Xcode to switch back to the project “perspective” after running your app.

    SCM
    Setting up a source control repo is totally painless, and Xcode has a built-in SCM browser that’s as nice as anything I’ve used elsewhere. I got it hooked up to my SVN repo running on my old G4 tower in about ten seconds using svn+ssh.

    Unit Testing in Objective-C

    In Java, I always use JUnit and its associated set of libraries (such as JMock). There’s a framework for Objective-C called OCUnit which is basically identical to JUnit in purpose and operation, and an associated mocking framework called OCMock. Apparently OCUnit is such a standard that Apple decided to include it in Xcode 3.x, so unless you are developing in Xcode 2.x or lower you don’t need to download and compile OCUnit yourself.

    To get a basic Xcode project set up with unit testing, I found this tutorial on the ADC site to be the easiest to follow. There are a few gotchas.

    1. If you are using an older version of Xcode 3.x like I am and the ADC site is being retarded and not letting you download a newer non-Snow Leopard version of Xcode, then the panels are not as nicely broken down as the screenshots in the tutorial. It’s very easy to accidentally pick the C++ Unit Test Bundle instead of the Cocoa Unit Test Bundle. If your project compiles fine but you get linking errors during your build, you picked the wrong framework. You’ll also be able to tell this by looking in the Info window for the Unit Tests target (select the target, right click, and select Get Info). Under the Build tab, if the Linking => Other Linker Flags section shows “-framework Carbon -framework SenTestingKit” instead of “-framework Cocoa -framework SenTestingKit”, you selected the wrong thing – you need the Cocoa version for a Cocoa app.
    2. The way that OCUnit works, it links in to your main application as a dependency during building. So, you’ll create a regular GUI app, create a unit testing target with a dependency on this app, and then when you build the unit testing target it fires up a unit test wrapper during the build and exercises your code; the build will simply fail if any tests fail. The nice thing about this is that your test errors appear as build errors in Xcode, which lets you see build error bubbles adjacent to the broken assertions (in other words, no custom OCUnit runner plugin is needed in Xcode like the JUnit plugin is needed in Eclipse). The key takeaway here is that you want to make sure that your Cocoa GUI app fires up in main.m (i.e. the default “return NSApplicationMain(argc, (const char **) argv);” code is present); if not, then the OCUnit hooks can’t work their magic.
    3. Each class implementation file (i.e. .m file) in an Xcode project can be built for one or more targets. You choose the target for your classes as you create them using the “New File…” wizard, but you can verify and/or change your build targets by right-clicking the .m file and selecting “Get Info” and looking in the “targets” tab. Like with JUnit, you don’t want your tests ending up in your main application, so make sure your app code is aimed at the main application target in your project, and your test code is pointed to your unit testing target.

    Besides this, OCUnit is very similar to JUnit with the convention for test method names to begin with “test…”, setUp() and tearDown() methods, and automatic introspection of the unit test class to determine the tests to run. Assertions are implemented as macros (which are kind of like Java’s static imports from what I can see).

    Writing Some Objective-C

    I’m told Objective-C is like SmallTalk, but having never learned SmallTalk I can’t tell you if this is true or not. In any event, it’s a piece of cake to learn for anybody who has a basic understanding of object-oriented development and C/C++. I’ve forgotten a lot of the C/C++ I learned in college, and haven’t refreshed on method overloading or language specifics yet since my primary goal last night was to get a unit testable project up and running, so forgive the basic-ness of the code presented below, but I wanted to share what I wrote so that people familiar with Java and JUnit can get the idea.

    I found a few useful tutorials on the language to get me going, in addition to referring to my books for sample code. Tristan O’Tierney has a nice language overview on his blog.

    Here’s the awful Objective-C code for my calculator app.

    Calculator.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #import <Cocoa/Cocoa.h>
     
    @interface Calculator : NSObject
    {
     
    }
     
    - (int) addTwoNumbers: (int) first secondNumber:(int) second;
    - (float) addTwoDecimals: (float) first plus:(float) second;
     
    @end

    Calculator.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    #import "Calculator.h"
     
    @implementation Calculator
     
    - (int) addTwoNumbers: (int) first secondNumber:(int) second
    {
      return (first + second);
    }
     
    - (float) addTwoDecimals: (float) first plus:(float) second
    {
      return (first + second);
    }
     
    @end

    CalculatorTest.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    #import <SenTestingKit/SenTestingKit.h>
    #import "Calculator.h"
     
    @interface CalculatorTest : SenTestCase
    {
      // it's standard in Objective-C to declare class
      // members in the header file; this will be our fixture
      Calculator *calculator;
    }
     
    - (void) testAddTwoNumbers;
    - (void) testAddTwoDecimals;
     
    @end

    CalculatorTest.m

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    #import "CalculatorTest.h"
     
    @implementation CalculatorTest
     
    - (void) setUp
    {
      // I'm using Objective-C 2.0 which has built-in garbage collection
      // so I didn't use [[Calculator alloc] init] or use autorelease pools;
      // not sure if this is the right way to do this yet but I saw it in a
      // tutorial
      calculator = [Calculator new];
    }
     
    - (void) tearDown
    {
      // This resets the fixture reference for each test. Again, this
      // was recommended so I'm just towing the line
      calculator = nil;
    }
     
    - (void) testAddTwoNumbers
    {
      // I wanted to see where log output for tests goes; more on this later
      NSLog(@"Something in my test...");
      int result = [calculator addTwoNumbers:3 secondNumber:6];
     
      // This is how SenTest rolls for assertions... ugh. See my update
      // at the end of this blog post for a way to get JUnit-style
      // assertions with Hamcrest if you prefer them
      STAssertEquals(9, result, @"Expected 9, got %d", result);
    }
     
    - (void) testAddTwoDecimals
    {
      float result = [calculator addTwoDecimals:10.1 plus:1.2];
      STAssertEquals(11.3f, result, @"Expected 11.3, got %f", result);
    }
     
    @end

    Getting Output

    Any output from print statements in your main app code will show up in the console in Xcode, but output in the test classes themselves does not. However, everything you NSLog shows up in the OS X Console, so if you really need to print something in your unit test and see it come out as output, open up the Console application. There is a little lag since Console polls its logs. There might be a way to get the output of the unit test inside Xcode but I couldn’t find it.

    Next Steps

    Now that I have all that working, for my next trick I want to do something else that is familiar to me: talk to a web service. Apple has a few tutorials on their web service APIs as well as their tree-based XML parsing. I haven’t gone through these yet, but they look pretty thorough and have tutorials. They also provide a sample Java web service app (linked to in the web service document) which will echo back whatever is sent to it, so you can use this to test out your Cocoa calls to SOAP.

    I hope you find this useful. I’m looking forward to corrections/tips from anybody who really knows what they are doing with this stuff, so please add them in the comments.

    UPDATE 2010.02.06:The “STAssertEquals”-style syntax for assertions in SenTest is really annoying if you are used to JUnit-style assertXXX()-style assertions. I just found a blog post by the guys at CarbonFive where they describe how to set up Hamcrest matches for Obj-C. Check it out! The source for the Obj-C implementation of the Hamcrest project has an Xcode build that works flawlessly.

    2010.01.23 / 12 responses / Category: Uncategorized

  • Performing SQL Validation (a.k.a. “Data Dips”) with RIATest

    We started using RIATest at Highwinds to automate our Flex functional testing. For those of you who are unfamiliar, RIATest is a great Flex-only alternative to products like HP’s QuickTest Pro, allowing you to fully automate your Flex functional testing either from the RIATest IDE itself, or via the command line. While QuickTest Pro can be used to automate a wide variety of GUI-based apps, it costs about five times as much as RIATest, so if you are only testing Flex apps RIATest is a great low-cost alternative.

    Something else that QuickTest Pro lets you do that RIATest does not is perform “data dips” or, to put it in layman’s terms, query a database during functional testing. This can be useful for validating non-visual system state.

    For example, let’s say that you have an application that allows you to change user information, and that the requirements dictate that whenever the user information is changed, a last modified date on the user’s record should be updated. If the last modified date is not visible as a label within the Flex app, RIATest can’t validate that the last modified date has changed, since it can only validate the state of Flex components. In this scenario, you’d typically want to

    (a) execute a functional test to change a user’s info,
    (b) validate the changes to the UI after the user’s information is saved and loaded again for viewing, and
    (c) check the state of the database to validate that the last modified date has indeed been updated.

    However, since RIATest doesn’t offer data dip functionality, step (c) would be impossible without manual intervention from a QA tester. This is where riatest-integrator comes in.

    Thankfully, the RIATest developers put a special object in RIATest called Process. Process allows you to execute an external process, and interact with its input, output, and error streams. Once I discovered this, I decided to write a little Java library that would make it easy for me to fire up a Java process from the command line, hook RIATest to its input and output streams, and write input from RIATest to it. The process would then pass the input to some kind of integration inside of the Java process, and return output from the integration for inspection by RIATest. This turned out to be pretty easy as expected, and I published the library to Google Code under the name riatest-integrator.

    Currently, there is a download available on the Google Code site that lets you query MySQL databases right out of the box. There is a sample RIATest script on the home page of the project showing how you can call it from RIATest and validate output coming back from the database. It’s a really simple implementation, but if people are interested in it, I’ll add more features and functions. The API is also really straightforward, so any Java developer with even the most modest skills should be able to customize it to their needs.

    The API in the library is not limited to SQL; anything that Java can talk to can be hooked in to. We have some proprietary back-end servers at Highwinds that speak NNTP, so we could easily write an NNTP integration that allows us to have RIATest query the state of our NNTP message groups after actions are taken in our Flex apps.

    If you are a RIATest user, please take a look at the project, and share your feedback either here on my blog, or as feature/bug requests in the project’s issue tracker.

    2010.01.19 / 4 responses / Category: Uncategorized

  • Configuring Tomcat SSL Client/Server Authentication

    Setting up Tomcat to provide self-signed SSL certificates allowing secure client/server communication is well-documented and relatively easy to set up. It’s almost as easy to set up a configuration where Tomcat requires the client to specify an SSL certificate as well, but sadly nowhere near as well-documented since this is a much less-common use case.

    It’s exactly this use case that we needed to put in to place with a secure internal system that we’re working on. To make it as hack-proof as possible, we’re requiring that both the client and the server know about each other and authenticate each other before beginning any communication. I found all the individual fragments of what I needed to get this set up online, but no single resource covered the entire process in detail.

    Since I spent the better part of the day today figuring out how to get this to work, I figured I would share the complete configuration with the world, including Tomcat config, keytool commands, and how to connect a secured client/server from both Java and Safari on Mac OS X. Hopefully this will save the next guy some time.

    Overview

    With traditional SSL, a server presents a certificate to a user agent (such as a web browser) to both

    (a) allow the user agent to validate the server’s identity, and
    (b) begin the process of establishing a secure connection handshake.

    In this configuration, the user agent is not required to authenticate itself, since it is only the server that may be suspect – you don’t want to send your credit card details to a rogue server, but any server (rogue or legitimate) will happily accept credit cards or other sensitive data from any client willing to submit them, so there’s no need to validate the clients as far as the server is concerned.

    In higher-security configurations, the server also requires the client to identify itself by providing its own certificate. Examples include cases where the server has access to sensitive data/capabilities that it doesn’t want to allow any client to access. To facilitate this, the server maintains a keystore containing copies of certificates issued to trusted clients to whom the server will allow access. If a client is unable to supply a certificate, or the certificate that they supply is not in the server’s keystore of trusted certificates, access to the server’s resources is denied.

    The Setup

    The server is configured so that it will present a certificate to clients when an SSL connection is requested. This is achieved by setting up a keystore and providing the location and credentials for the keystore to Tomcat.

    As part of this configuration, Tomcat is told to require clients to present their own certificates authenticating them for access to the server. This is achieved by generating client certificates, and installing copies of these certificates in to the same server keystore used for presenting server SSL (described in the previous paragraph).

    When a client connects to the server, it needs to present a certificate when challenged to do so. To find the certificate that it will provide to the server, the client references its own keystore containing a copy of its certificate. As described in the previous paragraph, a copy of the same client certificate is installed in the server’s keystore (the one with the list of trusted client certificates).

    Finally, if the server’s certificate is self-signed and could be considered untrustworthy, then the client’s keystore must contain a copy of the server’s certificate so that it knows that the server is trustworthy. To facilitate this, a copy of the server’s public SSL certificate is installed in the client keystore as well.

    Keystore and Certificate Generation With keytool

    Java provides a handy command-line tool called keytool that you can use to generate keystores. Each keystore has a private key within it which cannot be exported, so in order to allow the client to share a certificate with the server, keytool lets you export a public version of the private key as a certificate. Exactly why and how this works is beyond the scope of this blog post, so check out some info on how SSL works elsewhere.

    By following the instructions below, you will create two keystores: client.jks (for the client to use) and server.jks (for the server to use). In order to provide copies of the client’s certificate to the server (and vice versa), you will export public certificates based on the private keys. Finally, you will install the server’s public certificate in to the client’s keystore and vice versa, allowing both the client and server to properly authenticate and trust each other when a secure connection is established.

    Generate the Client and Server Keystores

    keytool -genkeypair -alias serverkey -keyalg RSA -dname "CN=Web Server,OU=Application Development,O=Highwinds,L=Winter Park,S=FL,C=US" -keypass password -keystore server.jks -storepass password
    keytool -genkeypair -alias clientkey -keyalg RSA -dname "CN=client,OU=Application Development,O=Highwinds,L=Winter Park,S=FL,C=US" -keypass password -storepass password -keystore client.jks

    Export the Client’s Public Certificate and Import it in to the Server’s Keystore

    keytool -exportcert -alias clientkey -file client-public.cer -keystore client.jks -storepass password
    keytool -importcert -keystore server.jks -alias clientcert -file client-public.cer -storepass password -noprompt
     
    # view the contents of the keystore (use -v for verbose output)
    keytool -list -keystore server.jks -storepass password

    Export the Server’s Public Certificate and Import it in to the Client’s Keystore

    keytool -exportcert -alias serverkey -file server-public.cer -keystore server.jks -storepass password
    keytool -importcert -keystore client.jks -alias servercert -file server-public.cer -storepass password -noprompt
     
    # view the contents of the keystore (use -v for verbose output)
    keytool -list -keystore client.jks -storepass password

    Configure Tomcat for SSL Using the Server Keystore
    Make the following addition to {tomcat.home}/conf/server.xml, substituting the entries for keystoreFile, keystorePass, truststoreFile, and truststorePass with the appropriate paths/passwords from your implementation. These paths will point to the keystores created earlier in this process.

    Note the clientAuth attribute – this is the attribute that causes Tomcat to require the client to provide a certificate; with this option, if no certificate is provided by the client then the connection is terminated by Tomcat immediately. If this is set to false, no client certificate is required or validated (useful for testing server-only SSL configuration). If clientAuth is set to want, client certificates are validated if presented to the server, but are not required.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    <Connector
       clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
       enableLookups="true" disableUploadTimeout="true"
       acceptCount="100" maxThreads="200"
       scheme="https" secure="true" SSLEnabled="true"
       keystoreFile="/Users/mporges/Desktop/tomcat-ssl/final/server.jks"
       keystoreType="JKS" keystorePass="password"
       truststoreFile="/Users/mporges/Desktop/tomcat-ssl/final/server.jks"
       truststoreType="JKS" truststorePass="password"
       SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2" sslProtocol="TLS"
    />

    You must restart Tomcat in order for this configuration change to take effect. Note that you must also restart Tomcat whenever you change the contents of the keystore; they are cached at launch and are not re-examined until the server process is bounced.

    Sample Client Application in Java

    The client application presented below uses Apache’s Commons HTTPClient library to establish a secure connection to the Tomcat server. Note the system properties defined in the static initializer; these properties tell the JVM where to find the trust store (telling it which self-signed server certificates it should trust) and the keystore (telling it where to find its own client certificates, which it will then present to the server when challenged). We happened to store both these items in the same keystore, but if you really wanted to you could split them up in to separate files.

    import java.io.IOException;
     
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpException;
    import org.apache.commons.httpclient.URI;
    import org.apache.commons.httpclient.methods.GetMethod;
     
     
    public class ClientConnectionTest
    {
       static
       {
          System.setProperty("javax.net.ssl.trustStore", "/Users/mporges/Desktop/tomcat-ssl/final/client.jks");
          System.setProperty("javax.net.ssl.trustStorePassword", "password");
          System.setProperty("javax.net.ssl.keyStore", "/Users/mporges/Desktop/tomcat-ssl/final/client.jks");
          System.setProperty("javax.net.ssl.keyStorePassword", "password");
       }
     
       /**
        * @param args
        * @throws IOException 
        * @throws HttpException 
        */
       public static void main(String[] args) throws HttpException, IOException
       {
          HttpClient client = new HttpClient();
          GetMethod method = new GetMethod();
          method.setURI(new URI("https://localhost:8443", false));
          client.executeMethod(method);
     
          System.out.println(method.getResponseBodyAsString());
       }
    }

    Configuring a Client Certificate in Safari on Mac OS X

    Typically, in a secure client/server setup such as the one we are creating, the client and server will both be application servers. However, nothing stops you from setting up your browser to be a secure client with its own certificate. This is an ultra-secure way to set up restricted access to a web site so that only certain known users can access the web site.

    Unfortunately, the creation and installation of the client certificates and the setup process for letting the browser know to send the certificate to the server are both operating system- and browser-dependent processes. The only one I have had success trying is Safari on Mac OS X, so I have included those instructions here. For instructions on setting up another browser (such as Firefox or Internet Explorer) on other operating systems, Google is your friend.

    How To Create and Install a Client Certificate in Safari on Mac OS X
    In order to connect to the secure server we created earlier from Safari in Mac OS X, a certificate must be created in the Keychain Access application and installed in the server’s keystore before connections will be accepted. This is achieved as follows.

    1. Open Keychain Access.
    2. In the menu bar, go to Keychain Access => Certificate Assistant => Create a Certificate…, which launches an assistant.
    3. Provide a name for the certificate (your own name is appropriate). Select “Self-Signed Root” for “Identity Type” and “SSL Client” for “Certificate Type.” At your option, you may select the “Let me override defaults” setting to specify items such as the key pair key size/algorithm (2048/RSA by default), Key Usage Extensions (only “Signature” by default), Extended Key Usage Extensions (only “SSL Client Authentication” by default), Basic Constraints Extension, Subject Alternate Name Extension, and keychain Location for Certificate (login by default).
    4. After completing the assistant, you will find a new certificate under My Certificates in Keychain Access (under Category in the lower left hand side of the window).
    5. To export the certificate, right click it and select “Export {certificate name}…” Choose a suitable location to save the certificate as a .cer file.
    6. In the command line, navigate to the location of the server.jks keystore created earlier, and enter the following command:
      keytool -importcert -keystore server.jks -alias safari-osx-cert -file {exported certificate file name}.cer -storepass password -noprompt
    7. Restart Tomcat if it is running so that it will pick up the new client certificate that you just installed.
    8. Open Safari and navigate to the location of the Tomcat server. If Tomcat is using a self-signed certificate, you will be prompted with a warning and will have to establish trust for the certificate (either permanently by checking the appropriate checkbox, or just for the life of the browser process by selecting “Continue”).
    9. You will then be challenged for a client certificate; accept the challenge. Safari should select the certificate you created, or alternatively it will prompt you to select a certificate; if so, select the certificate you created in this process. Once a certificate is selected you should not be challenged again for the life of the browser process.
    10. If Safari is unable to select the appropriate certificate automatically, you may need to set up an Identity Preference in Keychain Access. To do so, follow the instructions on Apple’s knowledge base.

    2009.11.18 / 18 responses / Category: Uncategorized

  • Calculating the Differences Between Consecutive Rows with SQL

    Just a quickie. I’m sure this is obvious to the seasoned SQL freaks out there, but it was a new solution for me.

    We were recently trying to figure out a simple query to generate a set of differences in values between sets of consecutive rows in a database table. Basically, the table is full of timestamp snapshots with associated values, and we need to calculate the differences between the values in each snapshot for a time period.

    The simple solution I came up with is to normalize the dates, and then use them as a join criteria with a virtual table and some simple date math. You treat the original unmodified table as one side of the join, and a virtual select of the same table with some date math applied to the normalized dates as the other side of the join. So, for tables with timestamps five seconds apart, you simply pull the date back by five seconds on the virtual table and join the dates together. You end up with a single row joining each row with its previous peer, and you can then do direct math within the row to calculate the differences in values.

    Here’s a simple MySQL script that demonstrates the technique, which will probably make more sense than my explanation.

    CREATE TABLE consecutiveDates (
      id INT NOT NULL AUTO_INCREMENT,
      valueDate TIMESTAMP NOT NULL,
      value NUMERIC(10) NOT NULL,
      PRIMARY KEY (id)
    )
     
    INSERT INTO consecutiveDates VALUES (NULL, TIMESTAMP('2009-08-01 10:00:00'), 10);
    INSERT INTO consecutiveDates VALUES (NULL, TIMESTAMP('2009-08-01 10:00:05'), 25);
    INSERT INTO consecutiveDates VALUES (NULL, TIMESTAMP('2009-08-01 10:00:10'), 50);
     
    SELECT    actual.*,
              virtual.*,
              IFNULL((virtual.virtualValue - actual.value), 0) AS 'difference'
    FROM      consecutiveDates actual
              LEFT OUTER JOIN (
                 SELECT   id AS 'virtualId',
                          valueDate AS 'actualVirtualDate',
                          value AS 'virtualValue',
                          TIMESTAMPADD(SECOND, -5, valueDate) AS 'adjustedVirtualDate'
                 FROM     consecutiveDates
              ) virtual ON virtual.adjustedVirtualDate = actual.valueDate

    If you have dates that don’t line up perfectly like my example, you can use basic date math/conversion to normalize the dates in each row in to a rounded representation (i.e. nearest five seconds, nearest minute, etc.). With basic SQL grouping, you can then easily smash together rows that are close enough to each other to be combined in to a single row and achieve the same effect as shown in the script.

    This technique is obviously not limited to dates; you can use a similar approach with virtual row IDs in MySQL. By creating an integer session variable representing a row ID, and then selecting/incrementing it with each row in the query, you can apply basic math to the virtual table’s select statement to offset the session variable by -1 and use that as the join criteria.

    2009.10.01 / 3 responses / Category: Uncategorized

  • Duct Tape, Astronauts, and Everything In Between

    Joel Spolsky recently blogged about what he calls a “duct-tape programmer.” The blog post made the rounds with a few people at the office after my boss brought it up at lunch yesterday.

    From what I read, Joel’s opinion is that it’s better to ship usable software than spend time engaging in architecture cosmology, which nobody with a moderate amount of experience and any sense would disagree with. However, Joel makes his point by drawing two totally different extremes and making some statements that completely conflict with both my experience and common sense.

    The first extreme is the “duct-tape programmer.” Joel lists a person of this description’s attributes as the following.
    - Not afraid to speak up when another programmer is pitching an overly-complicated solution.
    - Pragmatic.
    - Comfortable with a 50%-good solution that ships over a 99% solution that nobody uses.
    - Focuses on shipping as a top concern.
    - Avoids complicated coding and difficult frameworks/libraries/languages/techniques that are too hard for the human brain to handle.
    - Doesn’t give a shit what others think about them.
    - Spends little to no time writing unit tests.
    - Smart enough to do things like xor the “next” and “prev” pointers into a single DWORD (which makes you wonder how they are not smart enough to work with some of the languages/libraries/frameworks/techniques that are apparently so hard to grasp – but whatever).

    The second extreme is the “architecture astronaut.” Here’s the attribution for this person.
    - Likes over-complicated solutions too hard for the average programmer to understand.
    - Bullies other programmers in to using their frameworks/solutions by relying on the level of complication in code that only they understand as a barrier to objections.
    - Likes multiple inheritance.
    - Spends more time writing frameworks than shippable code.
    - Attends design pattern meetings.
    - Speaks at conferences, writes articles and books.

    I have a little perspective on this since (like most software engineers with a few years under their belt) I’ve both been and dealt with both personality extremes during my career. Both extremes are equally damaging to software products in different ways.

    Let’s start with the duct-tape guy. I’d say most of the attributes for this personality type are positive qualities; pragmatism, the self-confidence to disagree with bad ideas, a tendency for choosing the simpler approach, and a focus on making a shippable product. The quality of this guy that really bothers me is the lack of use/respect for unit testing, and the tone Joel takes with unit testing in general in his post. The argument seems to be that unit testing takes too long to do and doesn’t support rapid development and isn’t worth it.

    This is utter nonsense. I’ve been on projects where the only reason we were able to ship in a short timeframe is because we unit tested early and often, and were able to spot bugs within seconds of them being added to the codebase, which saved time we would have spent debugging broken code later in the product lifecycle.

    The thing with unit testing is that you have to be pragmatic with it as well. Looking to hit 100% coverage? You’re wasting your time. Only testing a handful of methods? You’re missing out on important stuff that will bite you in the ass later. Writing the core of an app with a GUI? If you wait to test until the GUI starts coming together, how do you know your code works? I’ve met nobody, and I mean truly nobody that is good enough to write code the first time and get it right every time. In the absence of unit tests, you find yourself manually testing everything from whatever presentation technology/transport you are using to ensure that it works, which is both slow and error-prone. The point is, choose a reasonable amount of coverage (60%-80% tends to be the sweet spot in my experience) and use it to your advantage.

    So what about the astronaut? Well, this guy suffers from two problems: he’s not a very good programmer, and he has an awful manager.

    Why isn’t he a good programmer? My experience has been that programmers go through four stages when learning a language or framework. As a novice, they barely understand what they are doing and mainly follow the advice of others. As they gain competence, they acquire understanding at a level that makes them productive. As an advanced user, they start pushing the limits of the technology and doing tricks with it, but their solutions are complicated and inelegant. As an expert, they learn to get the seemingly complicated stuff done in a manner that others can understand with little effort and put to use just as easily.

    Clearly, if the astronaut is making frameworks that are that complicated, they aren’t helping anybody. Using Spring as an example, the reason it’s such an excellent framework is that that it makes every part of itself so easy to use. The source code I have seen in Spring is terse and easy to follow, even though it deals with advanced techniques. This is the mark of expert programming worthy of respect.

    Why does his manager suck? Because they’re not keeping this guy on a tight enough leash to focus on what’s important, which is getting stuff done and writing maintainable code that anybody can walk in to and change. Instead, the astronaut is stroking his ego writing frameworks and libraries to “prove” how awesome he is at using the language. I can say this with confidence because I’ve been there and done it earlier in my career, and just like the astronaut, I pulled the wool over my manager’s eyes as well. Luckily, I came through the other side, but I’ve seen lots of people get stuck at this stage. They are easy to spot: they are the people who write code that only they understand – not because it’s good, but because it’s unreadable and unnecessarily complicated. A true expert with the language would certainly be able to slog through this spaghetti, but they’d spend most of that time wanting to punch the astronaut in the face for making it so hard on everybody else instead of making something elegant.

    That’s not all. There are some other things that simply don’t make sense or conflict with themselves in Joel’s post.

    If you write an app with no unit tests and ship it, unless you either (a) never have to change it again or (b) wrote a trivially tiny app, you are likely to find yourself having a really hard time refactoring/adding to it. After all, you’ve got no test suite to validate your changes and prove that you haven’t broken anything. The only way you could even say that you were confident the code still worked in the absence of a test suite is to be able to hold all the details about the app in your head (every branch, every scenario, etc.) which Joel already stated is too hard for the average programmer.

    If you are using a technology that is overcomplicated and/or is buggy (C++ on Windows, CORBA, COM, etc.), then use something else. Techniques like multiple inheritance aren’t so much difficult to grasp as they are generally acknowledged as a code smell in 90% of use cases. And to say that multi-threading is going to doom your project because it can be complicated is really kind of a stupid thing to say; there are some things that simply can’t be done effectively/performantly without multi-threading. Its use should be limited in scope accordingly and written by somebody who understands threading. I don’t think anybody writes multi-threaded code for the fun of it, except perhaps for the astronaut who we’ve already proven is an epic douche to begin with.

    There’s a general tone to the post that any time spent on creating utility library/framework code and/or researching elegant solutions is wasteful. This is a bad generalization. I once had to help save an app at the eleventh hour that one of the guys on my team had spent two months writing. It had failed an embarrassing number of QA drops due to input validation failures. Why? He hadn’t spent any time writing a basic framework for the validation concerns of the app, and every time he patched the bugs found in QA, something else got broken or acted inconsistently with other parts of the app. I sent everybody except me and my programmer home, spent an hour writing a simple validation framework, and we spent the night plugging it in to the app. It passed QA the next day. When I asked him why he hadn’t taken the time to do this in the first place, he said he was under pressure to get the app delivered and didn’t have time to implement a cleaner solution. It goes without saying that excessive architecture is wasteful and damaging, but no architecture at all is just as bad. Liek everything else, you need to be pragmatic and pick sensible battles.

    To summarize: no doubt, programmers should spend 90% of their time writing shippable code that is useful to end users, implemented in the simplest way, using the easiest thing that works. However, to unilaterally throw out unit testing and claim that any level of design work or framework implementation is a bad quality is a dangerous oversimplification that I fear many of the people following Joel’s blog may be inclined to interpret as good advice.

    2009.09.30 / no responses / Category: Uncategorized

  • JDK 1.7.0 on Snow Leopard

    I wanted to try out the DirectoryStream class in nio.2, but unfortunately it’s in Java’s 1.7.0 JDK and Apple hasn’t seen fit to get that out yet.

    The obvious solution is to use OpenJDK, and there are some great articles out there (here and here) about installing it on OS X versions earlier than Snow Leopard.

    I was able to get most of the way through the build process described, and hit a roadblock.

    Compiling /Users/mporges/bsd-port/hotspot/src/share/vm/runtime/arguments.cpp
    rm -f arguments.o
    g++ -D_ALLBSD_SOURCE -D_GNU_SOURCE -DIA32 -DPRODUCT -I. -I../generated/adfiles -I../generated/jvmtifiles -I/Users/mporges/bsd-port/hotspot/src/share/vm/asm -I/Users/mporges/bsd-port/hotspot/src/share/vm/c1 -I/Users/mporges/bsd-port/hotspot/src/share/vm/ci -I/Users/mporges/bsd-port/hotspot/src/share/vm/classfile -I/Users/mporges/bsd-port/hotspot/src/share/vm/code -I/Users/mporges/bsd-port/hotspot/src/share/vm/compiler -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation/g1 -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation/parallelScavenge -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation/parNew -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_implementation/shared -I/Users/mporges/bsd-port/hotspot/src/share/vm/gc_interface -I/Users/mporges/bsd-port/hotspot/src/share/vm/interpreter -I/Users/mporges/bsd-port/hotspot/src/share/vm/libadt -I/Users/mporges/bsd-port/hotspot/src/share/vm/memory -I/Users/mporges/bsd-port/hotspot/src/share/vm/oops -I/Users/mporges/bsd-port/hotspot/src/share/vm/opto -I/Users/mporges/bsd-port/hotspot/src/share/vm/prims -I/Users/mporges/bsd-port/hotspot/src/share/vm/runtime -I/Users/mporges/bsd-port/hotspot/src/share/vm/services -I/Users/mporges/bsd-port/hotspot/src/share/vm/utilities -I/Users/mporges/bsd-port/hotspot/src/cpu/x86/vm -I/Users/mporges/bsd-port/hotspot/src/os/bsd/vm -I/Users/mporges/bsd-port/hotspot/src/os_cpu/bsd_x86/vm -I../generated -DHOTSPOT_RELEASE_VERSION="\"16.0-b08\"" -DHOTSPOT_BUILD_TARGET="\"product\"" -DHOTSPOT_BUILD_USER="\"mporges\"" -DHOTSPOT_LIB_ARCH=\"i386\" -DJRE_RELEASE_VERSION="\"1.7.0-internal-mporges_2009_09_23_22_44-b00\"" -DHOTSPOT_VM_DISTRO="\"OpenJDK\"" -DCOMPILER2 -DCOMPILER1 -fPIC -fno-rtti -fno-exceptions -pthread -fcheck-new -m32 -march=i586 -mstackrealign -pipe -O3 -fno-strict-aliasing -DVM_LITTLE_ENDIAN -Werror -Wpointer-arith -Wconversion -Wsign-compare    -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -c -o arguments.o /Users/mporges/bsd-port/hotspot/src/share/vm/runtime/arguments.cpp 
    cc1plus: warnings being treated as errors
    /Users/mporges/bsd-port/hotspot/src/share/vm/runtime/arguments.cpp: In static member function 'static void Arguments::set_aggressive_opts_flags()':
    /Users/mporges/bsd-port/hotspot/src/share/vm/runtime/arguments.cpp:1398: warning: format '%d' expects type 'int', but argument 3 has type 'intx'
    make[6]: *** [arguments.o] Error 1
    make[5]: *** [the_vm] Error 2
    make[4]: *** [product] Error 2
    make[3]: *** [generic_build2] Error 2
    make[2]: *** [product] Error 2
    make[1]: *** [hotspot-build] Error 2
    make: *** [build_product_image] Error 2

    A little Googling led to this thread on the OpenJDK mailing lists. Apparently there are some issues installing 1.7.0 on Snow Leopard, although one of the guys got it working by using gcc-4.0 and g++-4.0 rather than the 4.2.x versions installed on Snow Leopard.

    I don’t really feel like installing older gcc and g++ versions on to my Mac and modifying the build to use them, so I’m hoping they can get this addressed soon so that OpenJDK will build on the mostly-vanilla Snow Leopard distribution.

    2009.09.24 / no responses / Category: Uncategorized

  • Using Axis’s wsdl2java in a Maven Build

    When using Apache Axis, you often want to generate the service stub code from a WSDL file provided by the remote API developer. We recently ran in to this situation at Highwinds.

    What we wanted to do was keep the WSDL in source control, and use Maven to build the source from the WSDL at build time during the generate-sources lifecycle hook. This seemingly simple task ended up taking me some time to figure out – not because it was hard, but because there are so many bad implementations of Axis plugins for Maven out there, and Google has all of them in its sights.

    Finally, I found a really nice implementation by the Codehaus guys. Here’s the POM for those of you who might be interested. Enjoy!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    
    <?xml version="1.0"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <name>Sample Axis-Maven Project</name>
      <groupId>com.maximporges</groupId>
      <artifactId>axis-maven</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
      <build>
        <plugins>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>axistools-maven-plugin</artifactId>
            <version>1.3</version>
            <configuration>
              <!-- The plugin navigates your source src/main/** tree and finds your WSDLs for you; just name them individually in a <wsdlFiles/> element. -->
              <wsdlFiles>
                <wsdlFiles>MyWsdlFile.wsdl</wsdlFiles>
                <wsdlFiles>MyOtherWsdlFile.wsdl</wsdlFiles>
              </wsdlFiles>
              <!-- This is optional, but lets you explicitly namespace the generated code. -->
              <packageSpace>com.whatever.i.want</packageSpace>
            </configuration>
            <dependencies>
              <!-- Required for attachment support; you can remove these dependencies if attachment support is not needed. Note that if you do want it, you have to specify the dependencies both here in the plugin and also in the POM dependencies. -->
              <dependency>
                <groupId>javax.mail</groupId>
                <artifactId>mail</artifactId>
                <version>1.4.1</version>
              </dependency>
              <dependency>
                <groupId>javax.activation</groupId>
                <artifactId>activation</artifactId>
                <version>1.1</version>
              </dependency>
            </dependencies>
            <executions>
              <execution>
                <goals>
                  <goal>wsdl2java</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <dependencies>
        <dependency>
          <groupId>org.apache.axis</groupId>
          <artifactId>axis</artifactId>
          <version>1.4</version>
        </dependency>
        <dependency>
          <groupId>javax.xml</groupId>
          <artifactId>jaxrpc-api</artifactId>
          <version>1.1</version>
        </dependency>
        <dependency>
          <groupId>javax.mail</groupId>
          <artifactId>mail</artifactId>
          <version>1.4.1</version>
        </dependency>
        <dependency>
          <groupId>javax.activation</groupId>
          <artifactId>activation</artifactId>
          <version>1.1</version>
        </dependency>
      </dependencies>
    </project>

    2009.09.23 / 12 responses / Category: Uncategorized

  • How to Install m2eclipse in Flex Builder 3

    Eclipse’s software installation process is something of a train wreck. So, when I finally crack the code for installing a particular plugin, I feel compelled to both (a) document the arcane path and (b) share it with others.

    As a result of my workhorse “Java + FB Plugin” Eclipse installation steadily progressing in to a state of unworkable slowness and a fresh Cocoa-native build of Eclipse hitting the scene a few months back, I decided to install standalone Flex Builder alongside the Cocoa Eclipse build. The Flex Builder standalone edition is really lightweight, but I like to round-trip debug on my local machine, so by having both FB and the Cocoa Eclipse build I can run Flex in FB and a Java server in Eclipse and do round-trip debugging.

    After installing FB standalone, I decided to install m2eclipse in to it. m2eclipse is an excellent plugin for working with Maven directly from Eclipse, and since we use flex-mojos at Highwinds, it’s a necessity for making our build and dependency resolution process seamless.

    Typically, this would be a simple process: set up the m2eclipse update site in FB, run the installer for new features, select it, resolve dependencies, and be done. But no, God forbid it be that simple. If you simply resolve the handful of dependencies indicated by Eclipse during the installation one by one, the plugin doesn’t show up. After finally figuring out the magic incantation required to install m2eclipse in to FB, I have documented the process below.

    Klaatu… Verata… Necto! (a.k.a. How to Install m2eclipse in to Flex Builder 3)
    1) Install Flex Builder 3 standalone
    2) Go to Help => Software Updates => Find and Install
    3) Select “Search for new features to install”, hit Next
    4) Click “New Remote Site”, entering http://m2eclipse.sonatype.org/update/ as the URL and naming it whatever you like.
    5) Check the box next to the site that you just created in step #4. Also select “Europa Discovery Site” and “The Eclipse Project Updates”, select “Automatically select mirrors”, and click Finish.
    6) Expand the tree for the m2eclipse project site. Open the “Maven Integration” project and select the “Maven integration for Eclipse (Required)” item as well as the “Maven POM XML Editor” and “Maven POM Editor.”
    7) Eclipse will complain that you don’t have all the appropriate dependencies. Expand all the top-level trees in the view you are looking at (i.e., “The Eclipse Project Updates”, “Europa Discovery Site”, “Eclipse GEF”, etc.)
    8) Click “Select Required.” About twenty dependencies will be selected in all the different trees. Some are for Eclipse’s modeling framework, others for the Web Tools Project, etc.
    9) Click Finish. Eclipse will download a metric assload of files and prompt you to restart FB. After the restart, Maven will be installed.

    I hope somebody else finds this useful and doesn’t have to spend an hour figuring this out like I did.

    2009.09.22 / 3 responses / Category: Uncategorized

  • Saving OmniGraffle Documents in Subversion

    I ran in to an issue today. We’ve been making a lot of wireframes for application user interfaces in OmniGraffle, and I wanted to get these in to version control along with everything else. Unfortunately, OmniGraffle typically stores files as bundles (special directories), and these bundles use OS X resource files for certain bits of the file format, which are fine for native OS X documents. However, these resource files have names like “Icon/r” (where /r is an escape sequence for a newline character), and that totally pisses off Subversion when committing resources.

    Luckily, OmniGraffle offers the ability to save files as flat files rather than bundles. The files can end up being fatter on disk, but that’s not really a problem considering how cheap disk space is today. You can go in to the Inspector for the document, and look in the Canvas accordion pane under the Document Settings tab. There, you will find a heading for “File format options”, which by default seems to be set to “Automatic.” You can change this to “Save as flat file”, and save the document, and you are now ready to commit the file to Subversion.

    However, I wanted to change the default file format to flat file so I don’t have to go through this process every time. I Google’d a bit and found some suggestions for setting default preferences for the OmniGraffle app using “defaults write” from Terminal. Unfortunately, that option no longer seems to work for OmniGraffle 4.2 and up. I was, however, able to figure out the solution.

    The problem seems to be that even with the defaults for the OmniGraffle app set to save to flat files, OmniGraffle always defers to the file format preference specified in the template that is used to create new documents. There are a set of document templates in the OmniGraffle application bundle that hold this setting, so you need to go in to each of these files and change the file format preference. You can find the location of these template files in the OmniGraffle preference pane under “Templates.”

    Once you have done changed the file format preference on the document templates, you are in business for all future documents created from those templates. This is how you do it.

    1) Go to the OmniGraffle application bundle, right-click, and select “Show Package Contents.”
    2) Finder will show you the inside of application bundle. Navigate within the application bundle to Contents => Resources => Templates. In here, you will find a set of OmniGraffle documents that are used as your default document templates.
    3) Open the document template that you want to modify. OmniGraffle launches and shows you the document.
    4) Open the Inspector for the document, go to Document Settings under Canvas, and set the document template file’s File Format option to “Save as flat file.”
    5) Save the document template.

    Now, all new OmniGraffle documents created from that document template will also have their default preference set to “Save as flat file” since the template’s preference has been set to that setting.

    I hope this helps any other OmniGrafflers out there using Subversion!

    2009.08.19 / no responses / Category: Uncategorized