Friday, August 26, 2011

Scala: The Manifest

Scala, as Java, implements generics using type-erasure.
The JVM has no knowledge of the concept of "generic type", only the compiler does. As an example a List<Integer> will be compiled to non-generic List, and all type checks will be performed at compile-time.
At the contrary, C# uses reified type.

I do not want to discuss this subject here, but with reification a type-parameter is a class and you can use it as a class
class Cl1<T>{
    public void m(){
        return new T()
    }
}
whereas in Java (or Scala) you can't.
Obviously, there are pros and cons for each approach.
But is's definitely true that a C#-like behavior is often very welcome (in the factory method pattern, for example).
Working with Scala, you can take advantage of the implicit parameters and use the Manifest class.
class Cl1[T]{
  def m()(implicit mf: Manifest[T]) = {
    val cl = mf.erasure.asInstanceOf[Class[T]]
    cl.newInstance
  }
}
This is a little more verbose than C#, but satisfies the demand.
But there is one limitation: you can use this only on non-generic classes.
class Cl2[T] extends Cl1[T]{
  def m2 = m
}
Well, it could look correct but the compiler doesn't agree with you. That is because type T cannot be understood at compile-time (could be Int, String or whatever). You must specify the implicit parameter as long as you are working with generic types.
In fact if you write
class Cl2 extends Cl1[String]{
  def m2 = m
}
the compiler understands that the implicit parameter is Manifest[String] and doesn't need any other information.

Wednesday, August 24, 2011

Scala - The singleton pattern

As a first example of how to use Scala, I want to show to you how you could implement the singleton pattern.
This is a basic pattern used when you want to ensure that no more than one instance of a class can be living in your application at the same time. A method, usually called "instance", is used to retrieve this single instance. Also, the lazy pattern is recommended: do not create the singleton until it's needed.

First, how a Java singleton looks like? Well...
public class Singleton {
    private static final class SingletonHolder{
        private static final Singleton INSTANCE = new Singleton();
    }
   
    private Singleton() {}
   
    public static final Singleton instance(){
        return SingletonHolder.INSTANCE;
    }
}

Instead, with Scala it would look like.
class Singleton private () {

}

object Singleton {
  private lazy val INSTANCE =  new Singleton()
  
  def instance = INSTANCE
}

That's all

Installing Sonatype Nexus on a Linux server

Recently I had to setup Nexus on my Ubuntu machine. The process is quite straightforward, but I'll try to describe every step as if using a Linux server (without GUI, only shell commands): this could scare the basic Linux user, but trust me, it isn't difficult.
Let's get started.
  1. Download nexus with wget and place in a folder of your choice. Let's assume we are installing Nexus on /usr/local/nexus and unpack it in the same folder
    cd /usr/local
    sudo mkdir nexus
    sudo wget http://nexus.sonatype.org/downloads/nexus-oss-webapp-1.9.2-bundle.tar.gz
    sudo tar -xvzf nexus-oss-webapp-1.9.2-bundle.tar.gz
    
    I'm assuming you have a JAVA_HOME var configured and that this is attached to the PATH variable (ie: you hava Java installed and running. If you want to know how to install Java, I've wrote a simple step-by-step guide
  2. Set up some variable (using the global profile).
    sudo gedit /etc/profile
    
    and add these lines
    export NEXUS_PLATFORM=linux-x86-32 # specify your platform here
    export NEXUS_HOME=/usr/local/nexus/nexus-oss-webapp-1.9.2
    export NEXUS_EXEC=$NEXUS_HOME/bin/jsw/$NEXUS_PLATFORM
    export PATH=$NEXUS_EXEC:$PATH
  3. Now we have nexus downloaded and installed. This will not suffice because the Nexus won't start as a service. To accomplish this task we need to do something more. First, we need to modify the file that launches Nexus
    sudo gedit $NEXUS_EXEC/nexus
    
    and modify these lines
    # Application
    APP_NAME="nexus"
    APP_LONG_NAME="Sonatype Nexus OSS"
    
    # Wrapper
    WRAPPER_CMD=/usr/local/nexus/nexus-oss-webapp-1.9.2/bin/jsw/linux-x86-32/wrapper
    WRAPPER_CONF=/usr/local/nexus/nexus-oss-webapp-1.9.2/bin/jsw/conf/wrapper.conf
    
    # Priority at which to run the wrapper.  See "man nice" for valid priorities.
    #  nice is only used if a priority is specified.
    PRIORITY=
    
    # Location of the pid file.
    PIDDIR="/var/run"
  4. Now you have to set up Nexus as a service. There are two ways to do so:
    • copy the nexus launcher in /etc/init.d, make it executable and update system services
      sudo cp $NEXUS_EXEC/nexus /etc/init.d/nexus
      sudo chmod 755 /etc/init.d/nexus
      sudo update-rc.d nexus defaults
    • create a launcher, make it executable and update system services
      sudo gedit /etc/init.d/nexus # file does not exist, will be created
      
      add the lines
      COMMAND_LINE="/usr/local/nexus/nexus-oss-webapp-1.9.2/bin/jsw/linux-x86-32/nexus start"
      eval $COMMAND_LINE
      
      then
      sudo chmod 755 /etc/init.d/nexus
      sudo update-rc.d nexus defaults
You are done! Restart your system and start working with your new Nexus repository. Note that if you want to import and old repository, you just need to overwrite the /usr/local/nexus/sonatype-work folder

Friday, August 19, 2011

Installing JDK on Ubuntu 11.04 (Natty Narwhal)

  1. Remove open-jdk (optional)
    sudo apt-get remove openjdk-6-jre
    sudo apt-get autoremove
    
  2. Add repository. You can browse http://archive.canonical.com to know which versions are supported. I'm working with a fresh install of Natty Narwal(11.04)
    sudo add-apt-repository "deb http://archive.canonical.com/ natty partner"
    sudo apt-get update
    
  3. Install software
    sudo apt-get install sun-java6-jre
    sudo apt-get install sun-java6-jdk
    sudo apt-get install sun-java6-plugin
    sudo apt-get install sun-java6-fonts
    
  4. Set global variables editing file /etc/profile
    sudo gedit /etc/profile
    and add the following lines
    export JAVA_HOME = /usr/lib/jvm/java-6-sun
    export PATH = $JAVA_HOME:$PATH
    
    Alternatively you can do the same on /home/[user]/.profile

The JDK will be placed in /usr/lib/jvm/java6-sun.

If you didn't execute step 1, you may need to tell the system which alternative to use with:
sudo update-alternatives --config java
and select the new installation (you'll be prompt with altenatives, don't worry).