Thursday, October 28, 2010

Ubuntu 10.10 Maverick Meerkat Netbook - fails to impress

I've recently bought a new netbook, and with the new Ubuntu Netbook edition coming out, I thought I'd take it for a test. Unfortunately it completely failed to impress me within the first 30 minutes.

Disclaimer: I've been a big fan of Debian, and now Ubuntu (stability of Debian, but with ease of use) for a while. I believe Ubuntu is a great system, and it is still my Nr.1 Linux distribution of choice. All the problems listed below are no challenge for a technical person, but Ubuntu aims to support the casual user as well.

Disclaimer 2: The following is my personal definition of a netbook: It is a laptop

  • with a small screen
  • and little processing power
  • focussing on quick time-to-Internet
  • and long battery life

As my netbook currently runs a proprietary system, I used WUBI to install.

Blocker #1: WUBI downloaded from the WUBI page still had only Ubuntu 10.4 (that was on oct.11, where 10.10 was one day old). Only when accessing the Ubuntu download page i got the newest version. The main page now redirects there.

Ubuntu installed fine, at some time it rebooted and

Blocker #2: Windows boots up! The installer can create a boot menu entry, but it cannot set it to Linux to finish the installation?

Finally Ubuntu booted, I selected the "netbook" session and

Blocker #3: failed to start because my card did not support the necessary 3D features! Why does Ubuntu need a 3D graphics card on a Netbook? This collides with long battery life and low processing power. BTW: My Nvidia card is supported just fine, once i could log in the desktop session, install the proprietary driver, etc.... Why wasn't this done at install time?

As said, I had to log into the desktop session and

Blocker #4: got a cryptic error message about missing language packs. It gave me two choices: Either I install them now, or I have to do this later (hidden in some menu you instantly forget). This brings me to two questions: 1) Why wheren't those installed before? I did select my language. 2) Until this point I was never asked for my WiFi credentials, which would have enabled me to do the immediate install. After all, this is my portable, and I expect it to work without wires.

After setting all these up, I finally rebooted and

Blocker #5: was asked for a username and password! While this is fine for laptops and desktops, its a most-people-don't-want-this-on-a-netbook feature. I want to turn it on and surf the web, not wait, enter my password, and then have to wait again for the window manager to load.

Try finding the setting in the netbook remix window manager, guess what:

Blocker #6: Settings are only available in the Gnome (desktop) session.

Conclusion: Ubuntu still has ways to go before they can close Ubuntu Bug #1.

Sunday, July 18, 2010

Eclipse Helios - New Apply Patch Features

Eclipse Helios has a few nice new features for applying patches. In this post I would like to point some of the out

Apply Patch using URL

The Apply Patch wizard now accepts URLs. This is great when you a working with open source projects where patches are frequently added as attachment to bug reports. Previousely, I had to download the patch, find it again (which is difficult when all patches are named patch, and therefore end up being downloaded as patch, patch (1), patch (2), ... ), an then apply. Now I just click on "copy link" and it is automagically pasted into the apply-patch box. Nice one!

Apply Patch in Synchronize View

Even nicer is applying patches in synchronize view - the option is, however, hidden:

  • Switch to the synchronized perspective
  • In the synchronize view, click on the arrow next to the synchronize icon (the first one from the left
  • Select synchronize...

Now you can finally partially apply patches! What makes this feature even better is that it also accepts URLs, so it can be directly used with patches attached to bug reports!

And to bring this all together, there is now the

Apply patch in Synchronize view preference

Hidden in the preferences under "Team", you can check "Apply patch in Synchronize view" to always get this behavior. Now this is one of the most useful settings - unfortunately it is off by default.

Saturday, July 17, 2010

Eclipse Helios and Java 1.6u21 deadlocks

I wanted to write a post about the new Eclipse Helios, which was just released to participate in the Helios Blogathon. So, on my personal machine, I installed the newest JDK (1.6u21), the new eclipse, started it up, tried to work with it and after a few seconds.... It just hangs!

But whait - it worked nicely on my work machine, so what's the deal? Did I install the wrong plug-ins? Tried to open up the wrong editor? I had the same problem on my work machine (Windows 7 x64 with the newest Java 64 bit (1.6u21)). On this machine I fixed it using the 32 bit Java version instead (which just happend to be 1.6u20).

After spending several hours with several 32 and 64 bit versions of Eclipse and Java, I found the deadly combination. It is:

  • Windows 7 x64 (may be unrelated to the problem)
  • Java 1.6 u 21
  • Eclipse Helios

The fix? Get an older Java Version - which is not simple - if you try to get an older version of Java, Oracle asks you to register and wants your email address. They don't tell you that there is a public archive of older Java versions. Why should they? You always want the latest version, right? Even if this means your Eclipse Helios session is limited to 5 seconds.

Helios now runs fine on an Jdk 1.5, with a separate JDK 1.6 installed to actually run my apps.


Update: 11 days after my post Slashdot has some more information: Oracles Java Company Change Breaks Eclipse. Also, there is Bug 6969236.


Thursday, April 1, 2010

DataSource in Jetty through JNDI

Prerequesite: Please ensure JNDI is configured properly and you can pass parameters to Jetty via JNDI.

First, you need to add the used libraries to Jettys classpath. In my case, I wanted commons-dbcp (alternative: c3p0) over an H2 database, so I added the following to my pom.xml


      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>7.0.1.v20091125</version>
        <dependencies>
          <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
          </dependency>
          <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.2.131</version>
          </dependency>
        </dependencies>
      </plugin>

On Jetty standalone, I copied the libraries to the lib/ext directory and added ext to the options in start.ini. Please note that commons-dbcp also requires commons-pool.

Next, add the configuration of your DataSource to jetty-env.xml:


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="thisfile" class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref id="thisfile"/></Arg>
    <Arg>jdbc/nameOfMyDatabase</Arg>
    <Arg>
      <New class="org.apache.commons.dbcp.BasicDataSource">
        <Set name="url">jdbc:h2:/path/to/your/DataBase</Set>
      </New>
    </Arg>
  </New>
</Configure>

To actually have access to the datasource, you also need modify web.xml to declare that you want a resource unter this name:


  <resource-ref>
    <res-ref-name>jdbc/nameOfMyDatabase</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

The database is now available as DataSource at java:/comp/env/jdbc/nameOfMyDatabase and can be used directly in tools such as hibernate by setting hibernate.connection.datasource to this value.

Background: Hibernate did not properly release the database connection when the WebApp shut down. This resulted in Exceptions when trying to undeploy and deploy the webapp without killing Jetty, as the embedded database existed both in the old and the new context. By moving the connection out of the WebApp, and into Jetty's responsibility, the embedded database driver now only exists in Jetty's context. Adding the connection pool is just decoration.

Passing parameters to Jetty 7 via JNDI

If you have the jetty-maven-plugin properly configured in the pom.xml, then everything is already set up.

For Jetty Standalone, please see my other post about configuring JNDI in jetty standalone.

Passing parameters through JNDI proved to be very simple. In src/main/webapp/WEB-INF create a file jetty-env.xml, with the following contents:


<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="thisfile" class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.EnvEntry">
    <Arg><Ref id="thisfile"/></Arg>
    <Arg>paramname</Arg>
    <Arg type="java.lang.String">A sample parameter value</Arg>
    <Arg type="boolean">false</Arg>
  </New>
</Configure>

You can then load your parameter through the standard naming context:


import javax.naming.Context;
import javax.naming.InitialContext;
...
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
String param = (String) envCtx.lookup("paramname");

Of course, you can add other parameters, rename paramname to something that makes more sense, or use other data types. Please note: Jetty supports more datatypes than required by the J2EE standard.

Configuring Jetty 7 standalone for JNDI

Configuring Jetty 7 for JNDI can be a bit tricky. If you miss any of these points, you may end up passing JNDI parameters, but they will not be available in your webapp.

  1. Ensure the plus libraries are loaded. You can to this by adding the option plus in Jetty's start.ini
  2. Ensure jetty is configured to use the plus configuration classes. You can do this by adding the following inside the context, or the jetty-env.xml:
      <Set name="ConfigurationClasses">
        <Array id="plusConfig" type="java.lang.String">
          <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
          <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
          <Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
          <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
          <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
        </Array>
      </Set>
    

    The documentation suggests adding etc/jetty-plus.xml to the startup, which would make this configuration available as plusConfig to refer to. This did not work on my machine.

You can now continue with Passing parameters to Jetty 7 via JNDI.

Wednesday, February 10, 2010

Jetty 7 maven plugin authentication realms

The configuration directive UserRealm seems to no longer work with the jetty 7 maven plugin (jetty-maven-plugin). I received the following error:

java.lang.IllegalStateException: No LoginService for org.eclipse.jetty.security.authentication.BasicAuthenticator@4095c5ec in ConstraintSecurityHandler@28f52a14@

Fixing this involved:

  • Creating a jetty configuration file, such as the following:


    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
    <Configure class="org.eclipse.jetty.webapp.WebAppContext">
      <Get name="securityHandler">
        <Set name="loginService">
          <New class="org.eclipse.jetty.security.HashLoginService">
            <Set name="name">YourSecurityRealmHere</Set>
            <Set name="config">src/test/resources/jetty-realm.properties</Set>
            <Call name="start"/>
          </New>
        </Set>
        <Set name="checkWelcomeFiles">true</Set>
      </Get>
    </Configure>

    To be saved as src/test/resources/jetty-test.xml

  • Create a src/test/resources/jetty-realm.properties with your Jetty 7 password file.

  • Updating the jetty configuration in my pom.xml:

          <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>7.0.1.v20091125</version>
            <configuration>
              <webAppXml>src/test/resources/jetty-test.xml</webAppXml>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-servlets</artifactId>
                <version>7.0.1.v20091125</version>
              </dependency>
            </dependencies>
          </plugin>
    

    The important entry is webAppXML. The extra dependency to jetty-servlets was added to support GZip in Jetty 7.

Jetty seems to ignore webdefault.xml

If just tried to edit webdefaults.xml to disable directory views, and the change was not reflected in my webapp. The reason: webdefaults.xml is not read by default, but must be explicitly added to the context of the webapp:


 <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>

And suddenly all changes in webdefaults.xml are applied.

Wednesday, January 27, 2010

Enabling JSP support in Jetty 7

As Jetty 6 failed to use the port inherited from xinetd, I have to use Jetty 7. Unfortunately Jetty is missing the JSP support by default. Here is how to enable it:

  1. Download the Jetty 6 distribution.
  2. Copy the jsp-2.1 folder to the Jetty 7 lib/ folder.
  3. You can check if it works by running java -jar start.jar --list-options
  4. Edit start.ini to include jsp-2.1 in the OPTIONS line.

Jetty 6 vs. Jetty 7

There are several differences between Jetty 6 and Jetty 7:

  • Most classes have been renamed from org.mortbay to org.eclipse and sometimes moved to a different path. Find the new class names in the Jetty 7 JavaDoc. This applies to most settings in jetty.xml and web.xml.
  • Jetty 7 comes with fewer plugins. Important extras such as JSP support are missing from the standard distribution.
  • Jetty 7 includes several bugfixes. Example: Taking a port from xinetd did not work with Jetty 6 on my machine.

More information is at the Porting to Jetty 7 page.

Jetty 7 gzip Filter

Jetty includes a gzip-filter for dynamic compression of contents, thus saving bandwidth and enabling your site to load faster (especially important if you have a lot of javascript).

To configure it, add the follwing filter definition to your web.xml:


  <filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
    <init-param>
      <param-name>mimeTypes</param-name>
      <param-value>text/html,text/plain,text/xml,application/xhtml+xml,text/css,application/javascript,image/svg+xml</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping> 

Please note: This configuration is for Jetty 7. For Jetty 6 change the filter to org.mortbay.servlet.GzipFilter.

Jettys missing passwd.sh

Jetty comes with a very nice Password encrypting command. Unfortunately, there is no passwd.sh to call it, and you have to manually find out where it is defined. Also, the documentation is for Jetty 6 only, and the names of the classes and libraries have changed in Jetty 7.

Here is the missing passwd.sh for Jetty 7:


#!/bin/bash

# look for JETTY_HOME
if [ -z "$JETTY_HOME" ] 
then
  cd $(dirname "$0")
  JETTY_HOME_1=$(pwd)
  cd - > /dev/null
  JETTY_HOME_1=$(dirname "$JETTY_HOME_1")
  JETTY_HOME=${JETTY_HOME_1} 
fi

java -cp $JETTY_HOME/lib/jetty-http-7.0.1.v20091125.jar:\
$JETTY_HOME/lib/jetty-util-7.0.1.v20091125.jar \
org.eclipse.jetty.http.security.Password $*

Please note that the JETTY_HOME detection is also changed from the original jetty shell scripts to be more sane.

Tuesday, January 26, 2010

Jetty vs. Tomcat

When setting up a new webserver, I decided to evaluate Jetty as an alternative to Tomcat. I have previousely used Tomcat, and was content with it. Here is what I've found:
Both:
  • Implement recent JSP and Servlet standards
  • Can easily run .WAR files
  • Are pretty fast when serving content (speed comparisons on the web show only minor differences)
Pro Jetty:
  • Jetty uses less memory
  • Jetty seams more "lightweight"
Pro Tomcat:
  • Tomcat is very well documented - Jetty Documentation is sparse and targeted towards Java developers. The Jetty config file is (intentionally) like coding
  • I know Tomcat by now
As the machine I am using now is low on memory, I decided to give Jetty a try. However, installing it was not easy. But that's a topic for the next post.

Monday, January 25, 2010

Useful PNG commands

Useful command for handling PNG files.

Prerequisites: ImageMagick, Pngcrush

Resizing

Resize to a given maximum size

for i in *png ; do convert $i -geometry 16x16 x/$i; done

Resize exactly to given size, adding transparent borders

for f in $(for i in x/* ; do file $i | grep -v '16 x 16' | cut -d: -f1; done) ; 
  do convert $f -type TrueColorMatte -compose Src -gravity center -extent 16x16 y/$f ; 
done

Optimizing

Trying different PNG compression settings, removing extra PNG contents (such as comments)

for i in y/*png ; do pngcrush  -rem alla -reduce -brute "$i" z/"$i"; done

Why (not) 64 bit

Why 64 Bit Windows

Most chosen actual reason:

  • Because you payed a lot of money for that new 64 bit processor and feel cheated if you don't use it

Technical Reasons

  • You really have an Applications which needs more than 4 GB of memory. (In most cases: You don't, unless you run a large database or huge self-written scientific applications). Use the system profiler to find out how much memory you actually need.)
  • Your System has more than 3,5 GB of memory (3 GB for Windows XP) and you actually need it.

Why not 64 Bit Windows

  • Because you don't need it (see above)
  • Drivers support is incomplete
  • Some applications don't work
  • Many programs are installed twice: in the 32bit and 64bit versions, and some plugins work in one, but not the other. Notable Examples: Internet Explorer, Firefox, Explorer

Biggest Myth

  • a 64 bit OS is not faster than a 32 bit OS!

Please note: Most of this is also true for 64 bit Linux.

Desktop file format

Confused about all the .desktop files in Gnome / KDE? There is an official spec at: www.freedesktop.org/wiki/Specifications/desktop-entry-spec.

Where are they?

All User files are in /usr/share/applications
Personal files are in $HOME/.local/share/applications

Gnome additions: / Autostart

 
X-GNOME-Autostart-enabled=true

should be set for files in $HOME/.config/autostart. This describes autostart applications. More info on autostart: KDE Bug #170817.

PEM from/to P12

I commonly need to convert between PEM and p12

PEM
Is an ASCII format and can be opened with a text editor. It is used by most SSL-based tools. Key and certificate are two separate files.
p12
Acutally: Pkcs12 is used by most browsers. Key and certificate are in one file.

PEM to P12

You need both the key and the certificate:

 
openssl pkcs12 -export -in usercert.pem -inkey userkey.pem -out bundle.p12

P12 to PEM

 
openssl pkcs12 -in bundle.p12 -out userkey.pem -nodes -clcerts

The resulting file contains both the key and certificate. Use a text editor to split into two files again.

Singleton Pattern in Java

The singleton pattern ensures that there is exactly one instance of a class.

There are multiple ways to implement the Singleton Pattern in Java, here is my personal favorite:


 
public final class SomeClass {
 
  private static final class SingletonHolder {
    private static final SomeClass INSTANCE = new SomeClass();
    private SingletonHolder() {}
  }
 
  private SomeClass() {
    // Add code if needed
  }
 
  /**
    * @return the Singleton Instance.
    */
  public static SomeClass getInstance() {
    return SomeClass.SingletonHolder.INSTANCE;
  }
 
  // add other methods
 
}

Notes:

  • Replace SomeClass with the class name, keep all other names exactly as given.
  • Class is final to ensure its constructor cannot be made public by subclassing.
  • The SingletonHolder nested class enables lazy loading and ensures synchronization without performance loss.
  • Constructor must be made private.
  • getInstance returns the singleton instance of this class.

Find mime-type for a file

Here is how to determine the mime-type for a given file on the command line.

OS X

file --mime '''filename''

Linux

xdg-mime query filetype '''filename'''
gvfs-info -a standard::content-type '''filename''' | grep content | cut -d: -f4 | cut -d\  -f2-
gnomevfs-info '''filename''' | grep MIME | cut -d\: -f2- | cut -d\  -f2-
file --mime '''filename''' | cut -d\: -f2- | cut -d\  -f2

Everywhere

Update: We can modify the conditional alias to support mime types as well:

conditional_alias2 () {
  UNSET=false
  alias $1 > /dev/null 2>&1 || UNSET=true
  [ $UNSET = true ] && which $2 > /dev/null 2>&1 && alias $1=$3
}
mime_gvfs() {
  gvfs-info -a standard::content-type $1 | grep content | cut -d: -f4 | cut -d\  -f2-
}
mime_xdg() {
 xdg-mime query filetype $1
}
mime_gnomevfs() {
 gnomevfs-info file://$PWD/$1 | grep MIME | cut -d\: -f2- | cut -d\  -f2-
}
conditional_alias2 mime gvfs-info mime_gvfs
conditional_alias2 mime xdg-mime mime_xdg
conditional_alias2 mime gnomevfs-info mime_gnomevfs

Command Line SSL

Finally found out how to connect to an SSL server over the command line:

openssl s_client -connect www.example.com:443

What a great netcat replacement!

Command Line Open in UNIX

On OS X I can just "open" any file. On Windows, I can use "start". And on Linux? On modern installations, the "xdg-open" command works just fine. Unfortunately - this is not always the case. And I don't want to remember different commands for different machines. So here is the ultimate open alias setting for bash, for all systems that I use (it can be easily extended for other environments).


 
conditional_alias() {
  UNSET=false
  alias $1 > /dev/null 2>&1 || UNSET=true
  [ x$UNSET = xtrue ] && which $2 > /dev/null 2>&1 && alias $1=$2
}
 
conditional_alias open gvfs-open
conditional_alias open xdg-open
conditional_alias open gnome-open
conditional_alias open exo-open
uname | grep MINGW > /dev/null 2>&1 && alias open=start