Програмування в IDE – прекрасно: пов'язаність залежностей коду, зручний дебаг, зрозуміле тестування, темна тема. Так ось, завдяки IDE розробка розвивається семимильними кроками. Але вона розслабляє. З кожним днем, занурюючись у функціонал IDE, розробник звикає до коміту однією кнопкою або збірки двома кліками.
Набагато гірша ситуація з новачками в програмуванні, які з самого початку працюють в IDE, ігноруючи роботу в командному рядку. Наприклад, в Intellij IDEA компіляція Java-застосунку демонструється завантажувальним баром у нижній панелі, а всі параметри компіляції, оброблення classpath та інші принади Java-життя залишаються за кадром.
Пропонуємо поговорити про компіляцію в Java без IDE. Для запуску прикладів у статті слід переконатися, що на вашій машині встановлено JDK 1.7 і старше.
На скриншоті видно, що у виведенні отримуємо якісь ієрогліфи: очевидно, це збите кодування. Зазвичай це відбувається в системі Windows. Для коректного відображення кирилиці в консолі, є такі команди:
Правила збирання, залежності та інше описано у файлі pom.xml. Зазвичай він міститься в головній папці проєкту. Під час запуску Maven перевіряє структуру і синтаксис файлу, попереджаючи про помилки.
У головній директорії поруч із папками bin і src створюємо файл pom.xml, всередину додаємо:

Як скомпілювати програму?
Компіляція в програмуванні – це приведення вихідного коду в байт-код для подальшого старту програми. Порядок дій від вихідного коду до запуску програм виглядає так:- Є вихідний код у файлі з ім'ям НазваКласу.java;
- Якщо в коді немає помилок, він компілюється в байт-код (у файл НазваКласу.class);
- Програма запускається.
class Test {
public static void main(String[] args) {
System.out.println("Це говорить застосунок із командного рядка");
}
}
Для чого потрібна команда javac
Окей, перший пункт виконано. Йдемо далі, щоб зрозуміти: скомпілювати – це як? :) У цьому нам допоможе команда javac, в аргументі якої необхідно вказати потрібний файл:javac Test.java
Якщо немає помилок у коді, поруч із файлом Test.java з'явиться файл Test.class. Це і є скомпільований байт-код. Тепер його потрібно запустити. Тут використовується команда java, що запускає байт-код: 
REM change CHCP to UTF-8
CHCP 65001
CLS
Вони змінюють поточну кодову сторінку командної консолі на період роботи поточного вікна.
Спробуємо ще раз:
D:\Java>java Test
Це говорить застосунок із командного рядка.
Знати принцип роботи команди javac дуже корисно, тому що ця команда лежить в основі будь-якої системи збирання проєктів.
Компіляція та виконання декількох класів
Для роботи з кількома класами потрібен classpath. Він схожий на файлову систему, у якій містяться класи, а функцію папок виконують пакети (packages). На цьому етапі варто поміркувати про відокремлення файлів вихідного коду від скомпільованих файлів. Зазвичай вихідні коди знаходяться в каталозі src, а скомпільовані класи – в bin. Наприклад, у нас є клас Box і клас BoxMachine, у якому міститься метод main. Клас Box:
package src;
public class Box {
private double size;
public Box(double size) {
this.size = size;
}
public String toString() {
return "Box have size " + size;
}
}
Він знаходиться в пакеті src, це необхідно зафіксувати.
Клас BoxMachine:
package src;
public class BoxMachine {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) {
System.out.println(new Box(Math.random()*10));
}
}
}
Цей клас також знаходиться в пакеті src. У методі main він створює п'ять об'єктів класу Box різного розміру і виводить у консоль інформацію про них.
Щоб скомпілювати цю групу класів, необхідно з головного каталогу (в якому лежать папки src і bin) використовувати команду javac з аргументами:
javac -d bin ./src/*
-d – прапор, після якого слід вказати місце, куди потраплять скомпільовані класи. Це дуже зручно, оскільки перекладати, наприклад, 1000 класів – дуже трудомісткий процес.
bin – назва папки.
./src/* – розташування вихідних файлів.
* вказує, що необхідно скомпілювати всі файли.
Тепер скомпільовані класи з'явилися в папці bin. Для їхнього запуску використовується команда java з тієї ж директорії, також з аргументами:
java -classpath ./bin src.BoxMachine
-classpath – прапор, після якого слід вказати місце розташування скомпільованих класів. Java шукатиме головний клас і всі супутні саме в цій директорії.
./bin – назва папки, в якій знаходяться скомпільовані класи.
src.BoxMachine – повна назва головного класу. Як і в першому випадку, не слід вказувати .class, оскільки це назва класу, а не файлу.
Виведення:
D:\Java>java -classpath ./bin src.BoxMachine
Box have size 4.085985295359718
Box have size 8.63682158248986
Box have size 6.027448124299726
Box have size 7.288317703877914
Box have size 1.106181659384694
Створення JAR-файлів
Щоб програму було легко переносити і запускати, можна зібрати скомпільовані класи в jar-файл – архів класів. Головна відмінність від zip або rar-архівів – наявність файлу маніфесту. У цьому маніфесті вказується головний клас, який буде запускатися під час виконання jar-файлу, classpath, а також багато додаткової інформації. У головному каталозі створимо файл manifest.mf. Його вміст буде таким:main-class: src.BoxMachine
class-path: bin/
main-class вказує клас, який містить метод main і буде виконаний під час запуску.
class-path – шлях до скомпільованих класів або додаткових бібліотек.
Настав час зібрати справжню програму без IDE за допомогою команди jar:
jar -cmf manifest.mf box-machine.jar -C bin .
-cmf – прапор, після якого слід вказати шлях до файлу маніфесту.
manifest.mf – шлях до маніфесту. box-machine.jar – назва вихідного jar-файлу.
-С – прапор, після якого вказується шлях до скомпільованих класів.
. – шлях, куди буде поміщено jar-файл. У нашому випадку – це головний каталог.
Тепер можна запустити. Запуск jar-файлів виконується також за допомогою команди java, але одразу ж після потрібно вказати прапор -jar: він говорить про те, що запускається Jar-файл, а другий аргумент – шлях до jar-файлу, включно з розширенням:
java -jar box-machine.jar
Виведення:
Box have size 5.5495235762547965
Box have size 9.695870044165662
Box have size 2.3408385788129227
Box have size 7.2790741216674135
Box have size 2.3620854470160513
Компіляція в Java без IDE: огляд систем збирання
Незважаючи на відносну простоту використання командного рядка, з його допомогою дуже складно збирати середні та великі проєкти. Це займає багато часу і загрожує помилками різного ступеня. На щастя, є системи збирання, які в рази полегшують процес роботи. Кількома командами ця система може зібрати проєкт будь-якої складності, а велика кількість плагінів, створених за час існування таких систем, може позбавити практично від будь-якого головного болю.Як скомпілювати Java?
Найвідоміші системи збирання на Java – це Ant, Maven і Gradle. Серед них немає поганої чи хорошої: кожна з них створена для вирішення певних завдань. Розглянемо кожну з них докладніше.Ant
Ant – інструмент збирання, який використовує сценарій, описаний за допомогою xml-файлу. Структура xml-файлу:
<?xml version="1.0"?>
<project name="имяПроекта" default="сценарийПоУмолчанию">
<target name="имяСценария">
// Дії сценарію
<echo>Hello, World!</echo>
</target>
// Другий сценарій
// Тощо
</project>
Створимо в головному каталозі файл build.xml з таким вмістом:
<?xml version="1.0"?>
<project name="BoxMachine" default="test">
<target name="test">
<echo>First build in Ant!</echo>
</target>
</project>
У цьому ж каталозі викличемо команду ant:
D:\Java>D:\Temp\ant\bin\ant
Buildfile: D:\Java\build.xml
test:
[echo] First build in Ant!
BUILD SUCCESSFUL
Total time: 0 seconds
У тезі <target> можна вказувати різні завдання, що дають змогу керувати збиранням і файловою системою. У Ant є понад 150 доступних команд, які вказані в документації. У прикладі нижче використовуємо тільки 5:mkdir – створення директорій - delete – видалення файлів і директорій
- javac – компіляція Java-коду
- java – запуск скомпільованого коду
<?xml version="1.0"?>
<project name="BoxMachine" default="compile">
<target name="compile">
<mkdir dir="result/classes"/>
<javac destdir="result/classes" includeantruntime="false">
<src path="src"/>
</javac>
</target>
<target name="run" depends="compile">
<java classname="BoxMachine" classpath="result/classes"/>
</target>
<target name="clean">
<delete dir="result"/>
</target>
</project>
У сценарії описано три дії – compile, ,code>run і clean.
compile створює директорію result, у ній classes, потім за допомогою javac компілює класи у створену директорію.
run запускає скомпільовані класи командою java.
clean видаляє директорію result.
Якщо в головному каталозі виконати команду ant без аргументів, запуститься дія compile. Якщо потрібно виконати певну дію, її вказують в аргументі.
D:\Java>D:/Temp/ant/bin/ant compile
Buildfile: D:\Java\build.xml
compile:
[mkdir] Created dir: D:\Java\result\classes
[javac] Compiling 2 source files to D:\Java\result\classes
BUILD SUCCESSFUL
Total time: 1 second
Maven
Maven пропонує дещо інший підхід до збирання проєктів. Тут розробник радше описує свій проєкт і додаткові інструменти, які використовує, на відміну від Ant, де збирання – це послідовність дій. Maven популярний серед розробників завдяки простому управлінню залежностями та зручній інтеграції з усіма середовищами розробки. Під час роботи з Maven дотримуються такої структури проєкту:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>ru.javarush.testmaven</groupId>
<artifactId>testMavenWithoutIde</artifactId>
<version>1.0.0</version>
<build>
<defaultGoal>compile</defaultGoal>
<sourceDirectory>src</sourceDirectory>
<outputDirectory>bin</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
</build>
</project>
Далі в командному рядку виконуємо команду mvn:
D:\Java>mvn
[INFO] Scanning for projects...
[INFO]
[INFO] -------------< ru.javarush.testmaven:testMavenWithoutIde >--------------
[INFO] Building testMavenWithoutIde 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ testMavenWithoutIde ---
[WARNING] Using platform encoding (Cp1251 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Java\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ testMavenWithoutIde ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding Cp1251, i.e. build is platform dependent!
[INFO] Compiling 2 source files to D:\Java\bin
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.521 s
[INFO] Finished at: 2019-06-25T20:18:05+03:00
[INFO] ------------------------------------------------------------------------
Тепер у папці bin є папка src, в якій знаходяться скомпільовані класи. У pom.xml у тезі build визначено ціль збирання – компіляцію, директорії файлів вихідного коду і результату компіляції, а також ім'я проєкту.
У Maven є безліч цілей збирання і плагінів для запуску тестування, створення Jar-файлів, збирання дистрибутивів та інших завдань.
Gradle
Це наймолодша система збирання, яка ґрунтується на Ant і Maven. Головна відмінність – робота на базі ациклічного графа для визначення порядку виконання завдань. Це дуже корисно у разі більш складних завдань, наприклад, інкрементальних і багатопроєктних збірках. Під час збирання за допомогою Gradle також рекомендується дотримуватися структури папок проекту Maven. До речі, файл для збирання в Gradle називається build.gradle і має набагато менший вигляд, ніж у Maven. Приклад для наших класів:
apply plugin: 'java'
apply plugin: 'application'
sourceSets {
main {
java {
srcDirs 'src'
}
}
}
sourceSets.main.output.classesDir = file("bin")
mainClassName = "src.BoxMachine"
defaultTasks 'compileJava', 'run'
У файлі відбувається підключення плагінів, визначення директорії файлів вихідного коду (якщо не використовується структура проєктів Maven), директорія результатів збирання, ім'я головного класу, а також завдання за замовчуванням.
За запуск збирання відповідає команда gradle в директорії, де лежить файл build.gradle:
d:\Java>D:\Temp\gradle\bin\gradle
Welcome to Gradle 5.4.1!
Here are the highlights of this release:
- Run builds with JDK12
- New API for Incremental Tasks
- Updates to native projects, including Swift 5 support
For more details see https://docs.gradle.org/5.4.1/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :help
Welcome to Gradle 5.4.1.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
To see more detail about a task, run gradle help --task <task>
For troubleshooting, visit https://help.gradle.org
BUILD SUCCESSFUL in 52s
1 actionable task: 1 executed
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ