FAQ

From J2me wiki

Table of contents

General

How do I write a j2me game ?

By knowing how to write it, we are here to help each other program not design, code and debug apps for people.

Where can I find j2me 's developer's site? Where can I find j2me's SDKs ?

Here is a list of the majority of the developer sites:

How do I make a game? Do I need to learn Java first ?

Yes. Learning Java in order to make games/apps on J2ME devices means understanding the workings of OOP, Threading (especially scheduling differences in embedded devices), Memory Management, Exceptions (checked, runtime, errors). MYTH: J2ME is not a lesser version of J2SE when it comes to the Java language. It is not like comparing VBA to VB. J2ME maybe a smaller subset of the J2SE API but the language and all its features are identical in both platforms.

What are the basic differences between developing in J2SE and J2ME?

  • J2ME devices use a Kilobyte Virtual Machine (KVM) instead of a Java Virtual Machine (JVM) due to memory restrictions.
  • Only the basic packages from the J2SE API are available in J2ME and the classes within those packages have some methods removed.
  • J2ME specific packages and classes have been added to give control over the devices resources.
  • Optional/Vendor specific APIs are available to allow finer control over a particular model or series' functionality.
  • Thread scheduling on lesser devices is usually handled cooperatively meaning a thread may hog the CPU and prevent other threads from getting a chance to execute whereas in J2SE the thread scheduling is usually preemptive in nature (actually depends on OS!) meaning each thread gets a fair slice of the CPU's time. Setting the thread's priority in either environment does not guarantee that one thread will get more time than another!
  • J2ME devices do not have a rich file system. They use a RecordStore to store simple binary streams by name. Typically small amounts of data such as high scores, progress, preference data are stored here.

How do I do j2me? (Which isn't realated to or doesn't use J2me)

Simple, you use GOOGLE or find a forum that covers that topic. This is a J2ME wiki!

How much Heap/What screen size is/What MIDP or CLDC version is XXX handset/device?

Either, take a look at the manufacturers sites above, or you can try other sites, such as

How do I know which Firmware my phone is using?

Use the following codes:
*#0837#SGH
*#1234#SGH
*#9999#SGH
*#0000#NOKIA
*#06#infoSiemens
*#RELEASE# (*#7353273#)SONY
2945#*#LG
*#06#'V'Alcatel
*#369#S/FW versionPanasonic
>*<<*<*!SonyEricsson

Where can I find j2me's developer's site? Where can I find j2me's SDKs ?

Here is a list of the majority of the developer sites:

How do I make a game? Do I need to learn Java first ?

Yes. Learning Java in order to make games/apps on J2ME devices means understanding the workings of OOP, Threading (especially scheduling differences in embedded devices), Memory Management, Exceptions (checked, runtime, errors). MYTH: J2ME is not a lesser version of J2SE when it comes to the Java language. It is not like comparing VBA to VB. J2ME maybe a smaller subset of the J2SE API but the language and all its features are identical in both platforms.

What are the basic differences between developing in J2SE and J2ME?

  • J2ME devices use a Kilobyte Virtual Machine (KVM) instead of a Java Virtual Machine (JVM) due to memory restrictions.
  • Only the basic packages from the J2SE API are available in J2ME and the classes within those packages have some methods removed.
  • J2ME specific packages and classes have been added to give control over the devices resources.
  • Optional/Vendor specific APIs are available to allow finer control over a particular model or series' functionality.
  • Thread scheduling on lesser devices is usually handled cooperatively meaning a thread may hog the CPU and prevent other threads from getting a chance to execute whereas in J2SE the thread scheduling is usually preemptive in nature (actually depends on OS!) meaning each thread gets a fair slice of the CPU's time. Setting the thread's priority in either environment does not guarantee that one thread will get more time than another!
  • J2ME devices do not have a rich file system. They use a RecordStore to store simple binary streams by name. Typically small amounts of data such as high scores, progress, preference data are stored here.

How do I do j2mex? (Which isn't realated to or doesn't use J2me)

Simple, you use GOOGLE or find a forum that covers that topic. This is a J2ME wiki!

How much Heap/What screen size is/What MIDP or CLDC version is XXX handset/device?

Either, take a look at the manufacturers sites above, or you can try other sites, such as

How do I know which Firmware my phone is using?

Use the following codes:
*#0837#SGH
*#1234#SGH
*#9999#SGH
*#0000#NOKIA
*#06#infoSiemens
*#RELEASE# (*#7353273#)SONY
2945#*#LG
*#06#'V'Alcatel
*#369#S/FW versionPanasonic
>*<<*<*!SonyEricsson

APIs and Libraries

I do not know

How do I add API X (bluetooth, wma, mmapi, Image.getRGB, ...) to a phone that does not have built in support for API X?

You can?t, the only way to add that sort of functionality to J2ME is to upgrade the Virtual Machine on the phone which is something only the phone manufacturer can do.

I am using a third party library in my app and when I try to emulate it I gives me an error like: preverfication error: com/cool/library/ClassA. What am I doing wrong?

You are most likely putting the library jar in the "libs" directory when you should be putting it in the "src" directory. If that does not work try unzipping it into the source directory. (Some IDE's require this). If this doesn't work - read over the IDE or APIs documentation - it might have some vital information that you overlooked.

But it's a library therefore it goes into the library directory right?

Nope, its confusing but the library directory is there to let you make the library that you are compiling your application against be the same as what is actually what is going to be on the phone. Your third party library is not going to be on the phone so you need to include it like any other code.

Where can I find out about XXX api to see if it is possible to do YYY with j2me?

jcp.org j2me jsr list (http://www.jcp.org/en/jsr/tech?listBy=1&listByType=platform)
This is the location of the j2me related jsrs, you can see an individual technology and get hold of the specification for that JSR.

Where can I find out if my phone supports XXX JSR?

Your favourite phone manufacturer's developers portal, check the list above for links.

How can I find out about whether a specific phone supports soemthing with closed APIs?

Most vendors that do support or extend MIDP1.0 have those issues lsited within the developer portals for j2me developers.

Servers, Communication and Databases

What language should I write my server in?

Whatever you feel most confortable in, as long as it can handle HTTP requests then it will work to talk to J2ME phones.

How do I talk to a FTP server, database, www.something.com:xxx?

You need to have a phone that handles socket connections and handle everything on that level.

How do I connect to an Database? / Can I use SQL?

J2ME has no support for SQL or JDBC. (But it exists some J2ME databases like Mimer) If you want to connect to a database, you need to use the network (http, udp, https) to connect to a server which handles the database queries. The next best thing on J2ME is to use the Record Store Management (RMS) system, which allows the storage of byte arrays.

I get an Exception when I try to connect to web services from the WTK emulators?

So you get an error message something like the following:
Exception caught:
java.io.IOException: Error initializing HTTP tunnel connection:
HTTP/1.0 403 Forbidden
Server: squid/2.5.STABLE4-20031106
Mime-Version: 1.0
Date: Tue, 13 Apr 2004 04:22:26 GMT
Content-Type: text/html
Content-Length: 6650
Expires: Tue, 13 Apr 2004 04:22:26 GMT
X-Squid-Error: ERR_ACCESS_DENIED 0
X-Cache: MISS from proxy-28-03.its.monash.edu.au
Proxy-Connection: close
    at com.sun.midp.io.j2me.http.Protocol.doTunnelHandshake(+282)
    at com.sun.midp.io.j2me.http.Protocol.connect(+132)
    at com.sun.midp.io.j2me.http.Protocol.streamConnect(+44)
    at com.sun.midp.io.j2me.http.Protocol.startRequest(+12)
    at com.sun.midp.io.j2me.http.Protocol.sendRequest(+38)
    at com.sun.midp.io.j2me.http.Protocol.sendRequest(+6)
    at com.sun.midp.io.j2me.http.Protocol.openInputStream(+9)
    at HttpTest$WebPageDisplayer.getFromHttpConnection(+35)
    at HttpTest$WebPageDisplayer.run(+8)
This is because your proxy (squid in this case) is DENYing access to CONNECT methods on specific port numbers.
To fix the problem, you need to reconfigure squid to allow CONNECT requests on the port number you are trying to access, usually port 8080 for servlets / jsps ...
modify /etc/squid.conf
modify the line:
    acl SSL_ports port 443 563
add the port number you want to allow access to ... often 8080 to the end of that line and restart squid..
NOTE: This is a bit of a HACK fix, and you should really create a new "acl" and modify the following line:
    # Deny CONNECT to other than SSL ports
    http_access deny CONNECT !SSL_ports
to allow access for your new acl

Where can I find a list of GPRS access points for REAL internet access not just WAP gateway access?

http://www.reqwireless.com/apns.html
Some of them MIGHT be out of date, but it should give you an idea, if you have corrections, let them know.

Wireless Messaging API

What port numbers should I use for SMS (WMA) MIDlets?

According to the 3GPP specifications, the range of ports which are for use by applications area 16000 -> 16999, so you should use ports numbered within that range for your WMA applications.
It is also important to note that there ARE some port numbers within that range which are reserved on some manufacturers devices, for examples on Sony Ericsson devices:
  • 16733: Calendar Application
  • 16987: E-Mail Notifications
  • 16988: E-Mail Account Settings
So you should avoid those, there are probably others which are reserved on other manufacturers devices.
But normally you shouldn't use any port at all if you want to send a ordinary SMS to the SMS-inbox.

Storage and SIM access on the phone

Can I access the phone's j2me? (memory, phone book, inbox, pictures...) ?

Generally no, this is considered a security risk and most manufacturers don't allow it. However, a very small minority do, so check out their developer's site.

Is it possible to access the SIM card from a java midlet in order to get the operator ID and the telephone number?

No. Although a future JSR will allow this.

Can I access the Pictures/SMS/Phones numbers that are already on my phone?

Generally, NO. If you can find one of the small percentage of phones that support the file:// protocol then you may be able to access these files.
However...
Pictures: You can take your own pictures using the phone's camera and MMAPI.
SMS: You can write your own app to send and recieve SMS, but you must use a different port from the standard SMS port (at least for recieving).

Canvas, Forms and Alerts

I want to display a "Busy, please wait..." screen while i do my networking/any other lengthy process, but the waiting screen never appears, and after the process is over the result screen appears. What's wrong ?

Most likely you are blocking the main thread that is in charge of refreshing the screen. This is the same thread that calls all the input methods (like commandAction() or keyPressed()), so if you perform a lengthy process in this thread you are blocking it and there is no way the screen will be updated. Perform the lengthy operation in a separate thread.

How do I capture keypresses on a Form/List/Alert?

You don't, atleast not in MIDP 1.0, the high level apis were written so that the programmer did not have to worry about programming a response to every keypress. If you have to have that level of control you will need to use a Canvas and do everything yourself including creating your own textboxes, lists, option buttons....

Ok, then how do I put a canvas on the form or use a highlevel widget on the canvas?

You cant see above.

Why doesnt my app switch between my two/three/fifty-seven canvases when I call myDisplay.setCurrent(nextCanvas)?

Well the technical answer is that you are most probably doing something like this:
myDisplay.setCurrent(canvas1);
someFunctionUsingCanvas1();
myDisplay.setCurrent(canvas2);
That doesnt work beacuse the function allways returns instantly and the display is actually updated when the KVM feels like it. Having said that, the real answer is dont use multiple canvases. They are memory hogs and having more than one in a Midlet is a very bad idea. Use a single canvas that just has differnt states and then paint the correct info depending on what state the app is in. Not only that but the state machine architecture is very simple and easy to expand as your app evolves.

Why when I set the GameCanvas to full screen does getHeight() not return the right value?

The main reason for this is that if you call setFulLScreenMode(true) within the constructor of a class - the actual update wont happen until after the constructor has finished. If you have the calls to getHeight() within the same constructor, or within another constructor in a sequence of class initialisations, then it will return the wrong value.
Here is one solution (assuming you use a thread for your game loop):
1) Move your call to setFullScreenMode(true); outside of any constructor - preferably move it to the startApp() method for your main MIDlet:
(e.g.)
  public void startApp()
  {
      if(canvas== null)
      {
        canvas = new MyCanvas(this);
        canvas.setFullScreenMode(true);
      }
      Display.getDisplay(this).setCurrent(canvas);
      canvas.start(); // To start the Thread.
  }
2) You then need to override the sizeChanged(int w, int h) method of GameCanvas:
(e.g)
  public void sizeChanged(int _w, int _h)
  {
      slx = _w;
      sly = _h;
      screenUpdated = true;
  }
You will notice here that I am using a boolean flag to identfy whether the screen has been updated or not...
3) In your thread's run() method, inside the while loop, add the following call:
  while(!screenUpdated)
  {
      currentThread.yield();
  }
This will yield() your current Thread and wait until the Canvas has been updated and hopefully you should now have the right values.
Note: Some devices and emulators may not call the sizeChanged() method - in those cases you may have to hard code the height value.

JAD and MANIFEST

What does this mean? "Unable to create MIDlet SimpleGame java.lang.ClassNotFoundException: SimpleGame"

99% of the time this error is due to a bad JAD entry. The line "MIDlet-1" needs to contain the full name of the MIDlet class as the last item. The full name of the class is allways the package name and the class name.



You can check back the MIDlet class name in setting-->MIDlet, then edit the the class.

If your MIDlet is called "ABCMIDlet" and putted under scr/com/aaa/bbb/ccc/ABCMIDlet Your class should be "com.aaa.bbb.ccc.ABCMIDlet"

Hope this can solve your problem.

Installing and Updating MIDlets

I've just developed a J2ME app in an emulator. Now I want to try it in a real phone. How can I transfer my app to a phone? Do I need to do it Over the Air (OTA) and pay a call charge each time?

Many phones support some kind of local connectivity through a USB cable, infra-red or Bluetooth, allowing you to transfer J2ME apps directly to your phone from your PC. Whether any particular phone does or not can be determined by consulting the phone's documentation on one of the manufacturer's web sites listed above.
The PC software required to allow you to do these local transfers will usually either be supplied with the mobile phone or can be downloaded from the manufacturer's web site. If a USB cable is required, it will sometimes be supplied with the mobile phone at purchase time but more usually will have to be bought separately, either from the manufacturer itself or from a mobile phone accessory supplier. The USB cables required vary from one phone model to another (ie. there is no "One size fits all" USB cable available) but typically work with a number of phones within the manufacturer's product range.

But how do I do an OTA installation?

It is quite simple - all you need is a basic web server with the correct MIME types set (most come with these already set, but it's best to check to make sure!):
For the JAR:
application/x-java-archive (Some phones prefer application/java-archive)
For the JAD:
text/vnd.sun.j2me.app-descriptor
Note: Some phones require an absolute URL in the MIDletURL entry in the JAD.
Then all you need to do is point your phone's browser at the JAD and voila your MIDlet will be downloaded.

How can I automatically update my MIDlet from within the MIDlet?

Since this seems to be asked quite a lot, here is the answer... using MIDP1 there isn't really a nice solution. However for MIDP2, this is how you do it ...
Use the platformRequest("http://<server-url>/<new jadfile>");
If the jad file is for the new version of your application it will update the existing application as if you had used a wap browser and gone to the jad file yourself... this allows you to have an UPDATE menu option within your MIDlet.
Here is the relevant bit from Sun about it:
MIDlet Life-Cycle Considerations
You must take the MIDlet life-cycle into account when you use platformRequest().
Some MIDP platforms are more restricted than others. For example, some don't support concurrent processing,
so the MIDlet must exit before the platform can honor a service request. Recall that platformRequest() 
returns true in such cases, giving your MIDlet fair warning that it must exit.
If the platform request is to download and install an update of the currently loaded MIDlet suite, 
the currently running MIDlet is first terminated.
In both these cases, the MIDlet must be prepared to exit gracefully, first managing its state so as to
resume appropriately later.
NOTE: apparently Motorola devices do NOT support JAD and JAR types through the platformRequest() method

Bluetooth

Where can I find information about using Bluetooth in J2ME and some example code?

  • Ben Hui's Site (http://www.benhui.net) is a good place to look for Bluetooth info and examples and also has a forum where you can ask questions.
  • Java Bluetooth (http://www.javabluetooth.com) is the website of the book "Bluetooth for Java" by Bruce Hopkins and Rajith Anthony. The source code examples from the book, which cover most aspects of the use of Bluetooth from Java, is available for free download from the site.

Memory Management

Memory Management In J2ME

Most java programmers are aware of the System.gc() and/or Runtime.gc() method. However most programmers have only a partial grasp of the effects of calling one of these methods. This document is about dispelling some of the myths of garbage collection and about memory management in general. The target audience ranges from newbie to mid-level Java programmer.

What is garbage collection?

Garbage collection is a service that can be provided by the Java Virtual Machine to reclaim memory that is deemed eligible for garbage collection. All classes of Java (J2ME, J2SE, and J2EE) are capable of providing this service.

Where is the Java equivalent of delete?

Unlike C/C++ which allows the programmer direct access to memory addresses and makes him/her responsible for allocating and deallocating memory, Java hides the true location of allocated objects and does not offer a means for the programmer to directly deallocate them. In other words the JVM/KVM is in charge of such actions.

What happens when I call System.gc()?

There is no definitive answer to this question. The JVM/KVM is NOT required to even perform garbage collection services. That's right. Read that statement again and embed it in your mind. Now, what good is a JVM without garbage collection? I don't know. Perhaps none, but if you wanted to implement your own JVM you could make it a spec-compliant one without collecting any garbage at all.
It is very important to realize that calling this method is merely a suggestion to the JVM to perform garbage collection. Even if it supports garbage collection it may choose not to perform it. Also the JVM may decide to perform garbage collection on its own without the program calling System.gc() if it deems such an action necessary (such as dwindling free memory).

Assuming garbage collection does occur, how does it work?

Again, no definitive answer. It may take a "mark and sweep" approach or other. This is up to the maker of the JVM to decide. In most JVM implementations however the garbage collection seems to occur in its own thread and as such slows the application down somewhat.

This tutorial is pretty useless, what can you tell me that is definitive?

This much is for sure, in order for an object to be eligible for garbage collection, no live thread can have any way to access it. This can be accomplished in a few different ways:
  • A thread dies, taking the sole reference of the object with it to the grave.
  • All live threads nullify their references to it.
  • All references to an object are isolated (A points to B but A's reference was nullified so no way to access B anymore).
How the JVM knows that an object has references to is unknown. It might maintain counters or might have lookup tables or other... It is enough that the JVM knows which objects are and are not eligible for garbage collection.

How can I make it easy to ensure an object's eligibility for garbage collection?

Simple, maintain as few as possible references to the object. A good approach is to use the singleton pattern for having a "reference manager". Since only it maintains single references to all objects only one reference need be nullified.
Another approach that a member of these forums pointed out was to kill the thread that has only its own local references to objects. Once the thread is killed the references die with it, making the objects elegible for garbage collection.

How can I prevent my object from being elegible for garbage collection?

In the class' finalize method you can assign an outside reference to the object before it is collected. ( ex: OutsideClass.referenceToMe = this; ) This will only work the first time the object is attempted to be collected since the finalize method is only called once.

My device has XX kilobytes of memory but I cannot allocate all of it. What is going on?

As mentioned earlier, references aren't the same as pointers. Memory allocations can be made anywhere on the heap and we have no guarantee of where they occur. As such a small object might be allocated right in the center of the heap. A subsequent allocation of a large chunk may not be able to fit before or after this smaller chunk. To avoid these situations try not to allocate large chunks of memory.

When I print out an object I get something like Object@345563. Isn't this the address of the object?

No, that is the object's reference ID. It helps the VM lookup the actual object instance in the heap at some other location. Each JVM can decide how to implement this ID. You can still use this ID as a means to test whether two references refer to the same object ( a == b ).

How do I deal with OutOfMemoryErrors?

In theory you don't or at least shouldn't. Errors, as opposed to Exceptions are not meant to be caught by your application. The fact that this error occurs is a sign that you are trying to allocate more memory than is available as a single chunk. This usually occurs when you attempt to load a large image after loading many smaller ones. The smaller images used up half the heap and the large one can't be provided a large enough chunk in which to fit. To overcome this, call System.gc() more often (even if its performance is not guaranteed) and avoid loading such large resources into memory. This way you shouldn't need to catch the error.

Is there any way to determine the real addresses of objects on the heap?

No, at least not any offical way. Imagine the havoc that would be caused if there were. You could easily prevent the JVM from doing its job properly if you were able to manually delete an object by yourself

FILE API

Why cannot I access to c:/myFile using (FileConnection) Connector.open("file:///c:/myFile")?

FILE API give you access to filesystems and files placed in your device, so the file you want to open should be placed "inside" your emulator, and this is (for wireless toolkit) somewhere inside
                          {WTK-path}\appdb\DefaultColorPhone\filesystem
Here is where you can create your own tree-structure, and where should be placed the files you can access to.

How to manage memory within the main game loop?

A game loop in the part of the program that is called over and over again, each time reading user key presses and updating the screen.


Normally the loop runs as fast as it can to the limit of the CPU.
Now, a very important detail about garbage collection is that it can only run when there are some spare CPU cycles available. In the game loop normally all the CPU cycles are dedicated to updating the screen, so the garbage collecter never has a chance to run (regardless if you call System.gc(), or not). So the golden rule is:
Never, create any objects in your game loop, because they will never get garbage collected and, if the user plays the game long enough, it will eventually run out of memory. Instead assign your objects outside of the game loop and re-use them.
Also, don't forget that string addition causes String objects to be implicitly created:
g.drawString("Score: "+score);  // this causes a new string to be created on heap
In this case, for example, you might consider using Graphics.drawChars, which draws an array of chars.


It may be unavoidable that some objects are created in the game loop, in this case you could try puting a pause in the game at regular intervals (for instance, at the start of a new level):
// this introduces idle time and allows the gargage collector to run
try{ Thread.sleep(500); } catch(Exception e) {}

Signing and Certificates

This post on kvm interest (http://archives.java.sun.com/cgi-bin/wa?A2=ind0601&L=kvm-interest&P=7105) sums up the current situation quite well.