Raspberry Pi и чашечку Java, пожалуйста! (Часть 1)

  • Tutorial

Данная статья перевод с английского статьи Vladimir Alarcón и Nathaniel Monson «A Pi and a cup of Java, please!» вышедшей в 14 номере журнала MagPi. Эта статья является первой в цикле статей посвящённых описанию практических основ программирования на Java использую Raspberry Pi.

Что вам необходимо:
  • Raspberry Pi и ОС Raspbian.
  • 150 Мб свободного места на SD карте.
  • Базовые знания программирования.
  • Базовые навыки использования командной строки.


Вступление



В данной статье я расскажу вам как писать и запускать Java программы на вашем Raspberry Pi.

Java — это объектно-ориентированный язык программирования, транслирующий исходный код программ в байт-код, для запуска их независимо от операционной системы и без необходимости перекомпилляции. Также в Java входит широкий спектр технологий предназначенных для решением задач в таких областях, как запуск кластеров веб-сайтов или высоконагруженных приложений критичных к результату выполнения. В данной статье я затрону только основы данного языка. Как только вы узнаете его основы, вы без труда найдёте в Интернет веб-сайты с более подробным описанием технологий Java и содержащие более сложные примеры по ним.

В начале я покажу, как установить Java на Raspberry Pi. Затем мы создадим пару простых Java программ… И только потом мы их запустим! В первой части статьи вы в общем узнаете как запустить примеры, а затем более подробно я разъясню принципы их работы. Идея в том, что это позволит вам легче увидеть основы написания реальных Java программ, а затем самостоятельно вы сможете попробовать создать для них новые элементы и задать необходимый функционал. Как это можно сделать, я постараюсь объяснить после того, как вы напишите и запустите первую свою программу.

1. Установка



Чтобы написать, копиллировать и запустить программу вам необходимо две вещи: текстовый редактор и JDK. Вы можете использовать любой текстовый редактор для написания Java программ. Я предпочитаю Geany, так как он поддерживает подсветку синтаксиса, но Leafpad или GEdit это тоже делают. В качестве JDK я выбрал OpenJDK 7. Стандартно в пакет JDK входит компиллятор и виртуальная машина Java(JVM). Компиллятор генерирует из исходного кода программы для выполнения, а JVM обеспечивает их запуск.

Установим Geany и OpenJDK 7 открыв окно терминала и набрав:

  sudo apt-get install -y openjdk-7-jdk geany


Это займёт около 9 минут на загрузку и установку всех необходимых пакетов, но это может занять и больше времени, так как всё зависит от скорости вашего интернет соединения.

После завершения проверьте, что всё корректно было установлено. Для этого вы можете открыть Geany из вкладки «Programming» основного меню Raspbian. А для проверки OpenJDK 7, откройте окно терминала и наберите:

  java -version


На экране должно появится несколько строк начинающихся с:

  java version "1.7...
  OpenJDK ...


2. Запуск первой программы



Начнём с создания каталога для хранения наших программ. Я выбрал для него имя «cupofjava», но вы можете по желанию выбрать любое другое. Открываем окно терминала и набираем:

  mkdir cupofjava


Теперь начнём писать нашу первую программу(класс) на Java. Я назову его «HiThere». Пожалуйста помните, что Java, это объектно-ориентированный язык программирования, и что каждая программа является классом, который в свою очередь можно использовать другими классами.

Открываем текстовый редактор(в моём случае Geany) для создания файла HiThere.java и сохраняем его в предварительно созданном каталоге. В этом файле набираем(или копируем) следующий исходный код программы:

public class HiThere {

  public static void main(String[] args) {
    System.out.println("A Java Pi!");
  }

}


А теперь компилируем его. Используя окно терминала переходим в каталог «cupofjava», где до этого вы создали программу:

  cd cupofjava


и набираем:

  javac HiThere.java


Команда javac компиллирует программы написанные на Java. Она проанализировав набранный вами исходный код генерирует программу для запуска. Через 15 секунд или около того, данная команда закончит выполнение. Если вы допустили ошибку она об этом сообщит, указав где эта проблема возникла. Для исправления вернитесь в текстовый редактор, проверьте свой код и исправьте допущенные ошибки, сохраните файл, и попробуйте запустить компилляцию повторно. Если ошибок больше нет, то компилляция выполнена успешно. После чего вы найдёте новый файл HiThere.class в текущем каталоге. Это программа и будет вами запускаться.

Хорошо, теперь запустим нашу программу. В окне терминала набираем:

  java HiThere


Вам необязательно указывать расширение .class. А в чём разница? Команда javac компиллирует программы, а команда java их запускает.

Программа будет запущена и выполнена:

  Hi there!


Отлично… Поздравляю! Вы написали и запустили вашу первую Java программу на Raspberry Pi.

Наверное вы заметили, что программе потребовалось несколько секунд для того, чтобы написать это сообщение. Почему так долго? На самом деле, Java работает довольно быстро. Программе в целом понадобилось только пара миллисекунд для выполнения, всё остальное время потребовалось на загрузку в начале JVM среды для выполнения Java кода. Но есть и приятная новость, что после загрузки JVM программа будет работать очень быстро.

Ну, а теперь, можем рассмотреть программу более внимательно. В ней по сути выполняется только одна строка. Это строка:

  System.out.println("A Java Pi!");


В остальных строках задаётся название класса «HiThere» (в строке 1), а также название основного метода в строке 3). В данный класс, как и в любой другой класс Java, может входить много методов, но для данного примера мы используем только один основной метод main.

Усложним задачу #1: Ваши действия. Откройте файл с исходным кодом в текстовом редакторе, измените сообщение в кавычках с «A Java Pi!» на «My name is Name.»(введите своё имя) и сохраните результат. В окне терминала снова скомпилируйте программу и запустите её использованными уже командами javac и java. Если всё сделали правильно, то теперь программа покажет ваше имя. Вы отлично справились!


Примечание: Синтаксис(словарь команд и пунктуация) написания программ на языке Java очень похож на синтаксис языка C. Любой программист знакомый с C сможет легко освоит основы Java.


3. Переменные Java и управляющие конструкции



Следующий пример иллюстрирует применение переменных и управляющих конструкций. В том-же каталоге, где мы сохраняли первую программу, создадим вторую программу назвав её DiceRoller.java. Наберите(или скопируйте) приведённый ниже исходный код:

import java.util.Random;

public class DiceRoller {

  public static void main(String[] args) {
    Random generator = new Random();
    int d = 0;

    while (d < 4) {
      System.out.print("Rolling... ");
      int face = 1 + generator.nextInt(6);
      System.out.print("I got a "+ face
        + ".  ");
      if (face == 1) {
        System.out.print("Wow! An ACE!");
      }
      System.out.println();
      d = d + 1;
    }
  }

}


Сохраним его в файле. Скомпиллируем и запустим нашу новую программу набрав две команды:

  javac DiceRoller.java
  java DiceRoller


Вы увидите что-то подобное:

Rolling... I got a 2.
Rolling... I got a 1.  Wow! An ACE!
Rolling... I got a 4.
Rolling... I got a 5.


Программа будет бросать четыре кубика и тот на котором выпадет единица победит. Вам интересно узнать, как это работает?

На данном примере можно продемонстрировать несколько интересных вещей. Эта программа использует две переменные d и face. Переменная d применяется когда мы делаем только четыре броска, не три и не пять, а переменная face запоминает какое значение было получено при каждом из бросков. Также программа получает набор строк в переменной args. Эта переменная передаёт параметры командной строки, если вы их задали, но в нашем примере их нет.

И ещё, помните классы Java могут использовать другие классы? В нашем примере это переменная generator. Через неё наша программа обращается к внешнему классу Random, который выполняет генерацию псевдослучайных чисел. В нашем случае мы вызываем только один из его методов nextInt() для получения случайного числа в диапазоне от 0 до 5.

Дополнительно в Java применяются фигурные скобки { и } определяющие область действия команд вызываемых в блоках. Каждый блок может быть пустой или содержать от одной и более команд. Если это необходимо, вы можете, используя управляющие конструкции, выделять подблоки внутри существующих блоков.

А теперь можно поговорить и об этом. В данном примере используются две управляющие конструкции: if и while. Управляющая конструкция if запускает выполнения блока только в случае если логическое выражение в скобках истина(true). А управляющая конструкция while работает наоборот, её блок выполняется до тех пор, пока логическое выражение в скобках не станет ложным(false). Ещё в Java применяются управляющие конструкции: for, do-while, switch, if-else и т.п.

В нашем примере if проверяет истинность выражения face == 1. По этому сообщения о выигрыше появляется только при выпадении единицы.

Управляющая конструкция while запускает свой блок четыре раза пока значение переменной d меньше чем 4. Первоначальное значение этой переменной равно 0 и с каждым циклом выполнения блока оно увеличивается на 1. Поэтому первые четыре раза(0, 1, 2, 3) блок выполняется успешно, и только в пятый раз(когда переменная d равна 4) он будет прерван.

Усложним задачу #2: Измените программу для 7 бросков кубик, увеличив диапазон возможных вариантов значений до 10. В окне терминала снова скомпилируйте программу и запустите её использованными уже командами javac и java. Если всё сделали правильно, то теперь программа покажет значение для 7 бросков кубика. А теперь, за работу!


Примечание переводчика: Исходные коды, сам текст статьи и вёрстку в Scribus вы можете найти в репозитарии github.com/svininykh/magpi-issue14-ru/tree/master/cup-of-java
Поделиться публикацией

Комментарии 41

    +10
    Вот вообще не понял причём тут Raspberry Pi )
      +1
      Whisper words of wisdom: let it be :)
        0
        Согласен, что подойдёт для программирование на любом железе где запустится Java. Но так как это единственные статьи про Java опубликованные в MagPI, решил перевести их, чтобы помочь переводу этого журнала на русский язык.
        +2
        Вот только openjdk на Raspberry PI использовать крайне не рекомендуется. Тормозит и жрёт ресурсы неимоверно. Лучше использовать JDK8 EA от Oracle. Реально в разы быстрее шевелится.
          0
          JDK8 пока только Early Access Releases.
          Так что лучше все таки использовать JDK7
            0
            Вообще планирую на Raspberry Pi запускать Java Embedded Suite, как раз для проверки насколько он требователен к ресурсам. Платформа в нём Java SE Embedded 7.
            0
            Кем не рекомендуется. Вами?
              0
              В том числе и мной. Серьёзные проблемы с производительностью OpenJDK на Raspberry PI, впрочем, известны всякому, кто пытался запускать на ней что-то посерьёзнее Hello World.
                0
                безусловно, JDK8 будет шустрее: три года не прошли даром, технология развивается. но вот openjdk или oracle jdk — совершенно не важно.

                Иное дело, что в Java 8 самой по себе есть compact profiles. а в сборках оракла для Java SE 7 Embedded наверняка есть embedded-версия hotspot. И вот это реально может помочь. Странно, что об этих важнейших фичах Вы забыли.
                  0
                  OpenJDK 8 даже не пробовал, если честно. Я лишь знаю, что OpenJDK 7 загружает процессор в разы (в моём случае — более чем в 5 раз) больше, чем Oracle JDK8. В причинах я не разбирался. Возможно, дело в отсутствии HotSpot. Это не важно, потому что факт остаётся фактом: OpenJDK (актуальную версию) использовать на Raspberry PI невозможно.
                    –1
                    Возможно, дело в отсутствии HotSpot

                    ЩИТО?
                      0
                      А заяснить слабо своё ЩИТО?

                      В OpenJDK на ARM используется JamVM или ZeroVM. В Oracle JDK — HotSpot VM.

                      Я неправ? Тогда проясните. Это же вы вроде в Oracle работаете, а не я.
                        0
                        Судя по вот этой статье, там давно уже HotSpot, причём есть и C2.

                        Иной вопрос, какую VM бандлят в OpenJDK разработчики того или иного дистрибутива Linux под ARM.
                          0
                          Судя по этой статье, HotSpot — в Java SE-Embedded.

                          А в стандартной JavaSE/OpenJDK 7? Судя по всему — нет.

                          В любом случае — это не важно. OpenJDK 7 непригодна для использования на Raspberry Pi.
                            0
                            Ерунда. В стандартной OpenJDK всегда был и есть Hotspot.
                              0
                              Плевать. Всё равно не работает.
                                0
                                $ java -version
                                java version "1.7.0_07"
                                OpenJDK Runtime Environment (IcedTea7 2.3.2) (7u7-2.3.2a-1+rpi1)
                                OpenJDK Zero VM (build 22.0-b10, mixed mode)
                                $ java -hotspot
                                Error: hotspot VM not supported
                                

                                  0
                                  это у вас IcedTea — сборка от RedHat из какого-то дистрибутива. Они какую угодно JVM могут прикрутить.
                                    0
                                    Именно это JDK устанавливается в Raspbian командой

                                    apt-get install openjdk-7-jdk

                                    и именно о ней идёт речь в статье.

                                    Нужна другая сборка? Попробуйте найти и проверить производительность. И не нужно будет теоретизировать.
                                      0
                                      Мало ли кто, что и по каким причинам ставит в родной дистрибутив (тем более, по Вашим словам, оно не работает).

                                      Вот я Вам и говорю: поставьте нормальную сборку вместо родной. Авось полегчает.
                                        0
                                        А я и поставил. И проблему решил. И поделился решением в самом первом посте. Только вам почему-то оно не понравилось. При том, что вы, похоже, Raspberry, в глаза не видели. Ну что же, критикуешь — предлагай. И не надо больше теорий. Только практика.
                                          0
                                          Дык я и предложил: поставить OpenJDK 7. Просто нормальную сборку, а не родную.
                                            0
                                            А вы просто дайте ссылку.
                                              0
                                              Апдейты:

                                              1. Судя по этому комментарию apangin, в Java SE 7 Embedded от Oracle уже давно HotSpot

                                              2. Согласно этой статье, c HotSpot C1 под Paspberry PI всё хорошо, а вот в C2 всё же есть некоторые проблемы.

                                              3. Злые языки говорят, что (вроде как) в OpenJDK под ARM действительно не ставится HotSpot. То ли из лицензионных соображений, то ли из-за того, что Oracle Java SE Embedded под ARM стоит денег и поэтому этот кусок выкладывать в opensource не хотят. Видимо, Вы были правы в этом вопросе, а я поторопился.

                                              4. Судя по вот этому замечанию, c портированием С1/С2 JIT есть сложности в ассемблерной части, поэтому ребята из IcedTea портировали только интерпретатор. Это и есть Zero; название видимо троллит C1 и C2, намекая на C0 :)

                                              5. Согласно комментарию alexbel, для Raspberry PI лучше подойдёт Java ME Embedded, которая сразу оптимизирована для мелких дивайсов.

                                    0
                                    Попробовал установить Oracle Java 7 на Raspberry:

                                    $ sudo apt-get install -y oracle-java7-jdk

                                    Вот результат:

                                    $ java -version
                                    java version «1.7.0_40»
                                    Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
                                    Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)

                                    $ java -hotspot
                                    Error: hotspot VM not supported

                                    Какие-то взаимоисключающие параграфы получаются. Так всё-таки, как узнать есть HotSpot или нет?
                                      0
                                      Это Oracle JDK, а не OpenJDK. В ней-то как раз есть HotSpot.
                                        0
                                        А почему выдаёт «hotspot VM not supported»?
                                          0
                                          А, не увидел. Видимо, старая версия. В более новых вроде бы уже поддерживается.

                                          Вообще, с поддержкой HotSpot для ARM всё не просто. Вроде бы есть сторонняя (не Oracle) реализация, и называется она ZeroVM. Вот тут написано. Но она для IcedTea. Про поддержку в OpenJDK именно для ARM ничего не знаю.
                                            0
                                            Для Java 8 получается во так:
                                            $ /opt/jdk1.8.0/bin/java -version
                                            java version "1.8.0-ea"
                                            Java(TM) SE Runtime Environment (build 1.8.0-ea-b111)
                                            Java HotSpot(TM) Client VM (build 25.0-b53, mixed mode)
                                            
                                            $ /opt/jdk1.8.0/bin/java -hotspot -version
                                            Unrecognized option: -hotspot
                                            Error: Could not create the Java Virtual Machine.
                                            Error: A fatal exception has occurred. Program will exit.
                                            
                                            $ /opt/jdk1.8.0/bin/java -client -version
                                            java version "1.8.0-ea"
                                            Java(TM) SE Runtime Environment (build 1.8.0-ea-b111)
                                            Java HotSpot(TM) Client VM (build 25.0-b53, mixed mode)
                                            
                                            $ /opt/jdk1.8.0/bin/java -server -version
                                            Error occurred during initialization of VM
                                            Server VM is only supported on ARMv7+ VFP
                                            
                                              0
                                              Конечно надо всё замерять. Сейчас установил Tomcat и при использовании Oracle JDK скорость отклика сервлета выше. Хотя сервлет простенький. По потребляемым ресурсам:

                                              3496 tomcat7 20 0 269m 53m 7680 S 0.3 12.3 0:56.24 java
                                              0
                                              Сейчас проверил у себя на Debian

                                              $ java -version
                                              java version «1.7.0_51»
                                              Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
                                              Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

                                              $ java -hotspot
                                              Error: hotspot VM not supported
                +1
                Через apt-get там доступно множество языков — те же scala, clojure. Без IDE (которое Raspbery Pi не потянет) они будут удобнее, чем java.
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Я вот узнал, что в nano есть подсветка синтаксиса Java :)
                  0
                  Java, это язык объектно-ориентированного программирования для запуска исходного кода без необходимости комилляции под конкретную операционную систему.

                  А давно Java программы запускаются из исходного кода?
                    0
                    В оригинале:

                    Java is an object-oriented language designed to run on many operating systems without requiring recompilation of the source code.


                    Буде-ли корректно эту фразу перевести так:

                    Java, это объектно-ориентированный язык программирования, транслирующий исходный код в байт-код для запуска независимо от операционной системы без необходимости перекомпилляции.
                      0
                      Так было бы лучше.
                      Если переводить дословно, получится что-то вроде «Java — это объектно-ориентированный язык программирования, созданный для запуска на разных операционных системах без необходимости перекомпиляции исходного кода.» Правда, так теряется немного смысл (хотя это и не отражено в оригинале), что же будет запускаться на разных ОС? Язык программирования?
                      Если писать коротко, то для большей ясности я бы написал как-нибудь так: «Java — объектно-ориетнированный язык программирования, исходный код которого компилируется в байт-код, который может быть запущен на любой платформе, для которой существует JVM, т.е. нет необходимости компилировать исходный код под целевую платформу». Разумеется, это не поймёт человек, не знающий, что такое JVM :)
                        0
                        Спасибо! Исправил.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое