j2me MIDP Device Fragmentation Tutorial with Marv The Miner
<script language=JavaScript type=text/javascript>
</script> http://www.netbeans.org/kb/articles/tutorial-j2mefragmentation-40.html
Feedback
This tutorial shows how to configure the IDE to work with existing JavaTM 2, Micro Edition Platform (J2METM Platform) MIDP projects and, specifically, how to use the NetBeansTM IDE's built-in solution to the device fragmentation problem. Following this tutorial from start to finish will illustrate the following:
- How to port an existing fragmented MIDP project to NetBeans
- How to use the IDE's built-in device fragmentation solution
The example program this tutorial uses is the popular j2me game "Marv The Miner," which was released under GPL and written to run on several different mobile platforms.
This tutorial should take approximately two hours to complete and covers the following topics:
- Import sources from an existing MIDP project.
- Create and customize project configurations for each distribution Jar.
- Mark pieces of source code as being specific to each configuration.
- Build several distribution Jars for the project.
- Use external emulators from within the IDE.
To follow this tutorial you need the MarvTheMiner_120_all.zip file, which contains the original source files of the program. Click here and download "Marv the Miner v1.2.0 (including level editor)" to obtain the source files.
- Setting Up Your Environment
- Obtaining the Required Source Files
- Developing the Marv The Miner Application in NetBeans
- Building and Executing the Marv the Miner Application
- Exploring Configurations Further
- Using Non-UEI compliant Emulator Platforms
Setting Up Your Environment
This section describes how to set up your system before starting the tutorial.
Obtaining and Installing the Required Software | The following software is required for the example:
Use the instructions provided at the download sites to install the software. | ||||||||||||
Starting the IDE | To start the NetBeans IDE:
The IDE-install-path variable stands for the path to the IDE's home directory. | ||||||||||||
Obtaining the Required Source Files | The MarvTheMiner_120_all.zip file contains the source files of the original Marv The Miner application. The zip includes a MarvTheMiner directory, which contains the src and res subdirectories that you will use in this tutorial. To unzip the MarvTheMiner_120_all.zip file:
|
Developing the Marv The Miner Application in NetBeans IDE
In this section, you set up and work with the existing project sources within the NetBeans IDE.
Import existing sources
Creating the Project | The first step is to create a new project in the NetBeans IDE.
|
Creating Project Configurations
The NetBeans device fragmentation solution is based on the use of project configurations. A project should have one project configuration for each distribution Jar/Jad you would like created for that project.
If you examine the file Main.java
, you will see that the the authors support multiple platforms with a combination of comments (for Nokia's FullCanvas) and Class.forname()
. They also define a variable vendor that is used to track on which phone the application is running. Based on this information, you can see that they are supporting five different groups of phones:
- Nokia Series 60
- Other Nokia
- Motorola
- Vodafone
- Other
As such, you will create four configurations to handle differences between these distributions.
Creating a Configuration |
The Project Configuration combo box at the top of the Project Properties page should now contain five configurations. We will use these configurations in a moment, but for now lets add some emulators into the IDE. |
Adding Emulators to the IDE | To run the project using the emulator platforms you have installed on your computer, you must first register them with the IDE.
|
Customizing Project Settings for Configurations | Each panel in the Project Properties page can be customized separately for each project configuration. By default, configurations will use the settings defined in the default configuration.
|
Creating Custom Code Blocks for each Configuration | The second part of the device fragmentation solution is the ability to specify certain blocks of code in your source files as being specific to one or more configurations. This is accomplished by using actions in the right-click context menu of the editor, or from the Edit > Preprocessor Blocks menu.
When you are done, your class definition should appear like so: |
Building and Executing the Marv the Miner Application
Building and Executing the Application | At this point, we should be able to compile and run the program for all of our configurations. Clicking any of the icons in the main toolbar will execute the selected action for the Active configuration.
|
5. Exploring Configurations Further
This tutorial should have given you a good understanding of how you can import your existing MIDP projects into the NetBeans environment, but it does not cover all of the Device Fragmentation issues solved by the IDE. Below are some more examples of common problems and how they can be solved within the IDE.
- Each panel in the project properties page can be configuration-specific (except the General page). This gives you a great amount of flexibility. For example, you can have different MIDlet-Version values (Application Descriptor panel) for each configuration's uniquely named (Creating Jar panel) distribution Jar.
- When setting up dependencies between projects, especially when using Project Configurations, make sure to select the correct output jar in the Project Jar Files list box of the Select Project dialog. A project Jar will appear for each configuration in the project you have selected.
If, for example, you have two projects MyLibrary and MyApplication, both containing two configurations ReleaseConfiguration and DebugConfiguration, then you would take the following steps to set up the dependency correctly:
- Open Project Properties for MyApplication. Select ReleaseConfiguration in the Project Configuration combo.
- Select Libraries & Resources panel, and click the Add Project button.
- Navigate to the location of MyLibrary project. The Project Jar Files listbox will now contain three Project Jars. Select the one in path dist/ReleaseConfiguration/ and click Add Project Jar Files
- Switch to DebugConfiguration and repeat these steps, except this time add the project jar located in dist/DebugConfiguration/
This is the manner in which you should set up dependencies between projects when configurations are involved.
- The solution is VCS-friendly. All source files will always be saved to the hard drive as if DefaultConfiguration was selected. This prevents conflicts during VCS check-in or update resulting from have a different active configuration. Be sure to also share your project.properties file (located in {projecthome}/nbproject)!
- Projects can be run from the command line without the use of the IDE. Just type ant run in the project home directory and the project will be run using the active configuration. You can pass a different configuration to the ant script by typing ant run -Dconfig.active={config_name}
- Projects that used existing preprocessor solutions should be easy to import. Though the NetBeans preprocessor is less complex than some, any situation can be expressed using the provided directives.
- The Libraries & Resources panel or the Filtering panel can be used to determine which version of a resource should be deployed to a distribution Jar.
- Libraries & Resources: Create multiple versions of a Jar file containing all resources for the application and then point to the correct version of the Jar for each configuration. So you might have 3 jars:
large_res.Jar
,medium_res.Jar
,small_res.Jar
each containing resources of the same name, but different resolutions. Then point your Nokia_large, Nokia_med, Nokia_small configurations at the correct version. - Filtering: Include your resources directly in or under the src directory then use the Filtering tree to control which version of the resources are included in the distribution Jar.
- Libraries & Resources: Create multiple versions of a Jar file containing all resources for the application and then point to the correct version of the Jar for each configuration. So you might have 3 jars:
Using Non-UEI Compliant Emulator Platforms
Though only 3rd party emulator platforms that follow the UEI specification can be automatically detected by the IDE, non-UEI complient emulators can still be used. This section describes how it can be done.
-
Adding Non-UEI Compliant Emulators - In your userhome directory (the Windows default is C:/Documents and Settings/{username}/.netbeans and the Linux default is /home/{username}/.netbeans), examine the {userhome}/config/Services/Platforms/org-netbeans-api-java-Platform directory.
This directory contains xml files that define the installed emulator platforms. You can manually create these files for any emulator which is not UEI-compliant. The DTD for this xml file can be found at http://www.netbeans.org/dtds/j2me-platformdefinition-1_0.dtd - Save the following as SDK_4.1_MRI_7.5.xml to use the Motorola 7.5 emulator needed for this tutorial. Note that the use of " is intentional, and should be saved as such.
<?xml version='1.0'?> <!DOCTYPE platform PUBLIC '-//NetBeans//DTD j2me PlatformDefinition 1.0//EN' 'http://www.netbeans.org/dtds/j2me-platformdefinition-1_0.dtd'> <platform name="Motorola_7_5" home="C:/WTK/Motorola/SDK v4.1 for j2me/Emulator7.5" type="custom" displayname="Motorola 7.5" srcpath="" preverifycmd=""{platformhome}/bin/preverify.exe" -classpath "{classpath}" -d "{destdir}" "{srcdir}"" runcmd=""> <device name="Motorola_7_5" securitydomains="trusted,untrusted" description="Motorola_7_5"> <configuration name="CLDC" version="1.1" displayname="CLDC" classpath="${platform.home}/lib/cldc.zip" dependencies="" default="true"/> <profile name="MIDP" version="2.0" displayname="MIDP" classpath=";${platform.home}/lib/midp.zip" dependencies="" default="true"/> </device> </platform>
You will need to restart the IDE after saving this XML file. Once you have done so, you will be able to choose Motorola 7 5 as a platform and Motorola_7_5 as a device. You should associate the Motorola configuration with this new platform. Note that you may need to delete the cache files located in {userhome}/var/cache in order for the manually installed platform to be detected. Also, you should not delete the mdrstorage folder that may also be located there.
Notice that the runcmd attribute is set to empty string. This is because the command to start this Motorola emulator takes the MIDlet to execute as one of its parameters. This is nothing like UEI standards, and cannot be directly supported in the IDE. However...
-
- Security Domain
- Platform Type
- Platform Home
- Jad Location
- Jad Destination Directory / Jad Name
If your emulator requires additional information (such as the location of project Jar or the name of the MIDlet to execute), you can execute emulators by modifying the build.xml file located in your project home directory.
This file controls all project actions. We can create a new target here that executes the motorola emulator and passes all appropriate data whenever the Run action is invoked on the Motorola configuration.
Add the following code your project's build.xml:
<target description="Run MIDlet suite." depends="init" name="run"> <condition property="run.motorola"> <!-- arg2 must match the configuration name you would like to use the special emulator --> <equals arg1="${config.active}" arg2="Motorola"/> </condition> <ant inheritrefs="true" inheritall="true" target="run_normal"/> <ant inheritrefs="true" inheritall="true" target="run_motorola"/> </target> <target description="Run MIDlet suite the normal way." depends="init" name="run_normal" unless="run.motorola"> <nb-run commandline="${platform.runcommandline}" securitydomain="${evaluated.run.security.domain}" execmethod="${run.method}" platformtype="${platform.type}" platformhome="${platform.home}" device="${platform.device}" jadurl="${dist.jad.url}" jadfile="${dist.dir}/${dist.jad}"/> </target> <target description="Run MIDlet suite for motorola's non-UEI emulator." depends="init" name="run_motorola" if="run.motorola"> <property name="project.home" location="."/> <!-- the last arg line contains an value "Miner". This must match the name of the midlet you want to execute --> <java dir="${platform.home}/bin" fork="true" classname="com.mot.tools.j2me.emulator.Emulator" classpath="${platform.home}/bin/Emulator.jar;${platform.home}/bin/configtool.jar"> <jvmarg value="-Djava.library.path=${platform.home}/lib"/> <arg value="-classpath${project.home}/${dist.dir}/${dist.jar}"/> <arg line="-deviceFile"/> <arg value="${platform.home}/bin/RESOUR~1/T720I~1.PRO"/> <arg line="javax.microedition.midlet.AppManager Miner -JSA 1 1"/> </java> </target>
So the
run_motorola
target will be run whenever the active configuration is Motorola. Otherwise, therun_normal
target (which uses the normal emulator execution) will be invoked.This concludes the Marv the Miner tutorial.
- In your userhome directory (the Windows default is C:/Documents and Settings/{username}/.netbeans and the Linux default is /home/{username}/.netbeans), examine the {userhome}/config/Services/Platforms/org-netbeans-api-java-Platform directory.