How to use a web service with Mirae
This is a guide to show you onto how to use a simple web service from the j2me platform with the Mirae API. This year in the Google Summer of Code , my project was to add extra protocol handlers to Mirae , so I'll be also demonstrating on how to use them as well.
At the moment if you get a Mirae source code checkout, it won't extirely build succesfully. So here as I was initially instructed by my mentor Mr.Chanshin Lee , we'll be using the Mirae source directly in our project , so we'll import the needed source files from Mirae and compile the whole thing into one jar file , instead of having the Mirae API in a seperate jar. Here I'll be building a mirae client project that accesses a simple web service called " MiraeAdd " that just adds 2 given numbers and returns the result. The Eclipse/EclipseME project's zip file is attached here " http://www.box.net/public/bvgak9qu3k " , but here we'll be using the command line to do all the building and running of the application. I'll show step by step on how to do that.
*** Step 1: Get the Mirae source code. ***
The neede Mirae source code is included in my " MiraeAdd " project , there " java , javax, org.apache " packages are the ones that's from Mirae. So if you are making another new project you have to import those packages to the project. Anyway also if you're doing this from the beginning get the full Mirae source code from "svn checkout https://svn.apache.org/repos/asf/webservices/mirae".
*** Step 2: Find the WSDL file that you are going to make the stubs from. ***
Ah I was told, Mirae only works with doc-lit wsdl's. So you would need to find one like that. Here the web service I picked is " http://webservices.iter.dk/calculator.asmx?WSDL ". And let's get down to creating the stubs. I once pointed a way to build the stubs becouse currently the tool they have given is outdated. So wat you have to do is goto root folder of mirae and type " ant jar-wsdl2javame " , after that copy "...\build\lib\wsdl2javame.jar" to "...\lib\wsdl2javame.jar". Then copy this " http://www.box.net/public/rlhb8ridgy " file to " ...\trunk\bin\windows\" folder. and cd to that folder and type " wsdl2javame <url-to-wsdl-file> ", in our case it's " wsdl2javame http://webservices.iter.dk/calculator.asmx?WSDL ". After that it'll generate the source files in that folder and then what you have to do is copy those source files in to your project.
*** Step 3: Compiling. ***
So we got all the source code together, so now you use the stubs and use the operations of the web service. So after you write the those, we are ready to compile it. First you have to choose a j2me library too use when building , here I'm using the Sun WTK 2.2 library files , the files I'll be using are " midpapi20.jar;cldcapi11.jar;jsr082.jar;wma20.jar ". So you have to give those with the -bootclasspath switch when compiling the files.
create 2 folders " classes " and " tempclasses " , and run this line
" javac -g:none -d tmpclasses -bootclasspath C:\WTK22\lib\midpapi20.jar;C:\WTK22\lib\cldcapi11.jar;C:\WTK22\lib\jsr082.jar;C:\WTK22\lib\wma20.jar -classpath tmpclasses src\javax\xml\*.java src\javax\xml\namespace\*.java src\javax\xml\parsers\*.java src\javax\microedition\xml\rpc\*.java src\javax\xml\rpc\*.java src\javax\xml\stream\*.java src\dk\iter\www\webservices\calculator_asmx\*.java src\java\rmi\*.java src\org\apache\mirae\io\*.java src\org\apache\mirae\j2me\xml\*.java src\org\apache\mirae\j2me\xml\sax\*.java src\org\apache\mirae\stax\*.java src\org\apache\mirae\stax\util\*.java src\org\apache\mirae\transport\*.java src\org\apache\mirae\util\*.java src\org\apache\mirae\ws\*.java src\org\apache\mirae\ws\util\*.java src\org\xml\sax\*.java src\org\xml\sax\helpers\*.java src\org\laf\addservice\*.java ".
At the end of the line give rest of the files that needed to be compiled.
So with this command the mirea source and your files will be compiled, and then for the next step that's to obfuscate the classes.
*** Step 4: Obfuscating. ***
Here my greatest need to obfuscate the classes is becouse the Mirae source code have classes that are in the java system packages like " java and javax " , and this is not allowed in most of the j2me devices and emulators. So to work around that problem we have obfuscate the classes so the names of the full package and class names will be changed, and also the obfuscation reduces the size of the classes by a considerable amount. The obfuscator I've choosen is RetroGuard. To obfuscate in the Sun WTK or EclipseME should have Proguard to do that , but that doesn't change the names of the package names only the class names ( this is to be changed in Proguard 4, still not released ) , so RetroGuard is my only option. This is the reason I'm doing all this on the command line. To obfucate with retroguard you need a jar file to do that , so we have to jar up the class files we've built , you can do that with this command.
jar cmf Manifest.mf temp.jar -C tmpclasses .
After that we obfuscate temp.jar
set classpath=C:\WTK22\lib\midpapi20.jar;C:\WTK22\lib\cldcapi11.jar;C:\WTK22\lib\jsr082.jar;C:\WTK22\lib\wma11.jar;C:\retroguard-v2.2.0\retroguard.jar; java RetroGuard temp.jar temp2.jar script.rgs
Change the classpath according to your settings.
Here the script.rgs contains the classes that's to be excluded from obfuscating , that's cos we have to give the proper name of the main midlet class in the " MANIFEST.MF " , so we only leave that class.
So after obfuscating we extract the class files in that to get it ready for preverifying.
del tmpclasses\** /S /Q /F cd tmpclasses jar xf ..\temp2.jar cd ..
*** Step 5: Preverifying. ***
Preverifying is done by this command ,
C:\WTK22\bin\preverify -classpath C:\WTK22\lib\midpapi20.jar;C:\WTK22\lib\cldcapi11.jar;C:\WTK22\lib\jsr082.jar;C:\WTK22\lib\wma11.jar; -d classes tmpclasses
( set the suitable classpath ).
Now the next final step is to make the final jar file.
*** Step 6: Final jar file ***
To make the jar; run ,
jar cmf Manifest.mf MiraeAdd.jar -C classes . -C res .
So here it'll create " MiraeAdd.jar ".
*** Step 7: Run it. ***
After that get a suitable emulator and run it , I used the nokia 6230i emulator.
That's it to making a simple web service client with Mirae, it's easy to get all those commands into batch file and run it when needed. There's a " make.bat " in the " MiraeAdd " project that I used to make myn , so you can modify it and use it.
How to use protocols other than HTTP
This is the part that I made , I developed a MMS and a Bluetooth transport handler. From those 2 you can send web services request by mms messages or through bluetooth.
In Mirea the protocol handlers are choosen by looking at the url pattern , for example if the the url starts with " http:// " then HTTP handler will be used , and if it starts with " mms:// " then MMS handler and at last if " bt:// " is used that means the Bluetooth handler will be used.
When using the mms transport handler the end point is resolved using the url and the soap_action attributes , for example the url = " mms://+9477234124 " soap_action = " webservice_name ", so when given like this mirae will create a MMS message with the destination " +9477234124 " and with the message subject " webservice_name ". And also the default application id used is " WS_MMS " , this is like the port in HTTP protocol. The recipient of the MMS message will get this and look at the subject field and invoke the correct web service and return the result as a MMS message. So to send via the MMS protocol we must edit the client stubs and change the endpoint url and the soap_action to the suitable value.
In Bluetooth there's a concept called a service, and there's a specific service id for every bluetooth service. In the protocol handler this service is directly mapped to a service in Mirae. The service id is a 128 bit number which is represented by hexadecimal numbers. And also there can be several services active in one device. Mirae activates the Bluetooth protocol handler when the url starts with " bt://" , an example of a url will be " bt://ab54f92ce871 " , the " ab54f92ce871 " is the service id that's used to recognize the service. So what will happen is when some one wanted to create a service available via bluetooth he'll create a bluetooth service with the id , let's " ab54f92ce871 " and keep it running. So then the client , which is the mirae client will invoke a service through the stub which had the endpoint url as " bt://ab54f92ce871 ", when that happens mirae searches near by bluetooth devices for services with that service id , if it finds one , it'll send the soap request throught established data stream, this works same as the streams used in http.
I've created a proxy server called " KProxyServer" , which works in a j2me device that can be used to try out the above 2 protocol handlers, it maps mms and bluetooth services to http web services. You can get the project from here, " http://www.box.net/public/ma663v8psx ".
For more info about my work look at " http://wiki.apache.org/general/AnjanaFernando/GSoC2006Work ".