×

Discussion Board

Results 1 to 13 of 13
  1. #1
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    65

    To Mr. Graham Hughes and/or other experts on MIDP MIDlet packaging...

    Hi, all

    I have seen sooo... many posts on how to creat a project upon you finished coding your MIDP MIDlet in sooo...many ways and sequences.

    I have to admit I am a beginer in this field. But may I please you to give us a clear and standard (hopefully) way (including preverify,obfuscation, 'JARing') on how to creat the application package after finishing coding *.java file assuming we already have MIDP SDKs, NDS 2.0 (or v1.1), Wireless Toolkit, RetroGuard, and other necessary IDEs.

    We will be pretty appreciated on your contribution although we understand that you have done a lot on that.

    Waiting for kind answers from you all....

    Br,
    Leo
    Last edited by zhaolikang; 2003-10-24 at 08:08.

  2. #2
    Registered User
    Join Date
    Jul 2003
    Location
    Finland, Tampere
    Posts
    1,113
    If you have some non-free version of JBuilder, after you set JDKs and obfuscator classpathes it will do everything for you.

  3. #3
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395
    Leo,

    A wise man always listens to his Doctor... paying money and buying JBuilder is likely to be by far the easiest way of building a JAR!

    I am not so wise, so had to spend many hours writing .BAT files to do it for me!

    Roughly, this is the basic process, with compilation, obfuscation, preverification and JAR/JAD building. You should read all the documentation for the programs involved to make sure you know what this is doing. In the future, you may want to tailor this process.

    I've butchered this from the file I use... I do some extra bits that you really don't want to know about!!! Copy this into the directory where your .java files are, then type "make" at a command prompt. I don't place any of my classes in packages; if you do, you may need to change some bits. Please keep in mind that this script is built for the way I work... if you work in a different way, it may be unsuitable.

    You'll need to make changes where I've indicated, to configure your file locations and project options.
    Code:
    setlocal
    
    rem *** set MIDlet parameters for this project
    rem --- set these to whatever you want!
    
    rem --- this will build "test.jar" and "test.jad"
    set FILE_NAME=test
    
    rem --- this is the descriptive name for the app
    set NAME=Test Application
    
    rem --- this is the main class
    set MAIN_CLASS=MyMidlet
    
    rem --- icon file
    set ICON=icon.png
    
    rem --- version number and vendor name
    set VERSION=1.0.0
    set VENDOR=I made this
    
    rem --- list of extra files (other than classes)
    set RESOURCE_LIST=%ICON% ball.png profile.png table.png
    
    
    rem *** set paths to JDK, WTK and RetroGuard
    rem --- these need setting to where yours are installed
    
    set JDK_PATH=c:\apps\j2sdk1.4.1
    set WTK_PATH=c:\apps\WTK104
    set LIB_PATH=%WTK_PATH%\lib\midpapi.zip
    set EMPTY_LIB_PATH=%WTK_PATH%\wtklib\emptyapi.zip
    set RETRO_PATH=c:\retroguard-v1.1\retroguard.jar
    
    
    rem *** temporary directories
    rem --- we need these to store class files in
    
    set JAVAC_OUT=classes
    set RETRO_OUT=retro
    set VERIFY_OUT=verified
    
    if not exist %JAVAC_OUT% md %JAVAC_OUT%
    if not exist %RETRO_OUT% md %RETRO_OUT%
    if not exist %VERIFY_OUT% md %VERIFY_OUT%
    
    rem *** compile
    
    %JDK_PATH%\bin\javac -bootclasspath "%LIB_PATH%" *.java -d %JAVAC_OUT%
    if errorlevel 1 goto END
    
    rem *** obfuscate
    
    rem --- don't change the name of the main class
    echo .class %MAIN_CLASS%>mainclass.rgs
    
    rem --- we build a jar first
    %JDK_PATH%\bin\jar cvfM temp.jar -C %JAVAC_OUT% .
    rem --- then run RetroGuard
    %JDK_PATH%\bin\java -cp "%RETRO_PATH%;%EMPTY_LIB_PATH%" RetroGuard temp.jar retro.jar mainclass.rgs rg.log
    
    rem --- the obfuscated jar is then "un-jared"
    cd %RETRO_OUT%
    %JDK_PATH%\bin\jar xvf ..\retro.jar
    cd ..
    
    rem *** delete unwanted files
    
    del %RETRO_OUT%\META-INF\MANIFEST.MF
    rd %RETRO_OUT%\META-INF
    
    del temp.jar
    del retro.jar
    
    rem *** preverify the obfuscated classes
    rem --- you must preverify AFTER obfuscation
    
    %WTK_PATH%\bin\preverify.exe -classpath %LIB_PATH% -cldc -d %VERIFY_OUT% %RETRO_OUT%
    
    rem *** build manifest file
    
    echo Manifest-Version: 1.0> MANIFEST.MF
    echo MIDlet-1: %NAME%, /%ICON%, %MAIN_CLASS%>> MANIFEST.MF
    echo MIDlet-Name: %NAME%>> MANIFEST.MF
    echo MIDlet-Version: %VERSION%>> MANIFEST.MF
    echo MIDlet-Vendor: %VENDOR%>> MANIFEST.MF
    echo MicroEdition-Profile: MIDP-1.0>> MANIFEST.MF
    echo MicroEdition-Configuration: CLDC-1.0>> MANIFEST.MF
    
    rem *** build JAR
    
    %JDK_PATH%\bin\jar cvfm %FILE_NAME%.jar MANIFEST.MF -C %VERIFY_OUT% . -C . %RESOURCE_LIST%
    
    rem *** build JAD
    
    rem --- this works in Win2000 to find the size of the jar
    for %%f in (%FILE_NAME%.jar) do set JARSIZE=%%~zf
    
    echo MIDlet-1: %NAME%, /%ICON%, %MAIN_CLASS%> %FILE_NAME%.jad
    echo MIDlet-Name: %NAME%>> %FILE_NAME%.jad
    echo MIDlet-Version: %VERSION%>> %FILE_NAME%.jad
    echo MIDlet-Vendor: %VENDOR%>> %FILE_NAME%.jad
    echo MIDlet-Jar-URL: %FILE_NAME%.jar>> %FILE_NAME%.jad
    echo MIDlet-Jar-Size: %JARSIZE%>> %FILE_NAME%.jad
    
    rem *** that's it!
    
    :END
    endlocal
    It would be a good idea to add some extra bits to clean up all the temporary files, either at the start or the end, but I'll leave that to you!!

    Graham.

  4. #4
    Regular Contributor
    Join Date
    Mar 2003
    Location
    USA, FL
    Posts
    148
    Nice

    Actually, look at %WTKDIR%\apps\demos\bin\
    there are 2 files: build.bat and run.bat

    I build mine using these as example.

  5. #5
    Regular Contributor
    Join Date
    Aug 2003
    Location
    Eire
    Posts
    182
    Please excuse my ignorance!

    Why not just use WTK with retrogaurd to obfuscate, preferify and build the jars?

    What benefit is there to going through that process?

    Does it reduce Jar size?

  6. #6
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395
    I also have some schematics for a new "wheel" I'm working on...

    K-Toolbar has a build thingy in it, doesn't it? My main reason for not using it is that my PC is sh*t, and Java applications that use Swing tend to run like slow-running things on it.

    Also, I do customize the process to save JAR space. I use a C pre-processor before compiling (it works on Java as well as C, though I'm told there are Java-specific tools around). I also have some resources that get compiled from scripts, images that get concatenated into binary files, that kind of thing. I build a number of configuration parameters for apps into the JAD, and sometimes need to build multiple JADs for testing on the emulator and the real phone. I use some modified processing for debug and production builds (like I don't always obfuscate a debug build, I might use the pre-processor to include some extra code, or I might add an extra class or MIDlet).

    Having your own build process (whether a batch file, or using Ant or whatever) means you can tweak it and add extra processing steps in, which you might not be able to do using an IDE's "make" facility". In my case, it wasn't a big task to put together a script to perform a build... I was using one for J2SE programs before, which just got the preverify step added in. After that, it grew over the course of the project; at the end, I went through it, and made it more general by parameterizing bits into environment variables.

    Like I say, this suits the way I work... different people work different ways, and I don't suggest that mine is best!

    Graham.

  7. #7
    Registered User
    Join Date
    Jul 2003
    Location
    Finland, Tampere
    Posts
    1,113
    Graham, simplest way is almost always not the most effective

    I've got an appearence that zhaolikang is just starting off in J2ME development. I would really advise using trial JBuilder version for some 30-90 days (don't remember). This will help not to bother with packaging issue, while there are that many other questions.

    Personally I currently use free JBuilder 9 Personal as editor/debugger + Ant as building/packaging tool + WinRar to repack JARs after obfuscating (makes them even more small

    I also plan to use Antenna preprocessor for the next project.
    However, C preprocessor can also be lauched by Ant.

    P.S.
    For those considering using Ant:
    1. It took few hours from me to learn it.
    2. It took about an hour to learn Antenna, I use it mainly for automatic JAD file updating
    3. It took about 2 days to create full-scale Ant build file for my project, both for Series 40 and Series 60 versions. Most of the time was spent on careful learning of obfuscators parameters and on Antenna workarounds. Antenna is still quite a beta thing, I found it working 100% correctly only on simple archiving, JAD updating and preprocessing

  8. #8
    Super Contributor
    Join Date
    Jun 2003
    Location
    Cheshire, UK
    Posts
    7,395
    I agree... if a point-and-click option is available, then it makes sense to use it. Until you need something more complex, which might be never.

  9. #9
    Registered User
    Join Date
    Jul 2003
    Location
    Finland, Tampere
    Posts
    1,113
    Yep, there is point-n-click. Well... you have to set up 1 directory in obfuscator settings

    Forgot to mention. I call WinRar also from Ant.
    Actually currently I'm quite impressed with Ant.

    Basically it's almost the same as BAT file and you convert your existing BAT files easily, but not talking of platform independence (who is really concerned about it it's much more powerful and has a growing list of useful tasks.

  10. #10
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    65
    Hi, everyone

    Thanks a lot for all your replies and special thanks come to Graham, doctordwarf and dpolyakov. I found the batch file in WTK which is quite simply and VERY easy to modify according to your own case if you just have Sun Wireless Toolkit installed, even though the batch-file work from Graham is very appreciated!

    To doctordwarf, I have a non-free JBuilder8 with Mobile set installed, but how to create application package by using that if I just have a .java file and resource file in hand?

    Anyway, I have finished packaging and can be built well in both ways of using batch file and Wireless Toolkit but the new problem occured when the emulator (MIDP SDK 1.2 Chinese, because of my CHINESE specified Apps) initiated: There is only the function table appeared as if I typed " epoc" and return!! My App should have been a welcome Form !!

    The warning indication (I am not sure whether it is related to my problem, possiblly NO) in WTK is :

    "
    Project settings saved

    Building "DishesList"

    Build complete

    WARNING: Attribute value for MicroEdition-Profile defined in JAR manifest is not supported.

    Emulator command: d:\WTK104\wtklib\devices\Series_60_MIDP_SDK_for_Symbian_OS_v_1_2_chinese\bin\Series_60_MIDP_SDK_for_Symbian_OS_v_1_2_chinese\epoc32\release\wins\udeb\kmidp_debug.exe -parent_port 2810 -classpath c:\tmp\midp\DishesList.jar -descriptor c:\tmp\midp\DishesList.jad DishesList
    "
    If you are really helpful may I take you several minutes in reading my foolish code (forget any Chinese characters inside which are all in String )and find any possible reason of how it comes to that?


    Ma......ny thanks go in advance!!

    package DishesList;

    import java.lang.*;
    import java.io.*;
    import javax.microedition.midlet.*;
    import javax.microedition.lcdui.*;

    public class DishesList extends MIDlet implements CommandListener {

    Display display;
    private Command selectCommand = new Command( "Details",Command.OK, 1 );
    private Command backCommand = new Command( "Back",Command.BACK, 1 );
    private Form preForm, listForm, detailForm;
    private ChoiceGroup aChoiceGroup, bChoiceGroup;
    private final String[] sectionList ={"Main Course (Ö÷²Ë)", "Cold Dishes (Á¹²Ë)"};
    //private final String titleString = " Dishes List ";
    private String selectedSection, selectedDishName;
    private Command cmdOK, cmdDetail, cmdBack, cmdSelect, cmdExit;

    public void startApp() throws MIDletStateChangeException{

    /*public DishesList()
    {
    }
    */
    preForm = new Form("Welcome to Dishes List Exercice!");
    aChoiceGroup = new ChoiceGroup("Which section do you need?",Choice.EXCLUSIVE,sectionList,null);
    preForm.append(aChoiceGroup);
    preForm.addCommand(cmdSelect);
    preForm.addCommand(cmdExit);
    preForm.setCommandListener(this);

    listForm = new Form(selectedSection);
    bChoiceGroup = new ChoiceGroup(null,List.EXCLUSIVE,getNameList(selectedSection),getImageList(selectedSection));
    listForm.append(bChoiceGroup);
    listForm.addCommand(cmdDetail);
    listForm.addCommand(cmdBack);
    listForm.setCommandListener(this);

    detailForm = new Form(selectedDishName);
    detailForm.append(getImageByName(selectedDishName));
    detailForm.addCommand(cmdOK);
    detailForm.setCommandListener(this);

    display = Display.getDisplay(this);
    Displayable current = display.getCurrent();
    if(current == null)
    display.setCurrent(preForm);
    else
    System.out.println("Can not be displayed!");
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) throws MIDletStateChangeException {
    }

    public void commandAction(Command cmd, Displayable d)
    {
    if(cmd == cmdSelect)
    {
    display.setCurrent(listForm);
    selectedSection = aChoiceGroup.getString(aChoiceGroup.getSelectedIndex());
    }

    if(cmd == cmdExit)
    {
    try{
    destroyApp(false);
    notifyDestroyed();
    }
    catch(MIDletStateChangeException e){
    System.out.println("Destroy exception: "+e);

    }
    }

    if(cmd == cmdDetail)
    {
    display.setCurrent(detailForm);
    selectedDishName = bChoiceGroup.getString(bChoiceGroup.getSelectedIndex());
    }

    if(cmd == cmdBack)
    {
    display.setCurrent(preForm);
    }

    if(cmd == cmdOK)
    {
    display.setCurrent(listForm);
    }

    }

    private String[] getNameList(String sectionName)
    {
    String st = sectionName;
    String[] mc = {"µ°Ëþ_Sweat Egg Cake","¶¬¹ÏÅŹÇ_Pork Souce","·Ûзʨ×ÓÍ·_Lion Head"};
    String[] cd = {"¶¹Æ¤Èâ¾í_Pork Solid Beancurd","½ðÕë¹½_JinZhenGu","һƷ¶¹¸¯_First Beancurd"};
    if (st == "Main Course (Ö÷²Ë)")
    return mc;
    else
    return cd;
    }

    private Image[] getImageList(String sectionName)
    {
    Image[] ri = new Image[6];
    String st = sectionName;
    String[] gst = getNameList(st);
    for (int i = 0;i< gst.length;i++)
    try
    {
    ri[i] = Image.createImage(gst[i] +"_sml.png");
    }
    catch(Exception e)
    {
    System.out.println("***Creat small image error: " + e);
    }
    return ri;
    }

    private Image getImageByName(String dishName)
    {
    Image r = null;
    String se = dishName;
    try
    {
    r = Image.createImage(se +".png");
    }
    catch(Exception e)
    {
    System.out.println("***Creat large image error: " + e);
    }

    return r;
    }


    }
    THE END

    Thanks for reading...

  11. #11
    Super Contributor
    Join Date
    Mar 2003
    Location
    Israel
    Posts
    2,280
    WARNING: Attribute value for MicroEdition-Profile defined in JAR manifest is not supported
    Look at the jad file created, does it say:
    Code:
    MicroEdition-Profile: MIDP-1.0
    or, maybe (this is what I suspect):
    Code:
    MicroEdition-Profile: MIDP-2.0
    If your answer is the second option then you have to change it back to MIDP-1.0, and it should work....

    shmoove

  12. #12
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    65
    Thanks shmoove!

    However, In my MANIFEST.MF I ever change "MicroEdition-Profile:" into MIDP-1.0, 2.0 and even BLANK (leave it blank). The result when running my MIDlet in emulator of MIDP SDK 1.2 Chinese is still:

    WARNING: Attribute value for MicroEdition-Configuration defined in JAR manifest is not supported.

    Emulator command: d:\WTK104\wtklib\devices\Series_60_MIDP_SDK_for_Symbian_OS_v_1
    _2_chinese\bin\Series_60_MIDP_SDK_for_Symbian_OS_v_1_2_chinese\epoc32\release\wi
    ns\udeb\kmidp_debug.exe -parent_port 2811 -classpath c:\tmp\midp\DishesList.jar
    -descriptor c:\tmp\midp\DishesList.jad DishesList

    =========================================================================

    But I tried other apps which CAN succesfully run I found that in this item of their MANIFEST file there is also 'leave blank' and the same warning infomation appeared while the MIDlet running!!

    I guess there is something else hide behind other than this warning info..

    Could you or other experts give me a hand as I have been struggling for that for two days!! :-(

    PS.
    1) My jar file size is about 400k;
    2) I have to run my MIDlet under Simplified Chinese versioned SDK's emulator.

    Many thanks go ahead... ...

    Br,
    -Leo

  13. #13
    Regular Contributor
    Join Date
    Aug 2003
    Posts
    65
    Further, I am hunger to know whether it is a known issue about there is ONLY a function table picture (you can go into each functional block like phone book, messaging...etc. as if you JUST run a Epoc.exe) instead of the MIDlet Welcome interface appeared when actually running your MIDlet!!!

    I am so....frustrated about it and sincerely hope someone could spend several mins on that for me!! Thanks a lot!!

    Br,
    -Leo

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •