TSM - Aplicaţii IoT cu Java ME Embedded 8 şi Eclipse

Dănuţ Chindriş - Java Developer

Aplicaţiile Java ME Embedded 8, în forma lor cea mai simplă, sunt uşor de configurat şi gestionat, aşa cum am văzut în articolul din numărul precedent al revistei Today Software Magazine. Totuşi, în cadrul proiectelor software moderne avem nevoie de unelte care să automatizeze anumiţi paşi, să ne atenţioneze atunci când suntem pe punctul de a introduce erori de programare în codul sursă, cu alte cuvinte, să ne sporească productivitatea.

La momentul scrierii acestui material, Oracle oferă suport pentru două dintre cele mai cunoscute medii integrate de dezvoltare, Eclipse şi NetBeans. În acest articol vom discuta despre uneltele pe care le avem la dispoziţie folosind Eclipse, întrucât acest IDE se bucură de un număr mai mare de utilizatori, după cum arată unele surse. Astfel, similar articolului precedent, vom arăta care sunt pachetele software pe care trebuie să le instalăm şi cum putem crea o aplicaţie Java ME Embedded 8 cu Eclipse.

Tooling pentru aplicaţii ME cu Eclipse - Plugin-uri necesare

Pentru a putea urmări paşii prezentaţi în acest articol, avem nevoie, în primul rând, de Oracle Java ME SDK 8.1, pachet software prezentat în articolul Aplicații IoT cu Java ME Embedded 8. De aceea, încurajăm cititorii să răsfoiască numărul 36 al revistei, pentru a afla mai multe despre acest . Pentru a putea beneficia de toate funcţionalităţile pe care Oracle Java ME SDK 8.1 ni le pune la dispoziţie, următorul lucru pe care trebuie să-l facem este să instalăm -urile Java ME SDK Tools. În plus, Oracle ne oferă o serie de proiecte demonstrative, distribuite cu ajutorul plugin-ului Java ME SDK Demos. Aceste pachete pe care tocmai le-am amintit depind de extensia ce poartă numele Mobile Tools for Java sau, pe scurt, MTJ. În mod normal, MTJ se instalează automat împreună cu plugin-urile Java ME SDK Tools, însă în cazul în care acest lucru nu se întâmplă, putem adăuga manual această extensie distribuţiei noastre Eclipse, prin intermediul opţiunii Install New Software din cadrul meniului Help. Mai multe detalii despre instalarea acestor unelte, dar şi despre instalarea Eclipse, putem găsi în documentul Oracle Java Micro Edition Software Development Kit, Developer's Guide.

Crearea unui proiect

O dată ce au fost instalate plugin-urile Java ME SDK Tools şi extensiile MTJ, putem accesa perspectiva Java ME, care ne întâmpină cu o pagină de bun venit, ilustrată în următoarea captură de ecran:

Pagina de bun venit a perspectivei Java ME

Eclipse împreună cu MTJ ne oferă câteva şabloane, care ne ajută să creăm mai rapid proiecte Java ME şi componente ale acestora. Acest lucru este demonstrat în figura următoare:

Şabloane disponibile pentru dezvoltarea aplicaţiilor Java ME

În continuare, dorim să creăm un proiect simplu cu ajutorul noilor unelte pe care tocmai le-am instalat. Pentru aceasta, alegem opţiunea Java ME Project din fereastra de tip dialog Select a wizard. Apăsând Next, ajungem la fereastra în care ni se cere să introducem un nume pentru proiectul nostru. Pentru acest exemplu ne vom folosi de codul listat şi discutat în documentul Oracle Java ME Embedded, Developer's Guide, capitolul General Purpose Input/Output. Acest exemplu ne arată cum putem accesa pinii GPIO (General Purpose Input/Output) ai unei plăcuţe de dezvoltare. La fel ca în articolul precedent, vom folosi un dispozitiv Raspberry PI Model B+.

Revenind la paşii pe care trebuie să-i urmăm pentru a crea un astfel de proiect cu Eclipse şi MTJ, introducem în câmpul Project name numele LEDSwitcher, întrucât dorim să realizăm o aplicaţie care să deschidă şi să închidă un LED (Light-emitting diode), o dată la câteva secunde. Aceeaşi fereastră ne permite să dăm un alt nume fişierului JAD (Java Application Descriptor) şi să facem alte configurări legate de proiectul Eclipse. O dată ce am dat un nume proiectului nostru, mediul de dezvoltare ne avertizează că trebuie să alegem cel puţin o configuraţie pe care va fi rulată aplicaţia. Astfel, apăsăm butonul Add... din partea mediană a ferestrei şi ni se prezintă un alt dialog, cu titlul Add Configuration. Din meniul drop-down SDK alegem Oracle Java(TM) Platform Micro Edition SDK 8.1, iar Eclipse completează automat câmpurile Configuration Name şi Device cu valoarea EmbeddedDevice1. Apăsăm butonul Finish pentru a reveni la dialogul anterior. În acest moment putem apăsa Finish în dialogul New Java ME Project deoarece vom accepta valorile prestabilite propuse de IDE.

Imediat ce proiectul a fost creat, Eclipse deschide un editor, care ne permite să edităm proprietăţi ce ţin de Application Descriptor, dar şi să facem alte configurări. Vedem acest editor ilustrat în figura următoare:

Privire de ansamblu asupra configuraţiei proiectului

Accesarea pinilor GPIO

Este timpul să prezentăm codul sursă care accesează pinii GPIO şi, pentru aceasta, creăm o clasă LEDSwitcher, care extinde clasa abstractă javax.microedition.midlet.MIDlet. În cele ce urmează, prezentăm codul sursă al acestei clase, iar apoi vom analiza câteva aspecte importante:

package ro.leje;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.midlet.MIDlet;
import jdk.dio.DeviceManager;
import jdk.dio.gpio.GPIOPin;
public class LEDSwitcher extends MIDlet {
    private static final int PIN_NUMBER = 7;
    private static final int SLEEP_TIME_MILLIS = 2000;
    private GPIOPin pin;

    public void startApp() {
        try {
            pin = DeviceManager.open(PIN_NUMBER);
            Thread.sleep(SLEEP_TIME_MILLIS);
            for (int i = 0; i < 20; i++) {
            System.out.println("Setting pin to"+ 
        "true");

        pin.setValue(true);
                Thread.sleep(SLEEP_TIME_MILLIS);
                System.out.println("Setting pin to"+
         "false");

        pin.setValue(false);
                Thread.sleep(SLEEP_TIME_MILLIS);
 }
        } catch (IOException e) {
       Logger.getLogger(LEDSwitcher.class.getName()).
                log(Level.SEVERE, null, e);
        } catch (InterruptedException e) {
       Logger.getLogger(LEDSwitcher.class.getName()).
                log(Level.SEVERE, null, e);
        }
    }
    public void destroyApp(boolean unconditional) {
        try {
            if (pin != null) {
                pin.close();
            }
        } catch (IOException e) {
       Logger.getLogger(LEDSwitcher.class.getName()).
                log(Level.SEVERE, null, e);
        }
    }
}

Cu ajutorul clasei DeviceManager, care oferă servicii de gestionare a dispozitivelor de tip Device, deschidem pinul GPIO cu numărul 7 al plăcuţei noastre Raspberry PI. Acesta este referit prin variabila pin de tip GPIOPin, căreia putem să-i setăm valoarea ca true sau false, reprezentând stările de high şi low. În metoda startApp()alternăm aceste stări de douăzeci de ori, făcând pauză de două secunde la fiecare iteraţie. În cadrul metodei destroyApp()eliberăm resursele folosite, respectiv închidem dispozitivul ce reprezintă pinul GPIO.

Dorim acum să testăm aplicaţia LEDSwitcher dar, pentru a face lucrurile mai interesante, vom încerca să o instalăm pe dispozitivul Raspberry PI. Aşa cum am văzut în articolul la care am făcut referire mai sus, trebuie să lansăm în execuţie mediul Java ME şi putem face acest lucru conectându-ne la plăcuţă prin SSH. O dată ce am făcut acest lucru rulând scriptul usertest.sh, înregistrăm dispozitivul cu ajutorul utilitarului Device Manager pe care ni-l pune la dispoziţie SDK-ul. Faptul că RPi este înregistrat se reflectă şi în view-ul Device Selector pe care perspectiva Java ME l-a deschis automat:

View-ul Device Selector

Acum putem apăsa click-dreapta pe elementul ce reprezintă plăcuţa RPi, şi să alegem din meniul de context Run Project şi apoi numele proiectului nostru. Platforma deschide aplicaţia Java ME Embedded Emulator şi instalează aplicaţia, încercând să o pornească. În acest moment observăm că aplicaţia emulator afişează o fereastră pop-up, care ne avertizează că lansarea aplicaţiei a eşuat. Pentru a afla cauza, putem fie să analizăm view-ul Console din IDE, fie terminalul PuTTY. Amândouă ne arată că s-a aruncat o excepţie java.security.AccessControlException atunci când am încercat să deschidem dispozitivul de tip GPIOPin. De asemenea, log-ul ne oferă o informaţie importantă, prin mesajul

[CRITICAL] [SECURITY] iso=2:Permission check failed: jdk.dio.DeviceMgmtPermission "GPIO7:7" "open"

În primul articol din această serie am amintit faptul că securitatea este unul dintre cele mai importante aspecte ale creării aplicaţiilor IoT. Java ME Embedded 8 ia în serios acest lucru şi implementează mecanisme moderne pentru a asigura un nivel de securitate ridicat. Astfel, pentru a accesa pinul plăcuţei trebuie să permitem acest lucru setând permisiunea jdk.dio.DeviceMgmtPermission pentru dispozitivul GPIO7:7, cu acţiunea open.

Eclipse ne pune la dispoziţie tab-ul Security al editorului despre care am amintit mai devreme unde, în cadrul secţiunii Required Permissions, putem adăuga permisiuni, apăsând butonul Add.... Acest pas este ilustrat în următoarea captură de ecran:

Adăugarea unei permisiuni

Salvăm modificările, care se reflectă în descriptorul aplicaţiei, LEDSwitcher.jad, şi lansăm aplicaţia în execuţie, folosind acelaşi mecanism. De data aceasta, observăm că aplicaţia rulează fără probleme.

Mesajele scrise de aplicaţie în consolă

Dacă realizăm montajul folosind un LED, o rezistenţă, un breadboard şi doi conectori, obţinem configuraţia prezentată în imaginea de mai jos. Vedem, de asemenea, că LED-ul s-a aprins atunci când valoarea pinului a fost setată la true.

Montajul folosind plăcuţa Raspberry

Debugging cu Eclipse

Una dintre cele mai importante activităţi implicate în dezvoltarea produselor software este cea de debugging. Cu siguranţă,
fiecare inginer software care foloseşte mediul de dezvoltare Eclipse a intrat în contact cu uneltele de debugging consacrate pe care acesta ni le pune la dispoziţie.

Şi în cazul aplicaţiilor Java ME Embedded 8 putem folosi perspectiva Debug, împreună cu toate view-urile cunoscute. Este interesant faptul că putem face debugging chiar şi atunci când rulăm aplicaţia pe dispozitivul real și nu suntem obligaţi să o instalăm pe un dispozitiv emulat. Folosind fereastra de tip dialog Debug Configurations putem seta diverşi parametri, cum ar fi dispozitivul pe care dorim să rulăm aplicaţia, care este MIDlet-ul ce trebuie executat etc. .Stabilind breakpoint-uri în codul sursă şi lansând aplicaţia în modul debug, execuţia se va opri la liniile pe care dorim să le investigăm.

Concluzii

Dezvoltarea aplicaţiilor IoT utilizând platforma Java ME Embedded 8 este alcătuită dintr-un complex de activităţi care aparţin mai multor discipline, printre care se numără alături de ingineria software şi electronica. Realizând care este complexitatea unei astfel de configuraţii, care implică hardware diferit de maşina pe care se face dezvoltarea, putem să ne dăm seama de beneficiile multiple pe care le aduce o platformă cum este SDK-ul, dar şi uneltele de dezvoltare precum Eclipse sau NetBeans.