Pages

Monday, April 26, 2010

How to Stop a Thread or a Task in Java

Abstract

How to stop a Thread is a perannual question for Java programmers. Finally with the release of Java V5.0 (or V1.5), which incorporates java.util.concurrent, a definitive answer can be given. The answer is you stop a thread by using interrupt(). This article covers some of the background to stopping threads and the suggested alternatives and discusses why interrupt() is the answer. It also discusses interrupting blocking I/O and what else the programmer needs to do to ensure their threads and tasks are stoppable.

Introduction

One of Java's claims to fame is that it was conceived from the start as a language that would support multi-threaded programming. Threads are a first class object and the synchronized keyword was provided to assist in co-ordinating threads. Unfortunately as one of the first (the first?) languages to incorporate threads into its design, Java's designers did not get everything right the first time round.

In particular, they failed in their attempts to provide a safe and effective means of stopping a thread once it had started. The original java.lang.Thread class included the methods, start(), stop(), stop(Throwable) and suspend(), destroy() and resume(), which were intended to provide the basic functionality for starting and stopping a thread. Of these only the start() method has not been depreciated. The javadoc comments for the other methods warn against their use.

The Sun article, Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? , goes into some detail as to why these methods were deprecated (Note: destroy() has now also been depreciated). Some of that discussion will be covered below.

The problems with stopping Threads were not the only problems the previous versions of Java had. There was also no straight forward mechanism to catch and handle any exception the thread might throw out of its run method. This lead to poor coding like



public void run() {
// note the Thread.run() method is declared
// NOT to throw any checked exceptions
try {
....
// some code here which might throw
// a checked exception such as an IOException
..
} catch (IOException ioex) {
ioex.printStackTrace();
}
}

because it was not easy to let the rest of the program know that the thread had terminated with an exception. A related problem was that of returning the results of a thread's action. Typically these results had to be stored in some synchronized variable and then the thread had to notify the caller when the results were valid. For Java V1.4 and below, my ThreadReturn package provided a solution to both these problems.

Other problems with multi-threaded programming in previous versions of Java include a lack of common robust utilities to do such things as,

  • synchronize two threads at a point and exchange objects

  • a counting semaphore to control/restrict concurrent access to a resource (synchronized limits access to just one thread at a time)

  • a countdown latch that blocks one or more threads until a set of operations performed by other threads completes

  • read/write locks which allow any number of thread to read but only one thread to write.

  • atomic updates for Integer, Long etc which allow a value to be set in a thread safe lock-free manner.

Java V5.0 incorporates Doug Lee's Concurrent package as java.util.concurrent . This package provides robust utilities for the above items. You are encouraged to read the javadocs carefully and make use of these utilities. Since this article is primarily about stopping Threads it will not go into any more detail on these utilities.

Suggested Methods for Stopping a Thread.

Now that the Thread's stop(), suspend() etc., methods have been deprecated, the only way to safely terminate a thread is to have it exit its run() method, perhaps via an un-checked exception. In Sun's article, Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? , there are some suggestions for how to stop a thread without using the unsafe deprecated methods.

The method suggested there is to use a volatile stop flag (blinker in the code below)



private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}

The volatile keyword is used to ensure prompt communication between threads. “A field may be declared volatile, in which case a thread must reconcile its working copy of the field with the master copy every time it accesses the variable. Moreover, operations on the master copies of one or more volatile variables on behalf of a thread are performed by the main memory in exactly the order that the thread requested.” (See http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930 for more details.

Synchronization, Volatile and Atomic Variables

In general, multi-threaded access to non-atomic variables should be synchronized to avoid invalid values being retrieved. Atomic variables are guaranteed to be updated (saved or loaded) in one machine instruction and so are always in a valid state regardless of the number of threads accessing them. Note however due to caching the valid state may not be the most up todate one. What are atomic variables varies from architecture to architecture (32 versus 64 bit for example) . In general primitive data types with sizes smaller then the machine word length are atomic. On most (all) architectures these include, char, byte, short, int, boolean.

However “The load, store, read, and write actions on volatile variables are atomic, even if the type of the variable is double or long. “ http://java.sun.com/docs/books/jls/second_edition/html/memory.doc.html#28733

So declaring the Thread variable, blinker, as volatile makes its update atomic and hence synchronization is not needed for this variable. Also marking this variable as volatile ensures the most up todate value is always used.

Non-Runnable Thread States

In order for the thread to respond to the stop flag the thread has to be running. A thread is in a non-runnable state if

  • Its sleep method is invoked.

  • The thread calls the wait method to wait for a specific condition to be satisfied.

  • The thread is blocking on I/O.

If thread is in a non-runnable state, setting the stop flag variable will have no effect. In the above example, after calling the stop() method above, you have to wait until the sleep interval has expired before the thread stops. To get the thread to stop promptly you need to break out of the sleep using interrupt(). (Interrupt() will also break out a wait method.)



public void stop() {
Thread tmpBlinker = blinker;
blinker = null;
if (tmpBlinker != null) {
tmpBlinker.interrupt();
}
}

Note: tmpBlinker does not need to be declared volatile because the load from volatile blinker is guaranteed to be atomic.

To summarize, now that the Thread stop() method has been found to be unsafe and has been depreciated, Sun suggests its functionality be replaced with a stop variable. However this by itself is not sufficient to stop the thread promptly. You also need make sure that the thread runnable. At the very least this requires a call to the Thread interrupt() method to break out of sleep() and wait() methods that the thread may be trapped in, in some lower level method. Breaking out of the third non-runnable state, blocking on I/O is more involved and will be discussed below.

IfInterruptedStop()

In the ThreadReturn package I combined the need for a stop variable and the need to call interrupt() into one. As discussed above the only safe way to stop a thread is to exit its run() method. In order to do that the thread needs to be running, so when trying to stop a thread you would normally call its interrupt() method as part of the stopping process.

Now when a thread is in a sleep() or wait() method, calling interrupt() on that thread breaks out of the sleep or wait and throws an InterruptedException. Ensuring this exception propagates all the way back up to the exit of the run() method is the simplest means of stopping a thread. Since the run() method is not declared to throw any checked exceptions, the InterruptedException needs to be caught and wrapped in an un-checked exception (such as a RuntimeException). Java will insist you catch and handle the InterruptedException because it is a checked exception. So code your handler like so



try {
....
wait();
} catch (InterruptedException iex) {
throw new RuntimeException("Interrupted",iex);
}

You may like to define your own un-checked exception class to use for this purpose so you can distinguish it from other RuntimeExceptions. In Java V1.5 there is a java.util.concurrent.CancellationException you can use, although it does not have a constructor that takes a throwable which limits is usefulness. You are probably better off defining your own.

Then provided you do not catch the un-checked exception at some intermediate level, it will ensure the thread stops by exiting the run() method. There may be some cases where you want to interrupt a thread's wait() or sleep() method when you don't want to stop the thread. In these cases you should put a try/catch block around the wait() or sleep() and catch and handle the InterruptedException there without propagating an exception back up to the top run() method.

Now if the thread has started, and was not in a sleep() or wait() method, then calling interrupt() on it does not throw an exception. Instead it sets the thread's interrupted flag. This flag can then be used as the thread's stop flag. To do this insert the following code fragment in those places you want to check for stopping the thread. (See the note below about stopping threads that have not yet started.)



Thread.yield(); // let another thread have some time perhaps to stop this one.
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Stopped by ifInterruptedStop()");
}

The call isInterrupted() does not clear the thread's interrupted flag. You should avoid using the interrupted() method (not to be confused with interrupt()) because a call to interrupted() clears the thread's interrupted flag and will prevent you detecting the request to stop.

The static methods ThreadReturn.ifInterruptedStop(), FutureTalker.ifInterrruptedStop() and TaskUtilities.ifInterruptedStop() all contain this code. FutureTalker requires Java 1.5 while the other two only need Java 1.4 or higher. So you can inserting the following line at strategic points in the thread in place of the previous code

  TaskUtilities.ifInterrruptedStop();

Why interrupt() is the answer.

In the preceding section I have shown how you can stop your thread by only using interrupt(). The question to be answered now is why this is the preferred method of stopping threads. The answer lies in the code of the new Java V1.5 standard library java.util.concurrent. This standard library provides a unified means of passing Tasks to threads and retrieving the results, or the error if one occurred. This standard library, together with my FutureTalker package provides Java V1.5 with the functionality my ThreadReturn package provided for Java V1.4.

Multi-Core Hardware

Before delving into the code, lets examine what java.util.concurrent means for multi-threaded programming. In java.util.concurrent Threads are abstracted to Tasks. When using Threads directly, you override the run() method to do something useful and then create the Thread object and call start() which initializes the thread and calls the run() method. This thread initialization is not cheep. Allen Holub (Taming Java Threads, pp209) reports it takes 15 times longer to start the thread then it does to create it. Also the number of threads can be a limited resource in some systems.

With this in mind you can see the advantage of separating the task to be run from the thread running it and using a pool of reusable threads to run the tasks. This functionality is provided by java.util.concurrent. Instead on concentrating on Threads and their run() methods, java.util.concurrent instead talks about tasks which implement Callable. The Callable interface defines just one method,

  V call() throws Exception

which computes a result, or throws an exception if unable to do so. This is a noticeable improvement over the Thread's run() method because call() can return a result and throw a checked exception. Building on the Callable interface, java.util.concurrent provides classes for the asynchronous execution of Callable tasks. The Future interface represents the result of an asynchronous task. FutureTalker is a concrete implementation of this interface which provides the ability to add listeners which will be informed when the task terminates.

In a recent Scientific American article, “A Split at the Core” (Nov. 2004, Vol 291, No 5), Gibbs reported the move to multi-core processors which provides multiple processors in a single package. To take advantage of such hardware, programs will need to run as many tasks in parallel as possible. This is where java.util.concurrent and the Callable interface come into their own. By separating the task from the thread that runs it and by reducing the overhead of starting multiple tasks, the programmer can make many more operations into tasks and even break a task in to sub-tasks, leaving the thread pool factory class as the single point of configuration to efficiently allocate these tasks to utilize the available processing power. Apart from the fact that java.util.concurrent is now a standard Java library, the move to multi-processor hardware should be enough to convince you that programming tasks based on the Callable and Future interfaces is the way to go.

Cancelling a FutureTask

Getting back to why interrupt() is the answer, the Future interface provides a method to cancel a pending or running task;

  boolean cancel(boolean mayInterruptIfRunning);

The method returns false if the task could not be cancelled, typically because it has already completed. As the argument suggests, you have a choice if the task has already started. You can let if run to completion but ignore the result (mayInterruptIfRunning = false) or you can try and interrupt it. Not surprisingly delving down into the code of the only concrete implementation of the Future interface provided by java.util.concurrent, FutureTask, you find the code


if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt();
}
}

As you can see the default method of stopping a task in java.util.concurrent is to call interrupt(). This is why using interrupt() as described above, is now the preferable way stop threads. Java.util.concurrent takes care of clearing the thread's interrupted flag before it re-uses it.

Blocking I/O

As mentioned above threads are in the non-running state if they in a sleep() or wait() method or are blocking on I/O. Most read() methods block if data is not available and prior to Java V1.4 there was no means interrupting a blocking read(). However Java V1.4 introduced the InterruptibleChannel interface. Classes implementing the InterruptibleChannel interface can interrupt blocking I/O. This will cause the channel to be closed, the blocked thread to receive a ClosedByInterruptException, and the blocked thread's interrupt status to be set.

Lets look as a simple example of using an interruptible channel to overcoming a common blocking I/O problem. That of interrupting a thread that is blocked waiting for input from System.in. To do this we create an InputStreamReader that is based on an interruptible channel.


new InputStreamReader(
Channels.newInputStream(
(new FileInputStream(FileDescriptor.in)).getChannel())));

The following code is a simple example of its use. (Note: this program needs to be run from the command line. It does not work when run from within Eclipse)




import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.Channels;

public class InterruptInput {
static BufferedReader in = new BufferedReader(
new InputStreamReader(
Channels.newInputStream(
(new FileInputStream(FileDescriptor.in)).getChannel())));

public static void main(String args[]) {
try {
System.out.println("Enter lines of input (user ctrl+Z Enter to terminate):");
System.out.println("(Input thread will be interrupted in 10 sec.)");
// interrupt input in 10 sec
(new TimeOut()).start();
String line = null;
while ((line = in.readLine()) != null) {
System.out.println("Read line:'"+line+"'");
}
} catch (Exception ex) {
System.out.println(ex.toString()); // printStackTrace();
}
}

public static class TimeOut extends Thread {
int sleepTime = 10000;
Thread threadToInterrupt = null;
public TimeOut() {
// interrupt thread that creates this TimeOut.
threadToInterrupt = Thread.currentThread();
setDaemon(true);
}

public void run() {
try {
sleep(10000); // wait 10 sec
} catch(InterruptedException ex) {/*ignore*/}
threadToInterrupt.interrupt();
}
}
}

Classes that implement InterruptibleChannel include, FileChannel, ServerSocketChannel, SocketChannel, Pipe.SinkChannel and Pipe.SourceChannel, so in principle you can interrupt I/O for files, sockets and pipes. The class TaskUtilities, which only requires Java 1.4 or higher, provides a number of static methods to create interruptible I/O for files.

Unfortunately there are still some problems with Sun's implementation of deriving Streams from Channels. These include

  1. flush does not flush

  2. you cannot interrupt a write to a file.

The problem with flush() is that when deriving an OutputStream from a channel, Sun has not linked the OutputStream's flush() method back to its underlying channel's force(true) method. This means if you interrupt a file being written to, the file will be closed but you may not get the previous data even if you have called flush(). This is mainly a problem for log files and for debugging.

The second problem is that when writing to a file, interrupt() will not interrupt a write in progress. This is technically correct as the I/O is not blocking but actually writing. However it means there is no way to interrupt writing a large block of data to a slow device. It would be useful if Sun modified the library code to allow writes to be interrupted. As it is you should avoid writing large blocks of data if you want the task to be responsive to interrupts. Instead write a number of small blocks in a loop. Then after you call interrupt(), at the next write() the InterruptibleChannel will be closed and a ClosedByInterruptException will be thrown. As an alternative, given the problems with flush() noted above, you may prefer not to use an interruptible file output, but instead write in small blocks and call TaksUtilities.ifInterruptedStop() between each write which will throw an InterruptedException if the thread has been interrupted.

Stopping Threads that have Not been Started

In this article I have suggested using the Thread's interrupted state as a flag to stop it, however in spite of what the Java docs on interrupt() say, a thread's interrupt state will not be set if it has not yet been started (by calling start()). Since each thread is an object is seems reasonable that its interrupted state be an internal field that can be set once the object has been created. Alas this is not the case in Java V1.5 and below. This means special handling is required to stop a thread between the time it is created and time it is started. If you are using java.util.concurrent Tasks this is handled for you automatically when you use cancel() on a FutureTask. The ThreadReturn package also handles this case via its ThreadReturn.stop(thread) method.

If you are writing your own small thread then you should follow the following example code.



private volatile Thread myThread;
public void stopMyThread() {
Thread tmpThread = myThread;
myThread = null;
if (tmpThread != null) {
tmpThread.interrupt();
}
}
public void run() {
if (myThread == null) {
return; // stopped before started.
}
try {
// all the run() method's code goes here
...
// do some work
Thread.yield(); // let another thread have some time perhaps to stop this one.
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Stopped by ifInterruptedStop()");
}
// do some more work
...
} catch (Throwable t) {
// log/handle all errors here
}
}

However most threads need to return a result or at least notify the caller if they fail, for these reasons you are better off using java.util.concurrent, FutureTalker or ThreadReturn even for small threads.

Summary

This article has covered some of the history of stopping Java threads and shown how both a stop flag and a call to interrupt() is required for prompt termination of threads. With the introduction of Java V1.5 java.util.concurrent expects interrupt() alone to stop the thread. To make this effective it was suggested the the thread's interrupt flag be used as the stop flag and an ifInterruptedStop() method be used to check for the interrupt flag being set and to throw an exception. Stopping the thread depends on two other things, i) that the interrupt exception thrown propagates back up and out of the run method (or call method) and ii) that the thread is in a running state. The problem of Blocking I/O was discussed and a solution based on InterruptibleChannels presented. The existing problems in the Sun library implementation where discussed.

Resources

FutureTalker – the source, javadocs and jar file are available in zip and gz form. FutureTalker requires Java V1.5 to compile. See here for more details.
ThreadReturn – the source, javadocs and jar file are available in zip form. ThreadReturn requires Java V1.4 or higher. See here for more details.
TaskUtilities – the source and javadocs are included in the FutureTalker package (zip or gz). The TaskUtilities are compiled under Java V1.5 but will recompile under Java 1.4 or above.

Saturday, April 10, 2010

Canvas Vs Game Canvas In J2ME

Some differences between Canvas and GameCanvas. This article show an example where an actor is represented by a square that moves freely on the screen.

Canvas:

Known as low-level user interface it provides a rich variety of possibilities to draw onto the display. A class which extends Canvas has to implement the method “paint ()” with instructions that draw elements in the screen.

GameCanvas:

GameCanvas is an extension of Canvas to simplify game development and to fix weak points from Canvas. Using GameCanvas is easier to control key events and update the screen. To control key events you just have to use the method getKeyStates() instead of using 3 methods (keyPressed, keyReleased keyRepeated) used in Canvas and to update the screen you just use flushGraphics() method.

Example:

Let’s suppose we’ve created an actor that is represented by a square in the screen. It has X, Y, Dx and Dy parameters. X and Y are coordinates from the upper left vertex and they cannot be less than zero. Dx and Dy represents the actor’s width and height respectively.

The following snippet of code below will show the difference between Canvas and GameCanvas for handle key events.

Using Canvas:


protected void keyPressed(int keyCode) {
switch (getGameAction(keyCode)) {
case UP:
actor.changePosition(actor.getX(), actor.getY() - 5);
break;
case DOWN:
actor.changePosition(actor.getX(), actor.getY() + 5);
break;
case RIGHT:
actor.changePosition(actor.getX() + 5, actor.getY());
break;
case LEFT:
actor.changePosition(actor.getX() - 5, actor.getY());
break;
}
//This method prevents the actor to get out of the screen
verifyPosition();

}

protected void keyRepeated(int keyCode) {
switch (getGameAction(keyCode)) {
case UP:
actor.changePosition(actor.getX(), actor.getY() - 5);
break;
case DOWN:
actor.changePosition(actor.getX(), actor.getY() + 5);
break;
case RIGHT:
actor.changePosition(actor.getX() + 5, actor.getY());
break;
case LEFT:
actor.changePosition(actor.getX() - 5, actor.getY());
break;
}
//This method prevents the actor to get out of the screen
verifyPosition();
}


Using GameCanvas:


public void createMoviment() {

int key = getKeyStates();

// changing actor coordinates according to key events
if ((key & LEFT_PRESSED) != 0) {
actor.changePosition(actor.getX() - 5, actor.getY());

} else if ((key & RIGHT_PRESSED) != 0) {
actor.changePosition(actor.getX() + 5, actor.getY());

} else if ((key & UP_PRESSED) != 0) {
actor.changePosition(actor.getX(), actor.getY() - 5);

} else if ((key & DOWN_PRESSED) != 0) {
actor.changePosition(actor.getX(), actor.getY() + 5);

}
// This method prevents the actor to get out of the screen
verifyPosition();
}


As you can see using GameCanvas for handle key events is simplier than use Canvas because you only have to implement one method and call getKeyStates() to know about key events. In this example when we use Canvas the methods keyPressed() and keyRepeated() had to be implemented with the same code. The keyPressed() method is called when you press one key and release and keyRepeated() is called when you press one key and takes sometime until release it.

Now a snippet of code showing the differences between Canvas and GameCanvas to update the screen.

Using Canvas:


Image offScreenBuffer;

(...)

protected void paint(Graphics graphics) {

Graphics aux = offScreenBuffer.getGraphics();
// clean the screen
aux.setColor(0xffffffff);
aux.fillRect(0, 0, getWidth(), getHeight());

// draw the actor in the screen
aux.setColor(actor.getColor());
aux.fillRect(actor.getX(), actor.getY(), actor.getDx(), actor.getDy());
graphics.drawImage(offScreenBuffer, 0, 0, Graphics.LEFT| Graphics.TOP);
}


Using GameCanvas:


Graphics graphics;

(...)

private void paint() {
// clean the screen
graphic.setColor(0xffffffff);
graphic.fillRect(0, 0, getWidth(), getHeight());

// draw the actor in the screen
graphic.setColor(actor.getColor());
graphic.fillRect(actor.getX(), actor.getY(), actor.getDx(), actor.getDy());
flushGraphics();
}


Updating screen with GameCanvas is very simple, you just have to use flushGraphics() method every time you need to update the screen. However if you are using Canvas you will have two buffers, one is on the screen and the other you are updating all elements that you need (everything inside paint() method) in the end of paint() method you uptade everything. So it is simpler to control your game cycle and update the screen using GameCanvas than using Canvas.

Sunday, April 4, 2010

Bugs When Coding J2ME With Netbeans

1. Message "There is insufficient storage to install this suite"

- On Windows:
Just open up a terminal and change your directory to "<Java ME SDK directory>\runtimes\cldc-hi-javafx\bin". Find the file called "jwc_properties.ini", and find the system property system.jam_space, and change it to a bigger number (I added two zeros, for instance).
- On Mac:
Just open up a terminal and change your directory to "/Applications/Java_ME_SDK_3.0.app/Contents/Resources/runtimes/cldc-hi-javafx/bin". Find the file called "jwc_properties.ini", and then find the system property system.jam_space, and change it to a bigger number (I added two zeros, for instance).

Using the PIM and FileConnection of Sun Java Wireless Toolkit for CLDC

The Sun JavaTM Wireless Toolkit for CLDC supports JSR 75, the PDA Optional Packages (PDAP) for the J2ME Platform. JSR 75 includes two independent APIs:
  • The FileConnection optional package allows MIDlets access to a local device file system.
  • The Personal Information Management (PIM) optional package includes APIs for manipulating contact lists (address book), calendars, and to-do lists.

This chapter describes how the Sun JavaTM Wireless Toolkit for CLDC implements the FileConnection and PIM APIs.


FileConnection API:

On a real device, the FileConnection API typically provides access to files stored in the device's memory or on a memory card.

In the Sun JavaTM Wireless Toolkit for CLDC emulator, the FileConnection API enables MIDlets to access files stored on your desktop computer's hard disk.

The files that can be accessed using FileConnection are stored in subdirectories of workdir\appdb\skin\filesystem. For example, the DefaultColorPhone emulator skin comes with a root directory installed called root1, which contains a file called Readme and an empty directory named photos. The full path of the file is:

Windows:

workdir\appdb\skin\filesystem\root1\photos

Linux:

workdir/appdb/skin/filesystem/root1/photos


(example: in my PC, the dir workdir i installed is C:\Documents and Settings\user\j2mewtk\2.5.2, and skin maybe DefaultColorPhone)

Note - If multiple instances of the same emulator skin run simultaneously, the Sun JavaTM Wireless Toolkit for CLDC generates unique file paths for each one. For instance, the first directory is named DefaultColorPhone and the second instance is named DefaultColorPhone1.

Each subdirectory of filesystem is called a root. The Sun JavaTM Wireless Toolkit for CLDC provides a mechanism for managing roots. While the emulator is running, choose MIDlet > External events from the emulator window's menu. A utility window for adding and removing roots appears.

Managing File System Roots:

The mounted roots and their contents are available to applications using the FileConnection API.

To add a new root directory, click Mount New and fill in a name for the directory. To make a directory inaccessible to the FileConnection API, select it in the list and click Unmount.

The PIM API:

The Sun JavaTM Wireless Toolkit for CLDC emulator stores contact, calendar, and to-do information in standard files on your desktop computer's hard disk. All information is stored in workdir\appdb\skin\pim. This directory is shared by all running emulators. Lists are stored in subdirectories of the contacts, events, and todo directories. For example, a contact list called Contacts is contained in:

Windows:

workdir\appdb\skin\pim\contacts\Contacts

Linux:

workdir/appdb/skin/pim/contacts/Contacts


Inside the list directory, items are stored in vCard (.vcs) or vCalendar (.vcf) format (see http://www.imc.org/pdi/). Contacts are stored in vCard format, while calendar and to-do items are both stored in vCalendar format.
Source: java.sun.com

Bugs Config BlackBerry Projects In Eclipse

1. Can't build BlackBerry Project:
Need config environments: PATH, JAVA_HOME
2. Can't manage Cookie by Code on Simulator:
Go to \BlackBerry JDE \MDS\config
Open file rimpublic.property
The value: application.handler.http.CookieSupport = true
=> Modify: application.handler.http.CookieSupport = false
3. Can't access localhost on your PC on Simulator:
The directory: http://localhost:8080/myweb
Change: http://:8080/myweb

BlackBerry MDS Simulator

Configuring the BlackBerry MDS Simulator simulator
The default values for the BlackBerry® MDS Simulator parameters are appropriate in most cases; however, you can change parameters to set the following features:

* logging
* HTTP support
* HTTPS support
* push support
* email-to-PIN mappings.

In a production environment, the BlackBerry® Enterprise Server system administrator sets the BlackBerry MDS Connection Service parameters using the BlackBerry device management software. Contact your system administrator for more information.

Configure BlackBerry MDS Simulator properties

  1. In a text editor, open the rimpublic.property file from the Program Files\Research In Motion\BlackBerry Email and MDS Services Simulators 4.1.2\MDS\config\ folder.
  2. Configure the file settings as necessary.
  3. Restart the BlackBerry® MDS Simulator.

BlackBerry MDS Simulator logging properties
Property Description Default

Logging.file.
log.level

Specify the type of information to record, if you enable logging:

  • 1 — logs information about events only, such as connection service start or stop
  • 2 — logs events and errors
  • 3 — logs events, errors, and warnings
  • 4 — logs events, errors, warnings and debug messages

4


Logging.console.
log.level

Specify the type of information that appears in the console, if you enable logging. See the description for the Logging.level property.

4


application.
handler.
http.logging

Set to TRUE or FALSE to enable or disable HTTP standard logging (HTTP headers only).

FALSE


application.handler.
http.
logging.verbose

Set to TRUE or FALSE to enable or disable HTTP debug logging (HTTP data as well as headers). Set this parameter to TRUE only when necessary to debug a specific problem.

FALSE


BlackBerry MDS Simulator HTTP properties
Property Description Default

Logging.file.log.
levelapplication.handler.
http.CookieSupport

To enable the connection service to store cookies on behalf of the BlackBerry® device, set this property to TRUE. To store cookies on the BlackBerry device, set this property to FALSE.

TRUE


application.handler.
http.
AuthenticationSupport

Set to TRUE or FALSE to enable or disable storage of user authentication information.

TRUE


application.handler.
http.
AuthenticationTimeout

If HTTP authentication is set to TRUE, specify the length of time (in milliseconds) before the authentication information becomes invalid. This timer resets whenever the user requests authentication information for a particular domain.

3600000


application.handler.
http.device.
connection.timeout

Specify the length of time (in milliseconds) before a BlackBerry device connection attempt expires.

140000


application.handler.
http.server.
connection.timeout

Specify the length of time (in milliseconds) before a server connection attempt expires.

150000

http.proxyHost

This is the HTTP proxy host name.

n/a

http.proxyPort

This is the HTTP proxy port number. This is also used by Sun implementations of HTTP URL connections.

n/a

BlackBerry Simulators Reference Guide for Eclipse 3.5 plugin

Before providing a reference guide to the simulators available, here is a quick start guide to get going in Eclipse.

  1. Download and install Eclipse 3.5 (Galileo). I used the EE package.
  2. Download the BlackBerry Java® Plug-in for Eclipse® v1.1
  3. Install the plug-in, pointing it to your Eclipse installation.
  4. In Eclipse->Window->Preferences->Install/Update->Available Software Sites add the following site: http://www.blackberry.com/go/eclipseUpdate/3.5/java
  5. In Eclipse->Help->Install New Software, using the Software site added above and download the desired Component Packs.
  6. Restart Eclipse after installing plugins

Simulator Reference Guide

Component Pack: 5.0.0.14
Blackberry (JRE) version: 5.0.0

Device Family Display Screen Size Interaction Method
9000 Bold 480x320 trackball
9550 Storm 360x480 touch screen
9700 Bold 480x360 trackball

Component Pack: 4.7.0.53
Blackberry (JRE) version: 4.7.0

Device Family Display Screen Size Interaction Method
9500 Storm 360x480 touch screen
9530 Storm 360x480 touch screen

Component Pack: 4.6.1.36
Blackberry (JRE) version: 4.6.1

Device Family Display Screen Size Interaction Method
8350i Curve
320x240
trackball
8900 Curve
480x360
trackball

Component Pack: 4.6.0.21
Blackberry (JRE) version: 4.6.0

Device Family Display Screen Size Interaction Method
9000 Bold
480x320
trackball

Component Pack: 4.5.0.21
Blackberry (JRE) version: 4.5.0

Device Family Display Screen Size Interaction Method
8100
Pearl
240x260
trackball
8110 Pearl 240x260 trackball
8120 Pearl 240x260 trackball
8130 Pearl 240x260 trackball
8300 Curve 320x240 trackball
8310 Curve 320x240 trackball
8320 Curve 320x240 trackball
8330 Curve 320x240 trackball
8700-black Electron 320x240 trackwheel
8703e Electron 320x240 trackwheel
8800 88XX 320x240 trackball
8820 88XX 320x240 trackball
8830 88XX 320x240 trackball

Component Pack: 4.3.0.17
Blackberry (JRE) version: 4.3.0

Device Family Display Screen Size Interaction Method
8120 Pearl
240x260
trackball
8130 Pearl 240x260 trackball

Component Pack: 4.2.1.19
Blackberry (JRE) version: 4.2.1

Device Family Display Screen Size Interaction Method
7130
7130
240x260
trackwheel
7130e 7130 240x260 trackwheel
8100 Pearl 240x260 trackball
8700-black Electron 320x240 trackwheel
8700-blue Electron 320x240 trackwheel
8703e Electron 320x240 trackwheel
8707
Electron 320x240 trackwheel
8800 88XX 320x240 trackball

Simulator Reference Guide

Device Family Display Screen Size Interaction Method Component Pack
7130 7130 240x260 trackwheel 4.2.1.19
7130e 7130 240x260 trackwheel 4.2.1.19
8100 Pearl 240x260 trackball

4.2.1.19

4.5.0.21

8110 Pearl 240x260 trackball 4.5.0.21
8120 Pearl 240x260 trackball

4.3.0.17

4.5.0.21

8130 Pearl 240x260 trackball

4.3.0.17

4.5.0.21
8300 Curve 320x240 trackball 4.5.0.21
8310 Curve 320x240 trackball 4.5.0.21
8320 Curve 320x240 trackball 4.5.0.21
8330 Curve 320x240 trackball 4.5.0.21
8350i Curve 320x240 trackball 4.6.1.36
8700-black Electron 320x240 trackwheel

4.2.1.19

4.5.0.21

8700-blue Electron 320x240 trackwheel 4.2.1.19
8703e Electron 320x240 trackwheel

4.2.1.19

4.5.0.21

8707 Electron 320x240 trackwheel 4.2.1.19
8800 88XX 320x240 trackball

4.2.1.19

4.5.0.21

8820 88XX 320x240 trackball 4.5.0.21
8830 88XX 320x240 trackball 4.5.0.21
8900 Curve 480x360 trackball 4.6.1.36
9000 Bold 360x480 trackball

4.6.0.21

5.0.0.14

9500 Storm 360x480 touch screen 4.7.0.53
9530 Storm 360x480 touch screen 4.7.0.53
9550 Storm 360x480 touch screen 5.0.0.14
9700 Bold 360x480 trackball 5.0.0.14

Using the BlackBerry Simulator on Windows

Like other operating systems like Windows Mobile, Symbian, Android, Black Berry is also a replica running on Windows - Black Berry Simulator - to support the test features, software development, without having a physical device.

Download BB Simulator: link. After the link above, click on Download a BlackBerry Device selection Simulator.

On the image above, clicking on the triangle icon to select the version of the BB Simulator, then click the Next button. Appears a list of the BB Simulator machine corresponding to BB. Click Download to download the corresponding documents, such as BlackBerry ® Device Simulators v4.2.2.163 (Rogers 8310) - Supported devices: BlackBerry ® Curve ™ 8310 smartphone (Rogers 8310).

Perform the following steps, the result will download the file to run the BB Simulator, for example file-Rogers.exe BlackBerry_Simulators_4.2.2.163_8310. Run this file to install. After installation, BB Simulator to run on the device, click Start -> Programs -> Research In Motion to select the BB Simulator necessary and run it. BB Simulator Interface of the following:

With the BB Simulator, you can perform functions similar to the buttons so the device. Can see the BB Simulator window menu selection is convenient features than the command using the Android Emulator.

It should be noted on the menu options may vary in the version of the BB Simulator.

Using SD Card
On the BB Simulator is a feature that allows to change SD cards. On the BB Simulator window, select the simulate menu -> Changer SD Card, SD Card dialog box appears
SD Card dialog
On the dialog box, SD Card, SD Card can create a new card by typing in the box size Size (eg 512 MB) and click the Create button. When it appears the Windows Open dialog box lets you type the file name of the SD Card. After typing the file name, in the Current SD Card SD Card will appear new. Select the SD Card and click the Close button. BB Simulator will then use this SD Card.

BB Simulator can test using any SD Card by clicking on the BB Simulator Menu key, then select Options -> Media Card:

Media Card management device
Note the parameters for the BB Total Space Simulator not use the new SD Card.

Connection between the BB Simulator and Windows
Just like real devices, BB Simulator to connect to Windows via BB Desktop Manager program. Download the program by following link: https://www.blackberry.com/Downloads/entry.do?code=A8BAA56554F96369AB93E4F3BB068C22

BB Desktop Manager Download
Follow the link above, select the version of BB Desktop Manager in the arrow pointing down. The latest version is version 4.6, then click the Next button. When the list of the BB Desktop Manager will appear below. Can click Download to download the necessary files, in this example, you can download the BB Multilaguage without Media Manager.

After downloading, run this file to install. When the installation finished, click Start -> Programs -> BlackBerry -> Desktop Manager to run the program. BB Desktop Manager interface is as follows:

BB Desktop Manager Interface
BB Desktop Manager to connect to the real BB device, USB cable needed to connect it with USB devices on your computer. With the BB Simulator, simulation needs to run a USB port.

On the BB Simulator Interface, click the simulate menu -> USB Cable Connected. When the BB Desktop Manager and BB Simulator will connect with each other to perform necessary tasks like installing / removing software, ...

Select USB Cable Connected
Note that when running BB Desktop Manager, which appears in the Device Manager icon BB system tray (bottom right corner of the screen). Double click on this icon, appearing BB Device Manager Properties dialog box:
BB Device Manager Properties dialog box

On the BB Device Manager Properties dialog box, notice the list of Connection to accurately determine the connection between the BB Desktop Manager and BB Simulator.

Installing software on the BB through the BB Desktop Manager Simulator
After running the BB Simulator, BB Desktop Manager and select the USB Cable Connected as the above steps, can install software on the BB Simulator.

On the main window of the BB Desktop Manager, select Application Loader, then click the Start button in the Add / Remove Applications. Appears Device application selection dialog:

Device application selection dialog box, use the Browse button to open the file. ALX file is installed for BB. In the above example make install 2 programs Repligo Reader and Mobipocket Reader.

Upon completion of the selection, click Next, the dialog will appear Sumary announced programs will be installed. On this dialog box, click Finish. The installation program on the BB Simulator will be implemented.

How to install offline Maps on your BlackBerry using TrekBuddy 0.973


BlackBerry smartphones are handy for GPS navigation helped by the excellent BlackBerry and Google Maps applications. When you are out of range of a data signal both these applications are unable to continue to provide a map. With TrekBuddy you can use offline maps, from Google and elsewhere, record route speed and waypoints, or use your phone as a direction finder. TrekBuddy is a great, freeware application developed by Kruch a Czech developer and is suitable for J2ME devices including a BlackBerry with OS 4.1 or greater.

Using offline maps with TrekBuddy enables you to download maps at detail levels that suit you, that load quickly as they are stored on the SD Card, and of course do not incur any data download costs, this is especially useful when you are roaming overseas. The map on the right is a screen shot from a Curve 8310, using a map created with the excellent gm2tb- GoogleMaps to TrekBuddy site.
How To

1. Download TrekBuddy: The ALX and COD files can be found via this link.

2. Install TrekBuddy: Use the BlackBerry Application Loader to install the application. Instructions on how to use application loader can be found here.

3. Set up the Folder System: Using Mass-Storage mode navigate to your SD Card using Windows Explorer, you need to create a folder called “data dir” with subdirectories called maps, resources, sounds, tracks-gpx, tracks-nmea, ui-profiles, wpts as shown on the diagram on the right.

Disconnect your BlackBerry from your PC and load the TrekBuddy application. Press the BlackBerry key to bring up the menu.

Go to Menu->Basic->Data Dir

This needs to be set to the location of the data directory you created, mine is

file:///SDCard/blackberry/data dir/

ensuring the slashes and capitalisation are correct. Next go to

Menu->Location-> GPS provider

for a BlackBerry such as the 8310 you should set it to internal GPS. If you have an external GPS puck it can be set up here.

5. Test GPS Connection: To test the GPS connection on menu, go to Start to enable GPS and then press the # key to bring up compass mode. Once you have a signal you should have a compass display with your current location like this. The green dot shows that you have a GPS signal.

6. Download a Map:As standard no maps are supplied with TrekBuddy. The easiest way to download a map quickly is using the Google Maps to TrekBuddy website by AwokenMind. To use this website use Google Maps to find the area you want to create a map for, give it a name then click download. The tar file that you create should be placed in the maps directory of your BlackBerry.

6. Use your map!: Disconnect the USB cable, load TrekBuddy, Start the GPS, and select the map you have just added.

Potential Problems

Setting Application Permissions:I didn’t need to do this, but you may need to give TrekBuddy access to your SD card and access to your internal GPS Device. This is done on the BlackBerry by navigating to
Options->Security Options->Application Permissions->TrekBuddy->Edit Permissions->Set all to'Allow'

Setting the Path to Media Card: If your path is not correct you will get the following error:
Failed to start tracklog: file://wrong-path/ net.rim.device.api.io.file.FileIOException: File system error
This means you should carefully check your path to the SD Card

Connecting with USB: Always exit TrekBuddy before connecting the USB cable and entering Mass Storage Mode, otherwise TrekBuddy can crash and may require a battery pull.

Further Information

  • TrekBuddy is not a route-planning application for calculating a route form A to B. There are better applications around if you wish to achieve this, for an application which has can continue to function in voice mode despite data connection loss try AmAze.
  • To create large atlas files I recommend the excellent GoogLeak application which can be found here. This enables you to download Terrain, Hybrid and Street Map style Google Maps, and store them at various resolutions in the atlas format.
  • Open Source Street Maps are available, such as OpenStreetMap, a utility to create TrekBuddy maps using this database can be found here.
  • Official TrekBuddy Wiki
  • Official TrekBuddy Forums
  • TrekBuddy creates .gpx files which can easily be plotted on to Google Maps in elevation and 2D using a utility such as GPS Visualiser.
  • A CMS theme for the Curve’s 320*240 designed by Trispark can be found here.

Source: medicalnerds

Geohot and the new Jailbreak tool can be applied with iPad

Recently, hacker famous for providing the tools to unlock, jailbreak iPhone and also the hack was announced Sony PS3 has announced a new jailbreak tool for iPhone 3GS. In addition, Geohot (George Hotz) adds new jaikbreak how this can be applied to both upcoming iPad.

Geohot said that the new jailbreak method is completely software, not hardware interference, it is as simple as it used blackra1n. This new method allows you to jailbreak jailbreak completely and reboot computer without plugging the USB cable to the computer (untethered). Moreover, it can run on existing models like ipt2 (iTouch 2), and ipt3 3gs (iTouch 3) and especially the iPad can jailbreak was released on April 3 to, allowing installation applications are not up on copyright iPad easily.

Geohot said The reason for his new jailbreak method was not used cable (untethered) is because with the new bootrom released by Apple late last year (as iBoot code-359.32) is the current jailbreak tool to plug cable USB to reboot the computer when the device is very inconvenient. Geohot not time for him to release this new tool but if it can be iPad jailbreak days, then perhaps it will appear close to or after iPad shelves. Let's wait for the latest information from Geohot.

BBC puts iPhone app plans on ice


The BBC has postponed plans to release free iPhone news applications after concerns about an unfair market advantage.

A report on BBC News said that the BBC Trust had decided to halt the planned April release of news and sports applications for the Apple handsets, after newspaper publishers claimed that the BBC would unfairly influence the market for news apps.

The BBC Trust will review the plans, and decide whether the apps would violate its public service agreement.

The row comes as newspaper publishers seek to capitalise on Apple's iPhone, iPod Touch and iPad platforms amid slowing sales of print editions.

Major papers such as The Wall Street Journal and The New York Times have announced agreements with Apple to offer special subscription offers formatted for the iPad tablet.

Recent media reports claim that the BBC intends to reduce its web operations by as much as a half.
Source: V3

Zynga brought Mafia Wars to iPhone

Zynga, the company produced games, online games have brought famous Mafia Wars on their Apple App Store yesterday. This is one of the online games attracted many visitors today. Alone version on Facebook, more than 9 million participants.

If you have an iPhone and was known Mafia Wars, work simply click on this link to install the application in iTunes. The program is free.

The content of the game is to build a virtual mafia gang, to do "tasks" for virtual money and buy weapons. The glance, this seems a simple game, but it easily addictive. Although the game is free, some members have put up real money to hundreds of dollars to equip their "powerful" than the other players with class.






















In this version of the iPhone, users must create a new account. You can not reuse the old account on social networking sites like Facebook or MySpace. Zynga also does not mention the possibility of using the account in the next version, although they use Facebook Connect on other applications. As predicted by Jason Kincaid at TechCrunch, Zynga may want to eliminate caste gap (level) of new players on the iPhone.

The first impression on this iPhone version include better sound quality, attractive graphics, friendly interface, fast and useful. Web version uses AJAX on Facebook is much slower, or having problems recently due to overload. However, not to mention Facebook had 150 million visitors per month, with 9 million players. Now on iPhone application just released one day, and at present only about 20 million iPhones sold.