<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Infernus &#187; Development</title>
	<atom:link href="http://infernus.org/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://infernus.org</link>
	<description>Don&#039;t feel you have to take any notice of me, please.</description>
	<lastBuildDate>Sat, 17 Sep 2011 19:57:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Swinging Clojure</title>
		<link>http://infernus.org/2010/08/swinging-clojure/</link>
		<comments>http://infernus.org/2010/08/swinging-clojure/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:25:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://infernus.org/?p=513</guid>
		<description><![CDATA[Having played with threading, I thought I&#8217;d have a go with Java integration. Swing was the obvious target, and a simple quote fetcher was the result. For simplicity, I stuck with URLConnection, but there are a number of Clojure libraries to solve the HTTP problem. All of them are somewhat nicer to deal with. I [...]]]></description>
			<content:encoded><![CDATA[<p>Having played with threading, I thought I&#8217;d have a go with Java integration. Swing was the obvious target, and a simple quote fetcher was the result.</p>
<p>For simplicity, I stuck with URLConnection, but there are a number of Clojure libraries to solve the HTTP problem. All of them are somewhat nicer to deal with.</p>
<p>I also completely failed to get <code>apply</code> working with <code>addItem</code> on the ComboBoxes &#8211; I&#8217;m assuming PEBKAC at present, given my limited knowledge of the integration.</p>
<p>Still, the Swing integration was surprisingly easy to do &#8211; I had envisioned nightmares here, given the variation in style, but it proved not half as horrid as expected.</p>
<pre>
(import
  '(java.net URL URLConnection)
  '(java.io BufferedReader InputStreamReader)
  '(javax.swing JFrame JLabel JTextField JButton JComboBox BorderFactory)
  '(java.awt.event ActionListener)
  '(java.awt GridBagLayout GridBagConstraints Insets)
  )

(def currencies ["EUR" "GBP" "JPY" "USD"])

(defn build-url [from-code to-code]
  (str "http://quote.yahoo.com/d/quotes.csv?s="
    from-code to-code "=X&#038;f=sl1d1t1c1ohgv&#038;e=.csv")
  )

(defn read-file [input-stream]
  (loop [line (.readLine input-stream)
         content []]
    (if (= line nil)
      content
      (recur (.readLine input-stream) (concat content [line]))
      )
    )
  )

(defn get-quote [quote-string]
  (nth (.split quote-string ",") 1))

(defn read-url [url]
  (let [connection (.openConnection (URL. url))]
    (read-file (BufferedReader. (InputStreamReader.
      (.getInputStream connection)))))
  )

(defn set-currencies [combo-box]
  (loop [current (first currencies)
         remainder (rest currencies)]
    (if (not (= nil current))
      (do
        (.addItem combo-box (str current))
        (recur (first remainder) (rest remainder))
        )
      )
    )
  )

(defn quote-fetcher []
  (let [frame (JFrame. "Quote Fetcher")
        button (JButton. "Get Quote")
        from-label (JLabel. "From:")
        from-field (JComboBox.)
        to-label (JLabel. "To:")
        to-field (JComboBox.)
        value-label (JLabel. "Result:")
        value-field (JTextField.)]

    (.addActionListener button
      (proxy [ActionListener] []
        (actionPerformed [e]
          (let [from-code (.getSelectedItem from-field)
                to-code (.getSelectedItem to-field)]
            (.setText value-field
              (get-quote (first (read-url
                (build-url from-code to-code)))))
            )
          )
        )
      )

    (.setEditable value-field false)

    (set-currencies from-field)
    (set-currencies to-field)

    (.setBorder (.getContentPane frame)
      (BorderFactory/createEmptyBorder 10 10 10 10))

    (doto frame
      (.setLayout (GridBagLayout.))
      (.add from-label (GridBagConstraints. 0 0 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add from-field (GridBagConstraints. 1 0 1 1 1.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.add to-label (GridBagConstraints. 0 1 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add to-field (GridBagConstraints. 1 1 1 1 1.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.add button (GridBagConstraints. 0 2 2 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add value-label (GridBagConstraints. 0 3 1 1 0.0 0.0
        (GridBagConstraints/EAST) (GridBagConstraints/NONE) (Insets. 4 4 4 4) 0 0))
      (.add value-field (GridBagConstraints. 1 3 1 1 1.0 1.0
        (GridBagConstraints/EAST) (GridBagConstraints/HORIZONTAL) (Insets. 4 4 4 4) 0 0))
      (.setSize 300 176)
      (.setVisible true)
      )
    )
  )

(quote-fetcher)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2010/08/swinging-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Travels in Clojure</title>
		<link>http://infernus.org/2010/08/travels-in-clojure/</link>
		<comments>http://infernus.org/2010/08/travels-in-clojure/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 10:04:20 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://infernus.org/?p=504</guid>
		<description><![CDATA[I&#8217;m currently reading through Pragmatic&#8217;s Seven Languages in Seven Weeks. After every chapter it has a series of small &#8216;self-study&#8217; tasks. For Clojure, the final of these is the Sleeping Barber problem. So, mostly for my own reference, I present my solution. If anyone who actually knows Clojure ever reads this, I&#8217;d welcome any suggestions. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently reading through Pragmatic&#8217;s <a href="http://pragprog.com/titles/btlang/seven-languages-in-seven-weeks">Seven Languages in Seven Weeks</a>. After every chapter it has a series of small &#8216;self-study&#8217; tasks. For Clojure, the final of these is the <a href="http://en.wikipedia.org/wiki/Sleeping_barber_problem">Sleeping Barber problem</a>.</p>
<p>So, mostly for my own reference, I present my solution. If anyone who actually knows Clojure ever reads this, I&#8217;d welcome any suggestions.</p>
<p>As for Clojure, I&#8217;m still endlessly conflicted on whether Lisp is the most elegant language of them all, or if the endless mass of paranthesis is just syntactic pain. What I am sure of is that I wouldn&#8217;t trust many of the programmers I&#8217;ve run into with a language of its power. Mind, I don&#8217;t trust many of those same with the relatively limited power of Java.</p>
<pre>
(ns barber)

(def seats (ref (clojure.lang.PersistentQueue/EMPTY)))
(def the-barber (agent 0))

(defn barber [b]
    (dosync
        (if (peek @seats)
            (do
                (alter seats pop)
                (Thread/sleep 20)
                (inc b)
            )
            b
        )
    )
)

(defn enter-shop [customer]
    (dosync
        (if (< (count @seats) 3)
            (alter seats conj customer)
        )
    )
)

(defn run-barber [milliseconds]
    (do
        (add-watch seats :send-to-barber
            (fn [_ _ _ _] (send-off the-barber barber))
        )

        (def end-time (+ milliseconds (System/currentTimeMillis)))

        (while (< (System/currentTimeMillis) end-time)
            (Thread/sleep (+ 10 (rand-int 20)))
            (send (agent :customer) enter-shop)
        )
        (await the-barber)
        @the-barber
    )
)

(run-barber 10000)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2010/08/travels-in-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two Datasources, One Rails Application</title>
		<link>http://infernus.org/2010/03/two-datasources-one-rails-application/</link>
		<comments>http://infernus.org/2010/03/two-datasources-one-rails-application/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 19:27:51 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://infernus.org/?p=380</guid>
		<description><![CDATA[Rails has a habit of lulling you into a false sense of security. The ease of use for common tasks makes you wonder why you&#8217;re wasting your time with Spring or JEE. Then you try to do something off the common path and watch Rails just shrug its shoulders and grin. I was working on [...]]]></description>
			<content:encoded><![CDATA[<p>
   Rails has a habit of lulling you into a false sense of security. The ease of use for common tasks makes you wonder why you&#8217;re wasting your time with Spring or JEE. Then you try to do something off the common path and watch Rails just shrug its shoulders and grin.
</p>
<p>
	I was working on a community project recently and ran into the requirement to access some static data in another database. Multiple datasources, easy enough. Unfortunately, Rails expects you&#8217;ll be sticking with just one, and so I had to go hunting for a solution. Thankfully, I wasn&#8217;t the first to hit this and so many people had already done the hard work, leaving me with my piecing together the most elegant solution.
</p>
<p>
	The first thing to do is define your datasource, presumably in <i>database.yml</i>.
</p>
<pre>
legacy_datasource:
  adapter: mysql
  database: legacy_database
  timeout: 5000
  encoding: utf8
  host: localhost
  username: readonly
  enable_call: true
  password: readonly
</pre>
<p>
	You&#8217;ll then need to introduce a base class for the models which will use this datasource. It&#8217;ll need to be abstract, to avoid declaring any columns and establish a connection to the secondary source.
</p>
<pre>
class LegacyObject < ActiveRecord::Base
  establish_connection :legacy_datasource

  self.abstract_class = true

  def self.columns() @columns ||= []; end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

end
</pre>
<p>
	Now build the model classes you require, making sure to extend from your new base class.
</p>
<pre>
class AnObject < LegacyObject

  column :object_id, :integer

  # and so on...

end
</pre>
<p>
	If you just require read-only access then you're now done. If you require migration support then a bit more work is needed.
</p>
<p>
	Create a new base class for the migrations that redefines the connection.
</p>
<pre>
class LegacyMigration < ActiveRecord::Migration
  def self.connection
    LegacyDatasource.connection
  end
end
</pre>
<p>
	Now, extend from the new base class and write your migration as normal.
</p>
<pre>
class AMigration < LegacyMigration
  def self.up
    # ...
  end

  def self.down
    # ...
  end
end
</pre>
<p>
	And you now have a complete solution. Despite the lack of official documentation, it's surprisingly easy to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2010/03/two-datasources-one-rails-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CheckStyle-IDEA: Adopt a project!</title>
		<link>http://infernus.org/2009/12/checkstyle-idea-adopt-a-project/</link>
		<comments>http://infernus.org/2009/12/checkstyle-idea-adopt-a-project/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 22:10:29 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://infernus.org/2009/12/checkstyle-idea-adopt-a-project/</guid>
		<description><![CDATA[As any users have probably noticed, little is happening on this at present bar bug-fixes. This is primarily as I am no longer using it at work and therefore have little inclination to work on it, other than the guilt of support. Therefore, if you are interested in it and would like a try at [...]]]></description>
			<content:encoded><![CDATA[<p>As any users have probably noticed, little is happening on <a href="http://checkstyle-idea.googlecode.com/">this</a> at present bar bug-fixes. This is primarily as I am no longer using it at work and therefore have little inclination to work on it, other than the guilt of support.</p>
<p>Therefore, if you are interested in it and would like a try at either contributing or taking over the project, please drop me a line. I&#8217;d hate to see something I know people are using die through my neglect.</p>
<p>In the meantime, 3.0.9 has been uploaded to Jetbrains with some synchronisation fixes. Hopefully this will fix the NPE a few have seen.</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/12/checkstyle-idea-adopt-a-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CheckStyle IDEA 3.0 Release</title>
		<link>http://infernus.org/2009/06/checkstyle-idea-30-release/</link>
		<comments>http://infernus.org/2009/06/checkstyle-idea-30-release/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 14:43:12 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://infernus.org/2009/06/checkstyle-idea-30-release/</guid>
		<description><![CDATA[After a long long wait, I&#8217;ve finally bit the bullet and released CheckStyle-IDEA 3.0. What is it? Integrated real-time and static CheckStyle scanning for IntelliJ IDEA 7 and 8. What&#8217;s new in 3.0? CheckStyle 5.0 support (thanks to jicken) Per-module configuration support Severity filtering on result list. Please note that you will need to reconfigure [...]]]></description>
			<content:encoded><![CDATA[<p>After a long long wait, I&#8217;ve finally bit the bullet and released <a href="http://checkstyle-idea.googlecode.com/">CheckStyle-IDEA 3.0</a>.</p>
<p><b>What is it?</b> Integrated real-time and static <a href="http://checkstyle.sf.net/">CheckStyle</a> scanning for <a href="http://www.jetbrains.com/idea/index.html">IntelliJ IDEA</a> 7 and 8.</p>
<p><b>What&#8217;s new in 3.0?</b></p>
<ul>
<li>CheckStyle 5.0 support (thanks to <a href="http://code.google.com/u/jicken/">jicken</a>)</li>
<li>Per-module configuration support</li>
<li>Severity filtering on result list.</li>
</ul>
<p><b>Please note</b> that you will need to reconfigure the plugin, due to changes in how we store configuration information. Annoying, but it was necessary to support multiple configuration files.</p>
<p>As always, you can find it in the <a href="http://plugins.intellij.net/plugin/?id=1065">IntelliJ Plugin repository</a>. And please throw any bugs you find into the <a href="http://code.google.com/p/checkstyle-idea/issues/">issue tracker</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/06/checkstyle-idea-30-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux love for TeamCity</title>
		<link>http://infernus.org/2009/02/linux-love-for-teamcity/</link>
		<comments>http://infernus.org/2009/02/linux-love-for-teamcity/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 15:41:22 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://infernus.org/2009/02/linux-love-for-teamcity/</guid>
		<description><![CDATA[For far too long we&#8217;ve been running our TeamCity build agents on Windows 2003 Server. This was, originally, driven by necessity. We were using Selenium, and out client cared only for a single browser: Internet Explorer. As time progressed we decided Selenium was costing us more than we received from it, so we dropped it. [...]]]></description>
			<content:encoded><![CDATA[<p>For far too long we&#8217;ve been running our <a href="http://www.jetbrains.com/teamcity/index.html">TeamCity</a> build agents on Windows 2003 Server. This was, originally, driven by necessity. We were using Selenium, and out client cared only for a single browser: Internet Explorer. As time progressed we decided Selenium was costing us more than we received from it, so we dropped it. And so we ended up using Windows to build for historical reasons only. And, of course, inertia.</p>
<p>So, over the last day or two, I&#8217;ve been building up replacements. Our build box is actually a PowerEdge 1950, split into two machines with the aid of <a href="http://www.vmware.com/products/esxi/">VMWare ESXi</a>. So I hacked together a build agent on VMWare Fusion to use as a template, copied it onto ESX, and set it spinning.</p>
<p>This was the point I got a kick in the arse. We were using Ubuntu 8.10 64bit &#8211; and ESX didn&#8217;t like it one bit. So I dragged a LCD and keyboard up to the server room and had a nose in the BIOS &#8211; sure enough, Dell had left VT off. Bloody Dell. I took advantage of the visit to <a href="http://www.yellow-bricks.com/2008/08/10/howto-esxi-and-ssh/">hack SSH on in ESXi</a> and headed downstairs.</p>
<p>No luck. Same error.</p>
<p>An hour later I stumbled on the solution. The VM had paravirtualisation turned on. Paravirtualisation, apparently, only supports 32bit hosts. Off went paravirtualisation and on went the build server. Win!</p>
<p>So, victory, one less Windows server, and once more a severe wish that VMWare would produce Infratructure Client for either Linux or Mac OS X.</p>
<p>That wasn&#8217;t all I learnt of value, however. JetBrains are good enough to <a href="http://www.jetbrains.net/confluence/display/TCD4/Setting+up+and+Running+Additional+Build+Agents">tell you how to start TeamCity automatically</a> on Windows (via a server) and the Mac (via launchd) and complete omit Linux. So I went and found out about <a href="http://upstart.ubuntu.com/">Upstart</a>.</p>
<p>End solution: create the scripts below in /etc/event.d. They&#8217;ll run on startup/shutdown, and can also be started manually using:</p>
<pre>sudo start [start|stop]-teamcity-buildagent</pre>
<h2>/etc/event.d/start-teamcity-buildagent</h2>
<pre>
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5

console output

script
	exec su -l buildagent -c '/opt/build-agent/bin/agent.sh start'
end script
</pre>
<h2>/etc/event.d/stop-teamcity-buildagent</h2>
<pre>
start on shutdown

console output
script
	exec su -l buildagent -c '/opt/build-agent/bin/agent.sh stop'
end script
</pre>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/02/linux-love-for-teamcity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Java 7 on Mac OS X</title>
		<link>http://infernus.org/2009/02/building-java-7-on-mac-os-x/</link>
		<comments>http://infernus.org/2009/02/building-java-7-on-mac-os-x/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 22:11:13 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://infernus.org/2009/02/building-java-7-on-mac-os-x/</guid>
		<description><![CDATA[Update 26/5/9: Updated for last night&#8217;s source with the JIBX libraries, and note on the version of XCode. So, I&#8217;ve just got my laptop back after a brief separation. What does one do? Compile the JDK, of course! For those unfamiliar with the situation, Apple hate Java developers. Well, one suspects they do. Apple being [...]]]></description>
			<content:encoded><![CDATA[<p><b>Update 26/5/9:</b> Updated for last night&#8217;s source with the JIBX libraries, and note on the version of XCode.</p>
<p>So, I&#8217;ve just got my laptop back after a brief separation. What does one do?</p>
<p>Compile the JDK, of course!</p>
<p>For those unfamiliar with the situation, Apple hate Java developers. Well, one suspects they do. Apple being Apple, one never knows. We could get Java 1.6.0_12 with 32bit support tomorrow, or it could never come. You&#8217;ll never know until it appears.</p>
<p>Luckily, <a href="http://landonf.bikemonkey.org/">Landon Fuller</a> loves us. Which Apple play with their iPhones, he beat the OpenJDK into submission on OS X. Only drawback &#8211; Swing is X11 based. But still, it&#8217;s JDK6 for 10.4, 10.5 and in both 32 and 64bit, and available as <a href="http://landonf.bikemonkey.org/static/soylatte/">SoyLatte</a>.</p>
<p>This work has all found its way back into the trunk, and so JDK7 is buildable on the Mac (usually). The only catch: the instructions are scattered, and often vary slightly. So I&#8217;m documenting them here for tonight&#8217;s build, mostly for my reference.</p>
<p>Thanks go to Landon Fuller and <a href="http://mail.openjdk.java.net/pipermail/bsd-port-dev/2009-January/000499.html">Stephen Bannasch</a> for putting these together.</p>
<p>1. Get version 3.1 (or above, presumably) of XCode.</p>
<p>2. Download <a href="http://landonf.bikemonkey.org/static/soylatte/">SoyLatte</a>. I found the JDK7 build Landon released in 2008 did not work as a bootstrap.</p>
<p>3. Get Mercurial</p>
<pre>sudo port install mercurial +bash_completion</pre>
<p>4. Install the Forest extension</p>
<pre>hg clone http://bitbucket.org/pmezard/hgforest-crew</pre>
<p>You&#8217;ll need to point Mercurial at the hgforest-crew directory, by adding the following to ~/.hgrc:</p>
<pre>[extensions]
hgext.forest=/opt/hgforest-crew/forest.py</pre>
<p>5. Grab Kurt Miller&#8217;s BSD binary plugs:</p>
<pre>wget http://www.intricatesoftware.com/distfiles/jdk-7-icedtea-plugs-1.6b.tar.gz</pre>
<p>6. Get the JIBX libraries (version 1.1.5) from:</p>
<pre>http://sourceforge.net/project/showfiles.php?group_id=69358&#038;package_id=68290</pre>
<p>7. Check out the OpenJDK:</p>
<pre>hg fclone http://hg.openjdk.java.net/bsd-port/bsd-port</pre>
<p>8. Place the following in build.sh in the bsd-port directory (modify as appropriate, depending on where you placed downloaded items):</p>
<pre>LC_ALL=C
LANG=C
unset CLASSPATH
unset JAVA_HOME
make \
  ALT_BOOTDIR=/opt/soylatte16-i386-1.0.3/ \
  ALT_BINARY_PLUGS_PATH=/opt/jdk-7-icedtea-plugs \
  ALT_FREETYPE_HEADERS_PATH=/usr/X11R6/include \
  ALT_FREETYPE_LIB_PATH=/usr/X11R6/lib \
  ALT_JIBX_LIBS_PATH=/opt/jibx/lib \
  ALT_CUPS_HEADERS_PATH=/usr/include \
  ANT_HOME=/usr/share/ant \
  NO_DOCS=true \
  HOTSPOT_BUILD_JOBS=2</pre>
<p>9. Run, and cross your fingers!</p>
<p>10. I ran into a ld error (archive has no table of contents). Should you hit this, try the following and then rerun build.sh:</p>
<pre>ranlib build/bsd-i586/tmp/java/fdlibm/obj/*.a</pre>
<p>11. Copy bsd-port/build/bsd-i586/j2sdk-image somewhere useful &#8211; and you&#8217;re done!</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/02/building-java-7-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Keyboard Woes</title>
		<link>http://infernus.org/2009/02/keyboard-woes/</link>
		<comments>http://infernus.org/2009/02/keyboard-woes/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 01:11:08 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://infernus.org/wordpress/?p=3</guid>
		<description><![CDATA[Like many programmers, I&#8217;m very picky about my input devices. Particularly about keyboards &#8211; both at home and work I use a Microsoft Natural Ergonomic Keyboard 4000. Despite the overly lengthy name, it&#8217;s a superb piece of kit and I wouldn&#8217;t work without it. Apple, however, don&#8217;t believe in locales outside the US. And so [...]]]></description>
			<content:encoded><![CDATA[<p>Like many programmers, I&#8217;m very picky about my input devices. Particularly about keyboards &#8211; both at home and work I use a Microsoft Natural Ergonomic Keyboard 4000. Despite the overly lengthy name, it&#8217;s a superb piece of kit and I wouldn&#8217;t work without it.</p>
<p>Apple, however, don&#8217;t believe in locales outside the US. And so the UK keyboard layout on my MBP is designed around the hacked-together monstrosity Apple consider a UK keyboard layout. Those who have used MacBooks will know this is essentially a slightly hacked US layout, and so it doesn&#8217;t help with the NEK4000. Luckily, unlike the rubbish that <a href="http://www.logitech.com/index.cfm/494/3129&amp;cl=us,en">Logitech put out</a>, <a href="http://www.microsoft.com/hardware/downloads/default.mspx">Intellitype</a> has been stable and useful for me, and sorted the problem.</p>
<p>Until recently&#8230;</p>
<p>At work we&#8217;re currently doing Swing development on Java 6. Java 6 for the Mac is 64bit only. And, unlike the 32bit Java 5, the Microsoft Keyboard driver refuses to offer keystrokes to the 64bit JVM. Hence i had to swap keyboard layouts if I wanted to do crazy things such as entering text into our application.</p>
<p>Luckily, <a href="http://scripts.sil.org/ukelele">Ukulele</a> has saved me. It is a keyboard layout editor for the Mac, and I was quickly able to knock up an appropriate layout. And so I can now happily type sans-Intellitype.</p>
<p>I&#8217;ve also dumped LCC and will be trying <a href="http://www.orderedbytes.com/controllermate/">ControllerMate</a> for my mapping needs. Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/02/keyboard-woes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Checking the EDT with aspects</title>
		<link>http://infernus.org/2009/02/checking-the-edt-with-aspects/</link>
		<comments>http://infernus.org/2009/02/checking-the-edt-with-aspects/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 17:27:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Aspects]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://infernus.org/wordpress/?p=5</guid>
		<description><![CDATA[I am unreasonably fond of Swing. While it has plenty of foibles, and brings a new horror to UIs with Metal, it&#8217;s nevertheless quite a nice framework to use &#8211; once you&#8217;re familiar with it. The problem is that getting familiar is a path strewn with brambles and holes full on punji sticks. One of [...]]]></description>
			<content:encoded><![CDATA[<p>I am unreasonably fond of Swing. While it has plenty of foibles, and brings a new horror to UIs with Metal, it&#8217;s nevertheless quite a nice framework to use &#8211; once you&#8217;re familiar with it.</p>
<p>The problem is that getting familiar is a path strewn with brambles and holes full on punji sticks. One of the bigger holes is the event dispatch thread (EDT) &#8211; everything Swing related should take place on the EDT (even initialisation, under the latest Sun guidelines). When you&#8217;re trying to keep the UI fluid it&#8217;s all too easy to break the rule &#8211; hence, aspects to the rescue!</p>
<p>This topic has been covered by many before, including <a href="http://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html">Alexander Potochkin</a> and <a href="http://thejavacodemonkey.blogspot.com/2007/08/using-aspectj-to-detect-violations-of.html">Anders Prisak</a> &#8211; however, I found their solution needed a little tweaking to be used in our environment. In particular, they had missed two cases we cover &#8211; SwingUtilities and SwingWorker.</p>
<p>So, here&#8217;s the tweaked aspect. safeMethods now includes a few extras.</p>
<pre>package org.infernus.swing.aspects;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.awt.*;

@Aspect
public class EDTCheck {

    @Pointcut("call (* javax.swing..*+.*(..)) || "
            + "call (javax.swing..*+.new(..))")
    public void swingMethods() {
    }

    @Pointcut("call (* javax.swing..*+.add*Listener(..)) || "
            + "call (* javax.swing..*+.remove*Listener(..)) || "
            + "call (* javax.swing..*+.getListeners(..)) || "
            + "call (* javax.swing..*+.revalidate()) || "
            + "call (* javax.swing..*+.invalidate()) || "
            + "call (* javax.swing..*+.repaint()) || "
            + "target (javax.swing.SwingWorker+) || "
            + "call (* javax.swing.SwingUtilities+.invoke*(..)) || "
            + "call (* javax.swing.SwingUtilities+.isEventDispatchThread()) || "
            + "call (void javax.swing.JComponent+.setText(java.lang.String))")
    public void safeMethods() {
    }

    @Before("swingMethods() &amp;&amp; !safeMethods() &amp;&amp; !within(EDTCheck)")
    public void checkCallingThread(final JoinPoint.StaticPart thisJoinPointStatic) {
        if (!EventQueue.isDispatchThread()) {
            System.err.println("Swing EDT violation: " + thisJoinPointStatic.getSignature()
                    + " (" + thisJoinPointStatic.getSourceLocation() + ")");
            Thread.dumpStack();
        }
    }
}</pre>
<p>Once it&#8217;s built, we just need to weave it &#8211; I&#8217;ve already got compile-time weaving configured for <a href="http://infernus.org/node/269">Spring @Configurable support</a>, so just add the JAR containing the aspect as a weaveDependency and then the magic happens.</p>
<p>Now, if a Swing call is made off of the EDT, you&#8217;ll get complaints:</p>
<pre>Swing EDT violation: String javax.swing.JTextArea.getText() (YourSwingClass.java:98)
java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1224)
        at org.infernus.swing.aspects.EDTCheck.checkCallingThread(EDTCheck.java:55)
     ... and so on</pre>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2009/02/checking-the-edt-with-aspects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Curse of Open Source</title>
		<link>http://infernus.org/2008/12/the-curse-of-open-source/</link>
		<comments>http://infernus.org/2008/12/the-curse-of-open-source/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 20:57:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://infernus.org/wordpress/?p=8</guid>
		<description><![CDATA[One must only browse the vast repositories of half-finished software at SourceForge to see that many promising (or just plain useful) projects seem to just vanish, left incomplete and at the mercy of bit-rot. The main reasons for this are threefold: A lot of open-source software is written to scratch an itch. That itch may [...]]]></description>
			<content:encoded><![CDATA[<p>One must only browse the vast repositories of half-finished software at SourceForge to see that many promising (or just plain useful) projects seem to just vanish, left incomplete and at the mercy of bit-rot.</p>
<p>The main reasons for this are threefold:</p>
<ul>
<li>A lot of open-source software is written to scratch an itch. That itch may not be quite the same as yours, and so it may be regarded as finished by the author.</li>
<li>Support and bug-fixes are generally dull; certainly a lot less interested that writing something new.</li>
<li>Polish is hard &#8211; it&#8217;s easy to build something rough and ready, and significantly harder to add the sparkle.</li>
</ul>
<p>I&#8217;m first to admit I&#8217;m guilty of all points with regards to <a href="http://plugins.intellij.net/plugin/?id=1065">CheckStyle-IDEA</a>.</p>
<p>This was written to scratch an itch &#8211; real-time scanning in IDEA. I have a CI server to do static scans, and my needs are simple with regards to plug-ins and the like. So I was happy with a fairly minimal feature set. Nevertheless, I did try to add more features to help others, and these are mostly where the bugs have crept in.</p>
<p>Unfortunately I gave into temptation and played with other things rather than fixing said bugs. And so, with the holiday upon us, I have done a little to whittle away at my laziness and released a bug-fix version: 2.3, with all reported issues fixed.</p>
<p>So, apologies for the tardiness, and I hope this solves most people&#8217;s issues with the current feature set!¹</p>
<p class="footnote">¹ Of course, if not, please feel free to submit a patch!</p>
]]></content:encoded>
			<wfw:commentRss>http://infernus.org/2008/12/the-curse-of-open-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: infernus.org @ 2012-02-10 02:52:52 -->
