JaanusSiim

Mobile (J2ME, Android, iPhone) nut with some Ruby love

Eclipse with preprocessing

September 7, 2008 | Posted in J2ME, Tagged , ,

When working with code that was written by somebody else, one of the most annoying issues for me was inconsistent code formating. Actually in this particular case the indentation was totally screwed up.

Only option was automatic formatting with Eclipse. But there was a problem with preprocessing directives in code. They all got screwed up, a space was added between // and #, and nothing worked. To my luck (and for the luck of other J2ME developers :P ) there is a setting ‘Enable line comment formatting’ buried inside code formating settings. With this option disabled, preprocessing worked as a charm.

This particular code was also using code preprocessing in imports, that got still screwed up. But this should be considered a bad style anyway. And it is really not needed. You should preprocess code/class usage and let obfuscation do rest of the work – removing unneeded imports/classes.

J2MEDB version 0.2.0 has been released

March 2, 2008 | Posted in J2ME,Ruby, Tagged

Updated version of J2MEDB has been launched on j2mehandsets.com. Main work has gone into usability and handset detection improvement.

On MIDlet side key mappings test was altered a bit. I hope that new graphics will make the test more understandable. Also it has been made clearer, that on every upload only data for current test will be uploaded. I was thinking about uploading all test data in one go, but because of media test crash on Nokia 7650 I decided to drop it.

On server side handsets approving and some minor data editing options have been added. Handsets listing by supported APIs has also been enabled. I tried to improve handset detection based on current data available, but probably more issues can come up in that area.

At the moment the database only contains Nokia and SonyEricsson phones, which is bad :) But I am working on plan for adding more handsets (also from different manufacturers) to database.

For next version I would like to add some simple wiki implementation for known issues and general test descriptions.

So, please, keep testing :P

J2MEDB – version 0.1.0

January 22, 2008 | Posted in J2ME,Random,Ruby, Tagged

After playing with the idea really long time, initial version of J2MEDB is up and running on www.J2MEHandsets.com.

The Idea

The idea for my own database came from dissatisfaction with other databases available at that time. There were databases, that had a lot of useful data, but were a bit too generic. For example they listed all available sound formats, but did not mention, which protocols supported these. There were also databases, that were just filled from official specs, even if Java implementation did not support it.

At some point I would like to add database support to midlet-builder. In theory it should be possible to just tell midlet-builder to generate build for all handsets contained in database. And if midlet-engine implementation is also mature enough, it could really happen.

Current implementation

In current implementation I have mostly focused on data upload and simple data display. I feel, that I could have made it a bit better, but wanned to have some initial feedback. And also see, what kind of data could I expect. And where might the bottlenecks be.

At the moment SonyEricsson and Nokia support should be decent, but I did not have any other devices available during development – so, you may never know…

Future plans

  • Make it more prettier :)
  • Add some kind of simple screening support. At the moment all devices will be added in ‘pending for approval’ status.
  • Improve handset detection on midlet/server

MIDlet localization done right

November 5, 2007 | Posted in J2ME, Tagged

I have used two ways for MIDlet localization since I started coding J2ME. I will be describing my changes in localization handling based on demand from clients.

Actually I have used three solutions. The first solution was having all your strings hard coded in source files and never change them. It worked until we found a client in Italy and we needed to support two languages.

Then we opted on using the tools that we knew at the time. We used ant’s replace task for processing translation strings. It worked really well at that time. Of course we had to create two builds for every targeted phones group, but we could handle it. What made things a bit difficult was that the build system we used then produced some times broken builds. So the release schedule also included me running every build in emulator. Just in case. If some code path did not work we made a new build for that device and everything was fixed.

Then we got a client, that wished to support twelve languages. It was clear, that our procedure at that time did not work anymore. I think that the idea for current implementation (used also in midlet-builder/midlet-engine) came from J2ME-Polish. It was how they were handling localization (disclaimer – I can’t remember, if I have ever actually looked at localization code in J2ME-Polish), or at least how I understood it.

In first step of localization midlet-builder will generate two files from input directory. The actual localization file and a file used by preprocessor later on. The localization file generated has following format:

< number of languages > at the moment this is byte
< number of translation keys > number if different strings used
    in MIDlet. This number does not include some special keys
    described later.

Next we will have stings used on localization screen for language selection by user

< language codes > two character language codes that can be used for
    automatic language selection on the phone (comparing it to
    microedition.locale property. A note – this will not work on
    some Samsung phones).
< language names > localized languages names. Preferably in native language.
< special select keys > also used on localization key. If you
    were moving up/down in languages list, 'select' string will
    be shown in highlighted language.
< help strings >
< about strings >
< all keys for every language > This is where all translation
    strings for every language are entered. All the keys will be
    same for every localization set. And they will be entered in
    the same order.

The other file generated is used in source files preprocessing. We’ll call it ‘key_map.txt’. It has key-number pairs for key index in localization set. For example ‘menu.help = 0′ would mean that translation for ‘HELP’ string in main menu is located in first position for every language.

In the source code we have languages screen for language selection. It will load language codes, language names and select strings for displaying these on the screen

    InputStream is="".getClass().getResourceAsStream("/loc.bin");
    DataInputStream dis=new DataInputStream(is);
    final byte languages=dis.readByte();
    languageNames=new String[languages];
    languageCodes=new String[languages];
    selectStrings=new String[languages];
 
    //ignore translations length
    dis.readByte();
    for(int i=0;i &lt; languageCodes.length;i++){
      languageCodes[i]=dis.readUTF();
    }
 
    for(int i=0;i &lt; languageNames.length;i++){
      languageNames[i]=dis.readUTF();
    }
 
    for(int i=0;i &lt; selectStrings.length;i++){
      selectStrings[i]=dis.readUTF();
    }

Here the translation keys length is ignored, because it has no meaning here. Maybe it should be moved to different position.

Because all languages are shown in the order, as they are in localization file, we can search for used language keys start position, after user has selected one. Until now no actual translations have been loaded. To load the keys into array we skip all special keys and also all different language keys that can come before selected language.

For accessing localization keys from code we have two methods in translation handler: get(String keyName) and get(int keyIndex). The first method will have no implementation and is there only for compiler and will be replaced by translation preprocessor. The preprocessor will replace all get(“key.name”) calls with get(index) calls based on values loaded from ‘key_map.txt’.

Because help and about text are usually not displayed that often and take more space in memory, they are handled a bit differently. They are loaded ‘on demand’ and are not kept in memory (unlike other strings for loaded language).

So this is my opinion of ‘localization done right’. I should really create a wiki page describing the process and all included file formats.

In the future I would also like to add localization loading from server and maybe just keep actually used translations in memory (for example only main menu elements). But this would require an automated way for detecting keys used on every screen… Looks like an idea for future projects!

How I made a backup from a public wiki

October 29, 2007 | Posted in Random,Ruby, Tagged

Background

Lately the J2ME forums wiki has been under constant spam attacks. As the owner of the forum seems to be rather busy, to implement some spam protection, there was an idea to create a backup from the data in wiki before spam. I have no access to the wiki server, so I had to use other means available. Hpricot to rescue.

Know the enemy

To me it looked like there is no way to be sure, if site contains spam or not. Some users experimented with adding spam links into hidden div in hopes that spam robot will be fooled. But it had no effects. So we may have spam links on all pages. There was also no 100% sure way to know, when spam posts started, so I opted for full backup of the wiki.

So I needed a history for all discovered pages. In MediaWiki the pages history is available using address:

index.php?title=#{page_name}&amp;action=history

As I had no idea how many pages there were in history I had to add parameters

&amp;limit=1000&amp;offset=0

to the url. As default I would have gotten

limit=50

From history page I searched links for every available revision for the page. Armed with this knowledge I could scan every revision of the page, search for additional internal links, and save page content.

The code

Can be downloaded from s3 bucket

I created a Parser object, that will be initialized with the wiki url. After that You just call the

parse(entry_page)

method and it will start making backups of the wiki pages. Saving these into ‘data’ directory. All saved pages will have modification date in their name.

The result

After 10 hours of running and 3GB data transferred I had 850 MB of knowledge in ‘data’ directory. Probably a lot of it is also spam. The next step should be converting these pages automatically to DocuWiki format and removing spam. At the moment I will probably create clean pages by hand and look at it later.

I also tried to use [urls blacklist from blacklist.chongqed.org but in my experiments it turned out to be rather useless. The latest urls were not listed there… I the end it actually did not make any difference. I just made a dump of data on the page.

Was it worth it – for me definitely. I added my url as user agent in request and until now nobody from J2ME forums has also complained.

Lessons learned

Hpricot made the task a lot easier. I must admit, that I had some small problems with it at first… But it got better.

In the parser, there is also one redundant step. There is no point for getting internal links from actual history page. This data is also available on edit page, that will be visited anyways… If this step would be removed, then the parser could have completed the backup in 50% less time transferring 50% less data. Too bad I realized that next morning, when script was already running.

And the revelation today – I need to start commenting my code better. You never know, when it will get published.

Anyway – have fun! Now I’m going back to mobile development.

A library repository for midlet-builder

October 17, 2007 | Posted in Random, Tagged

One feature for midlet-builder would be dynamic jars selection for source compilation. The selection would be handled based on supported device properties. This should, in theory, add additional security level, that the compiled code is also suitable for the device. You could immediately see, if you are using classes from unsupported packages.

First of all I need a cheap location for the repository. And at the moment Amazon’s S3 looks like a perfect solution. It is lacking possibility for browsing, but I’m sure there are ways around it.

After playing a bit with S3 I have one tip for you – go straight to s3sync. In my opinion the fastest way to test S3. I started experimenting with Ruby code. And it was really not going anywhere… But it was my problem – some times I just can’t stand, if something is holding me back from working on my ideas.

Anyhow – the tough part will be dependency handling. At the moment I’m leaning towards using Ivy for it. It could be used as standalone from command line. What I do not like about it is, that it will create additional dependency inside midlet-builder. Already I’m relying on too many external programs, that can’t be configured.

As another solution I should check dependency handling in Raven. If I only found some time for it…

And of course midlet-bulder could also handle the dependency resolving. As I figure – it does not have to me something fancy… Just some dirty version comparing and http requests… But at the moment it should be really low priority… I have more important issues to resolve.

Midlet-engine – J2ME on Rails?

October 11, 2007 | Posted in J2ME, Tagged

Ok, ok – the title is a bit bold. But the idea behind the framework for J2ME games should be the same – to handle all common behavior and let You just create.

midlet-engine is based on the idea that only places, where games code will change, are in main menu animation and game logic/rendering. Everything else can be handled by common code and can be reused. There is no need for creating screens flow handling, localization, resources loading, etc. from scratch for every new game. Just create a common framework for implementation, that would be reused, and innovate. The additional benefit of a framework would be, that it would contain all the knowledge about device specific bugs and workarounds for these.

Currently midlet-engine handles:

  • localization
  • screens flow (from intro screen to outro screen)
  • custom font implementation
  • a custom sprite implementation

Should handle:

  • network communication
  • generic high scores handling
  • generic saved game handling
  • handling and separation for thread driven and event driven MIDlets
  • resource packages for screen/level

The problem with the midlet-engine at the moment is, that it’s not really flexible. To use it for event driven MIDlet I had to use some hacks in midlet-builder, to ignore not needed classes. This should be some how configured and handled better.

Under resource packages I was thinking that there should be a way to determine automatically, what resources are needed by every step of the application. Basically between load screens. If it could be detected, then we could combine these resources in different resource packages, to gain some jar space. But at the same time the resource packages wold not get too big and make loading noticeably slower…

But the method for detecting the used resources is basis for another project…

So many ideas and so little time…

Midlet-builder

September 28, 2007 | Posted in Ruby, Tagged

The idea

First project by me will be midlet-builder. It is loosely based on idea of J2MEPolish.

For some unknown reason J2MEPolish stopped working for me. Previously working builds were no longer generated. Also I was a bit unsatisfied by their database, but that issue will be addressed by another project. So, after a week of banging my head on the table, I gave up. I dropped it and started to work on my own version for a builder.

Initial version of midlet-builder was created in Java and during my ‘day time’ work. I started a personal version in Ruby after reading some articles about learning a new programming language every year. At first I was thinking about learning Lisp, but decided to go with Ruby. Maybe also a bit because of Ruby on Rails.

At the moment the codes is really terrible and I have not used Ruby to it’s full potential. I have a feeling, that I have done everything the same way, as I would have done in Java. Only in different language.

Functions

At the moment midlet-builder handles:

  • source files preprocessing
  • localization handling
  • resource files copying
  • source files compiling
  • preverification
  • obfuscation
  • packaging of MIDlets

What it’s lacks is flexibility. It does everything the way I like it and how I have pictured it. I am hoping, with more input, to create a more flexible product.

Future ideas

At the moment the ideas I am playing with:

  • applet generation (for demo purposes)
  • more device specific preprocessing options
  • configuration of different obfuscators
  • resource files processing based on target device
  • different packaging options (test for best option)
  • device information from configurable locations (text files, database, etc)

I have a feeling, that this is only a beginning. Hoping to hear ideas from You also.

Choosing the license

September 25, 2007 | Posted in Random, Tagged

When I first read the article about licenses on Coding Horror, I had no idea what was really waiting for me.

The idea was simple – I needed to have an option for using the code also in closed source commercial projects. At the same time I needed something open enough for others to contribute. I must say, that choosing the license was really not fun. And I got an headache :) For me the Apache v2 looked good enough. At least it seemed to respond to my requirements.

Of course I got a bit more confused, when I was reading the discussion of using LGPL licensed code in Apache code. I found in my framework one piece of code, that was under LGPL. It is MD5 generation in midlet-engine. At the moment I have really no idea how LGPL is going to mix with Apache license. To my understandings, it should be OK :) If you have other opinions, then, please, let me know.

I really hope, that I do not have to come back to the license again…

The start of JaanusSiim

September 17, 2007 | Posted in Random, Tagged

What is or will be JaanusSiim?

My name is Jaanus Siim and this is where I will be showing my ideas and projects. The motivation for this project would be some peer pressure – to keep me focused on most essential issues with the problems I am facing. I’m hoping to give something useful to others and also learn something new.

My main interests at the moment are Ruby, J2ME and RoR development. I will be releasing everything open source. Hoping to get some contributions, new ideas and tips how to improve myself and my code :)

At the moment it will be a part time project, but I am very optimistic about making it some day my main work. At least I can achieve some J2ME/Ruby skill points. And maybe get my name out there.

“And so it begins” – Kosh – Babylon 5

PS! Special thanks to Helen. I’m not sure if I would ever started it without her positive attitude :)