donderdag 5 november 2009

Java + MySQL + Hibernate

Last time I explained how to set up your system so you could feed queries to a MySQL database from your Java application. Now, to make it prettier and easier, I added Hibernate.

Hibernate will let you get and put Java objects from and into the database.

Ok, download Hibernate Core here and maybe read this tutorial for extra information.

I will be using the database table I made in last example, a table named 'phonebook', with contents:

mysql> SELECT * FROM phonebook;
+----+-------+----------+
| id | name | number |
+----+-------+----------+
| 1 | Barry | 555-1234 |
| 2 | Bob | 555-5678 |
+----+-------+----------+
2 rows in set (0.00 sec)


Now, create a new Java project and add the jars of Hibernate Core and the MySQL Connector/J connector. Our project consists of 5 files, which are 1. a SessionFactoryUtil, to connect with our database, 2. a class which describes a entry of the database table, a phonebook entry, 3. a hibernate config file which lets our program connect to the database, 4. a hibernate mapping file, which maps a database row to the object made in 2. and 5. a test class to show (how) it works.

SessionFactoryUtil
This file creates a connection to the database.

package com.example.phonebook;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class SessionFactoryUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();

private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure("hibernate_phonebook.cfg.xml").buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed. " + ex);
throw new ExceptionInInitializerError(ex);
}
}



public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}


The PhoneBookEntry object

package com.example.phonebook;

public class PhoneBookEntry {
private Integer id;
private String name;
private String number;

/*public PhoneBookEntry(String name, String number) {
this.name = name;
this.number = number;
}*/

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}

public String toString() {
return "Name: " + getName() + " Number: " + getNumber();
}
}


The hibernate config file
I called my file hibernate_phonebook.xml.cfg. I needed to name this file in the SessionFactoryUtil, because by default hibernate looks for the file hibernate.xml.cfg.
In this file, there's all the data to connect to the database.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://192.168.1.74/test2</property>
<property name="connection.username">root</property>
<property name="connection.password">password</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

<!-- thread is the short name for
org.hibernate.context.ThreadLocalSessionContext
and let Hibernate bind the session automatically to the thread
-->
<property name="current_session_context_class">thread</property>

<!-- this will show us all sql statements -->
<property name="hibernate.show_sql">true</property>

<!-- mapping files -->
<mapping resource="phonebook.hbm.xml" />

</session-factory>
</hibernate-configuration>


The hibernate mapping file
I called this file phonebook.hbm.xml. I maps the database rows to the object PhoneBookEntry.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.example.phonebook.PhoneBookEntry" table="phonebook">
<id name="id" column="id" type="java.lang.Integer">
<generator class="increment"/>
</id>
<property name="name" column="name" type="java.lang.String" />
<property name="number" column="number" type="java.lang.String" />
</class>
</hibernate-mapping>


The test
The last file is a test. What it does: create a connection, read all entries from the table in the database, add an entry and display all entries again.

package com.example.phonebook;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class PhoneBookTest {
public static void main(String[] args) {
listEntries();
PhoneBookEntry entry = new PhoneBookEntry();
entry.setName("Jay");
entry.setNumber("555-8912");
addEntry(entry);
listEntries();
}


private static void listEntries() {
Transaction tx = null;
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
try {
tx = session.beginTransaction();
List entries = session.createQuery("select e from PhoneBookEntry as e").list();
for (Iterator iter = entries.iterator(); iter.hasNext();) {
PhoneBookEntry element = (PhoneBookEntry) iter.next();
System.out.println(element.toString());
}
tx.commit();
} catch (RuntimeException e) {
if (tx != null && tx.isActive()) {
try {
// Second try catch as the rollback could fail as well
tx.rollback();
} catch (HibernateException e1) {
//logger.debug("Error rolling back transaction");
}
// throw again the first exception
throw e;
} else throw e;


}
}

private static void addEntry(PhoneBookEntry entry) {
Session session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(entry);
session.getTransaction().commit();
}
}


The result
After running, the result is

Hibernate: select phonebooke0_.id as id0_, phonebooke0_.name as name0_, phonebooke0_.number as number0_ from phonebook phonebooke0_
Name: Barry Number: 555-1234
Name: Bob Number: 555-5678
Hibernate: select max(id) from phonebook
Hibernate: insert into phonebook (name, number, id) values (?, ?, ?)
Hibernate: select phonebooke0_.id as id0_, phonebooke0_.name as name0_, phonebooke0_.number as number0_ from phonebook phonebooke0_
Name: Barry Number: 555-1234
Name: Bob Number: 555-5678
Name: Jay Number: 555-8912

First, we see the SELECT query and the result, 2 entries. Then we see the INSERT query, and then another SELECT, now with 3 entries. Just as planned.

Of course, this is a very simple example. You could/should include functions to UPDATE and REMOVE entries in the database, and try to catch more Exceptions. This is just the very basics, to see if it works, and if you understand the basics.

woensdag 4 november 2009

Java and MySQL in Eclipse

Here's an example how to work with Java and MySQL in Eclipse, in my case on a Ubuntu machine. My original idea was to create an example with Java, Hibernate, Google Web Toolkit and MySQL in Eclipse, but because a lot of errors I decided to split up the project. Maybe later I'll post the intended example.

So, Eclipse, Java and MySQL, it don't sound that difficult, and actually it isn't.

Installing Eclipse
I started downloading Eclipse from http://www.eclipse.org/downloads/ I received the file eclipse-jee-galileo-SR1-linux-gtk.tar.gz
I extracted the file in ~/ so I got a directory ~/eclipse there.

MySQL
I already had MySQL installed. Information on installing MySQL is found over here http://dev.mysql.com/downloads/
I downloaded the MySQL Connector/J connector. It is the official JDBC driver for MySQL. (http://dev.mysql.com/downloads/connector/j/5.1.html)

Sun JDK
Make sure you are using the Sun java 6 JDK. As a Ubuntu user I installed the package sun-java6-jdk from the repository.

Now we have installed everything we need.

Create database
Login to MySQL as root:
$ mysql -u root -p
Create a new database:
mysql> CREATE DATABASE test2;
Open the database:
mysql> connect test2;
Create a new table:
mysql> CREATE TABLE phonebook (id INT(8) UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(32) NOT NULL, number VARCHAR(32) NOT NULL, PRIMARY KEY(id));
The table is a very simple phonebook, containing name and number and a unique id.
Now insert 2 rows for testing:
mysql> INSERT INTO phonebook (name, number) VALUES ('Barry', '555-1234');
mysql> INSERT INTO phonebook (name, number) VALUES ('Bob', '555-5678');

If you type the query SELECT * FROM phonebook; you should see something like this:
mysql> SELECT * FROM phonebook;
+----+-------+----------+
| id | name | number |
+----+-------+----------+
| 1 | Barry | 555-1234 |
| 2 | Bob | 555-5678 |
+----+-------+----------+
2 rows in set (0.00 sec)


Starting Eclipse
First of all, set up Eclipse so it uses the Sun JDK, because the default GNU JDK will produce errors. A nice howto is over here: https://help.ubuntu.com/community/EclipseIDE#Eclipse%20and%20Sun%20Java
It took me a long long time to realise the default VM was the cause of all kind of connection errors. So learn from it.

Now it's time to create a new project. File > New > Project opens a wizard. Just choose Java project and Next. I named the project mysqltest.
Include the downloaded JDBC driver for MySQL. Right-click on the project and select properties. Choose Java Build Path > Libraries > Add External JARs. Include the file mysql-connector-java-.bin.jar from the location you extracted the JDBC driver earlier on.
In the directory src, create a new class Test1. Test1.java can be the following.

package com.example.mysqltst;

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


public class Test1 {
public static void main(String [] args) {
try {
// load the driver
Class.forName("com.mysql.jdbc.Driver").newInstance();

// create a connection to the db
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test2", "root", "password");

// get some results
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM phonebook");
while (rs.next()) {
System.out.println(rs.getString(1) + " " + rs.getString(2) + " " + rs.getString(3));
}

} catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
} catch (Exception e) {
System.out.println("Other exception: " + e.getMessage());
}
}
}


Running the code will result on the stdout:

1 Barry 555-1234
2 Bob 555-5678


A useful link to get more in depth information (old, but still good): Writing JDBC Applications with MySQL

dinsdag 3 november 2009

Online mancala game

I wanted to train my java, gwt, junit and mockito skills. The result is an online mancala (or kalaha) game. It's a game for two players. You can try and play the mancala game over here: mancala game. Enjoy.

vrijdag 9 oktober 2009

How to install a printer on your Aspire One

I decided it's useful to install a printer after I wanted to print an e-mail. I have a network printer so it should be easy.

On the site of www.linuxprinting.org there are a lot of install guides and drivers.

My Linpus installation already had the 'cups' installed. Probably by default. Cups is the
printing system that's being used. I downloaded the ppd driver I needed.

I just opened the cups configuration website in a browser. The url is http://localhost:631/admin. I added a new printer with the Internet Printing Protocol (ipp), which my printer supports. It seems like a lot of modern printers are supported by cups. I had to provide the downloaded .ppd file though, because my printer wasn't.

After logging in as root on the install webpage, there's an option to set printer options, like paper size and double sided printing. After that, go to the tmenu item 'Printers' to test the installation with 'Print Test Page'. Mine worked fine!

So it's actually quite easy. Cups is already installed, and if you don't have an exotic printer, you shouldn't even have to look on the internet for drivers, and just follow the directions on http://localhost:631/admin

vrijdag 14 augustus 2009

New PopMundo city

I've updated my PopMundo tools at http://www.xs4all.nl/~jjokkema/popmundo/
It now includes the new city Manila. There are 2 new travel routes, Manila-Shanghai and Manila-Singapore.
I upgraded the tools so I'll only have to update an xml file with all travel routes instead of adding the travel routes in the code and recompiling and uploading it all.
Xml and google web toolkit was a pain right now, but in the long run, I'll reap the fruits.

donderdag 13 augustus 2009

How to play Championship Manager 01/02 on Linpus Lite

Last time, I showed how to mount an ISO file. My intention was to install Championship Manager 01/02, a Windows 95 football manager I was addicted to at the time. I'm playing it now again. Many say the 01/02 version is the most playable version.

As a promotion for the newest version of the game, the creators decided to give the 01/02 game away for free. You will have to register on their site, though. Once you're registered and logged in, you can download the original cd from this page.

In order to have our Linpus Lite be able to run Windows applications, we'll install Wine. The yum repository doesn't have the newest version (I have 0.9.47), but it's new enough to run CM01/02. Install it in a terminal screen by typing
sudo yum install wine

I have mounted my ISO of the game on /mnt/iso/. I now can install the game with
sudo wine /mnt/iso/Setup.exe
Just install the default directories.

Wine installed the game in ~/.wine/drive_c/Program Files/Championship Manager 01-02/
We can now start the game by typing
cd ~/.wine/drive_c/Program Files/Championship Manager 01-02/
sudo wine cm0102.exe
Unfortunately, when the guys at championshipmanager.co.uk decided to release the free version of the game, they didn't remove the cd check. If the original cd isn't in a cd drive, the game won't start. Since the Aspire One does not have a built in cd drive, it is impossible to have a cd in a drive. So i'm afraid a no cd crack is necessary. Although I don't like hacks en cracks, I don't see another option.
But first we're going to upgrade the game to the latest version.

The best site to find all kind of things for Championship Manager 01/02 is the fan site www.champman0102.co.uk. It's here I downloaded the SI Games Official Patch v3.9.68 which is the newest patch. All other patches and updates on the champman0102.co.uk site need this patch. I installed the patch:
sudo wine /home/user/Downloads/242.exe

I'm thinking about downloading and installing the Tapanified March 2009 Patch, which includes the current players (to start the season at 2008 instead of 2001). The game on my desktop computer also has this patch. It should enable me to use the other savegames, maybe save them to a server so both games can access them.

What is necessary is a no cd patch. I downloaded the file ppfcm68.rar from gamecopyworld. Unformtunately .rar was the only choice, so I extracted the file on my Windows desktop computer and rename the old .exe files and replaced them with the patched ones.

You can now play the game. Unfortunately you can't alt-tab in and out of the game, it will lock up. Windowed mode (cm0102.exe -windowed) also didn't help. So I'll play the game without multitasking. You can get the Linpus taskbar out of the screen by clicking on the arrow in the bottom left of the screen, the left of the taskbar. You'll have a full screen game then.
You can play the game:
sudo wine ~/.wine/drive_c/Program\ Files/Championship\ Manager\ 01-02/cm0102.exe -nosound
I disabled the sound, I guess you will too.

woensdag 12 augustus 2009

How to mount iso files in Linpus Lite, a script

This page showed me it is really simple to mount an ISO image in Linux, just type in the following line.
$ sudo mount -o loop <iso-file>
Of course, the blog adds some code around it to create a new directory and such.

I decided to use the mount call and create a script, for my -and maybe your- convenience. First, I'll give the script, then I'll explain, in case you're interested.
#!/bin/bash
FILENAME=$1

if ! [ -f $FILENAME ]; then
echo "ISO file does not exist, exiting."
exit
fi

if [ $# != 1 ]; then
echo "No ISO file given, exiting."
exit
fi

if ! [ -d /mnt/iso/ ]; then
sudo mkdir -p /mnt/iso/
echo "/mnt/iso/ did not exist, created."
fi

if [[ $(mount | grep -c /mnt/iso/) -ge 1 ]]
then
sudo umount /mnt/iso/
echo "/mnt/iso/ was already mounted, unmounted."
fi

sudo mount -o loop $FILENAME /mnt/iso/
echo "$FILENAME is now mounted on /mnt/iso/"


A script always starts with #!, this script uses /bin/bash.
The location and name of the iso file the user is required to give is begin remembered in a variable, FILENAME.

The script starts with two tests. Is a file given and does the given file exist. If the tests (or one of the tests) fail, the program exits.

Then the mountpount is being checked. The script mounts the iso by default at /mnt/iso/. If the directory doesn't exist, it's created.

Next we have the block which checks if there's already a mount active on /mnt/iso/. If so, it is being unmounted.

Now we're finally ready to mount the iso file. A message is printed the mount was successful.

You can place the script in your homedir, for example. Don't forget to make it executable by (I called the file 'mountiso')
$ chmod 755 mountiso
I placed an iso on a usb stick, which mounted as /media/UDISK/ (the name of the usb stick was UDISK, don't ask me why), and mounted it with the command
$ ./mountiso /media/UDISK/iso/CM0102.iso

dinsdag 28 juli 2009

Samba shares in Thunar (file manager of Linpus Lite)

Wow, I just found this very handy forum posting explaining how to mount a Windows (or Samba) share on Linpus. I don't know if Linpus has been updated, because earlier I wasn't able to let Thunar (the default file manager) open smb shares.

I will be using the words Samba or smb because I have my shares on a Linux computer.

Part 1: create a script which will mount the samba share


First of all, create a directory in /mnt/. For example /mnt/windows, /mnt/samba or /mnt/<servername>
sudo mkdir /mnt/samba

Now, create a new file called /root/samba-share.sh with the following content
#!/bin/bash
/bin/df -k | /bin/grep /mnt/samba > /dev/null
if [ $? != 0 ]; then
sudo /sbin/mount.cifs //<server>/<share> /mnt/samba -o user=<user>%<password>
fi
/usr/bin/launch-thunar.sh /mnt/samba


You will have to insert your own servername (or ip address), share, username and password. If your server allow anonymous logins, you can replace "user=<user> password=<password>" by "guest".
Let's go through the script. The first line checks if the share is already mounted. If so, the mounting by mount.cifs is skipped.
Finally the graphical file manager Thunar is opened at your samba share.

You will have to make this file executable with the command
sudo chmod 755 /root/samba-share.sh

Part 2: create a desktop item and show it in the interface


We will create a file called /usr/share/applications/sambashare.desktop
In this directory all desktop items are placed. These items are used by the default interface.
In this file we'll put
[Desktop Entry]
Name=My Samba Share
Comment=Files shared on Samba server
Exec=/root/samba-share.sh
Icon=mydownload.png
Terminal=0


Now, just add this desktop item to the files menu. Open the file /home/user/.config/xfce4/desktop/group-app.xml and add the following line to the group with id=8 (search for <id>8</id>).
<app sequence="6">/usr/share/applications/sambashare.desktop</app>
This will have added an icon the the files menu. A reboot is needed to show it, though.

Clicking the icon will open Thunar at the samba share.

maandag 27 juli 2009

Too many markers in Google Maps

When creating an application with the Google Maps Api I, as many, stumbled upon the problem of having too many markers on a maps. In some cases over 1000. On the web there are some good solutions.

Here's a blog with some solutions. I decided to try MarkerClusterer, which was added later to the article. The screenshots look good and it should work fine for my project.

Here's a blog of the creator of MarkerClusterer. It describes the use briefly.

A real good example of simple use, excellent to start out with, is over here. It shows the url of the script to include and how to display a bunch of markers on the map.

When you're somehow familiar with Google Maps and the MarkerClusterer, here's a good advanced example. The source code describes how to use the advanced setting, for example how to show your own markers instead of the colored circles that are standard for MarkerClusterer.

With these links, you should be able to create some nice applications.

vrijdag 24 juli 2009

Install FireFox3 on the Acer Aspire One

Also, a good thing to do with your Aspire One is to install Firefox 3. Firefox 2 is installed by default, but since several Linpus programmes (like email) depend on Firefox 2 libraries, you cannot just upgrade 2 to 3.
I found a very good tutorial you can use, or you can follow my summary of the tutorial.

On the Firefox site you can choose the newest Firefox in your favorite language. Make sure you choose a download with os=linux. In this example, I'll use version 3.5.1 in US English. I downloaded via the link http://www.mozilla.com/products/download.html?product=firefox-3.5.1&os=linux&lang=en-US and put it in /tmp.

Now extract the file as superuser to the directory /opt.
sudo tar -jxf firefox-3.5.1.tar.bz2 --directory /opt

Set the default user as owner of all the files with
sudo chown user -R /opt/firefox

I choose to rename the old startup script /usr/bin/firefox to firefox2. Then I set a symbolic link from /usr/bin/firefox to the newly installed one.
sudo mv /usr/bin/firefox /usr/bin/firefox2
sudo ln -fs /opt/firefox/firefox /usr/bin/firefox

The next step links all plug-ins (not to be confused with extensions) to Firefox 3.
sudo ln -s /usr/lib/mozilla/plugins/* /opt/firefox/plugins

Launch the profile manager using the command below. Create a new profile, name it anything you like and select it. If you want to keep your bookmarks export them via the bookmark manager first. You can then delete the old default profile.
The old profile has some things disabled, including the "check for updates".
firefox -profilemanager -no-remote

Now, I'm going to change the connect menu. First, copy the old .desktop file to a new one. I want to keep the old one, just in case.
sudo cp /usr/share/applications/linpus-web.desktop /usr/share/applications/firefox3.desktop

Edit the linpus-web.desktop file with your favorite editor. Search the line with "Exec=firefox" and edit it to "Exec=firefox2".
In the file firefox3.desktop, replace the old icon with a new one.
sudo sed '/Icon/ s/acs_//' -i /usr/share/applications/firefox3.desktop

Now, edit the menu. Edit the file ~/.config/xfce4/desktop/group-app.xml.
Optional: I copied the line <app sequence="0">/usr/share/applications/linpus-web.desktop</app> to the bottom of the block, replacing 0 by 11 (my last menuitem was 10).
We want to have the new FireFox icon on the first spot (replacing the old browser). Edit the line <app sequence="0">/usr/share/applications/linpus-web.desktop</app> and replace "linpus-web.desktop" by "firefox3.desktop".

Now, after a reboot of the system, it should work. You'll have a nice Firefox logo in the connect menu, which will open Firefox3.

Popmundo tools

For players of the online game Popmundo
, there are a few tools. Two of them are a travel route planner (to plan the quickest route between two Popmundo cities) and a tour planner.
I find them quite useful.

donderdag 23 juli 2009

How to install software in Linpus Lite on the Acer Aspire One

I wanted to install an irc-client on my AA1. I decided xchat was an ok option. I will post a step by step installation.

  1. First open a terminal screen. This can be done with Alt-F2 and run program xterm.
  2. Use the software package manager yum to install xchat. Yum is installed with Linpus. On the command line, type yum install xchat to install.
  3. Now the program is installed, but it's nice to have an icon in the connect-menu. The install made a file named /usr/share/applications/xchat.desktop with a desktop entry, containing links to an icon and the executable. This file we want to present to the menu.
  4. The menu is located in /home/user/.config/xfce4/desktop/group-app.xml, an xml file. Now look for the group where the first app is <app sequence="0">/usr/share/applications/linpus-web.desktop</app>. You can put the icon at the end, by adding the line <app sequence="9">/usr/share/applications/xchat.desktop</app> at the end of the apps, but I preferred to give it sequence=2 and give the other sequences an increase of 1, so xchat is displayed on the home screen.
Well, this installed xchat for me. In this way, you should be able to install most of the programmes.

First post!

I reinstalled my Acer Aspire One with Linpus Lite recently. I want to share my tips and tricks I found on the internet to help others, and for myself, in case I need it some other time. For example, how to install software, how to add memory, etc.

Sometimes, I won't suppress the urge to post other useful or even useless stuff.