<?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>Mikael Ståldal's technical blog</title>
	<atom:link href="http://www.staldal.nu/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.staldal.nu/tech</link>
	<description>Programming and software</description>
	<lastBuildDate>Tue, 22 Jun 2010 10:06:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Using Vaadin with Maven</title>
		<link>http://www.staldal.nu/tech/2010/06/09/using-vaadin-with-maven/</link>
		<comments>http://www.staldal.nu/tech/2010/06/09/using-vaadin-with-maven/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 11:44:39 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=125</guid>
		<description><![CDATA[Vaadin is a comprehensive framework for developing web applications in Java. The Vaadin web site presents a number of ways to use Vaadin with Maven, but I am not completely satisfied with any of those. Here is how I do it. Use a pom.xml like this: &#60;?xml version="1.0" encoding="UTF-8"?&#62; &#60;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"&#62; &#60;modelVersion&#62;4.0.0&#60;/modelVersion&#62; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://vaadin.com/">Vaadin</a> is a comprehensive framework for developing web applications in Java. The Vaadin web site presents a number of ways to use Vaadin with <a href="http://maven.apache.org/">Maven</a>, but I am not completely satisfied with any of those. Here is how I do it.</p>
<p>Use a <code>pom.xml</code> like this:</p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;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"&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

	&lt;groupId&gt;com.thecompany&lt;/groupId&gt;
	&lt;artifactId&gt;theapp&lt;/artifactId&gt;
	&lt;version&gt;1.0&lt;/version&gt;
	&lt;packaging&gt;war&lt;/packaging&gt;
	&lt;name&gt;The App&lt;/name&gt;

	&lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;com.vaadin&lt;/groupId&gt;
            &lt;artifactId&gt;vaadin&lt;/artifactId&gt;
            &lt;version&gt;6.3.3&lt;/version&gt;
        &lt;/dependency&gt;
	&lt;/dependencies&gt;

	&lt;build&gt;
		&lt;plugins&gt;
	        &lt;plugin&gt;
	            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
	            &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
	            &lt;configuration&gt;
	              &lt;overlays&gt;
	                &lt;overlay&gt;
		              &lt;groupId&gt;com.vaadin&lt;/groupId&gt;
		              &lt;artifactId&gt;vaadin&lt;/artifactId&gt;
		              &lt;type&gt;jar&lt;/type&gt;
		              &lt;includes&gt;
		                &lt;include&gt;VAADIN/**&lt;/include&gt;
		              &lt;/includes&gt;
	                &lt;/overlay&gt;
	              &lt;/overlays&gt;
	            &lt;/configuration&gt;
	         &lt;/plugin&gt;

		&lt;plugin&gt;
			&lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
			&lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
			&lt;version&gt;6.1.17&lt;/version&gt;
		&lt;/plugin&gt;
        &lt;/plugins&gt;
	&lt;/build&gt;
&lt;/project&gt;
</pre>
<p>And a <code>src/main/webapp/WEB-INF/web.xml</code> like this:</p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;

	&lt;context-param&gt;
	    &lt;param-name&gt;productionMode&lt;/param-name&gt; &lt;!-- Vaadin parameter --&gt;
	    &lt;param-value&gt;true&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;servlet&gt;
		&lt;servlet-name&gt;TheApp&lt;/servlet-name&gt;
		&lt;servlet-class&gt;com.vaadin.terminal.gwt.server.ApplicationServlet&lt;/servlet-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;application&lt;/param-name&gt;
			&lt;param-value&gt;com.thecompany.theapp.TheApp&lt;/param-value&gt;
		&lt;/init-param&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;TheApp&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/theapp/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre>
<p>In this way, the <code>VAADIN</code> directory with themes and widgetsets from <code>vaadin.jar</code> will be automatically copied to the produced web-app where it can be served as static content for optimal performance. You can also put your own themes under <code>src/main/webapp/VAADIN/themes</code> and they will be merged with the default themes.</p>
<p>Build a <code>.war</code> file for your application using <code>mvn package</code>. You can also quickly test it using Jetty by running <code>mvn jetty:run-exploded</code> (<code>jetty:run</code> won&#8217;t work properly).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2010/06/09/using-vaadin-with-maven/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implementing POX Web Services with Spring WS and JAXB</title>
		<link>http://www.staldal.nu/tech/2010/04/29/implementing-pox-web-services-with-spring-ws-and-jaxb/</link>
		<comments>http://www.staldal.nu/tech/2010/04/29/implementing-pox-web-services-with-spring-ws-and-jaxb/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 16:37:18 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=112</guid>
		<description><![CDATA[Spring Web Services together with JAXB 2.0 provides a convenient way to implement POX Web Services in Java. POX means Plain Old XML, and a POX Web Service is a protocol based on sending XML over HTTP without using any well-known protocol framework like SOAP or XML-RPC. First you have to define annotated JAXB classes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://static.springsource.org/spring-ws/sites/1.5/">Spring Web Services</a> together with <a href="http://java.sun.com/javase/6/docs/technotes/guides/xml/jaxb/index.html">JAXB 2.0</a> provides a convenient way to implement POX Web Services in Java.</p>
<p>POX means <cite>Plain Old XML</cite>, and a POX Web Service is a protocol based on sending XML over HTTP without using any well-known protocol framework like <a href="http://en.wikipedia.org/wiki/SOAP">SOAP</a> or <a href="http://en.wikipedia.org/wiki/XML-RPC">XML-RPC</a>.</p>
<p>First you have to define annotated JAXB classes for all XML request and response messages. If you have a schema, you can generate them with the <a href="https://jaxb.dev.java.net/nonav/2.0.2/docs/xjc.html"><code>xjc</code> tool</a>. Or you can create and annotate them manually. It can be a good idea to make one abstract base class for all requests, and one for all responses.</p>
<p>Then create a <code>WEB-INF/spring-ws-servlet.xml</code> file:</p>
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:oxm="http://www.springframework.org/schema/oxm"
	xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
      http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd"&gt;

	&lt;context:annotation-config /&gt;
	&lt;context:component-scan base-package="com.acme.coolservice" /&gt;

        &lt;oxm:jaxb2-marshaller id="marshaller" contextPath="com.acme.coolservice.jaxb" /&gt;
	&lt;bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" /&gt;
	&lt;bean id="messageFactory" class="org.springframework.ws.pox.dom.DomPoxMessageFactory" /&gt;
	&lt;bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter"&gt;
	    &lt;property name="marshaller" ref="marshaller" /&gt;
	    &lt;property name="unmarshaller" ref="marshaller" /&gt;
	&lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p>And finally implement your service endpoint class like this:</p>
<pre>
package <em>com.acme.coolservice.pox</em>;

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

import <em>com.acme.coolservice.jaxb.*</em>;

@Endpoint
public class CoolServiceEndpoint {

    @PayloadRoot(localPart="foo")
    public FooResponse foo(FooRequest request) {
        return new FooResponse();
    }

    @PayloadRoot(localPart="bar")
    public BarResponse bar(BarRequest request) {
        return new BarResponse();
    }

}
</pre>
<p>You can also make a client by adding this to your Spring context file:</p>
<pre>
    &lt;oxm:jaxb2-marshaller id="marshaller" contextPath="<em>com.acme.coolservice.jaxb</em>" /&gt;
    &lt;bean id="messageFactory" class="org.springframework.ws.pox.dom.DomPoxMessageFactory" /&gt;
    &lt;bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"&gt;
        &lt;property name="defaultUri" value="<em>server-URI</em>"/&gt;
        &lt;property name="marshaller" ref="marshaller"/&gt;
        &lt;property name="unmarshaller" ref="marshaller"/&gt;
        &lt;property name="messageFactory" ref="messageFactory"/&gt;
    &lt;/bean&gt;
</pre>
<p>And access it like this:</p>
<pre>
package <em>com.acme.coolservice.client</em>;

import <em>com.acme.coolservice.jaxb.*</em>;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.client.core.WebServiceTemplate;

public class CoolServiceClient {

    @Autowired
    private WebServiceTemplate webService;

    public void foo() {
        FooRequest request = new FooRequest();
        FooResponse response = (FooResponse)webService.marshalSendAndReceive(request);
    }

    public void bar() {
        BarRequest request = new BarRequest();
        BarResponse response = (BarResponse)webService.marshalSendAndReceive(request);
    }

}
</pre>
<p>The client uses the same JAXB classes as the server.</p>
<p>When running Java 6, or Java 5 inside a JavaEE 5 compliant application server, you already have the JAXB 2.x runtime available. If you run Java 5 without such application server, you have to include JAXB 2.x runtime libraries in your project.</p>
<p>You need these dependencies:</p>
<pre>
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ws&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ws-core&lt;/artifactId&gt;
            &lt;version&gt;1.5.9&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ws&lt;/groupId&gt;
            &lt;artifactId&gt;spring-ws-core-tiger&lt;/artifactId&gt;
            &lt;version&gt;1.5.9&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.ws&lt;/groupId&gt;
            &lt;artifactId&gt;spring-oxm-tiger&lt;/artifactId&gt;
            &lt;version&gt;1.5.9&lt;/version&gt;
        &lt;/dependency&gt;
</pre>
<p>You may have to make this exclusion from <code>spring-ws-core</code> when running in some application servers such as WebLogic:</p>
<pre>
            &lt;exclusions&gt;
		&lt;exclusion&gt;
			&lt;groupId&gt;wsdl4j&lt;/groupId&gt;
    			&lt;artifactId&gt;wsdl4j&lt;/artifactId&gt;
		&lt;/exclusion&gt;
	    &lt;/exclusions&gt;
</pre>
<p><b>Update:</b><br />
Include this in <code>WEB-INF/web.xml</code>:</p>
<pre>
&lt;context-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;/WEB-INF/spring-ws-servlet.xml&lt;/param-value&gt;
&lt;/context-param&gt;

&lt;servlet&gt;
    &lt;servlet-name&gt;context&lt;/servlet-name&gt;
    &lt;servlet-class&gt;org.springframework.web.context.ContextLoaderServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;

&lt;servlet&gt;
    &lt;servlet-name&gt;spring-ws&lt;/servlet-name&gt;
    &lt;servlet-class&gt;org.springframework.ws.transport.http.MessageDispatcherServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
    &lt;servlet-name&gt;spring-ws&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2010/04/29/implementing-pox-web-services-with-spring-ws-and-jaxb/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to implement RESTful JSON Web Services in Java</title>
		<link>http://www.staldal.nu/tech/2010/04/16/how-to-implement-restful-json-web-services-in-java/</link>
		<comments>http://www.staldal.nu/tech/2010/04/16/how-to-implement-restful-json-web-services-in-java/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 12:49:29 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=103</guid>
		<description><![CDATA[You can implement RESTful Web Services in Java using the JAX-RS framework. JAX-RS is part of the JavaEE 6 platform. But if you are not using a JavaEE 6 application server, you can use the reference implementation Jersey and embed it in any web application server. However, it&#8217;s quite awkward to produce JSON output from [...]]]></description>
			<content:encoded><![CDATA[<p>You can implement <a href="http://en.wikipedia.org/wiki/RESTful">RESTful</a> Web Services in Java using the <a href="http://jcp.org/en/jsr/detail?id=311">JAX-RS</a> framework.</p>
<p>JAX-RS is part of the <a href="http://java.sun.com/javaee/">JavaEE</a> 6 platform. But if you are not using a JavaEE 6 application server, you can use the reference implementation <a href="https://jersey.dev.java.net/">Jersey</a> and embed it in any web application server.</p>
<p>However, it&#8217;s quite awkward to produce <a href="http://json.org/">JSON</a> output from Jersey.</p>
<p>Jersey has some support for <a href="https://jersey.dev.java.net/nonav/documentation/latest/user-guide.html#d4e792">producing JSON via JAXB</a>, but to get the <code>NATURAL</code> encoding (which you probably want) you need JAXB 2.1. And that can be problematic since JAXB 2.0 is bundled with JavaSE 6 and with some application servers (such as WebLogic). Overriding that with a later version of JAXB can be really difficult. Using JAXB is also a bit clumsy if you only want to produce JSON.</p>
<p>And using the <a href="https://jersey.dev.java.net/nonav/documentation/latest/user-guide.html#d4e995">low-level JSON support</a> in Jersey is not fun at all.</p>
<p>The solution is to use <a href="http://jackson.codehaus.org/">Jackson</a> and refer to its JAX-RS integration package <code>org.codehaus.jackson.jaxrs</code> in Jerseys <code>com.sun.jersey.config.property.packages</code> parameter (remember to separate several packages with semicolon ; ).</p>
<p>Then just return POJO:s from your JAX-RS resource classes.</p>
<p>You need these dependencies:</p>
<pre>
	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.jersey&lt;/groupId&gt;
		&lt;artifactId&gt;jersey-core&lt;/artifactId&gt;
		&lt;version&gt;1.1.4.1&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.codehaus.jackson&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-core-asl&lt;/artifactId&gt;
		&lt;version&gt;1.2.1&lt;/version&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.codehaus.jackson&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-mapper-asl&lt;/artifactId&gt;
		&lt;version&gt;1.2.1&lt;/version&gt;
	&lt;/dependency&gt;
	        &lt;dependency&gt;
	        &lt;groupId&gt;org.codehaus.jackson&lt;/groupId&gt;
	        &lt;artifactId&gt;jackson-jaxrs&lt;/artifactId&gt;
	        &lt;version&gt;1.2.1&lt;/version&gt;
	&lt;/dependency&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2010/04/16/how-to-implement-restful-json-web-services-in-java/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Linux with / mounted read-only 2.0</title>
		<link>http://www.staldal.nu/tech/2009/11/15/linux-with-mounted-read-only-2-0/</link>
		<comments>http://www.staldal.nu/tech/2009/11/15/linux-with-mounted-read-only-2-0/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 11:15:05 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=100</guid>
		<description><![CDATA[(This is a new version of a previous post updated to work with Ubuntu 9.10 (karmic).) I wondered why you usually mount / (the root file system) read-write in Linux and decided to do some experiments to find out if it is possible to have it mounted read-only. So why do you want to do [...]]]></description>
			<content:encoded><![CDATA[<p>(This is a new version of a <a href="http://www.staldal.nu/tech/2008/07/26/linux-with-mounted-read-only/">previous post</a> updated to work with Ubuntu 9.10 (karmic).)</p>
<p>I wondered why you usually mount / (the root file system) read-write in Linux and decided to do some experiments to find out if it is possible to have it mounted read-only. </p>
<p>So why do you want to do that? Perhaps you have the root file system on a read-only media, such as CD-ROM. Or on a writable media which can only handle a limited number of writes, such as a CD-RW or flash disk. It would also increase security since it will be more difficult (though not impossible) for some <a href="http://en.wikipedia.org/wiki/Malware">malware</a> to infect your system.</p>
<p>I found out that it is possible to mount / read-only, but only after some tweaking. Here is how I did it in <a href="http://www.ubuntu.com/">Ubuntu</a> 9.10 (karmic) desktop.</p>
<p>The first obvious step is to change the mount options to &#8220;ro&#8221; for / in <code>/etc/fstab</code> and reboot. But the tweaking has to be done first, so don&#8217;t reboot yet!</p>
<p>There are some locations in the file system which has to be writeable, the solution is to mount them as <code>tmpfs</code>. After some experiments, I found out that I had to mount the following locations as <code>tmpfs</code> (assuming that <code>/dev</code> is already mounted in an appropriate way):</p>
<ul>
<li><code>/tmp</code></li>
<li><code>/media</code></li>
<li><code>/var/run</code></li>
<li><code>/var/lock</code></li>
<li><code>/var/tmp</code></li>
<li><code>/var/crash</code></li>
<li><code>/var/log</code></li>
<li><code>/var/lib/xkb</code></li>
<li><code>/var/lib/gdm</code></li>
<li><code>/var/lib/dhcp3</code>  (only if you use DHCP client)</li>
<li><code>/var/lib/nfs</code> (only if you use NFS)</li>
<li><code>/var/spool/cups</code></li>
</ul>
<p>Ubuntu mounts <code>/var/run</code> and <code>/var/lock</code> as <code>tmpfs</code> by default. This is done by the <code>mountall</code> tool.</p>
<p>Add this to <code>/etc/fstab</code>:</p>
<pre>
none /tmp             tmpfs mode=1777,nodev,exec,nosuid 0 0
none /media           tmpfs mode=0755,nodev,noexec,nosuid 0 0
none /var/tmp         tmpfs mode=1777,nodev,noexec,nosuid 0 0
none /var/crash       tmpfs mode=0755,nodev,noexec,nosuid 0 0
none /var/spool/cups  tmpfs mode=0710,nodev,noexec,nosuid,gid=lp 0
none /var/log         tmpfs mode=0755,nodev,noexec,nosuid 0 0
none /var/lib/dhcp3   tmpfs mode=0755,nodev,noexec,nosuid 0 0
none /var/lib/xkb     tmpfs mode=0755,nodev,noexec,nosuid 0 0
none /var/lib/gdm     tmpfs mode=0775,nodev,noexec,nosuid,gid=gdm 0 0
none /var/lib/nfs     tmpfs mode=0755,nodev,noexec,nosuid 0 0
</pre>
<p>And add this to <code>/etc/rc.local</code>:</p>
<pre>
mkdir /var/log/apt
</pre>
<p>There are some files in <code>/etc</code> which have to be writeable:</p>
<ul>
<li><code>/etc/mtab</code></li>
<li><code>/etc/resolv.conf</code> (only if you use DHCP client and let it set DNS configuration)</li>
</ul>
<p>I handle <code>/etc/mtab</code> by symlink it to <code>/proc/mounts</code>, that has some minor side-effects but I can live with it. I handle <code>/etc/resolv.conf</code> by symlinking it to <code>/var/lib/dhcp3/resolv.conf</code>. In order for this to work, you have to patch the DHCP client (dhcp3-client) accodring to <a href="https://bugs.launchpad.net/ubuntu/+source/dhcp3/+bug/251632">this bug report</a> (use the new version of the patch).</p>
<p>You also have to mount <code>/home</code> read-write somewhere, and I would not recommend using <code>tmpfs</code>. You can use a separate hard disk partition or NFS.</p>
<p>It is a bit tricky to get this to work with NFS. You have to set the NFS mount points in <code>/etc/fstab</code> as <code>noauto</code> and add these lines to <code>/etc/init/statd.conf</code> just before <code>status portmap...</code></p>
<pre>
mkdir /var/lib/nfs/sm
mkdir /var/lib/nfs/sm.bak
mkdir /var/lib/nfs/rpc_pipefs
</pre>
<p>Then mount the NFS shares in <code>/etc/gdm/PostLogin/Default</code>. For some reason it did not work to do it from <code>/etc/rc.local</code>, perhaps due to delay in DHCP lookup.</p>
<p>Finally it might be a good idea to set a password for the root account, this enables you to switch to a virtual console (<code>Ctrl</code>-<code>Alt</code>-<code>F1</code>) and login as root if something goes wrong.</p>
<p>If you then do want to change anything, such as edit a file in <code>/etc</code> or install or upgrade a package, you can just remount / as read-write temporary (assuming that the media actually is writeable):<br />
<code>sudo mount -o rw,noatime,remount /</code></p>
<p>and revert to read-only when finished:<br />
<code>sudo mount -o ro,noatime,remount /</code></p>
<p>Note that this setup is for a desktop or laptop system, it&#8217;s probably not appropriate for a server.</p>
<p>If you have plenty of RAM (such as at least 1 GB), then you can also mount <code>/var/cache/apt</code> as <code>tmpfs</code>. That helps if you have limited free space on <code>/</code> and want to do a distribution upgrade.</p>
<p>Add this to <code>/etc/fstab</code>:</p>
<pre>
none /var/cache/apt   tmpfs mode=0755,nodev,noexec,nosuid 0 0
</pre>
<p>And add this to <code>/etc/rc.local</code>:</p>
<pre>
mkdir -p /var/cache/apt/archives/partial
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/11/15/linux-with-mounted-read-only-2-0/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>How to get microphone to work un Ubuntu 9.04</title>
		<link>http://www.staldal.nu/tech/2009/09/18/how-to-get-microphone-to-work-un-ubuntu-9-04/</link>
		<comments>http://www.staldal.nu/tech/2009/09/18/how-to-get-microphone-to-work-un-ubuntu-9-04/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 21:10:31 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=97</guid>
		<description><![CDATA[I finally got the microphone input on my Acer Veriton X270 to work un Ubuntu 9.04. The trick is to uninstall PulseAudio and use ALSA only. It even works in Skype.]]></description>
			<content:encoded><![CDATA[<p>I finally got the microphone input on my <a href="http://www.staldal.nu/tech/2009/07/03/running-ubuntu-linux-on-acer-veriton-x270/">Acer Veriton X270</a> to work un Ubuntu 9.04.</p>
<p>The trick is to uninstall PulseAudio and use ALSA only. </p>
<p>It even works in Skype.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/09/18/how-to-get-microphone-to-work-un-ubuntu-9-04/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>java.util.Map is broken in Java 5</title>
		<link>http://www.staldal.nu/tech/2009/08/13/java-util-map-is-broken-in-java-5/</link>
		<comments>http://www.staldal.nu/tech/2009/08/13/java-util-map-is-broken-in-java-5/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 14:41:18 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=91</guid>
		<description><![CDATA[Java 5 added generics. The collection classes was modified to make use generics to provide compile-time type-safe collections. Sadly, this was not done properly. The worst problem is in the interface java.util.Map: public interface Map&#60;K,V&#62; { // more methods... V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object key); } The key parameters [...]]]></description>
			<content:encoded><![CDATA[<p>Java 5 added <a href="http://java.sun.com/javase/6/docs/technotes/guides/language/generics.html">generics</a>. The collection classes was modified to make use generics to provide compile-time type-safe collections. Sadly, this was not done properly.</p>
<p>The worst problem is in the interface <code>java.util.Map</code>:</p>
<pre>
public interface Map&lt;K,V&gt; {
    // more methods...

    V get(Object key);
    V remove(Object key);
    boolean containsKey(Object key);
    boolean containsValue(Object key);
}
</pre>
<p>The <em>key</em> parameters to these methods ought to be declared to be <em>K</em> and not <em>Object</em>. Now we don&#8217;t get any type-safety for those methods. If you create a <code>HashMap&lt;String,String&gt;</code> and then by mistake try to use an int as key when looking up a value, you will not get any compile-time error. Worse yet, you will not even get any run-time error, it will just appear as if there is no value with that key (which in some sense is correct).</p>
<p>This can cause hard to find bugs like this:</p>
<pre>
public class MapTest {
    private Map&lt;String,String&gt; map = new HashMap&lt;String,String&gt;();

    public void setFoo(int i, String s) {
        map.put(String.valueOf(i), s);
    }

    public String getFoo(int i) {
        return map.get(i); // OOPS, should have been String.valueOf(i)
    }
}
</pre>
<p>(Yes, this code is pretty stupid, but it&#8217;s only a simple example.)</p>
<p>There are similar problems in <code>java.util.Collection</code> (<code>contains</code> and <code>remove</code> methods) and some other interfaces, but that&#8217;s less serious since they are not used very often. However, it&#8217;s very serious in <code>java.util.Map</code> since you <em>always</em> use the <code>get</code> method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/08/13/java-util-map-is-broken-in-java-5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Misuse of HTTP GET is a cardinal sin</title>
		<link>http://www.staldal.nu/tech/2009/07/17/misuse-of-http-get-is-a-cardinal-sin/</link>
		<comments>http://www.staldal.nu/tech/2009/07/17/misuse-of-http-get-is-a-cardinal-sin/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 15:49:13 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=87</guid>
		<description><![CDATA[According to the RESTful style, you should make use of the four HTTP methods GET, POST, PUT and DELETE. However, in many cases only GET and POST is used, and POST is used when you really should use PUT or DELETE. I consider this as a quite minor issue. However, using GET instead of POST [...]]]></description>
			<content:encoded><![CDATA[<p>According to the <a href="http://en.wikipedia.org/wiki/RESTful">RESTful style</a>, you should make use of the four HTTP methods GET, POST, PUT and DELETE. However, in many cases only GET and POST is used, and POST is used when you really should use PUT or DELETE. I consider this as a quite minor issue.</p>
<p>However, using GET instead of POST (or PUT or DELETE) is much worse.</p>
<p>The current <a href="http://www.rfc-editor.org/rfc/rfc2616.txt">HTTP 1.1 specfication (RFC-2616)</a> clearly states that a GET request must be <em>safe</em>, i.e. not have any significant side-effect on the server. So in order to change anything on the server, you must use POST (or PUT or DELETE). The older <a href="http://www.rfc-editor.org/rfc/rfc1945.txt">HTTP 1.0 specification (RFC-1945)</a> from 1996 said the same.</p>
<p>This is important because the HTTP protocol supports caching, both in the client and in intermediate proxies. This caching may result in that GET requests will not get through to the server all the time. If you use GET to perform some action on the server, it will not work reliably unless you do ugly workarounds to circumvent the caching.</p>
<p>Public specifications of the HTTP protocol has made this clear for more than 12 years now. Misuse of the GET method in a web application, web service or any other application of HTTP is a <strong>cardinal sin</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/07/17/misuse-of-http-get-is-a-cardinal-sin/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Running Ubuntu Linux on Acer Veriton X270</title>
		<link>http://www.staldal.nu/tech/2009/07/03/running-ubuntu-linux-on-acer-veriton-x270/</link>
		<comments>http://www.staldal.nu/tech/2009/07/03/running-ubuntu-linux-on-acer-veriton-x270/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 19:49:06 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=79</guid>
		<description><![CDATA[I recently brought an Acer Veriton X270. Ubuntu Linux 8.04 works well except for sound. Basic stereo sound output works, but sound input (microphone) and some advanced 3D and surround sound does not work. The front headphone jack does not work correctly either. (All this works in Windows, so it&#8217;s not a hardware problem.) Apart [...]]]></description>
			<content:encoded><![CDATA[<p>I recently brought an <a href="http://www.acer.co.uk/acer/product.do?link=oln85e.redirect&#038;changedAlts=&#038;CRC=600100215#wrAjaxHistory=0">Acer Veriton X270</a>.</p>
<p>Ubuntu Linux 8.04 works well except for sound. Basic stereo sound output works, but sound input (microphone) and some advanced 3D and surround sound does not work. The front headphone jack does not work correctly either. (All this works in Windows, so it&#8217;s not a hardware problem.)</p>
<p>Apart from the poor sound support in Linux, I am quite happy with this computer. It&#8217;s small (though not super small like Mac Mini or Fujitsu ESPRIMO Q), quiet, has all features you need and works out of the box. And it has a compelling price.</p>
<p>An odd detail is that it has HDMI instead of DVI for digital video output (it has VGA too, but who wants to use that nowadays?). But with a cheap HDMI-DVI adapter, you can connect a regular DVI display.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/07/03/running-ubuntu-linux-on-acer-veriton-x270/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Type safe JSP and JSTL</title>
		<link>http://www.staldal.nu/tech/2009/04/23/type-safe-jsp-and-jstl/</link>
		<comments>http://www.staldal.nu/tech/2009/04/23/type-safe-jsp-and-jstl/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 16:15:06 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=72</guid>
		<description><![CDATA[When using JavaServer Pages, you want to use JSTL to be able to to flow-control (iterations and conditionals) in a reasonable way. And the recommended way to use JSTL is to use the Expression Language (EL). However, using EL is not a good idea at all. Contrary to Java and plain JSP, EL lacks static [...]]]></description>
			<content:encoded><![CDATA[<p>When using <a href="http://java.sun.com/products/jsp/">JavaServer Pages</a>, you want to use <a href="http://java.sun.com/products/jsp/jstl/">JSTL</a> to be able to to flow-control (iterations and conditionals) in a reasonable way. And the recommended way to use JSTL is to use the <a href="http://java.sun.com/products/jsp/reference/techart/unifiedEL.html">Expression Language (EL)</a>.</p>
<p>However, using EL is not a good idea at all. Contrary to Java and plain JSP, EL lacks static typing. This means that many errors which the compiler can catch is not detected until runtime when using EL. And even worse, EL doesn&#8217;t even do proper type checking at runtime. In many cases you just end up with an empty string when it in fact is a type error.</p>
<p>Proponents of dynamic languages usually say that static typing is not necessary since you should have automated testing of your code anyway, and that will catch any errors. However, automated testing of web pages is difficult and awkward. And reasonable dynamic languages (such as Python and Ruby) at least do type checking at runtime and generate a visible runtime error.</p>
<p>Fortunately, there is a feature of JSTL called <cite>rtexpvalue</cite> which makes it possible to use JSTL without EL and keep the static typing.</p>
<p>First you have to use alternative versions of the JSTL tag libraries:</p>
<pre>
&lt;%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/xml_rt" prefix="x" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/sql_rt" prefix="sql" %&gt;
</pre>
<p>Then you use plain JSP expressions instead of EL:</p>
<pre>
&lt;jsp:useBean scope="request" id="fuits" class="java.util.List"/>
&lt;jsp:useBean scope="request" id="foo" class="com.acme.Foo"/>

&lt;c:if test="&lt;%= foo.isBar() %>">
	&lt;p>Foo is bar since &lt;fmt:formatDate type="time" value="&lt;%= foo.getDate() %>"/>&lt;/p>
&lt;/c:if>
&lt;c:forEach items="&lt;%= fruits %>" var="fruit">
	  &lt;jsp:useBean id="fruit" class="com.acme.model.Fruit"/>
	      &lt;tr>
	        &lt;td>&lt;%= fruit.getColor() %>&lt;/td>
	        &lt;td>&lt;%= fruit.getTaste() %>&lt;/td>
              &lt;/tr>
&lt;/c:forEach>
</pre>
<p>As you see, you have to declare the variables using <code>&lt;jsp:useBean&gt;</code>. </p>
<p>This makes the syntax a bit more clumsy, but that&#8217;s a price worth to pay to get the static typing.</p>
<p>To get the full benefit of the static typing, you should compile all your JSP pages offline before deploying the web application. The best way to do this is to integrate JSP compilation in your build process so that JSP pages is compiled at the same time as your regular Java code is compiled. If you use <a href="http://maven.apache.org/">Maven</a>, you can use <a href="http://mojo.codehaus.org/jspc-maven-plugin/">this plugin</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/04/23/type-safe-jsp-and-jstl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>java -classpath *.jar</title>
		<link>http://www.staldal.nu/tech/2009/04/23/java-classpath-jar/</link>
		<comments>http://www.staldal.nu/tech/2009/04/23/java-classpath-jar/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 11:29:35 +0000</pubDate>
		<dc:creator>Mikael Ståldal</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.staldal.nu/tech/?p=66</guid>
		<description><![CDATA[It&#8217;s quite annoying that you cannot use wildcards in the -classpath command line option to java and javac. Quite often you want to include all .jar files in one directory. Here is a way to get that effect: java -classpath `echo lib/*.jar &#124; sed -e &#8220;s/ /:/g&#8221;` org.foo.MyApp You can even include all .jar files [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s quite annoying that you cannot use wildcards in the <code>-classpath</code> command line option to <code>java</code> and <code>javac</code>. Quite often you want to include all <code>.jar</code> files in one directory.</p>
<p>Here is a way to get that effect:</p>
<blockquote><p>
java -classpath `echo lib/*.jar | sed -e &#8220;s/ /:/g&#8221;` org.foo.MyApp
</p></blockquote>
<p>You can even include all <code>.jar</code> files in a whole hierarchy of directories:</p>
<blockquote><p>
java -classpath `find repository -name *.jar -printf %p:` org.foo.MyApp
</p></blockquote>
<p>In general it&#8217;s better to use <a href="http://ant.apache.org/">Ant</a> or <a href="http://maven.apache.org/">Maven</a> for compiling and <a href="http://wrapper.tanukisoftware.org/">Java Service Wrapper</a> for running, they have built-in support for wildcards. But they require some upfront setup, so my solution is useful for ad-hoc usage.</p>
<p>This works in Linux and probably in Solaris and other UNIX systems. If you use Windows, you need to install <a href="http://www.cygwin.com/">cygwin</a> or similar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.staldal.nu/tech/2009/04/23/java-classpath-jar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
