Monday, July 21, 2014

Make your Raspberry Pi wireless

Make your Raspberry Pi wireless and be able to hide it away wherever you have a power outlet handy, just follow these steps:

1. Buy a Edimax EW-7811Un 150M 11n Wi-Fi USB Adapter, great plug and play adapter.
2. Follow the steps on http://www.savagehomeautomation.com/projects/raspberry-pi-installing-the-edimax-ew-7811un-usb-wifi-adapte.html
3. Follow https://www.modmypi.com/blog/tutorial-how-to-give-your-raspberry-pi-a-static-ip-address to set a static IP address

Consider upgrading your software and firmware by following https://raspberrypi.stackexchange.com/questions/4698/how-can-i-keep-my-raspbian-wheezy-up-to-date

Good luck! Have fun with your pi. :)

Tuesday, June 24, 2014

Play 2 framework access files in WAR

So you've created WAR files from your Play project, see Play 2 framework WAR file. But how to fetch files within you WAR file.

I previously used:
new File(play.Play.application().path().toString() + "//mydirectory//myfile.txt");
which works fine when running on the Play "stack".

After exporting to WAR file the path ended up looking in the application home directory, e.g. /home/<runninguser>/.
Still works for files not in the WAR, since they are expected to be found here anyways.

Solution for my WAR files:
InputStream is = Play.class.getResourceAsStream("/mydirectory/myfile.txt"");
StringWriter writer = new StringWriter();
IOUtils.copy(is, writer, Charsets.UTF_8);
writer.toString();


Source: http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string and http://stackoverflow.com/questions/6888343/getting-a-resource-file-as-an-inputstream-in-playframework

Note: Jetty will unpack you WAR file to a temp directory, either /tmp or below you application path /home/<runninguser>/ so this is what you are accessing. Remember not to have a script deleting these files as this will crash your web application.

Play 2 framework WAR file

Play 2 framework is a nice framework for writing web applications in Java/Scala. Play runs it's own netty server so you get it up and running by just writing play run. It detects file changes and recompiles classes as needed upon page refresh in development mode.

A small catch is that Play does not natively support running in a container, e.g. Jetty, Tomcat, Glassfish, or JBoss. In fact it doesn't support ServletContext at all as far as I can see. (See http://www.playframework.com/documentation/1.2.2/faq and http://guillaumebort.tumblr.com/post/558830013/why-there-is-no-servlets-in-play)
This is a minus when trying to get started with Play in existing server environments. Luckily Damien Lecan started an open source project to build WAR files from Play, play2war plugin.

Follow https://github.com/play2war/play2-war-plugin/wiki/Configuration to install the plugin.

Basically your Build.scala file should look something like:
import com.github.play2war.plugin._
object ApplicationBuild extends Build {
    val main = play.Project(appName, appVersion, appDependencies)
        .settings(Play2WarPlugin.play2WarSettings: _*)
        .settings(
      // Add your own project settings here 
      Play2WarKeys.servletVersion := "3.0"
    )

}

and your plugins.sbt:
// Use play2war for creating war files using 'play war'
addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.2-beta4")

And hopfully, magic! (Note currently (2014.06.24) only support Play 2.2.1)

Once installed, just run play war and a war file is created for you. In addition you will need a config file for your application, the application.conf in your project folder, and any extra files/folders like the private folder of your project.

Wednesday, May 28, 2014

Add new user in Linux/Ubuntu

To add a new user using command line on an Ubuntu machine there are at least two commands that may be used: useradd and adduser

Use adduser instead of useradd if you are not totally certain useradd is the tool you want to use because:
1. useradd is a low level tool.
2. useradd will not add home directory for new user.
3. useradd will not add many other defaults for new user.
4. adduser is more user friendly (but uses useradd in backend).
5. adduser will create home directory.
6. manpages of useradd recommends use of adduser.

Use it like this:
sudo adduser <username>

and to add a system user which has no shell (cannot log in, but just run programs):
sudo adduser --system <username>
 instead of
sudo useradd <username> -s /bin/false
Using adduser, the system user a home directory will be created.

See http://askubuntu.com/questions/374870/home-directory-not-being-created and http://askubuntu.com/questions/345974/what-is-the-difference-between-adduser-and-useradd for good reasons with links to manpages.

Java Listeners and Adapters, almost anonymous functions

Java allows developers to easily add listeners to different events.
e.g. button.addMouseListener(this);
However, often you don't want to implement a listener interface for your class or add an inner class
MyClass implements MouseListener
MyClass {
    private class ListenerClass implements MouseListener {
            public void mouseClicked(MouseEvent e) {}
            public void mouseEntered(MouseEvent e) {}
            .
    }
}

With all the functions required by the interface cluttering up your code. Often you don't even need more than one or two of the functions.

Enter Adapters.
Adapters are classes which are made to match a listeners interface and only that. They do nothing when called, but the developer will override the function he needs:
button.addMouseListener( new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
    }
}


This adds flexibility to Java, almost like the anonymous functions of JavaScript.

Source: https://blogs.oracle.com/CoreJavaTechTips/entry/listeners_vs_adapters
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html

Wednesday, May 7, 2014

Play2 PersistenceException

You might come across the error:
[PersistenceException: Error loading on models.Period.startYear]
in Play 2 Framework.
This is most likely caused by your database having a NULLable field which doesn't map to a nullable member in the model.
E.g.:

You database has the following fields:
ADD COLUMN `start_year` INT(11) NULL DEFAULT NULL;
ADD COLUMN `end_year` INT(11) NULL DEFAULT NULL;

 which means start_year may be (null) or an int.

Your java model has the following members:
@Entity
public class Period extends Model {
    @Id
    public Long periodId;

    @Required
    public int startYear;
   
    @Required
    public int endYear;
}

Which means that startYear may be an int, but not null.

To fix, make change the database fields to not be nullable.
Or the java model members nullable also, by using the Integer object wrapper instead of int:
@Entity
public class Period extends Model {
    @Id
    public Long periodId;

    @Required
    public Integer startYear;
   
    @Required
    public Integer endYear;
}


See: http://stackoverflow.com/questions/18405141/persistenceexception-when-i-was-using-ebean-in-play-framework