Università degli Studi di Modena e Reggio Emilia Facoltà di Ingegneria – Reggio Emilia CORSO DI TECNOLOGIE E APPLICAZIONI WEB Java 2 Micro Edition (J2ME) Ing. Marco Mamei J2ME Introduzione Il linguaggio di programmazione Java rappresenta una piattaforma ideale per lo sviluppo di applicazioni. Per coprire al meglio le esigenze di diversi scenari, la Sun (la ditta alla base di Java) offre diverse “versioni” della piattaforma Java: • J2SE (Standard Edition) è la piattaforma di riferimento per lo sviluppo di applicazioni desktop (scenario obsoleto???) • J2EE (Enterprise Edition) è la piattaforma di riferimento per le applicazioni Web. Da notare che Tomcat, JSP, etc. fanno parte di J2EE • J2ME (Micro Edition) è la piattaforma di riferimento per applicazioni embedded (es. Cellulari, palmari, ma anche giocattoli ed elettrodomestici). I vantaggi (e gli svantaggi) di Java per quanto riguarda J2ME si accentuano: • La portabilità del codice diventa ancora più importante che per le applicazioni desktop e server – perchè aumenta l’eterogeneità dell’hardware. • Le applicazioni embedded tendono ad essere molto complicate. Quindi è le caratteristiche di java come linguaggio di programmazione pulito e potente sono molto utili • Si sta imponendo come standard (quasi tutti i cellulari offrono J2ME) • Problemi di performance (sia velocità che occupazione di memoria) Struttura J2ME La struttura J2ME nel suo complesso è abbastanza complicata e modulare. Questo perché gli scenari hardware J2ME sono molteplici e molto diversi tra loro (es. da un computer palmare a un giocattolo di ultima generazione). Per questo motivo J2ME si compone si compone di due parti separate: • Configurations • Profiles Una Configuration è un’infrastruttura per eseguire programmi Java in una certa classe di dispositivi. Fondamentalmente si compone di una Java Virtual Machine ottimizzata per quella classe di dispositivi. Allo stato attuale esistono solo 2 configuration: • CLDC (Connected Limited Device Configuration) che si basa sulla KVM ( Kilo Virtual Machine). Questa è la configurazione presente in quasi tutti i cellulari moderni • CLC (Connected Device Configuration) che si basa sulla CVM (Compact Virtual Machine). Questa è la configurazione presente sui palmari, il SonyEricsson P9000 e il Nokia Communicator I Profiles sono componenti aggiuntivi (delle specie di librerie – package java) che offrono strumenti e funzionalità evolute. Allo stato attuale sono disponibili diversi profiles, ma il più usato in assoluto e montato su tutti i cellulari che offrono CLDC è: • MIDP (Mobile Information Device Profile -- 1.0 e 2.0) In questa lezione ci occuperemo di CLDC-MIDP 1.0 MIDlet Le applicazioni che realizzo con il pacchetto MIDP si chiamano MIDlet. Sono applicazioni simili alle Applet, ma eseguono su un cellulare anziché in un browser. Vediamo subito un esempio di codice: import javax.microedition.lcdui.*; import javax.microedition.midlet.*; // notare extends MIDlet e implements CommandListener. // E’ come extends JApplet implements ActionListener public class HelloMIDlet extends MIDlet implements CommandListener { private Form mMainForm; public HelloMIDlet() { mMainForm = new Form("HelloMIDlet"); mMainForm.append(new StringItem(null, "Hello, MIDP!")); mMainForm.addCommand(new Command("Exit", Command.EXIT, 0)); mMainForm.setCommandListener(this); } public void startApp() { Display.getDisplay(this).setCurrent(mMainForm); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable s) { notifyDestroyed(); } } Notare che si tratta di un esempio di applicazione managed (senza main). MIDlet Una MIDlet rispecchia il seguente ciclo di vita. Midlet Life Cycle I metodi startApp(), pauseApp(), destroyApp() sono definiti nella classe astratta MIDlet e devono essere implementati a livello di sottoclasse. Oltre ai metodi sopraccitati, le Midlet devono essere provviste di un sistema di gestione di eventi che si costruisce in modo analogo a quanto visto per Java Swing. mMainForm.addCommand(new Command("Exit", Command.EXIT, 0)); mMainForm.setCommandListener(this); un Command è un tasto (tipo JButton) che compare sullo schermo. Il setCommandListener sottoscrive un oggetto (di tipo CommandListener) a reagire al pulsante. Notare che, a differenza di Java Swing, non si associa l’oggeto al singolo pulsante ma a tutta la finestra. public void commandAction(Command c, Displayable s) { notifyDestroyed(); } Il metodo commandAction (che deve essere definito da un oggetto che implementa CommandListener) permette di reagire all’evento. Il tutto è simile all’actionPerformed di Java Swing. L’oggetto Command c, permette di discriminare tra diversi comandi, proprio come ActionEvent in Java Swing MIDP Development This lecture contains everything you need to know to get started developing in the Java 2 Platform, Micro Edition (J2ME) environment. You'll learn how to install the development tools, how to write your first J2ME application, how to build it, and how to test the application in an emulator. The application you'll build, a MIDlet, runs on implementations of the Mobile Information Device Profile, one of the J2ME specifications. (For a background on wireless Java technology, read Introduction to Wireless.) What You Need You have lots of choices for a MIDP development environment. In this lecture you'll use Sun's J2ME Wireless Toolkit, which is both free and lightweight. The J2ME Wireless Toolkit can be integrated into IDEs but it can also run standalone, which is how I'll describe it in this lecture. Installing the J2ME Wireless Toolkit The next step is to install the J2ME Wireless Toolkit, a set of tools that make it easy to build and test MIDP applications. (You can think of the toolkit as a miniature IDE; it automates several of the tasks related to building MIDP applications.) Begin by downloading the J2ME Wireless Toolkit from http://java.sun.com/products/j2mewtoolkit/ . Execute the installation file. The installer tries to locate your J2SE SDK; if it's having trouble, make sure you are pointing it to the directory where you installed the J2SE SDK. You will also need to specify whether the toolkit will run by itself (standalone) or be integrated with an IDE. This lecture assumes you will be running the toolkit in standalone mode. The files for the toolkit will go into c:\WTK22 unless you specify a different directory, and the installer creates shortcuts for various parts of the toolkit. To run the toolkit itself, select the KToolbar shortcut. You should see the following screen. Opening screen of the J2ME Wireless Toolkit The J2ME Wireless Toolkit works with projects, where the end result of each project is one MIDlet suite. The toolkit works with one project at a time. You can change properties of the current project, build the project, and run the project in a device emulator. Several example projects come installed with the toolkit; we'll look at these later. Let's jump right in the water by creating a new project. Click on New Project in the button bar. The toolkit prompts you for a project name and the name of a MIDlet class in the project. Fill in HelloSuite and HelloMIDlet as shown below. Creating a new project Once you fill in the project name and first MIDlet name, the toolkit gives you a chance to edit the project settings. Just accept the defaults for now; press OK to finish creating the new project. In the text output pane of the J2ME Wireless Toolkit, you'll see several helpful messages telling you where to store the project's source files. The toolkit stores each project in a subdirectory of the apps directory. The name of the subdirectory is the same as the name of the project. Here, the toolkit has created a new directory, c:\WTK22\apps\HelloSuite. Each project subdirectory has a standard structure: Project directory structure The bin directory contains the compiled MIDlet suite (a .jar file) and the MIDlet suite descriptor (a .jad file). The lib directory is the location for any additional JAR files you would like to include in your project. res is the location for resource files, like images or text files, that should be bundled with your MIDlet suite. Finally, the src directory is the place where your source code should be saved. The standard rules about packages and directories apply; for example, source code for a users.Root class would go in src/users/Root.java. Create a MIDlet To get you started with MIDlet development, let's write a simple MIDlet. Once you've chosen a text editor, type or cut-and-paste the code reported at the beginning. Save this code as HelloMIDlet.java in the src directory of your project. On my computer, this file is saved in c:\WTK22\apps\HelloSuite\src\HelloMIDlet.java. Next, press the Build button in KToolbar. The toolkit will attempt to compile your project. If there are any compiler errors, you'll see them in the text output area of KToolbar. Fix the errors until the project builds successfully. Now you're ready to test your MIDlet suite. Click on the Run button. You should see a mobile phone emulator pop up: HelloSuite running on the emulator The emulator is showing a list of MIDlets in the MIDlet suite. This example shows only one MIDlet. Although the name you see here is HelloSuite, the class that will be run is HelloMIDlet. To see where this mapping occurs, go to KToolbar and select Settings.... Then click on the MIDlets tab to see a list of the MIDlets in the project. Back in the emulator, click on the soft button below Launch to start up the MIDlet. It will display a simple screen like the one below. Click on Exit to leave the MIDlet. Close the emulator window or hit the Escape key to end the emulator session. HelloMIDlet running on the emulator The emulator you've just used is the DefaultColorPhone. The J2ME Wireless Toolkit has other emulators as well. Try running HelloMIDlet on some other devices to see how the user interface adapts. Simply select the emulator you'd like in the combo box in KToolbar, then click on Run again. A Quick Look Under the Hood Now that you've had some fun, let's take a step back and talk about what it is that the J2ME Wireless Toolkit does for you. None of it is too complicated, but the toolkit takes several potentially aggravating steps and condenses them into a single button push. First, what happens when you press the Build button? The toolkit finds all the .java files in the src directory of your project and compiles them. This is no ordinary compilation, however, because the source files must be compiled in a MIDP environment rather than a J2SE environment. To understand this departure, think of a MIDlet that uses the java.lang.System class. This class has different APIs in J2SE and MIDP. When the toolkit compiles your MIDlet class, you want it to use the MIDP java.lang.System, not the J2SE version of the class. You could make this selection yourself, using the command javac and the bootclasspath option, but it's much simpler just to let the toolkit worry about it. Beyond compilation, MIDP classes must be preverified before they can be run on a MIDP device. You may recall that J2SE has a bytecode verifier that checks .class files before they are loaded. In the MIDP world, verification is split into two phases. The toolkit performs an initial verification at build time, then the device's runtime system performs a second verification when it loads the classes. You could perform the first verification yourself using the command line preverify tool, but it's much easier to leave this detail to the toolkit. Finally, MIDlets are bundled into MIDlet suites for distribution to actual devices. This process entails JARing the MIDlet suite class files and the resource files, and putting some extra information in the JAR manifest. Again, these chores are best left to the J2ME Wireless Toolkit. To bundle up your MIDlet suite, select Project | Package from the menu. The .jad and .jar files for the MIDlet suite will be generated and placed in the bin directory of the project. Hooking Up a MIDlet to a JSP The real power of MIDlet applications comes from the possibility of using them to access remote HTTP services. We already know how to program HTTP services via JSP. It’s time to have a MIDlet connect to the JSP. Start KToolbar (part of the J2ME Wireless Toolkit) and create a new MIDlet project with the code shown below. Then create a suitable – i.e., simple – JSP. import java.io.*; import javax.microedition.io.*; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class HitMIDlet extends MIDlet implements CommandListener { private Display mDisplay; private Form mMainForm; private StringItem mMessageItem; private Command mExitCommand, mConnectCommand; public HitMIDlet() { mMainForm = new Form("HitMIDlet"); mMessageItem = new StringItem(null, ""); mExitCommand = new Command("Exit", Command.EXIT, 0); mConnectCommand = new Command("Connect", Command.SCREEN, 0); mMainForm.append(mMessageItem); mMainForm.addCommand(mExitCommand); mMainForm.addCommand(mConnectCommand); mMainForm.setCommandListener(this); } public void startApp() { mDisplay = Display.getDisplay(this); mDisplay.setCurrent(mMainForm); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable s) { if (c == mExitCommand) notifyDestroyed(); else if (c == mConnectCommand) { Form waitForm = new Form("Waiting..."); mDisplay.setCurrent(waitForm); Thread t = new Thread() { public void run() { connect(); } }; t.start(); } } private void connect() { HttpConnection hc = null; InputStream in = null; String url = "http://localhost:8080/midp/index.jsp"; try { hc = (HttpConnection)Connector.open(url); in = hc.openInputStream(); int contentLength = (int)hc.getLength(); byte[] raw = new byte[contentLength]; int length = in.read(raw); in.close(); hc.close(); // Show the response to the user. String s = new String(raw, 0, length); mMessageItem.setText(s); } catch (IOException ioe) { mMessageItem.setText(ioe.toString()); } mDisplay.setCurrent(mMainForm); } } The main screen of HitMIDlet is similar to HelloMIDlet, but it includes two commands, Exit and Connect. Connect sets up a separate thread and calls the connect() method, which takes care of making a network connection and retrieving the results. Now, in the J2ME Wireless Toolkit, click on Build to build the project. Assuming you don't see any error messages, you are now ready to test the application. Make sure your server is running first. Then click on Run and select HitMIDlet. Select the Connect command. If everything goes well, HitMIDlet will invoke HitServlet and display the results on the device emulator screen: HitMIDlet running on the emulator OTA (Over The Air) MIDlet Provisioning The J2ME Wireless Toolkit is a powerful tool to develop and test MIDlets, but how to upload them into real phones?? Some phones can be connected to computers and the phone manufacturer provides suitable software to install .jad and .jar files on the phone. Alternatively, OTA MIDlet provisioning is a powerful protocol to install them over the network. Test OTA with Tomcat is very simple! You have to create a web application with the following index.html <html> <head> <title>Test</title> </head> <body> <a href="http://155.185.200.64/mob/ImageMove.jad">Install Midlet</a> </body> </html> File index.html The web application directory contains (at the top level) the .jad and .jar files of your midlet. Then you have to change the web.xml file in WEB-INF to let it contain the following lines. <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- JAD file --> <mime-mapping> <extension>jad</extension> <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type> </mime-mapping> <!--JAR file --> <mime-mapping> <extension>jar</extension> <mime-type>application/java-archive</mime-type> </mime-mapping> </web-app> File web.xml At last it is important to change the JAD file (you can open it with any text editor) so that the MIDlet-Jar-URL is a complete URL MIDlet-Jar-URL: http://155.185.200.64/mob/ImageMove.jar Now simply use the phone browser to access the index.html page. Follow the link and the MIDlet should install.