Archive for the ‘Java’ Category.

Databases are for …

Something I read recently reminded me of this.

At one point I was freelancing in New York city. This guy calls me up and wants to see if I can come over and take a look at this pogram “one of his coworkers” wrote. I’m like sure what’s going on with it, well I just want to make sure best practices were followed, we also seem to have some memory problems. Mind you this was early Java days and the program was written in Java. I show up in his office and he takes me to this laptop “the other guys laptop” I looked around but never saw the other guy. The IDE was open and the project loaded, lets take a look. I poked around some, the code seemed ok, the flow was fine.

But then I saw it, and I go hmmmm…. yea, what is it ? do you realize that all the data from the database is loaded into memory, right here. That’s what it’s doing, right ? Yes, that way it’s super fast…. but here is the thing when we have small amount of data the program works fine, but now I have to put it into production and we are using much more data. I tried my best holding a straight face and talking with him about databases and how they are great for querying for data. I left his office and promised to write up some suggestions about the code, how to make it better. I think he gave me a copy of the code to analyze. I wrote a list of 10 or so things and emailed it over to him. Needless to say the first suggestion was about not loading all the data from the database into memory !

A few days later I get an email from him which apperently he sent to everybody that had come over to evaluate the code, 5 or so consultants. He was asking for a short term fix, as the program needed to be demonstrated to management and he was still getting these memory errors when running with the bigger set of data. One of the consultants suggested a solution, increase the memory size for the JVM. It seems to have worked fine as I never got another email from him again, it’s great when you can find resonable fixes to your problems.

GoogleTv getting started

There were some GoogleTv guys ( Les Vogel and Paul Carff ) coming to town to hold a session on GoogleTv development. This event was facilitated by the local Android meetup group. Naturally I wanted to attend, I haven’t looked at GoogleTv before so why not jump on the oppertunity to get to know GoogleTv development a little. To my surprise I was handed a nice GoogleTv T-shirt and a Vizio GoogleTv device as I walked in the door, w00t !

Lets look at developing for the device, it’s recommended that you develop on Linux, as the Google Tv emulator uses KVM virtual machine to run in, most people use Eclipse as the IDE. Other than that setting up for coding for Google Tv is pretty much the same as coding for Android. First download and install the Android SDK, then download and install the Google Tv extension. Here is a little snag I ran into, when running the Android SDK Manager you will have to toggle the radio button to sort by repository rather than API level to find, “Google Inc. ( dl-ssl.google.com )” in the list. Once you see that you can find “Google Tv Addon” below, that’s the one you want, check the box and install the package. With that out of the way, next you need to setup a Android Virtual machine using the Android Virtual Device Manager. When you create your new GoogleTv AVD see if you can set the data partition to 1024 instead of 128, this will help with errors about the emulator not having enough space for installing your application. Otherwise you can also run it from command prompt, after you add the /tools and /platform-tools directories from the sdk to your path. Like this

$ emulator -avd googleTv -partition-size 1024

For some your keyboard might not work either in the Emulator, in order to activate that add Keyboard support in the harware properties of the AVD configuration and set it to “yes”. Now you should be good to go, you might have to start the Emulator from command prompt depending on your setup. Now in your Package Manger, you can look for KVM and install. You will also need computer that supports BIOS virtualization extensions, in order to check on that run

$ kvm-ok

you should see some message like “KVM acceleration can be used” if your good, otherwise you will get some kind of error.

That’s the Emulator at work

I wrote a sample app that plays different media over the internet, it turns out the emulator is not as capable of playing different formats as the regular Android emulator. Most of my streams played on the Android emulator but not on the GoogleTv emulator. It’s a good thing that they gave us GoogleTv devices when we attended the labs event at Google, now I can start coding and try it on the actual device which will work better than on the emulator. The Vizio GoogleTv is only $99 at the moment, if your going to develop for GoogleTv I would recommend getting the device to test on rather than using the emulator.

A lot of Android applications will work just fine on GoogleTv without any modifycation. The most important thing to keep in mind is that the GoogleTv display is Landscape only and the resolution is usually in the Tv format 1280 x 720 or 1920 x 1080. For example my Android BeerWidget runs fine on the GoogleTv without any modifycation.

HelloWorld deploy on Google Application Engine 1.6.4

I have seen a bunch of tutorials on how to deploy on the Google App Engine. Let me tell you my experience as well, no it does not take 5 minutes, it’s more like 15-20 minutes to get HelloWorld app going.

First you need application account, go to the location below, login with your Google account and create your own application

https://appengine.google.com/

I use Eclipse ( Indigo ), so let’s look at how you install the Google Engine / SDK and plugin from there. The App Engine just got update to version 1.6.4, naturally that’s what we will use.

Help -> Install New Software

Use the Google Eclipse Indigo ( ver 3.7 ) feed

http://dl.google.com/eclipse/plugin/3.7

You can skip the Android stuff, just check the other 3 check boxes and start your downloads, you will have to Accept the license etc, it’s self explanatory.

After a few long minutes of downloads Eclipse will ask for a restart to install everything properly and you will be in business.

Create a new project,
File -> New -> Other -> Google -> Web Application Project

This will create a sample Google Application Engine project for you.

Then simply choose the blue (g) icon from the toolbar menu, and choose Deploy to App Engine… You will be asked for account info etc, and you will connect this deployment with the app you created in the beginning. Now watch the Console portion as the info about your deployment are displayed until you get success info. Then you can go to your application URL and see your new project in action. To find the URL you can goto My Applications in the Google app dashboard, it will have links on the right ( instances ) click on the link there and it will take you to your app.

Your URL will be something like

http://yourapp.appspot.com/

Its worth to mention that Google will host your app for free, as long as you don’t exceed certain resource limits. They actually have generous free limits, you can read more about the limits and what else you can buy in terms of resources here. You can actually host your own domain on the Google App Engine as long as it’s not a naked domain, That is you will be able to host www.mydomain.com but you will not be able to host mydomain.com. That’s really because of security, you can find further reading about that here.

That’s all, happy coding !

Android Beer timer Widget

A friend of mine said he wanted a beer app for the Android, really what’s that ? It goes something like this, a beer glass on your Android desktop. The beer glass fills up from 9am to 5pm, once it’s full, well then it’s time to stop working and go out for a beer. On the weekends the glass is always full of course. This would have to be a widget on the desktop so the image / icon can be changed on a timer through the day. Since I hadn’t written an Android widget before, I told my friend, no problem I will write it for you.

Lets declare the widget in the manifest, the service and the alarm receiver as well.

<receiver android:name=“.FxBeerWidget” android:label=“Beer time widget”>
  <intent-filter>
    <action android:name=“android.appwidget.action.APPWIDGET_UPDATE” />
  </intent-filter>
  <meta-data android:name=“android.appwidget.provider” android:resource=“@xml/beerwidgetlayout” />
</receiver>
<service android:name=“.CxUpdateWidgetService” />
<receiver android:name=“.CxBeerAlarmReceiver” />

Then in the AppWidgetProvider we use AlarmManager to update our receiver

// Setup receiver that will call the widgetService     
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent2 =  PendingIntent.getBroadcast(context, 0,
      new Intent(context, CxBeerAlarmReceiver.class),  PendingIntent.FLAG_CANCEL_CURRENT);
// Use inexact repeating which is easier on battery (system can phase events and not wake at exact times)
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 500, (60*1000), pendingIntent2);

Note that you have to be mindful of the resources you are using and use a long interval. If the person using the phone is playing a game for example when the timer goes off. You do not want to take much resources in order for his game to keep playing smoothly. In our case it’s a simple check and a quick update of a icon if needed.

The CxBeerAlarmReceiver is a BroadcastReceiver which when woken up will start the CxUpdateWidgetService which is a IntentService. The CxUpdateWidgetService will take care of updating the widgets.

public static void updateAllWidgets(Context context)
{
  //
  final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
  final int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, FxBeerWidget.class));

  // Remote view for the widget
  RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.beerwidget );
       
  // Setup the beer main Activity as Intent
  Intent beerIntent = new Intent();
  beerIntent.setClass( context, FxMain.class);
  beerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  // Setup pending intent, when widget clicked show main screen
  PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, beerIntent, 0);
  views.setOnClickPendingIntent(R.id.Widget, pendingIntent);
        
  // Time status
  int iCurrentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
  // Format it in clock like format, leading zero
  views.setTextViewText( R.id.lbStatus, CxUtil.getTimeString() );
       
  // Update image only if needed
  int plusNum = whichIcon( iCurrentHour);
  CxLog.d( CxLog.TOKEN, “updating beer image, currhour=” + iCurrentHour + “, plusNum=” + plusNum   );
       
  // Set the current image
  views.setImageViewResource( R.id.widgetImage, R.drawable.beer72_0  + plusNum );
       
  // Associate the update views – Loop all id’s
  for(int i=0; i<appWidgetIds.length; ++i)
     AppWidgetManager.getInstance(context).updateAppWidget( appWidgetIds[i], views );
}

Note that the user can have more than more widget running, there could be one on each desktop, etc. The for loop will take care of that and update all of the widgets. Another cotcha is that you will have to set the click intent for the widget each time the update function is called. Otherwise it will get disconnected from the widget and clicking the widget will not open the FxMain screen.

Here is the Widget if you like to download and install on your Android – BeerTimeWidget

Here is how it looks in action.

Java log4J

I had the need to log from a java project I just created. Never used log4J before but heard good things. Man do I love it when things are simple and that’s just what log4J is. Download and extract the jar, in my case log4j-1.2.16.jar add it to your classpath and your off to the races. When reading the install document, they have what you need to get up and running ASAP a small HelloWorld that will get you going.

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
   
public class Hello
{
      private static final Logger logger = Logger.getLogger(Hello.class);
      public static void main(String argv[])
      {
        BasicConfigurator.configure();
        logger.debug(“Hello world.”);
        logger.info(“What a beatiful day.”);
      }
}

Create the file from the sample and compile
> javac Hello.java
and run it
> java Hello

It will give the following output
0 [main] DEBUG Hello – Hello world.
6 [main] INFO Hello – What a beatiful day.

Yes, super simple, of course it has all the bells and whistles you might need. Like logging just for a specific class or just at a certain level, log to file etc, etc,

UPDATE
Then you can create xml file and configure the appenders from there, below is a sample of console appender and then a file appender. To set it in code, you can use the following.

PropertyConfigurator.configureAndWatch( “log4j_config.xml” );

That will instruct log4J to monitor your configuration file. If you want to change the configuration on the fly all you need to do is to change your configuration file, log4J checks for changes every 60 seconds. You can also call with additional parameter setting your own frequency.

# Set root logger level and appenders
log4j.rootLogger=INFO, console, rollingFile

# Console appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss,SS} %-4r [%t] %-5p %c %x – %m%n

# Rolling file appender
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=mylog.log
log4j.appender.rollingFile.MaxFileSize=5MB
log4j.appender.rollingFile.MaxBackupIndex=20
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss,SS} %-4r [%t] %-5p %c %x – %m%n

Java Postgres connection sample

I had to setup Postgres on my linux box, configure and make sure it was working. Since that was the case I started the install, then wrote a very simple Java program to connect and retrieve some data from one of the database tables. The install is simple and pretty easy to google. Once your Postrgres database is up and running you should be able to connect to it. You will need a java Postgres database driver, the one I downloaded was the postgresql-9.1-901.jdbc4.jar then add the jar to your project. And finally to make sure your database is accessible from a program you can use the sample below.

//
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

// Simple test class to prove connection to Postgres database
public class Main
{

        public Main()
                { super(); }

        public static void main(String[] args)
        {
       
                System.out.println(” Postgres Test”);
                Connection myConn = null;
               
                try
                {
                        // The driver
                        Class.forName(“org.postgresql.Driver”);
                        System.out.println(“PostgreSQL JDBC Driver Registered!”);
               
                        myConn = DriverManager.getConnection( “jdbc:postgresql://127.0.0.1:5432/testDb”,
                                        “testUser”, “myPassword” );

                        // Connected ?
                        if (myConn != null)
                                System.out.println(“Successfully connected to Postgres Database”);
   
                        // Get data from the database
                Statement stGetCount = myConn.createStatement();
            ResultSet rs = stGetCount.executeQuery(“SELECT * from  cars”);
           
            while( rs.next() )
            {
                System.out.println(“result=” + rs.getString(1) + “,” + rs.getString(2) + “,” + rs.getString(3) );
            }
        }
        catch( Exception ex )
        {
            ex.printStackTrace();
        }
        finally
        {
                try{myConn.close();}catch(Exception IDontCare ){}
        }

        }
       
}  // EOC