<?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>Jayway Team Blog &#187; Tobias Södergren</title>
	<atom:link href="http://blog.jayway.com/author/tobiassodergren/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jayway.com</link>
	<description>Sharing Experience</description>
	<lastBuildDate>Sat, 11 Feb 2012 10:33:02 +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>How you list the available goals for a maven plugin</title>
		<link>http://blog.jayway.com/2012/02/11/how-you-list-the-available-goals-for-a-maven-plugin/</link>
		<comments>http://blog.jayway.com/2012/02/11/how-you-list-the-available-goals-for-a-maven-plugin/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 10:18:47 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[goals]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=11976</guid>
		<description><![CDATA[I've been attending an excellent lab by Sune Simonsen which was about how to create a Javascript twitter client. The lab utilizes the maven-lab-plugin, which can be used to create step-by-step labs using Maven. During the lab, i wanted to know which step I was at and I figured that there should be a goal [...]]]></description>
			<content:encoded><![CDATA[<p>I've been attending an excellent lab by <a href="https://twitter.com/#!/sunesimonsen">Sune Simonsen</a> which was about how to create a Javascript twitter client.</p>
<p/>
The lab utilizes the <a href="https://github.com/jayway/maven-lab-plugin">maven-lab-plugin</a>, which can be used to create step-by-step labs using Maven.</p>
<p/>
During the lab, i wanted to know which step I was at and I figured that there should be a goal for that. To list the available goals for a maven plugin you can use the goal <code>help:describe</code> like this:</p>
<pre>
  $ maven help:describe -DgroupId=com.jayway.maven.plugins.lab -DartifactId=maven-lab-plugin
</pre>
<p>This will give you an output like:</p>
<pre>
Name: maven-lab-plugin Maven Mojo
Description: Maven plugin used to create labs that provide more code once a
  step has been completed. Labs are a useful way to learn new technologies,
  frameworks and tools.
Group Id: com.jayway.maven.plugins.lab
Artifact Id: maven-lab-plugin
Version: 1.0.0.RELEASE
Goal Prefix: lab

This plugin has 7 goals:

lab:create
  Description: Goal to chunkify

lab:currentStep
  Description: Get the current step no

lab:findMax
  Description: Goal to find the max version

lab:init
  Description: Goal to create and initialize a lab.

lab:next
  Description: Change to next step

lab:reset
  Description: Goal to create and initialize a lab.

lab:setStep
  Description: Change version to versionNo

For more information, run 'mvn help:describe [...] -Ddetail'
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2012/02/11/how-you-list-the-available-goals-for-a-maven-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebook Test Java API release 1.1.5</title>
		<link>http://blog.jayway.com/2011/10/20/facebook-test-java-api-release-1-1-5/</link>
		<comments>http://blog.jayway.com/2011/10/20/facebook-test-java-api-release-1-1-5/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 12:23:38 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=10597</guid>
		<description><![CDATA[The Facebook Test Java API framework has been updated. There are two additions to the API and one bugfix: Bugfix for NPE when calling facebookStore.createTestUser(false,"..."). Added possibility of using a provided HttpClient instance in HttpClientFacebookTestUserStore. Added unit test that displays the use of json-path when asserting data. Here's a quick reminder of how to create [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://code.google.com/p/facebook-test-java-api/" title="Facebook Test Java API">Facebook Test Java API</a> framework has been updated. There are two additions to the API and one bugfix:</p>
<ol>
<li>Bugfix for NPE when calling facebookStore.createTestUser(false,"...").</li>
<li>Added possibility of using a provided HttpClient instance in HttpClientFacebookTestUserStore.</li>
<li>Added unit test that displays the use of json-path when asserting data.</li>
</ol>
<p>Here's a quick reminder of how to create test users for an application. The creation process is handled by an instance of FacebookTestUserStore, e.g. The HttpClientFacebookTestUserStore which uses Apache HttpClient as communication method. The class needs the <i>application ID</i> and the <i>application secret</i> for the application in order to be able to create the users and this is specified in the constructor:</p>
<pre class="brush:java">
FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;"));
</pre>
<p>Now you have a choice when creating a test user: You may say that the test user should accept the privileges that you specify for it, which is done by:</p>
<pre class="brush:java">
FacebookTestUserAccount aTestUser = facebookStore.createTestUser(true, "read_stream");
</pre>
<p>If you want to give a choice to the test user whether the privileges should be accepted or not, you do the following:</p>
<pre class="brush:java">
FacebookTestUserAccount aTestUser = facebookStore.createTestUser(false, "read_stream");
</pre>
<p>The accept/decline choice takes part in the web browser, hence you need the login URL for the test user to access the page. This URL is accessible from the FacebookTestUserAccount:</p>
<pre class="brush:java">
aTestUser.loginUrl();
</pre>
<h3>Specifying a HttpClient instance to HttpClientFacebookTestUserStore</h3>
<p>There might be occasions where you need a special HttpClient instance for communication, for example one instance with proxy settings configures, or another instance where you have stubbed all the communication that takes place. To provide the instance to HttpClientFacebookTestUserStore, just specify it in the constructor:</p>
<pre class="brush:java">
HttpClient httpClient = new DefaultHttpClient();
FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;", httpClient));
</pre>
<h3>Using json-assert to verify application behavior</h3>
<p>The <a href="http://code.google.com/p/json-assert/" title="json-assert">json-assert</a> project, which uses <a href="http://code.google.com/p/json-path/" title="json-path">json-path</a> can be used to make life a little less verbose when asserting on data from the JSON document representations of the Facebook data streams that are available in the FacebookTestUserAccount. For example, the user details of a test user can be accessed like this:</p>
<pre class="brush:java">
aTestUser.getUserDetails();
</pre>
<p>The result is a java.lang.String containing a JSON Document. To make it easier to assert that the user details actually contain the expected data, you may use json-assert and <a href="http://code.google.com/p/hamcrest/wiki/Tutorial" title="Hamcrest matchers">Hamcrest matchers</a>:</p>
<pre class="brush:java">
String userDetails = account.getUserDetails();

JsonAssert.with(userDetails).assertThat("$.first_name", equalTo("Sue"));
JsonAssert.with(userDetails).assertThat("$.last_name", equalTo("Ellen"));
</pre>
<p>Feel free to test it out, the code is open source an can be found on Maven central or on the<br />
<a href="http://code.google.com/p/facebook-test-java-api/" title="Facebook Test Java API project page">Facebook Test Java API project page</a>.</p>
<p>/Tobias</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/10/20/facebook-test-java-api-release-1-1-5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Finding unread mail in Gmail in your browser</title>
		<link>http://blog.jayway.com/2011/10/08/finding-unread-mail-in-gmail-in-your-browser/</link>
		<comments>http://blog.jayway.com/2011/10/08/finding-unread-mail-in-gmail-in-your-browser/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 09:01:36 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[filtering]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[unread]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=10057</guid>
		<description><![CDATA[Usually when I have a lot of emails in my inbox, I tend to skim most of them and then mark interesting mails as being unread so that I can read them later on. Sometimes that later on is getting pushed further and further away in the future and suddenly there's a bunch of unread [...]]]></description>
			<content:encoded><![CDATA[<p>Usually when I have a lot of emails in my inbox, I tend to skim most of them and then mark interesting mails as being unread so that I can read them later on. Sometimes that later on is getting pushed further and further away in the future and suddenly there's a bunch of unread mails in my inbox. The<br />
mails are scattered throughout the inbox and trying to find them using by<br />
paginating is quite tedious work. Luckily there's an easier way by using the search box:</p>
<p><code>is:unread label:inbox</code></p>
<p>This will list all unread mails in the inbox. Unfortunately this query is useless when saved<br />
as a filter, as new mail will not be processed by operators such as in:, has: and so on.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/10/08/finding-unread-mail-in-gmail-in-your-browser/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Create &#8216;native&#8217; Java applications on OS X and Windows using Maven plugins</title>
		<link>http://blog.jayway.com/2011/08/15/create-native-java-applications-on-os-x-and-windows-using-maven-plugins/</link>
		<comments>http://blog.jayway.com/2011/08/15/create-native-java-applications-on-os-x-and-windows-using-maven-plugins/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 09:07:21 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[native]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=9190</guid>
		<description><![CDATA[When building a desktop application, the target audience usually expects an executable to when launching it. If the application is written in Java you have the options to create a batch file to launch it, create an executable jar file, compile the application as a native application or wrap the application using a native 'launcher'. [...]]]></description>
			<content:encoded><![CDATA[<p>When building a desktop application, the target audience usually expects an executable to when launching it. If the application is written in Java you have the options to create a batch file to launch it, create an executable jar file, compile the application as a native application or wrap the application using a native 'launcher'. This post will result in a maven pom for dealing with the last option, it may be used in both Windows and OS X environments.</p>
<p>The pom is configured to use two different plugins depending on which operating system that is executing it.<br />
On Windows, a <a href="http://launch4j.sourceforge.net/">Launch4j</a> project <a href="http://alakai.org/reference/plugins/launch4j-plugin-usage.html">plugin</a> will be used. On OS X the <a href="http://mojo.codehaus.org/osxappbundle-maven-plugin/">osxappbundle</a> plugin is used, which creates an OS X application directory structure and uses the JavaApplicationStub binary for launching the application.</p>
<p>The <code>&lt;profile&gt;</code> tag is used for deciding which plugin to use depending on operating system.</p>
<p>The pom also points out different application icons for the binaries, OS X requires the icon to be in the <a href="http://en.wikipedia.org/wiki/Apple_Icon_Image_format">icns</a> and windows in the <a href="http://en.wikipedia.org/wiki/ICO_(file_format)">ico</a> format.</p>
<p>The wrapped application has a main class in the file <code>com.jayway.wrappedapplication.Launcher</code></p>
<h2>The pom.xml</h2>
<pre class="brush:xml">
<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>
  <groupid>com.jayway.wrappedapplication</groupid>
  <artifactid>launcher</artifactid>
<packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>launcher</name>
  <url>http://maven.apache.org</url>
<profiles>
<profile>
      <id>windows-deploy</id>
      <activation>
        <os>
          <family>Windows</family>
        </os>
      </activation>
      <build>
<plugins>
<plugin>
            <groupid>org.bluestemsoftware.open.maven.plugin</groupid>
            <artifactid>launch4j-plugin</artifactid>
            <version>1.5.0.0</version>
            <executions>
              <execution>
                <id>launch4j</id>
<phase>verify</phase>
                <goals>
                  <goal>launch4j</goal>
                </goals>
                <configuration>
                  <dontwrapjar>false</dontwrapjar>
<headertype>gui</headertype>
                  <outfile>${project.build.directory}/relauncher-${project.version}.exe</outfile>
                  <jar>${project.build.directory}/${project.build.finalName}.jar</jar>
                  <errtitle>Launcher</errtitle>
                  <jre>
                    <minversion>1.6.0</minversion>
                  </jre>
                  <classpath>
                    <mainclass>com.jayway.wrappedapplication.Launcher</mainclass>
                    <adddependencies>false</adddependencies>
<precp>anything</precp>
                  </classpath>
                  <icon>${basedir}/build-resources/win/icons/application.ico</icon>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
<profile>
      <activation>
        <os>
          <family>mac</family>
        </os>
      </activation>
      <build>
<plugins>
<plugin>
            <groupid>org.codehaus.mojo</groupid>
            <artifactid>osxappbundle-maven-plugin</artifactid>
            <version>1.0-alpha-2</version>
            <configuration>
              <mainclass>com.jayway.wrappedapplication.Launcher</mainclass>
              <iconfile>${basedir}/build-resources/osx/icons/application.icns</iconfile>
            </configuration>
            <executions>
              <execution>
<phase>package</phase>
                <goals>
                  <goal>bundle</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
</pre>
<p>And that's it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/08/15/create-native-java-applications-on-os-x-and-windows-using-maven-plugins/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Disappearing cursor in Gmail when using Safari</title>
		<link>http://blog.jayway.com/2011/07/07/disappearing-cursor-in-gmail-when-using-safari/</link>
		<comments>http://blog.jayway.com/2011/07/07/disappearing-cursor-in-gmail-when-using-safari/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 08:12:18 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=9021</guid>
		<description><![CDATA[I've had a really annoying problem where the cursor in Gmail disappears completely when composing mails. Being used to have a visual hint of where the next character is supposed to be placed, I was pleased to find a blog post [1] describing a workaround. The short story of the workaround it is to disable [...]]]></description>
			<content:encoded><![CDATA[<p>I've had a really annoying problem where the cursor in Gmail disappears completely when composing mails. Being used to have a visual hint of where the next character is supposed to be placed, I was pleased to find a blog post [1] describing a workaround.</p>
<p>The short story of the workaround it is to <strong>disable the advanced attachment features</strong> in Gmail. </p>
<p>You can look at the blog post to find out when the problem occur, why it does and why the workaround helps:</p>
<p>[1] <a href="http://db.tidbits.com/article/11495">http://db.tidbits.com/article/11495</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/07/07/disappearing-cursor-in-gmail-when-using-safari/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Editable lines in Google Maps using the Javascript v3 API</title>
		<link>http://blog.jayway.com/2011/04/28/editable-lines-in-google-maps-using-javascript-v3-api/</link>
		<comments>http://blog.jayway.com/2011/04/28/editable-lines-in-google-maps-using-javascript-v3-api/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 06:48:04 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=8222</guid>
		<description><![CDATA[The Google Maps Javascript API v3 provides overlays for drawing shapes, such as Polygons, Circles, Polylines and Rectangles. The shapes are not implicitly interactive in the respect that you cannot tell the shape to be 'editable' as you could in the Javascript v2 API (here's an example). To simulate the behavior using functionality provided by [...]]]></description>
			<content:encoded><![CDATA[<p>The Google Maps Javascript API v3 provides overlays for drawing shapes, such as Polygons, Circles, Polylines and Rectangles. The shapes are not implicitly interactive in the respect that you cannot tell the shape to be 'editable' as you could in the Javascript v2 API (<a href="http://gmaps-samples.googlecode.com/svn/trunk/poly/mymapstoolbar.html">here's an example</a>).</p>
<p/>
To simulate the behavior using functionality provided by maps v3 API, you'll need to find an element that supports the <code>drag</code> event, such as the <code>Marker</code> object. A marker has a position, a shape and provides events such as <code>click</code>, <code>dragstart</code>, <code>drag</code> and <code>dragend</code>.</p>
<h2>The code</h2>
<p>First off, we need to load the google maps API and specify which version to use. The code uses some extra goodies to calculate the length of the line, which is provided in the <code>geometry</code> library and it looks like this is available in the v3.3 of the API. Here's how to do specify this:</p>
<p/>
<pre class="brush:javascript; gutter:false">
   &lt;script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=false&v=3.3"&gt&lt;/script&gt;
</pre>
<p/>
The complete code looks like:</p>
<pre class="brush:javascript; gutter:false; highlight: [62]">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta name="viewport" content="initial-scale=1.0, user-scalable=no"/&gt;
    &lt;style type="text/css"&gt;
        html {
            height: 100%
        }

        body {
            height: 100%;
            margin: 0px;
            padding: 0px
        }

        #map_canvas {
            height: 100%
        }
    &lt;/style&gt;
    &lt;script type="text/javascript"
            src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=false&v=3.3"&gt;
    &lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        var g = google.maps;
        function initialize() {
            var latlng = new g.LatLng(62.397, 12.644);
            var myOptions = {
                zoom: 4,
                center: latlng,
                mapTypeId: g.MapTypeId.ROADMAP
            };
            var map = new g.Map(document.getElementById("map_canvas"), myOptions);
            registerMapDragHandler(map);
        }

        function registerMapDragHandler(aMap) {

            var map = aMap;

            g.event.addListener(map, 'click', function(event) {
                createLineBeingDragged(map, event.latLng);
            });

            function createLineBeingDragged(map, pos) {
                var line = new g.Polyline({map: map, path: [pos, pos]});
                g.event.addListener(map, 'mousemove', function(event) {
                    line.getPath().setAt(1, event.latLng);
                });
                g.event.addListener(line, 'click', function(event) {
                    g.event.clearListeners(map, 'mousemove');
                    g.event.clearListeners(line, 'click');
                    createMarkersForLine(map, line);
                });

                function createMarkersForLine(map, line) {
                    var startMarker = createMarker(line, 0);
                    var endMarker = createMarker(line, 1);
                    startMarker.nextMarker = endMarker;
                    endMarker.previousMarker = startMarker;
                }

                function createMarker(line, pathPos) {
                    var position = line.getPath().getAt(pathPos);
                    var marker = new g.Marker({map: map, position: position, visible: true, flat: true, draggable: true, raiseOnDrag: false});

                    // Marker functions
                    marker.getPathIndex = function() {
                        if (this.previousMarker != null) {
                            return this.previousMarker.getPathIndex() + 1;
                        } else {
                            return 0;
                        }
                    }

                    marker.startDrag = function(pos) {
                        if (!marker.previousMarker || !marker.nextMarker) {
                            line.getPath().insertAt(marker.getPathIndex(), pos);
                            var newMarker = createMarker(line, marker.getPathIndex());
                            if (marker.nextMarker) {
                                newMarker.previousMarker = marker;
                                newMarker.nextMarker = marker.nextMarker;
                                newMarker.nextMarker.previousMarker = newMarker;
                                marker.nextMarker = newMarker;
                            } else {
                                newMarker.nextMarker = marker;
                                newMarker.previousMarker = marker.previousMarker;
                                newMarker.previousMarker.nextMarker = newMarker;
                                marker.previousMarker = newMarker;
                            }
                        }
                    }

                    marker.beingDragged = function() {
                        line.getPath().setAt(marker.getPathIndex(), marker.getPosition());
                    }

                    // Listeners
                    g.event.addListener(marker, 'dragstart', function(event) {
                        marker.startDrag(event.latLng);
                    });

                    g.event.addListener(marker, 'drag', function(event) {
                        marker.beingDragged();
                    });

                    g.event.addListener(marker, 'click', function(event) {
                        var length = g.geometry.spherical.computeLength(line.getPath()) / 1000;
                        var infoWindow = new g.InfoWindow(
                        {
                            content: "&lt;ul&gt;&lt;li&gt;Line length: " + length.toFixed(2) + " km&lt;/li&gt;"+
                                    "&lt;li&gt;Latitude: " + marker.getPosition().lat().toFixed(6) + "&lt;/li&gt;"+
                                    "&lt;li&gt;Longitude: " + marker.getPosition().lng().toFixed(6) + "&lt;/ul&gt;"
                        });
                        infoWindow.open(map, marker);
                    });

                    return marker;
                }
            }
        }
    &lt;/script&gt;
&lt;/head&gt;
&lt;body onload="initialize()"&gt;
&lt;div id="map_canvas" style="width:100%; height:100%"&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>To start drawing, click on the map to specify the starting point and move the mouse to the end point.</p>
<p>
The highlighted function is the most interesting. It creates a marker representing one segment of the path of a <code>PolyLine</code>. The marker knows about the previous and next marker and calculates its position in the <code>MVCArray</code> of the path so that it updates the geo-position of the correct segment. This is done by the <code>getPathIndex()</code> function added to the marker.</p>
<p/>
The <code>Marker.dragStart()</code> function checks whether the marker is the first or last marker in the path. If it is, a segment is added to the <code>PolyLine</code> at the geo-position where the drag starts, and a new marker is created representing the new segment. This means that the line is extended when dragging the end markers.</p>
<p/>
The <code>Marker.beingDragged()</code> function updates the position of the segment for the <code>PolyLine</code> to the geo-position for the marker, which makes the segment 'editable'.</p>
<p/>
When clicking on a marker, the length of the line is computed using the <code>google.maps.geometry.spherical.computeLength()</code> function and an <code>InfoWindow</code> is shown displaying the length and the longitude/latitude for the selected marker.</p>
<h2>Conclusion</h2>
<p>It is possible to simulate the older Google Maps Javascript V2 functionality for editing shapes but it requires you to write your own editing functionality. The code above is just a proof-of-concept and needs a lot more love and caring to be useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/04/28/editable-lines-in-google-maps-using-javascript-v3-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Effective Terminal on OS X</title>
		<link>http://blog.jayway.com/2011/04/15/effective-terminal-on-os-x/</link>
		<comments>http://blog.jayway.com/2011/04/15/effective-terminal-on-os-x/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 12:14:21 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=7941</guid>
		<description><![CDATA[Here's a list of tips and tricks to make your OS X Terminal experience a bit more effective. Quick access to the Terminal In order not to be disctracted from your line of thoughts and leave the flow, you need to have a quick way of accessing your Terminal. That goes for other applications, and [...]]]></description>
			<content:encoded><![CDATA[<p>Here's a list of tips and tricks to make your OS X Terminal experience a bit more effective.</p>
<h1>Quick access to the Terminal</h1>
<p>In order not to be disctracted from your line of thoughts and leave the flow, you need to have a quick way of accessing your Terminal. That goes for other applications, and files, as well. I prefer to use <a href="http://qsapp.com/download.php">Quicksilver</a> myself, which pops-up a small UI with suggestions of what application, or file, to open. The UI is visible by pressing a hot-key. If you want to open the Terminal, you start writing the application name: <code>ter</code> and the Icon of the application and the name will be shown to you (in my case <code>Terminal</code>). When the right application icon is presented, you press <code>Enter</code> and the application is launched.<br />
<div id="attachment_8057" class="wp-caption alignnone" style="width: 110px"><a href="http://blog.jayway.com/wordpress/wp-content/uploads/2011/04/quicksilver.jpg" rel="lightbox"><img src="http://blog.jayway.com/wordpress/wp-content/uploads/2011/04/quicksilver.jpg" alt="The QuickSilver application" title="QuickSilver" width="100" height="109" class="size-full wp-image-8057" /></a><p class="wp-caption-text">QuickSilver UI</p></div></p>
<p/>
Quicksilver can do a whole lot of other things, I mainly use it for launching programs and occasionally to open recently opened files. Opening applications this way takes fractions of a second, compared to finding the application in the launch bar.</p>
<h1>Bash completion</h1>
<p>To work effectively from the command prompt you want to use completions when writing. For example, to navigate around in the file system with the <code>cd</code> command, you would press <code>Tab</code> to get the path filled in or get suggestions of available resources that matches what you have started to write.</p>
<p/>
OS X and bash comes with a number of these completions out of the box, but you can get even more support by installing <code>bash_completions</code>. One way of doing this is to install <a href="http://www.macports.org/install.php">MacPorts</a>, which according to their site is "an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading either command-line, X11 or Aqua based open-source software on the Mac OS X operating system."</p>
<p/>
After installing MacPorts, you can install <code>bash completion</code> by issuing:</p>
<p/>
<pre class="brush:shell">
sudo port install bash-completion
</pre>
<p/>
Then it needs to be activated, by pointing out the shell-script file from your <code>.profile</code> (or <code>.bash_profile</code> if you have one of those). Open the file <code>~/.profile</code> in a text editor and add the lines:</p>
<p/>
<pre>
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi
</pre>
<p/>
These settings are applied when you open up a new Terminal window. Depending on which file you have edited, you may have to logout and login again for the system to re-read the files.</p>
<p/>
One very nice example of the added completions is the ssh copy command <code>scp</code> that now have remote file completion support, that is if the command can access the server without having to prompt you for username/password. This can be achieved by using <a href="http://www.stocksy.co.uk/articles/Mac/ssh_on_mac_os_x/">passwordless logins</a>.</p>
<p/>
This means that you can write something like:</p>
<p/>
<pre class="brush:shell">
scp some.server.com:~/bac
</pre>
<p>and then press <code>Tab</code> to get completed with</p>
<p/>
<pre class="brush:shell">
scp some.server.com:~/backup-last-release
</pre>
<p>on the remote server. Isn't that cool?
</p>
<p>You can see a list of other programs that now have gotten bash completion support by listing the files in <code>/opt/local/etc/bash_completion.d</code> directory. Examples of supported programs are: Apache ant, ssh, MacPorts, perl, mysqladmin etc.</p>
<h2>Bash completion for subversion</h2>
<p>If use command-line subversion, installed using MacPorts, and want to add completions then you write:</p>
<pre class="brush:shell">
sudo port install subversion +tools
</pre>
<p>And activate it by adding the following lines to your <code>.profile</code> file:</p>
<pre>
if [ -f /opt/local/share/subversion/tools/client-side/bash_completion ]; then
    . /opt/local/share/subversion/tools/client-side/bash_completion
fi
</pre>
<h2>Bash completion for Git</h2>
<p>If you have installed git using MacPorts, you can get additional completions by writing:</p>
<pre class="brush:shell">
sudo port install git-core +bash_completion
</pre>
<p>and then add the following lines to your <code>.profile</code> file:</p>
<pre>
if [ -f /opt/local/share/doc/git-core/contrib/completion/git-completion.bash ]; then
    . /opt/local/share/doc/git-core/contrib/completion/git-completion.bash
fi
</pre>
<h1>Reverse history search</h1>
<p>If you often find yourself looking for previously written commands in the Terminal history by pressing the <code>Up/Down arrow</code>, you may speed up your search by activating the reverse-interactive-history-search using <code>Ctrl + R</code>. This will give you a prompt looking like:</p>
<pre class="brush:shell">
(reverse-i-search)`':
</pre>
<p>Here you can find commands in the history by writing the first letters, such as <code>cd</code> which might give you:</p>
<pre class="brush:shell">
(reverse-i-search)`cd': cd dev/myproject/target/classes
</pre>
<p>If that was the command you were looking for, press <code>Enter</code> to activate, or press <code>Ctrl + R</code> to find the next match. If you want to edit the command before activating it, you press <code>Right arrow</code>. Pressing <code>Escape</code> exits the reverse-i-search and returns to your normal prompt.</p>
<h1>History ignore</h1>
<p>If you still find yourself using the <code>Up/Down arrows</code> to navigate the history, you can make it more effective by specifying what should not appear in the history. For example, the <code>ls</code> command is probably faster to write than to find. Also the same command appearing three times in a row in the history is just annoying. </p>
<p/>
All of this can be controlled by setting the $HISTIGNORE variable. It takes a colon-separated list of ignores, where the &amp; sign is a special construct for the previous history line. To ignore the <code>ls</code> command and those pesky duplicates, you write:</p>
<pre class="brush:shell">
export $HISTIGNORE="&amp;:ls"
</pre>
<p>or better yet, add the line to your <code>.profile</code> file to have it activated all the time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/04/15/effective-terminal-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Send growl notifications from Java using a script engine and AppleScript</title>
		<link>http://blog.jayway.com/2011/04/12/send-growl-notifications-on-os-x-using-a-java-6-script-engine-and-applescript/</link>
		<comments>http://blog.jayway.com/2011/04/12/send-growl-notifications-on-os-x-using-a-java-6-script-engine-and-applescript/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 11:54:02 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[growl]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[script engine]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=7939</guid>
		<description><![CDATA[Growl is a notification system for Mac OS X and "Growl lets Mac OS X applications unintrusively tell you when things happen". The about page shows an example of what Growl looks like. If you have written a Java application and want to enable Growl notifications for it, you previously had the possibility to use [...]]]></description>
			<content:encoded><![CDATA[<p>Growl is a notification system for Mac OS X and "Growl lets Mac OS X applications unintrusively tell you when things happen". The <a href="http://growl.info/about.php">about page</a> shows an example of what Growl looks like. </p>
<p/>
If you have written a Java application and want to enable Growl notifications for it, you previously had the possibility to use cocoa Java bindings for Growl but they have been deprecated and are no longer supported. However, there is an <a href="http://growl.info/documentation/applescript-support.php">AppleScript API</a> that together with the AppleScript script engine can give access to Growl from Java. If you use Java 6 that is.</p>
<h2>The example</h2>
<p>This example code uses the Growl class, defined below, which uses the Growl AppleScript API and Java AppleScript script engine in OS X:</p>
<pre class="brush:java; gutter:false">
public class GrowlDemo {
    public static void main(String... args) {
        // System and boss messages will be enabled by default, spam must be configured in growl settings
        Growl growl = new Growl("Growl Demo",
                new String[]{"system", "boss", "spam"},
                new String[]{"system", "boss"});
        growl.init();
        growl.registerApplication();
        growl.notify("system", "System message", "This seem to be working");
        growl.notify("boss", "From: Big brother", "Get back to work!");
        growl.notify("spam", "Get a diploma", "By going to university");
    }
}
</pre>
<p>The output will look something like:<br />
<div id="attachment_7957" class="wp-caption alignnone" style="width: 322px"><a href="http://blog.jayway.com/wordpress/wp-content/uploads/2011/04/growl-notification-example.png" rel="lightbox"><img src="http://blog.jayway.com/wordpress/wp-content/uploads/2011/04/growl-notification-example.png" alt="Example of Growl notification with demo code" title="growl-notification-example" width="312" height="150" class="size-full wp-image-7957" /></a><p class="wp-caption-text">Demo code output</p></div></p>
<p/>
Now on to the Growl AppleScript API implementation.</p>
<h2>The Growl code</h2>
<p>In order to use the AppleScript engine, an engine and a context has to be retrieved. Here's an example:</p>
<p/>
<pre class="brush:java; gutter:false">
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine appleScriptEngine = scriptEngineManager.getEngineByName("AppleScript");
Script script = "&lt;AppleScript syntax goes here&gt;";
appleScriptEngine.eval(script, appleScriptEngine.getContext());
</pre>
<p/>
The rest of the code is just building the AppleScript API syntax for Growl:</p>
<p/>
<pre class="brush:java; gutter:false">
package com.jayway.growl;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * Notify with Growl using AppleScript and Java Script engine.
 *
 * @author Tobias Södergren, Jayway
 */
public class Growl {
    private static final String GROWL_APPLICATION = "GrowlHelperApp";
    private final String applicationName;
    private String[] availableNotifications;
    private String[] enabledNotifications;
    private ScriptEngine appleScriptEngine;

    public Growl(String applicationName, String[] availableNotifications, String[] enabledNotifications) {
        this.applicationName = applicationName;
        this.availableNotifications = availableNotifications;
        this.enabledNotifications = enabledNotifications;
    }

    public void init() {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        appleScriptEngine = scriptEngineManager.getEngineByName("AppleScript");
        if (appleScriptEngine == null) {
            throw new RuntimeException("No AppleScriptEngine available");
        }

        if (!isGrowlEnabled()) {
            throw new RuntimeException("No Growl process was found.");
        }
    }

    public void registerApplication() {
        String script = script().add("tell application ")
                .quote(GROWL_APPLICATION)
                .nextRow("set the availableList to ")
                .array(availableNotifications)
                .nextRow("set the enabledList to ")
                .array(enabledNotifications)
                .nextRow("register as application ")
                .quote(applicationName)
                .add(" all notifications availableList default notifications enabledList")
                .nextRow("end tell").get();
        executeScript(script);
    }

    public void notify(String notificationName, String title, String message) {
        String script = script().add("tell application ")
                .quote(GROWL_APPLICATION)
                .nextRow("notify with name ").quote(notificationName)
                .add(" title ").quote(title)
                .add(" description ").quote(message)
                .add(" application name ").quote(applicationName)
                .nextRow("end tell").get();
        executeScript(script);
    }

    private boolean isGrowlEnabled() {
        String script = script().add("tell application ")
                .quote("System Events")
                .nextRow("return count of (every process whose name is ")
                .quote(GROWL_APPLICATION).add(") > 0")
                .nextRow("end tell")
                .get();
        long count = executeScript(script, 0L);
        return count > 0;
    }

    private &lt;T&gt; T executeScript(String script, T defaultValue) {
        try {
            return (T) appleScriptEngine.eval(script, appleScriptEngine.getContext());
        } catch (ScriptException e) {
            return defaultValue;
        }
    }

    private void executeScript(String script) {
        try {
            appleScriptEngine.eval(script, appleScriptEngine.getContext());
        } catch (ScriptException e) {
            // log.error("Problem executing script, e);
        }
    }

    private ScriptBuilder script() {
        return new ScriptBuilder();
    }

    private class ScriptBuilder {
        StringBuilder builder = new StringBuilder();

        public ScriptBuilder add(String text) {
            builder.append(text);
            return this;
        }

        public ScriptBuilder quote(String text) {
            builder.append("\"");
            builder.append(text);
            builder.append("\"");
            return this;
        }

        public ScriptBuilder nextRow(String text) {
            builder.append("\n");
            builder.append(text);
            return this;
        }

        public String get() {
            return builder.toString();
        }

        public ScriptBuilder array(String[] array) {
            builder.append("{");
            for (int i = 0; i < array.length; i++) {
                if (i > 0) {
                    builder.append(", ");
                }
                builder.append("\"");
                builder.append(array[i]);
                builder.append("\"");
            }

            builder.append("}");
            return this;
        }
    }
}
</pre>
<p>That's it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/04/12/send-growl-notifications-on-os-x-using-a-java-6-script-engine-and-applescript/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Facebook Test Java API update</title>
		<link>http://blog.jayway.com/2011/03/25/facebook-test-java-api-update/</link>
		<comments>http://blog.jayway.com/2011/03/25/facebook-test-java-api-update/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 19:39:04 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=7626</guid>
		<description><![CDATA[As Feroz and Aleadam commented on my previous post, it is now possible to copy test users from one application to another in the Facebook Graph API. This functionality is now implemented in facebook-test-java-api version 1.1.4. Code example This method copies a test user to another FacebookTestUserStore instance: FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&#60;appId&#62;", "&#60;appSecret&#62;")); FacebookTestUserStore [...]]]></description>
			<content:encoded><![CDATA[<p>As Feroz and Aleadam <a href="http://blog.jayway.com/2011/02/03/java-api-for-testing-facebook-application-integration/#comments">commented on my  previous post</a>, it is now possible to copy test users from one application to another in the <a href="http://developers.facebook.com/docs/test_users/">Facebook Graph API</a>. This functionality is now implemented in <a href="http://code.google.com/p/facebook-test-java-api/">facebook-test-java-api</a> version 1.1.4.</p>
<p/>
<h2>Code example</h2>
<p>This method copies a test user to another FacebookTestUserStore instance:</p>
<pre class="brush:java">
   FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;"));
   FacebookTestUserStore facebookStore2 = new HttpClientFacebookTestUserStore("&lt;otherAppId&gt;", "&lt;otherAppSecret&gt;"));
   FacebookTestUserAccount account = facebookStore.createTestUser(true, "&lt;facebook_permissions&gt;");
   account.copyToOtherApplication(facebookStore2, true, "&lt;facebook_permissions&gt;");
</pre>
<p>This one can be used when you just want to specify the other application information</p>
<pre class="brush:java">
   FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;"));
   FacebookTestUserAccount account = facebookStore.createTestUser(true, "&lt;facebook_permissions&gt;");
   account.copyToOtherApplication("&lt;otherAppId&gt;", "&lt;otherAppSecret&gt;", true, "&lt;facebook_permissions&gt;");
</pre>
<p>Note that <code>&lt;appId&gt;</code> and <code>&lt;appSecret&gt;</code> should be replaced with the values from the application to copy from (the one owning the test user), <code>&lt;otherAppId&gt;</code> and <code>&lt;otherAppSecret&gt;</code> should be replaced with the values for the application to which the user should be copied.</p>
<h2>How to get it</h2>
<p>It is available on Maven central, use the following dependency:</p>
<pre class="brush:xml">
&lt;dependency&gt;
  &lt;groupId&gt;com.jayway.facebooktestjavaapi&lt;/groupId&gt;
  &lt;artifactId&gt;facebook-test-java-api&lt;/artifactId&gt;
  &lt;version&gt;1.1.4&lt;/version&gt;
&lt;/dependency&gt;
</pre>
<p>or have a look at the project page for downloads:<br />
<a href="http://code.google.com/p/facebook-test-java-api/">http://code.google.com/p/facebook-test-java-api/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/03/25/facebook-test-java-api-update/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java API for testing Facebook application integration</title>
		<link>http://blog.jayway.com/2011/02/03/java-api-for-testing-facebook-application-integration/</link>
		<comments>http://blog.jayway.com/2011/02/03/java-api-for-testing-facebook-application-integration/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 08:57:04 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=7081</guid>
		<description><![CDATA[Since november 2010 you may create test user accounts on Facebook for your application, so that you may test your application without creating dummy accounts and possibly break the Facebook EULA. The test users may be managed using the Facebook Graph API. The application I was working on, which integrated with Facebook, needed automated integration [...]]]></description>
			<content:encoded><![CDATA[<p>Since november 2010 you may create test user accounts on Facebook for your application, so that you may test your application without creating dummy accounts and possibly break the Facebook EULA. The test users may be managed using the <a href="http://developers.facebook.com/docs/test_users">Facebook Graph API</a>.</p>
<p>The application I was working on, which integrated with Facebook, needed automated integration tests but I could not find any Java API for managing test users. The end result is <a href="http://code.google.com/p/facebook-test-java-api/">facebook-test-java-api</a>, a project aimed at testing Facebook application integration.</p>
<h2>Usage</h2>
<pre class="brush:java">
FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;"));
FacebookTestUserAccount account = facebookStore.createTestUser(true, "");
</pre>
<p>Where <code>&lt;appId&gt;</code> and <code>&lt;appSecret&gt;</code> should be replaced with the values from your application.</p>
<p>From the FacebookTestUserAccount, you have access to the different user objects, such as the wall, friends, events etc.</p>
<pre class="brush:java">
String friendsAsJsonString = account.getFriends();
</pre>
<p>Assertions may be made on the JSON strings using your favorite toolkit, such as <code>json-path</code> (Yes Kalle, I'm looking at you. Time to release it!)</p>
<p>You can also let two test users be friends by issuing:</p>
<pre class="brush:java">
FacebookTestUserStore facebookStore = new HttpClientFacebookTestUserStore("&lt;appId&gt;", "&lt;appSecret&gt;"));

FacebookTestUserAccount account1 = facebookStore.createTestUser(true, "read-stream");
FacebookTestUserAccount account2 = facebookStore.createTestUser(true, "read-stream");

account1.makeFriends(account2);
</pre>
<p>When creating automated tests you probably want to start with a known state for your application. Use the void <code>deleteAllTestUsers()</code> method on the user store to start with an empty set of users. You can also get a list of available test users from the store by calling the <code>getAllTestUsers()</code> method.</p>
<pre class="brush:java">
List&lt;FacebookTestUserAccount&gt; users = facebookStore.getAllTestUsers();

facebookStore.deleteAllTestUsers();
</pre>
<p>For automated tests integrating with Facebook, the application need the access token for the test user to perform operations on its behalf. Here is an example of how a test case could look like.</p>
<pre class="brush:java">
FacebookTestUserAccount account = facebookStore.createTestUser(true, "email,read-stream");

systemUnderTest.doStuffIntegratingWithFacebook( account.accessToken() );

assertTrue("Wall did not contain expected data", account.getProfileFeed().contains("stuff posted on wall"));
</pre>
<h2>How to get it</h2>
<p>It is available on Maven central, use the following dependency:</p>
<pre class="brush:xml">
&lt;dependency&gt;
  &lt;groupId&gt;com.jayway.facebooktestjavaapi&lt;/groupId&gt;
  &lt;artifactId&gt;facebook-test-java-api&lt;/artifactId&gt;
  &lt;version&gt;1.0&lt;/version&gt;
&lt;/dependency&gt;
</pre>
<p>or have a look at the project page for downloads:<br />
<a href="http://code.google.com/p/facebook-test-java-api/">http://code.google.com/p/facebook-test-java-api/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2011/02/03/java-api-for-testing-facebook-application-integration/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>HP Laserjet 1020 in OS X Snow Leopard</title>
		<link>http://blog.jayway.com/2010/04/08/hp-laserjet-1020-in-snow-leopard/</link>
		<comments>http://blog.jayway.com/2010/04/08/hp-laserjet-1020-in-snow-leopard/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 06:55:00 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[laserjet]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=5315</guid>
		<description><![CDATA[I've got 3 different types of Mac computers at home, running Snow Leopard, and on each computer I've had the need to print stuff using my HP Laserjet 1020 model. Each time I used a new computer I realised that there is no built-in support for the printer and each time I had forgot the [...]]]></description>
			<content:encoded><![CDATA[<p>I've got 3 different types of Mac computers at home, running Snow Leopard, and on each computer I've had the need to print stuff using my HP Laserjet 1020 model. Each time I used a new computer I realised that there is no built-in support for the printer and each time I had forgot the steps of getting it to work. This time I figured I better blog about it, maybe someone else also have the same problem.</p>
<h3>Step 1, getting the drivers.</h3>
<ol>
<li>Go to the <a href="http://support.apple.com/kb/dl907">Apple support page</a>, click on the 'Download' button. Be aware that the file is about 350MB.</li>
<li>Install the drivers.</li>
</ol>
<h3>Step 2, select the driver</h3>
<ol>
<li> Turn on the printer and connect it to the Mac. </li>
<li> Open the printer preference page, press the '+' button to add the printer. </li>
<li> In the 'add printer' dialog, make sure that the printer is visible. Open the driver list. </li>
<li> Select HP Laserjet 1022, but not the gutenberg version.</li>
</ol>
<p>The steps above should do the trick.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2010/04/08/hp-laserjet-1020-in-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>110</slash:comments>
		</item>
		<item>
		<title>Generating diagrams in Asciidoc using Dia</title>
		<link>http://blog.jayway.com/2010/03/24/dia-diagrams-in-asciidoc/</link>
		<comments>http://blog.jayway.com/2010/03/24/dia-diagrams-in-asciidoc/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 19:59:52 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[asciidoc]]></category>
		<category><![CDATA[dia]]></category>
		<category><![CDATA[diagram]]></category>
		<category><![CDATA[documentation]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=5140</guid>
		<description><![CDATA[This article describes how Dia can be used to generate diagrams for the Asciidoc documentation toolkit. For those of you that have never worked with these products, I have added some short descriptions: This text is taken from the Asciidoc home page. Asciidoc is a text document format for writing short documents, articles, books and [...]]]></description>
			<content:encoded><![CDATA[<p>This article describes how Dia can be used to generate diagrams for the Asciidoc documentation toolkit. For those of you that have never worked with these products, I have added some short descriptions:</p>
<p>This text is taken from the <a href="http://www.methods.co.nz/asciidoc/index.html">Asciidoc home page</a>.</p>
<blockquote><p>
Asciidoc is a text document format for writing short documents, articles, books and UNIX man pages. AsciiDoc files can be translated to HTML and DocBook markups using the asciidoc(1) command.
</p></blockquote>
<p>This text is taken from the <a href="http://live.gnome.org/Dia">Dia home page</a>.</p>
<blockquote><p>
Dia is a GTK+ based diagram creation program for GNU/Linux, Unix and Windows released under the GPL license. Dia is roughly inspired by the commercial Windows program 'Visio', though more geared towards informal diagrams for casual use.
</p></blockquote>
<p><a href="http://live.gnome.org/Dia/Screenshots">Screenshots</a> for the Dia program.</p>
<p>Dia and Asciidoc is available for different linux distributions, I installed them in Ubuntu using</p>
<pre class="bash/script">
$ sudo aptitude install asciidoc dia
</pre>
<p>They can also be installed on OS X using, for example, the <a href="http://www.macports.org/">MacPorts</a> project, in which case you write:</p>
<pre class="bash/script">
$ sudo port install asciidoc
$ sudo port install dia
</pre>
<p>And then wait for a while when everything compiles..</p>
<h1>The solution</h1>
<p>Asciidoc has the possibility to import files when generating the documentation, which is a nice feature when you don't want to duplicate information and have it up-to-date. For example, it can import images, show the content of XML files, generate diagrams using various <a href="http://www.graphviz.org/">graphviz</a> syntax and so on. </p>
<p>Dia can export its diagrams to various image formats and this can be done on the command line. Using this feature of Dia it is actually possible to have Asciidoc generating image files from Dia's file format, here is how to do it:</p>
<h2>Step one, creating the Asciidoc plugin</h2>
<p>As asciidoc cannot read the native Dia's file format, it needs to trigger the export functionality of Dia. It is possible to extend Asciidoc by writing a filter, which is just a shell command reading from standard input and writing to standard output. In this specific case, the parameters to the shell process will be used and the image template functionality existing in Asciidoc will take care of reading from the generated image.</p>
<p>Asciidoc reads filter configuration files from four different locations in the following order:</p>
<ol>
<li> It looks in the user’s $HOME/.asciidoc/filters directory. </li>
<li> The global filters directory (usually /etc/asciidoc/filters or /usr/local/etc/asciidoc) directory is searched.</li>
<li> It looks in the asciidoc(1) ./filters directory. </li>
<li> It relies on the executing shell to search the environment search path ($PATH). </li>
</ol>
<p>Here I will put the filter in my home directory. Start with creating the document structure:</p>
<pre class="shell">
   $HOME/.asciidoc/filters/dia
</pre>
<p>In the <em>dia</em> directory, create the file <em>dia-filter.conf</em> with the following content:</p>
<pre class="plain">
#
# AsciiDoc Dia filter configuration file.
#
# Version: 0.1

[blockdef-listing]
dia-style=template="dia-block",subs=(),posattrs=("style","file","target","size"),filter='dia -t png -e "{outdir={indir}}/{imagesdir=}{imagesdir?/}{target}" "{outdir}/{file}" {size?-s {size}} > /dev/null'

[dia-block]
template::[image-blockmacro]
</pre>
<p>Now Asciidoc has been extended with a filter that takes the parameters <strong>file</strong>, <strong>target</strong> and <strong>size</strong> where the last parameter is optional. The next section describes how to use this filter in Asciidoc.</p>
<h2>Step two, Import Dia diagram files in Asciidoc</h2>
<p>To use the dia filter in Asciidoc, the following syntax is used:</p>
<pre class="plain text">
[dia "infile.dia", "outfile.png", "x480"]
-------------------------------
-------------------------------
</pre>
<p>The syntax above will trigger the filter and provide 'infile.dia' as source which should be a diagram saved in Dia, 'outfile.png' is the image file to be generated and create a 480 pixels wide image. Writing the size as '480x' will specify the height of the image.<br />
Don't forget the dashes, otherwise the filter will not be triggered.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2010/03/24/dia-diagrams-in-asciidoc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get nagged about keyboard shortcuts in Eclipse</title>
		<link>http://blog.jayway.com/2009/11/12/get-nagged-about-keyboard-shortcuts-in-eclipse/</link>
		<comments>http://blog.jayway.com/2009/11/12/get-nagged-about-keyboard-shortcuts-in-eclipse/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 08:29:08 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[User Experience]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=2226</guid>
		<description><![CDATA[I was attending the "The Productive Programmer: Mechanics" session, held by Neal Ford, at Oredev last week and I wanted to share one trick that will more or less force you to get faster when developing in Eclipse. The Eclipse plug-in MouseFeed, written by Andriy Palamarchuk, will repeatedly nag you with what keyboard shortcuts you [...]]]></description>
			<content:encoded><![CDATA[<p>I was attending the "The Productive Programmer: Mechanics" session, held by Neal Ford, at Oredev last week and I wanted to share one trick that will more or less force you to get faster when developing in Eclipse.</p>
<p>The Eclipse plug-in MouseFeed, written by Andriy Palamarchuk, will repeatedly nag you with what keyboard shortcuts you can use instead of using the mouse to perform actions. For example, if you constantly left-mouse-click the "step-over" button in the debug perspective, the MouseFeed plug-in will pop-up a notification window telling you to instead press "F6" on your keyboard. </p>
<p>You can also make the plug-in even more annoying by having MouseFeed canceling the mouse operation so that you have to use the keyboard shortcut.</p>
<p>I have installed it and forgotten about it until today, when it gently reminded me that collapsing all nodes in the Package Explorer view could be issued by "Shift-Command Numpad_Divide" on Mac OS X. Unfortunately my laptop does not come with a numeric keyboard so I have better to remap the shortcut if I find myself collapsing nodes often.</p>
<p>The MouseFeed home page can be found at: <a href="http://www.mousefeed.com">http://www.mousefeed.com</a><br />
The SourceForge project page: <a href="http://sourceforge.net/projects/mousefeed/">http://sourceforge.net/projects/mousefeed</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2009/11/12/get-nagged-about-keyboard-shortcuts-in-eclipse/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mocking Eclipse IResource.accept()</title>
		<link>http://blog.jayway.com/2009/01/15/mocking-eclipse-iresourceaccept/</link>
		<comments>http://blog.jayway.com/2009/01/15/mocking-eclipse-iresourceaccept/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 08:39:48 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[mock]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=761</guid>
		<description><![CDATA[I had a junit test situation where I wanted to mock an Eclipse IResource instance but still be able to test a call-back implementation given as parameter to the mocked IResource.accept(IResourceVisitor visit) method. By default, mocking an interface gives you "call count" and expected return values but no code is executed. In order to test the implementation of IResourceVisitor, something more had to be done. Here is how I did it.]]></description>
			<content:encoded><![CDATA[<p>I am currently involved in making the ClearCase plug-in for Eclipse, the one hosted at SourceForge, a bit better. Part of the job consists of creating unit tests to make sure that my fixes will stay fixed.</p>
<p>One interesting problem was that in some of my tests, I had to mock the <code>org.eclipse.core.resources.IResource</code> interface. Nothing too hard about that, just write the following code, using EasyMock 2.4:</p>
<pre class="java">&nbsp;
@Override
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #993333;">void</span> setUp<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AException+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #aaaadd; font-weight: bold;">Exception</span></a> <span style="color: #66cc66;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006600;">setUp</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
   resource1 = createMock<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;resource1&quot;</span>, IResource.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">&#41;</span>;
   resource2 = createMock<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;resource2&quot;</span>, IResource.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Now to my problem. First, I will discuss what the IResource.accept(IResourceVisitor visitor) metod does:<br />
The IResource.accept(...) method traverses the directory structure under the resource. For each resource found, starting with the IResource on which accept() was called, the visitor.visit(IResource resource) method is called. If the visit(...) method returns true, the directory structure under the resource is traversed, otherwise traversing stops for that specific resource. This way parts of the directory structure under an IResource can be visited.</p>
<p>The problem I encountered was that since I have an IResource mock, there is no code for the accept() method. The mock will just register that there has been a call for accept(), but the code in the IResourceVisitor.visit(IResource resource), which I want tested, is never called.</p>
<p>What to do? There are different solutions, one example is to use an implementation of IResource, for example <code>org.eclipse.core.internal.resources.Folder</code>, and create a partially mocked object and keep the code for accept(). Not a nice solution though, my test would depend on internal code in the Eclipse project. What I did instead was to use the <code>org.easymock.EasyMock.expectLastCall().andAnswer(IAnswer answer)</code> functionality. The andAnswer() method takes an IAnswer callback implementation, like this:</p>
<pre class="java">&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #993333;">void</span> testCollectRefreshStatus<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> CoreException <span style="color: #66cc66;">&#123;</span>
   <span style="color: #808080; font-style: italic;">// Normal mock expects</span>
   expect<span style="color: #66cc66;">&#40;</span>resource1.<span style="color: #006600;">getLocation</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">andReturn</span><span style="color: #66cc66;">&#40;</span>iPath1<span style="color: #66cc66;">&#41;</span>;
   expect<span style="color: #66cc66;">&#40;</span>iPath1.<span style="color: #006600;">toOSString</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">andReturn</span><span style="color: #66cc66;">&#40;</span>RESOURCE_PATH_1<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">times</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
   <span style="color: #808080; font-style: italic;">// Provide code for accept(...)</span>
   resource1.<span style="color: #006600;">accept</span><span style="color: #66cc66;">&#40;</span>isA<span style="color: #66cc66;">&#40;</span>IResourceVisitor.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
   expectLastCall<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">andAnswer</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> IAnswer<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AObject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #aaaadd; font-weight: bold;">Object</span></a> answer<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AThrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #aaaadd; font-weight: bold;">Throwable</span></a> <span style="color: #66cc66;">&#123;</span> <span style="color: #808080; font-style: italic;">// 1.</span>
        IResourceVisitor visitor = <span style="color: #66cc66;">&#40;</span>IResourceVisitor<span style="color: #66cc66;">&#41;</span> EasyMock.<span style="color: #006600;">getCurrentArguments</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span>; <span style="color: #808080; font-style: italic;">// 2.</span>
        visitor.<span style="color: #006600;">visit</span><span style="color: #66cc66;">&#40;</span>resource2<span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// 3.</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">null</span>;
      <span style="color: #66cc66;">&#125;</span>
   <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
   expect<span style="color: #66cc66;">&#40;</span>resource2.<span style="color: #006600;">getName</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">andReturn</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;file.txt&quot;</span><span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">// 4.</span>
&nbsp;
   replayMocks<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
   <span style="color: #808080; font-style: italic;">// Perform test</span>
   myTestTarget.<span style="color: #006600;">someMethod</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
   <span style="color: #808080; font-style: italic;">// Verify test</span>
   assertEquals<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>, myTestTarget.<span style="color: #006600;">getNumberOfResources</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
   verifyMocks<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;</pre>
<p>Here are some comments to the marked lines in the code above:</p>
<p>1. The answer() method is dictated by the IAnswer interface.<br />
2. EasyMock provides a method to get access to the objects sent as parameters for the expected call. In this case, the call is resource1.accept(...) and the parameter is the IResourceVisitor implementation defined in myTestTarget, which is the code that should be tested.<br />
3. Here the test code has control of the call to the IResourceVisitor.visit() and a mock IResource is provided as parameter. To make the test even better, the boolean return value from the visit() call should be saved and asserted for the correct value to ensure that the intended traversing works as expected.<br />
4. Here the expectations on the mock IResource, for the visit(IResource ...) call, is defined. In this case myTestTarget calls getName() on IResource for some reason, so expectations for that is defined together with a resulting return value that would steer the logic in some direction.</p>
<p>This way the test has full control of the visitor implementation and it is fairly easy to test all the criterias that makes the IResourceVisitor.visit(...) implementation return true or false. Also, the visit() method often changes state of something else, and here it is also possible to test that the state is changed correctly by simulating multiple visit(...) calls, by adding more calls to visit at 3. in the code above. </p>
<p>/Tobias S&ouml;dergren</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2009/01/15/mocking-eclipse-iresourceaccept/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EclipseCon 2008  &#8211; Santa Clara, California</title>
		<link>http://blog.jayway.com/2008/05/01/eclipsecon-2008-santa-clara-california/</link>
		<comments>http://blog.jayway.com/2008/05/01/eclipsecon-2008-santa-clara-california/#comments</comments>
		<pubDate>Thu, 01 May 2008 12:38:59 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[jayview]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=3134</guid>
		<description><![CDATA[EclipseCon 2008 took place between the 17:th and the 20:th of March and was held in Santa Clara, California. It is an event for, maybe not that surprising, people working with Eclipse, OSGi and sub-projects built on the Eclipse platform. This year there were 1400 visitors spread out among the four event days. EclipseCon is [...]]]></description>
			<content:encoded><![CDATA[<p><strong>EclipseCon 2008 took place between the 17:th and the 20:th of March and was held in Santa Clara, California. It is an event for, maybe not that surprising, people working with Eclipse, OSGi and sub-projects built on the Eclipse platform. This year there were 1400 visitors spread out among the four event days. EclipseCon is co-hosted with OSGi DevCon which focuses on the OSGi technology and surrounding projects. </strong></p>
<h2>Lots of tutorials</h2>
<p>The first day was the tutorial day with 22 simultaneous labs and tutorials. All in<br />
all there were about 80 sessions that you could attend, including “An introduction<br />
to Pax tools for OSGi” hosted by Stuart. Unfortunately we did not have time to<br />
see all of the tutorials, and it was often difficult deciding which ones to attend. </p>
<p>The sessions ranged from “introduction” to “advanced” in both core Eclipse, such as Equinox and the Debugger frameworks, and in the variety of sub-projects such as GMF, eRCP, BIRT etc. One interesting session was about the new debugger service framework, abbreviated as DSF, which supports asynchronous calls to and callbacks from the debug target. Much of the framework is dealing with the issues that stem from working asynchronously. </p>
<p>The framework is created by Windriver, a big player in C/C++ development for embedded devices, because debugging embedded devices in most cases has a different nature than debugging Java code. Embedded devices often have slow communication links and the response often come in data chunks because of optimization issues. These characteristics do not fit well with the standard debugging framework in Eclipse. </p>
<p>The OSGi tutorials were well attended, with the Spring Dynamic Modules tutorial almost standing room only. It was also good to see a lot of interest in the OSGi service registry from plugin developers, who are more used to the Eclipse extension point registry. The overall feeling was that most people knew the basics of OSGi and were now eager to learn best practices and more advanced use. </p>
<h2>Fake Steve Jobs</h2>
<p>Tuesday was the starting day of the “ordinary” conference. The keynote speaker was Dan Lyon a.k.a Fake Steve Jobs. Dan Lyon has been working as a tech writer for many years, and started his blog called Fake Steve Jobs where he was writing tech articles as he thought Steve Job would have written them. After a while, people started to try and guess who this Fake Steve guy was and ultimately his own boss was discussing it openly, to his surprise. Dan had no choice but to come clean, but the popularity of the blog still remained. Sun, Microsoft, Oracle and even Eclipse get hit by his wild bashes, where the latter was something he was nervous about, being a keynote speaker at EclipseCon. But not everything is fictional and as he put it: - People are returning because I occasionally put some seriousness in my blog entries. </p>
<h2>Services vs. Extensions </h2>
<p>Among the interesting sessions for the day, was a session by Neil Bartlett regarding how to integrate Eclipse Extensions in OSGi services and vice versa. Eclipse extensions are the base for how plug-ins extend the Eclipse platform, such as adding menu entries, dialogs, wizards etc. to the workbench. OSGi is the platform on which Eclipse plug-ins are implemented, and it provides modularity and dynamic services. By using extensions and OSGi services it is possible to write very modular applications which supports lazy loading, being robust and dynamic in nature. </p>
<h2>Services + Extensions using dependency injection</h2>
<p>Neil also gave a talk on how dependency injection could bridge the gap between extension points and services. This is a very promising approach because it would free developers from having to decide which one to use in their components, and this decision could then be made at configuration/ deployment time. The prototype work is now being continued in an official Eclipse incubator project. </p>
<h2>Automatically repairing pre-OSGi code</h2>
<p>Erik Wistrand from Makewave (Knopflerfish framework) had a short talk on using bytecode manipulation at load-time to automatically detect and repair potentially problematic legacy code. This is a popular topic at the moment, as many people are looking at how to migrate their current applications to OSGi so they can start taking advantage of OSGi for new components. </p>
<h2>OSGi on Android</h2>
<p>In another session, Neil Bartlett and BJ Hargrave, a senior manager at IBM, were<br />
presenting how they got two different open-source OSGi containers running on the Google Android mobile platform. Both Equinox, the OSGi container developed by Eclipse, and Concierge which is a small container and a research project developed at ETH Zurich, were running on the Android emulator. </p>
<p>Other OSGi frameworks able to run on Android are Apache Felix, which was the first container running on it, and mBedded Server, which is a commercial OSGi container developed by ProSyst. Being able to run is not the same as being supported by Google though, but it is interesting to see that there was not that much work involved in introducing OSGi to Android. </p>
<h2>Open Source Microsoft</h2>
<p>Wednesday started off with a keynote from Sam Ramji, director of the Open Source Software Lab at Microsoft. Knowing that the audience was probably quite skeptical about Microsoft’s relationship with open-source Sam’s first slide was about project “Supernova”, where Microsoft decides to buy Eclipse and use it for Visual Studio because they really love Java! After that ice-breaker, Sam went on to discuss some of the open-source projects his lab works on, such as dynamic languages, and how Microsoft has much more focus on interoperability these days. He already has developers working with Mozilla and Apache, but more relevant for Eclipse, they are looking at helping with SWT (Standard Widget Toolkit) support for WPF (Windows Presentation Foundation).However, during the Q&A session Sam said there’s no plan for Microsoft to join Eclipse, or even have their developers become committers, which made this sound like a token effort. </p>
<h2>Eclipse 4.0</h2>
<p>The initial work of Eclipse 4.0 was presented by Mike Wilson, Jochen Krause, Jeff McAffer and Steve Northover. The current state is “wild ideas” and the trends getting focus in this release are that Java software development is moving into Rich Web GUI backed by services, and that the IDE will move to be a mix of web and desktop targets. The presenters want to see an effort to take what currently exists and put it “in the web space”. </p>
<p>The community work in Eclipse is quite good today, but people need to be much more involved in the future platform. </p>
<p>They also want to see that work is put into making it easier to create plug-<br />
ins with a more uniform API in Eclipse. There will probably be some kind of dependency injection framework available to make it easier to use services and resources. The platform should be better documented, the API should be reasonably sized, and the API should be RESTful and accessible by JavaScript. </p>
<p>The timeline for e4 (Eclipse 4.0 platform) is that the project will be proposed and started after the Eclipse Summit later this year. Until now, everything is ideas that may or may not be included in the project. There will be regular platform builds of e4, including milestones, and it will be ready within 2 years from start. </p>
<p>It will not be an easy task to create the next version of the Eclipse platform, because of its widespread use and the many wills of the multitude of Eclipse projects. The time when Eclipse was just a Java IDE is now long gone and there are a lot of people that have invested a lot, both in time and money, in their existing projects. </p>
<h2>API Tooling</h2>
<p>Among the things that make OSGi, and also the plug-in concept of Eclipse, great is the possibility of having different versions of the same functionality available for applications without conflict. One application might need version 1.x of a jar file while another requires an API incompatible version 2.x, and with proper versions on the packages there will be no conflict. Although being a good thing, it can be quite challenging to keep the versions correctly updated. Sometimes the changes you do to a code base might break an API compatibility, sometimes not. To remedythe situation in Eclipse, there is a new toolkit called “API Tooling”. The description, which is taken directly from the developer site, states: “API tooling will assist developers in API maintenance by reporting API defects such as binary incompatibilities, incorrect plug-in version numbers, missing or incorrect @since tags, and usage of non-API code between plug-ins”. An example of functionality in the toolkit is that offending code is marked in eclipse and quick-fix will be provided for changes that can be automated. The tools are scheduled to be included in the Eclipse Ganymede release in June. </p>
<h2>Information Economy </h2>
<p>Thursday’s keynote was given by Cory Doctorow about the “information economy” where information is a commodity, and you should therefore try to keep the cost of “creating” information low. This was a very entertaining talk where he stressed the importance of collaboration over restricting access. With collaboration you can (hopefully) still maintain a competitive edge - while restricting access to information is a temporary solution that often drives up costs, like old fashioned protectionism. Cory finished by asking everyone to help preserve their existing freedoms, such as the freedom on the Internet. </p>
<h2>Some reflections</h2>
<p>It was nice to see that that OSGi as a concept has matured among both the speakers and visitors as opposed to last years EclipseCon where it was more in a state of hype and excitement. It was also interesting that OSGi is creeping into mobile phones, Spring revealed their Titan platform for Windows Mobile phones containing an OSGi container besides being MIDP compatible. Another announcement made during the conference was that EclipseLink has been chosen as the JPA 2.0 Reference implementation. </p>
<p><em>Tobias Södergren and Stuart McCulloch</em></p>
<p><em>Originally published in <a href="http://jayway.se/jayview">JayView</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2008/05/01/eclipsecon-2008-santa-clara-california/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forensic tools,  part 2</title>
		<link>http://blog.jayway.com/2008/05/01/forensic-tools-part-2/</link>
		<comments>http://blog.jayway.com/2008/05/01/forensic-tools-part-2/#comments</comments>
		<pubDate>Thu, 01 May 2008 09:14:21 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[bin]]></category>
		<category><![CDATA[jayview]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=3093</guid>
		<description><![CDATA[Have you ever been in the situation that an application behaves in strange ways and by the time you find out, you do not have access to your development environment. In this article we are discussing ways to pin- point the problem with tools available in the Sun SDK bin directory. In the first part [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Have you ever been in the situation that an application behaves in strange ways and by the time you find out, you do not have access to your development environment. In this article we are discussing ways to pin- point the problem with tools available in the Sun SDK bin directory. </strong></p>
<p>In the first part of this article, which can be found in the previous JayView, the monitoring tools of the Sun JDK 1.5 was presented. These monitoring tools can be a good start for looking at the current status, and behavior over time, for an application. While these tools can tell you some parts of the doings of an application, finding a problem is sometimes more effective using the troubleshooting tools. This second part of the article will present some of these tools. </p>
<h2>Tools overview </h2>
<p>The list below contains all tools presented in this article, where the first four can<br />
be found in part one.</p>
<p><img src="http://blog.jayway.com/wordpress/wp-content/uploads/2008/05/Picture-641.png" alt="Tools" title="Tools" width="526" height="336" class="alignnone size-full wp-image-3291" /></p>
<p>Note: A known issue for OSX require that some of the tools is run as root, which can be accomplished by putting ‘sudo ‘ before each command. </p>
<h2>Troubleshooting tools</h2>
<p>The troubleshooting tools provided by Sun Microsystems in the JDK bin directory are to be considered experimental. They come with no support and they might harm your system. Although being in an experimental state, the tools can be quite useful when looking for problems. </p>
<p>Some of the tools can connect to a locally or remotely running Java process, others operate on a core dump. This dump can be created by the JVM, by specifying Sun Hotspot specific flags such as <strong>-XX:+HeapDumpOnCtrlBreak</strong> or<br />
<strong>-XX:+HeapDumpOnOutOfMemoryError</strong>. These flags should be appended to the java command just like system properties: </p>
<pre>> java -XX:+HeapDumpOnOutOfMemoryError -jar application.jar</pre>
<p>The core dump can also be created with jmap and the syntax is described below. Be aware that the jmap of JDK 1.5 have some problems creating this core dump, sometimes it creates a corrupted file. This specific issue with jmap is fixed in Java 6. </p>
<h2>jinfo </h2>
<p>The jinfo tool connects to a running local process, a JVM core dump or a remote<br />
process. The purpose of the tool is to display the VM flags used and the values of<br />
the system properties for the process in question. The process id, or VMID, can be found using the jps command. Here is an example connecting to a running process with process id 1649:</p>
<pre>> jinfo -flags 1649
Attaching to process ID 1649, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_07-87
-Duser.property=somevalue </pre>
<p>In the example above, you can see that the Java application was started using the flag ‘user.property’. To see the system properties, use the -sysprops flag: </p>
<pre>> jinfo -sysprops 1649
Attaching to process ID 1649, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_07-87
java.runtime.name = Java(TM) 2 Runtime Environment, Standard Edition
sun.boot.library.path = /System/Library/Frameworks/JavaVM.framework/
Versions/1.5.0/Libraries
java.vm.version = 1.5.0_07-87
java.vm.vendor = ”Apple Computer, Inc.”
java.vendor.url = http://apple.com/
path.separator = :
   ...
</pre>
<p>The jinfo command can give a quick hint about what a java process can see from its environment.</p>
<h2>jstack </h2>
<p>The jstack command prints out the execution stack trace for threads for a process in the local JVM, a remote JVM or in a core dump. It also prints out thread deadlocks detected by the Hotspot VM, something that can come in handy for<br />
solving threading issues. The command for connecting to a local process looks like: </p>
<pre>
> jstack 1649
Attaching to process ID 1649, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_07-87 

Thread t@4099: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=44, line=116 (Interpreted
frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=132 (Interpreted
frame)
 - java.lang.ref.Finalizer$FinalizerThread.run() @bci=3, line=159
(Interpreted frame)
...
Thread t@4611: (state = IN_NATIVE)
 - java.io.FileInputStream.readBytes(byte[], int, int) @bci=0
 - java.io.FileInputStream.read(byte[], int, int) @bci=4, line=194
 - java.io.BufferedInputStream.read1(byte[], int, int) @bci=39, line=254
 - java.io.BufferedInputStream.read(byte[], int, int) @bci=49, line=313
 - sun.nio.cs.StreamDecoder$CharsetSD.readBytes() @bci=135, line=411
 - sun.nio.cs.StreamDecoder$CharsetSD.implRead(char[], int, int) @bci=112,
line=453
 - sun.nio.cs.StreamDecoder.read(char[], int, int) @bci=180, line=183
 - java.io.InputStreamReader.read(char[], int, int) @bci=7, line=167
 - java.io.BufferedReader.fill() @bci=145, line=136
 - java.io.BufferedReader.readLine(boolean) @bci=44, line=299
 - java.io.BufferedReader.readLine() @bci=2, line=362
 - se.jayway.jconsole.test.Application.run() @bci=29, line=24
 - se.jayway.jconsole.test.Application.main(java.lang.String[]) @bci=9,
line=14
</pre>
<p>In the example above, we can see that the Application.main( ) method is spending time in FileInputStream.readBytes( ).</p>
<h2>jmap</h2>
<p>This versatile command prints out information using the following flags:</p>
<ul>
<li> <strong>- heap</strong> prints out heap information, including the different memory pools
<li> <strong>- heap:format=b</strong> dumps the heap in a binary format
<li> <strong>- histo</strong> prints class histogram information of the object heap
<li> <strong>- permstat</strong> prints information class loader-wise about data in the permanent generation memory pool. The permanent generation memory pool contains class meta data and the String literals.
</ul>
<pre>> jmap -heap 1649
Attaching to process ID 1649, please wait...
...
using thread-local object allocation.
Mark Sweep Compact GC 

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize      = 67108864 (64.0MB)
NewSize          = 655360 (0.625MB)
...
</pre>
<p>In the example above only the first part of the heap information is printed, there’s a lot more to see. </p>
<pre>> jmap -histo 1649
Object Histogram:
Size    Count   Class description
-------------------------------------------------------
194408  1025    char[]
102840  160     byte[]
16032   668     java.lang.String
13208   297     java.lang.Object[]
8208    27      * ObjArrayKlassKlass
...
</pre>
<p>Above, the first part of the class histogram is printed for the process with VMID 1649. </p>
<pre>> jmap -heap:format=b 1649
Attaching to process ID 1649, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_11-b03
Unknown oop at 0x889ec790
Oop’s class is null
heap written to heap.bin </pre>
<p>The heap is dumped for the process with VMID 1649 in the example above, and the result is a file called heap.bin. </p>
<p>The jmap -heap and jstat with a suitable garbage collection flag can help with finding memory issues for object instances. Jmap -histo and jmap -permstat can be used for finding memory leaks in permanent generation memory space, e.g. when there are too many classes loaded by class loaders that never get garbage collected. </p>
<p>The jmap -heap:format=b flag has issues with the heap dump sometimes being corrupted, an issue which is fixed for Java 6. When the command is working the heap dump can be analyzed using tools described above and with a tool called jhat, which is bundled with Java 6 SDK. It is also possible to debug the heap dump using the java debugger, called jdb, which also can be found in the bin directory. </p>
<p>I recommend taking a look at jhat, which is a heap analysis tool that processes heap dumps. When invoking jhat it starts with analyzing all objects found in the heap core dump. After the analysis is finished a web server is launched. Use an ordinary web browser to connect to the web server to get access to the object browsing functions available. </p>
<p>One example of a function is the one that makes it possible to filter out weak<br />
references between objects, so that objects that are not eligible for garbage collection can be found. It is also possible to use OQL (Object Query Language) where you can use an SQL-like syntax to get object set results, such as the number of instances for a specific object type, the value for all String objects etc. </p>
<p>The jhat tool is available in Java 6 but can be downloaded from Sun for Java 1.5. </p>
<p>To conclude this article, the monitoring and troubleshooting tools found in the bin directory for the JDK provided by Sun can be a good start when finding bugs in your java code. Use them, you might already have them on your computer. </p>
<p><em>Originally published in <a href="http://jayway.se/jayview">JayView</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2008/05/01/forensic-tools-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forensic tools, part 1</title>
		<link>http://blog.jayway.com/2008/02/01/forensic-tools-part-1/</link>
		<comments>http://blog.jayway.com/2008/02/01/forensic-tools-part-1/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 11:57:50 +0000</pubDate>
		<dc:creator>Tobias Södergren</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[bin]]></category>
		<category><![CDATA[jayview]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.jayway.com/?p=3418</guid>
		<description><![CDATA[There are times when you really would like to know what the Java processes on the computer are doing at this very moment. Maybe the computer seems a bit sluggish, maybe the disk LED is not so much flashing but instead glowing constantly. Other times an application might seem just dead. A possible scenario You [...]]]></description>
			<content:encoded><![CDATA[<p><strong>There are times when you really would like to know what the Java processes on the computer  are doing at this very moment. Maybe the computer seems a bit sluggish, maybe the disk LED  is not so much flashing but instead glowing constantly. Other times an application might seem  just dead. </strong></p>
<h2>A possible scenario</h2>
<p>You have started up an application, let’s say it is a web application which is running in an  application server. After a while you notice that the application is behaving oddly. You cannot really  put your finger on the problem, but sometimes it looks like the web pages are not served as they  should. The application also feels slower than you expect.<br />
First thing could be to check out the log files, but as you all know, the debug level<br />
is set to INFO or  WARNING because the application is in production: </p>
<pre>10:10:40.542 INFOStarting  application...
10:12:21.650 INFOAll  service started.
10:14:22.145 INFOApplication  booted successfully. </pre>
<p>What conclusion do you draw from this output? The application has started and it<br />
looks like nothing  serious has detected in the code that is worth mentioning in the<br />
log. Is it time to start guessing or  just ignore the gut feeling  you have? Not quite yet,<br />
there are some help to be found not far away, and  it will not cost you a dime. </p>
<h2>Bring  out  the  tools</h2>
<p>In your Java SDK 1.5 (or higher) “bin” directory, there are tools that can be quite us-<br />
able for poking  around in the Java processes. There are different number of tools for<br />
different platforms and the  number of available functions per tool is also depending<br />
on the distribution. Sun Solaris and Linux  Java distributions have been blessed with<br />
the most number of tools and functions, Mac OSX and  Windows have the least.<br />
Also, the tools are getting constantly improved for newer releases of Java. </p>
<p>Here is a comprehensive list of the tools mentioned in this article and on which<br />
platforms they exist: </p>
<p><img src="http://blog.jayway.com/wordpress/wp-content/uploads/2009/12/Picture-811.png" alt="Figure 1" title="Figure 1" width="432" height="423" class="alignnone size-full wp-image-3419" /></p>
<p>This article consists of two parts, and this first part goes through the available moni-<br />
toring tools in  the Sun Java 1.5 SDK bin directory. </p>
<h2>Monitoring  tools</h2>
<h3>jps </h3>
<p>To see which java processes that are currently running on a machine use the  <strong>jps</strong><br />
command: </p>
<pre>> jps
1649 Application
2533 Jps </pre>
<p>The resulting output lists the VMID (Virtual Machine ID) and the Java process<br />
name. To get  extended information, append the  <strong>-v</strong>  flag to the jps command: </p>
<pre>
> jps v
1649  Application
2534 Jps
-Dapplication.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/
Home
-Xms8m </pre>
<h3>jstat</h3>
<p>This command gives performance statistic information from the JVM for a Java<br />
process. There are a  number of statistic options available, which is displayed using<br />
the  <strong>-options</strong>  switch:</p>
<pre>> jstat -options
-class
-compiler
-gc
-gccapacity
...
</pre>
<p>To print the statistics for one of the options above for a process, the VMID has to<br />
be specified after  the option. The VMID is the same id as listed with the  <strong>jps</strong> com-<br />
mand: </p>
<pre>> jstat -gcutil  1649
S0  S1  E  O  P  YGC  YGCT  FGC  FGCT  GCT
0,00  0,00  78,32  0,00  0,24  0  0,000  0  0,000  0,000
</pre>
<p>Using the jstat command, it is possible to create scripts that periodically checks the<br />
status for e.g.  the number of loaded classes or the garbage collection utilization. In<br />
the example above, the garbage  collection has taken place mostly in Eden memory<br />
space. Eden space is Sun Hotspot specific  memory space for shortlived  objects.<br />
Information about memory pools can be found at  http://java.sun.com. </p>
<h3>jstatd </h3>
<p>This command starts up a  <strong>jstat</strong> daemon on a machine and enables remote monitor-<br />
ing. To startup the  daemon on the computer which should be monitored, the port<br />
number where the remote clients can  connect to has to be specified: </p>
<pre>> jstatd -p  12345
</pre>
<p>After that, it is possible to use both <strong>jps</strong> and  <strong>jstat</strong> remotely by specifying the host-<br />
name and port: </p>
<pre>> jps example.computer.org:12345
2617 Jps
2611 Jstatd
1649 Application
</pre>
<p>The above example lists the processes on the ‘example.computer.org’ host using the<br />
port 12345.  Presented in the output, you can see the  <strong>jstatd</strong> is also a java process.</p>
<pre>> jstat  -gcutil  1649@example.computer.org:12345
S0  S1  E  O  P  YGC  YGCT  FGC  FGCT  GCT
0,00  0,00  78,32 0,00  0,24  0  0,000  0  0,000  0,000
</pre>
<p>Above we can see the same example for process 1649 as in the previous command,<br />
but this time  listed for host ‘example.computer.org’ using port 12345. </p>
<h3>jconsole </h3>
<p>On client computers, or servers with a graphical interface, it is possible to monitor<br />
the JVM status  by using a tool called  <strong>jconsole</strong>. The  <strong>jconsole</strong> tool visualizes services<br />
that exposes a JMX (Java  Management Extension) interface, and Java 1.5 and later<br />
contains JMX beans for exposing the data  defined in the java.lang.management<br />
package. </p>
<p>To be able to monitor java applications using  <strong>jconsole</strong> in Java 1.5, the application<br />
has to be started  with the system property <strong>-Dcom.sun.management.jmxremote</strong>.<br />
Example: </p>
<pre>> java -Dcom. sun.management.jmxremote jar  testapp.jar </pre>
<p>When the application has started, the  <strong>jconsole</strong> can be initiated: </p>
<pre>> jconsole </pre>
<p>The connection <strong>console</strong> displays all java processes that has JMX enabled.  After con-<br />
necting to the  Java process, jconsole provides the following tabs: </p>
<ul>
<li>		Summary	Tab
<li>		Memory	Tab	–	The	different	memory	pools	can	be	inspected
<li>		Thread	Tab	–	The	total,	peak	and	currently	live	threads	are	displayed
<li>		Classes	Tab	–	The	number	of	classes	are	displayed
<li>		Mbeans	Tab	–	Gives	access	to	the	JMX	beans	in	the	management	package
<li>		VM	Tab	–	Displays	information	for	the	VM	where	the	application	is	running	in
</ul>
<p>Below are example screenshots for the memory and thread tab:  </p>
<p><img src="http://blog.jayway.com/wordpress/wp-content/uploads/2009/12/Picture-82.png" alt="Figure 2" title="Figure 2" width="430" height="650" class="alignnone size-full wp-image-3420" /></p>
<p>The  <strong>jconsole</strong> application can be a tool to start with when looking at application<br />
behavior over time,  such as memory leaks or unusual thread behavior. </p>
<p>Using the Java monitoring and management tools you can get a better understanding<br />
of the runtime behavior of your application. Sometimes this information is enough<br />
for finding and fixing a problem. </p>
<p>This concludes the first part of the article. In the next issue of JayView we will look<br />
into the  troubleshooting tools. </p>
<p><em>Originally published in <a href="http://jayway.se/jayview">JayView</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jayway.com/2008/02/01/forensic-tools-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

