Настройка окружения для программирования на Java
19 мая 2014
Как ни крути, но Java — популярный язык программирования и программистам довольно часто приходится иметь с ним дело, нравится им это или нет. Причины могут быть разные. Возможно, вы хотите запустить примеры к прочитанной недавно книге. Или вы работаете с софтом, написанном на Java (Cassandra, Voldemort, Hadoop, ZooKeeper, Jenkins, …). Или вы просто играетесь с одним из относительно новых языков под JVM, например, Groovy, Scala, Clojure или даже каким-нибудь Frege. В общем, Java уже повсюду, и хочешь не хочешь, а приходится в ней немного разбираться.
На самом деле, есть подозрения, что Java не так уж плоха, как о ней говорят. Статическая типизация? Хорошо. Автоматическая сборка мусора? Отлично. Кроссплатформенность? Неплохая скорость дробления чисел? Множество готовых библиотек? Готовый инструментарий? Куча написанных книг? Лямбды и параллельные коллекции начиная с Java 8? Просто супер! Более того, в ранних версиях Java были даже легковесные потоки, но от них, к сожалению, решили отказаться. Есть, конечно, и множество шероховатостей, но, во всяком случае, общая идея, надо признать, правильная.
Нельзя не сказать пару слов о местной терминологии. В мире Java любят всякие непонятные аббревиатуры. В частности, вам часто будут встречаться следующие:
- JRE (Java Runtime Environment) — это виртуальная машина Java и стандартная библиотека, то есть, минимум из того, что необходимо для запуска Java-приложений;
- JDK (Java Development Kit) включает в себя компилятор Java (javac) и прочие утилиты, документацию, примеры, а также JRE — то есть, JDK представляет собой минимальный набор инструментов, необходимый программисту на Java;
- SDK (Software Development Kit) — устаревший термин, означающий в точности то же самое, что и JDK;
- Java SE (Standard Edition) представляет собой стандартный вариант платформы Java, «for general-purpose use», в состав Java SE входят такие стандартные библиотеки, как java.io, java.net, java.math и тд;
- Java ME (Micro Edition), урезанный вариант SE для использования на мобильных устройствах, телевизорах и так далее, включает в себя некоторые библиотеки, специфичные для такого окружения;
- Java EE (Enterprise Edition), расширенный вариант Java SE, в который дополнительно входят JMS (API для обмена сообщениями), библиотеки для парсинга XML, сервлеты и много чего еще;
- JNI (Java Native Interface) — такая штука, которая позволяет вызывать код на ассемблере, Си и C++ из Java, а также наоборот. В сообществе Java-программистов использование JNI не очень приветствуется, но на серверсайде, если очень нужно, то почему бы и нет;
Установка JDK. Есть больше одной реализации JDK, наиболее популярными являются OpenJDK и Oracle JDK. Опытные программисты на Java заверили меня, что OpenJDK ни на что не годится и что пользоваться нужно только Oracle JDK. Мои личные наблюдения это подтверждают, на Oracle JDK Java-приложения работают заметно быстрее. Установку Oracle JDK мы уже рассматривали здесь. Если в двух словах:
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer
sudo apt-get install oracle-java7-unlimited-jce-policy
Должна успешно установиться Java 1.7. Проверяем, сказав java -version
.
Также нам понадобится Maven (о нем чуть ниже):
Касательной версий Java нужно отметить, что тут есть небольшая путаница. Строго говоря, версии имеют номера 1.1, 1.2 и так далее до последней на сегодняшний день 1.8. Но единичку в начале иногда опускают. То есть, Java 7 и Java 1.7 — это одно и то же. Приложения на Java не всегда одинаково хорошо работают на разных версиях виртуальной машины Java. Очевидно, что если приложение писалось под Java 6, оно может не запуститься на Java 5. Но я наблюдал и обратное. Приложение, которое писалось и тестировалось на Java 6 может не совсем корректно работать, а то и вовсе не запускаться на Java 7.
Писать на Java без IDE, например, в Vim, можно, но не очень удобно. Отчасти это связано с необходимостью писать всякие public static void
, отчасти — с явной декларацией типов, отчасти — с тем, что для разрешения конфликтов имен в Java принято давать имена пакетов в стиле ru.example.some.package, то есть, как бы доменное имя, записанное задом наперед. Также предполагается, что вы владеете доменом example.ru, и потому ваши имена не будут конфликтовать с именами других разработчиков. При этом классы в пакете должны находится в каталоге src/main/java/ru/example/some/package — седьмой вложенности! Другими словами, без IDE на Java писать очень грустно.
Никакой IDE по умолчанию в JDK не входит, поэтому возникает проблема выбора. IDE под Java много, например, Eclipse, NetBeans и IntelliJ IDEA. Опрос среди коллег-джавников показал, что IDEA является наиболее адекватной (быстрой, удобной, …), поэтому ею и воспользуемся. Качаем с сайта JetBrains последнюю бесплатную версию (Community Edition), распаковываем куда-нибудь архив.
У себя для запуска IntelliJ IDEA я положил в ~/bin такой скрипт:
/home/eax/path/to/idea-ide/bin/idea.sh
В моем оконном менеджере теперь можно просто сказать «Ctr+D → idea» и IntelliJ IDEA будет запущена. Приятной неожиданностью лично для меня оказалось то, что как под Linux, так и под Windows (я не поленился проверить), IntelliJ IDEA внешне практически не отличается от нативных приложений, несмотря на то, что написана она на Swing, а не SWT.
Давайте попробуем создать новый проект. Create New Project → Java/Maven → Next. В GroupId пишем «ru.example», в ArtifactId — «helloworld», жмем Next. В поле Project name указываем «HelloWorld», затем находим Project SDK. Фактически, IntelliJ IDEA найдет подходящий путь за нас. Лично у меня он получился таким: /usr/lib/jvm/java-6-oracle. Жмем Finish. После первого запуска IntelliJ IDEA может иногда тупить, поскольку она будет занята индексацией классов и еще чем-то. Поглядывайте на статусбар внизу IDE.
Дополнение: На самом деле, с Java 6 лучше не связывайтесь. Работать с этой версией очень грустно из-за отсутствия try с ресурсами, diamond syntax, классов Path и Files, возможности ловить несколько исключений в одном catch’е, а также других фичей. Берите сразу Java 7 или старше.
Теперь создаем новый пакет таким образом:
В качестве имени пакета указываем «ru.example.helloworld».
Создаем новый класс в только что созданном пакете:
В качестве имени класса указываем «HelloWorld». Вводим следующий код:
/**
* Hello world class
*/
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello!");
}
}
Компилируем и запускаем программу, нажав Shift+F10. В появившемся терминале должны увидеть сообщение «Hello!».
Если теперь посмотреть на структуру проекта, она окажется примерно такой:
+-- HelloWorld.iml
+-- pom.xml
+-- src
| +-- main
| | +-- java
| | | +-- ru
| | | +-- example
| | | +-- helloworld
| | | +-- HelloWorld.java
| | +-- resources
| +-- test
| +-- java
+-- target
+-- classes
| +-- ru
| +-- example
| +-- helloworld
| +-- HelloWorld.class
+-- generated-sources
+-- annotations
В src/main лежат основные исходники, с разбивкой по использованным в проекте языкам программирования. В src/test лежит код тестов. В target/classes лежат скомпилированные классы. Файл pom.xml содержит информацию о проекте и его зависимостях. Это своего рода аналог rebar.config из мира Erlang или .cabal файла из мира Haskell. Аналог Rebar или Cabal здесь называется Maven. Помимо Maven есть и другие аналогичные утилиты, например SBT. Последний заточен под Scala. Но даже скалолазы по привычке часто продолжают пользоваться Maven.
Давайте попробуем поделать что-нибудь из консоли, чтобы лучше понимать, что как работает.
Например, запустить нашу программу можно так:
Вместо -cp
можно использовать -classpath
. Понятно, что эта опция задает путь до каталогов со скомпилированными классами. Также эти пути можно указать в переменной окружения $CLASSPATH. Последним аргументом в нашей команде указывается имя класса. Этот класс должен иметь метод main, который и будет вызван виртуальной машиной.
Сделаем ужасное. Удалим скомпилированный класс и соберем проект вручную, используя Maven:
mvn compile
Нетрудно убедиться, что файл .class снова появился и программа запускается, как и раньше.
Это все, конечно, замечательно, но распространять наше приложение в таком виде мы не можем. Сначала нам нужно упаковать его в исполняемый независимый (standalone) jar’ник. Эта задача решается при помощи Assembly Plugin для Maven. Подключается он довольно просто. Открываем в IDEA файл pod.xml и перед закрывающим тэгом </project>
дописываем:
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>ru.example.helloworld.HelloWorld</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
В консоли говорим:
Если все было сделано правильно, мы получим исполняемый jar’ник, который можно запустить так:
Этот jar-файл можно переименовать во что угодно и распространять, как готовое Java-приложение. Ну разве что можно упаковать вместе с ним пару скриптов для Windows и *nix, говорящих java -jar
.
За кадром осталось еще много вопросов, например, использование в проекте сторонних библиотек, интеграция IntelliJ IDEA с системой контроля версий, отладка, и так далее. Может быть, когда-нибудь эти вопросы будут освещены в отдельной заметке.
В качестве источников дополнительной информации, насколько я могу судить, можно порекомендовать:
- Java. Полное руководство, 8-е издание Герберта Шилдта;
- Thinking in Java, 4th edition Брюса Эккеля, рекомендуется читать только в оригинале, так как в русском издании выкинули пару глав;
- Двухтомник «Core Java», есть в русском переводе — том 1, том 2;
- Effective Java, 2nd edition, за авторством Joshua Bloch;
- Еще для изучения Java рекомендуют туториалы от Oracle, на первый взгляд выглядят они годно;
- А тут можно почитать отличный туториал по Maven, компенсирующий излишнюю увлеченность авторов книг самим языком;
Ну и дальше все зависит от интересующих вас задач — Spring, Hibernate, Swing, Netty или чем там принято решать проблему c10k в Java, разработка мобильных приложений под Android и так далее.
Отмечу, что я далеко не специалист по Java, так что если вы видите неточности в тексте, или у вас есть дополнения, не стесняйтесь пользоваться комментариями.
Дополнение: Функциональщик ботает Java — работа со сторонними библиотеками и хождение в РСУБД через JDBC
Метки: Java, Linux, Языки программирования.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.