MaxSite.org
Блог вебмастера

Как скомпилировать java-файл из консоли

Java и Android

Компиляция java-программы без проблем работает ровно до того момента, пока не потребуется создать что-то сложнее одного файла в проекте. Когда я попытался использовать два java-файла в разных каталогах, компилятор напрочь отказался работать, выдавая загадочные сообщения вроде «cannot find symbol»: чисто интуитивно я понял, что он просто не видит второй исходный файл.

Что может означать команда import(импорт)? Опять же интуитивно — это какой-то импорт из другого файла, например его подключение. В Java это означает лишь «расширение» области видимости — эдакое namespace, которое призвано исключить конфликт одинаковых имён. Никакого импорта здесь и в помине нет.

Другой пример — что такое package(пакет)? Какой-то пакет — набор модулей, файлов под одним именем, может архив. Ан, нет! В Jave к пакетам это никакого отношения не имеет — это всего лишь каталог. Причём каталог, который указывается в полном имени. Или чтобы его не указывать (частично), нужно задать его в import. О как!

При чём тут компиляция? А при том, что компилятор не шибко умный: чтобы он нормально заработал потребуется указать дополнительные параметры, которые завязаны на каталоги, файлы и классы (читай: «package» и «import»).

Проблемы?

Какие могут возникнуть проблемы? Вот список того, с чем мне пришлось столкнуться.

  • В консоли русские тексты крокозяблами.
  • Если исходные файлы в отдельных каталогах, компилятор их не видит.
  • Компилятор требует строгого соответствия указанным package в исходном коде реальной структуре подкаталогов.
  • Чтобы отделить скомпилированные class-файлы от java-файлов, также требуется указывать дополнительные параметры.
  • Каждый Java-проект имеет свои настройки, поскольку у них разные имена main-классов (его следует указывать при запуске программы на выполнение).

Тут ещё есть такой нюанс, что структура ява-программ у всех разная. В одних проектах для исходных файлов используется каталог src, в других java. Для скомпилированных часто встречаются варианты: bin и classes.

Что касается package, то тут всё значительно сложней, поскольку настоятельно рекомендуется создавать свои уникальные (в пределах всего Интернета) пространство имён. Например для моих программ (если их выкладывать в Сети) потребуется сделать такую структуру каталогов для Hello: org/maxsite/java/Hello.java.

В полноценных IDE, вроде Eclipse, данный вопрос решается просто — программа сама подставляет нужные параметры и компиляция работает из «коробки». Правда при этом создаётся куча служебных файлов. Но что делать, если нужно выполнить компиляцию из консоли? Скажем в том же Notepad++. Я потратил на решение несколько дней, поделюсь с вами.

Правила для Java-программ

Первое правило — каждая ява-программа должна находиться в своём каталоге. Какой бы она не была примитивной. Только так можно обеспечить корректную работу компилятора, который сам просто не понимает, где корень проекта.

Второе правило — исходые файлы нужно отделять от скомпилированных, иначе образуется страшное мессиво.

Третье правило — всегда используется хоть какой-то package, который указывает на «базовый» или «основной» подкаталог в каталоге исходных файлах.

Четвёртое правило — все исходные программы пишутся в UTF8 без сигнатуры BOM.

Структура файлов/каталогов

Чтобы было понятно, покажу на примере демо-программы HelloAlpha. Это очень простая программа, которая выводит сообщения из кучи одноименных классов. Я её написал, пытаясь разобраться с тонкостями import и package и возможно вам она окажется тоже полезной.

Программа имеет свой каталог проекта, который у меня расположен как d:\android\java\HelloAlpha\ У вас он может находиться в другом месте.

Каталог src — это исходные java-файлы с подкаталогами, которые совпадают со структурой package.

Напомню, что в тексте программы каталоги package указываются через точку вместо слэша. Вместо package mypackage/first;указывается package mypackage.first;

Каталог bin используется для размещения скомпилированных class-файлов. Компилятор сам повторит структуру подкаталогов из src. В Notepad++ исходный проект выглядит так:

Структура проекта HelloAlpha Структура проекта HelloAlpha

Файл compiling_and_run.bat используется для компиляции, а start.bat для запуска уже скомпилированного проекта (ему src не нужен).

Файл Alpha.java размещён в разных подкаталогах и представляет собой код, который просто выводит сообщение в консоль. Вот пример mypackage/first/Alpha.java:

package mypackage.first;
 
public class Alpha{
    
    public void out(String s){
        System.out.println("  mypackage/first/Alpha.java" + "  " + s);
    }
    
}

Вы можете загрузить zip-архив со всеми файлами: HelloAlpha.zip

В каждом подкаталоге Alpha.java немного разный: указан свой package и своё сообщение. Оно и используется для исследования (это тема другой статьи). :-)

После запуска compiling_and_run.bat произойдет компиляция и запуск программы на выполнение.

Компиляция

Теперь подходим к самому интересному — компиляции. Перед тем, как её запускать, в файле compiling_and_run.bat укажите полный каталог проекта.

set DIR_PROJECT=d:\android\java\HelloAlpha\

Если этого не сделать, то запускать bat-файл можно будет только из каталога проекта, но не получится из того же Notepad++. Второй момент — перед компиляцией удаляются все class-файлы из bin-каталога. Это сделано умышлено, поскольку в процессе программирования может быть сделано множество постороних class-файлов, которые компилятор сам не удаляет. Если же эта возможность не требуется, то удалите или закомментируйте строчку

del /s %DIR_BIN%\*.class >NUL

Сейчас bat-файл настроен на HelloAlpha, поэтому после запуска (после указания своего каталога!) вы увидите что-то вроде такого:

Выполненная HelloAlpha

Если возникнет ошибка компиляции, то будет немного другой экран:

Ошибка компиляции java

При этом, запуска на выполнение уже не будет.

Настройка bat-файла

Все настройки я вынес в верх файла compiling_and_run.bat:

set DIR_PROJECT=d:\android\java\HelloAlpha\
 
set MAIN_PACKAGE_DIR=mypackage
set MAIN_PACKAGE=mypackage
set MAIN_CLASS=HelloAlpha
 
set DIR_SRC=src
set DIR_BIN=bin
  • DIR_PROJECT — каталог проекта. Нужно указать слэш в конце.
  • MAIN_PACKAGE_DIR — «основной» пакет, то есть тот каталог, где размещается файл «запуска». Указывается относительно каталога src.
  • MAIN_PACKAGE — тот же «основной» пакет, но только разделители каталогов «\» указываются точками «.». Такое разделение — требование java.
  • MAIN_CLASS — это собственно то, что является программой. Для запуска java-программ указывается файл без расширения .class.
  • DIR_SRC — каталог исходных файлов. Именно он является «точкой отсчёта» для всех java-файлов.
  • DIR_BIN — в этот каталог складываем готовые файлы. Он может использоваться и для генерации jar-файла.
Разделение на MAIN_PACKAGE_DIR и MAIN_PACKAGE требуется, если у вас «длинный» пакет. Например для org.maxsite.java
set MAIN_PACKAGE_DIR=org\maxsite\java
set MAIN_PACKAGE=org.maxsite.java

Файл compiling_and_run.bat я сделал так, чтобы он работал в «правильной» кодировке, а также отслеживал ошибки компиляции. А цветовая дифференциация штанов раскраска немного упрощает отладку.

Учитывайте, что для java регистр файлов и каталогов имеет значение!

Файл start.bat используется для тех случаев, если нужно просто запустить программу без компиляции. Поскольку там одна строчка для Java, то просто укажите свой package и main-класс.

Порядок создания java-проекта

Схема простая: создать каталог проекта, скопировать структуру каталогов и bat-файлы. Поправить в них package и main-класс. Файл compiling_and_run.bat можно вообще переименовать под имя проекта (например HelloAlpha.bat).

Работа в Notepad++ с Java

Уж коли я затронул Notepad++, то покажу как настроить в нём компиляцию. В программе есть меню Запуск:

Меню Запуск в Notepad++

Здесь нужно выбрать compiling_and_run.bat.

Можно нажать Сохранить... и указать название команды и горячую клавишу, например F9.

Сохранение команды запуска

Если будет конфликт, то выскочит подсказка. После этого появится пункт меню, по которой и происходит запуск bat-файла.

Свой пункт в меню Notepad++

Существует ещё один способ: использование плагина NppExec. Но с ним довольно сложно, поскольку каждый проект потребует отдельной настройки, которую всё-таки проще сделать один раз в bat-файле.

Файл HelloAlpha.java

Изучение самого проекта HelloAlpha.java немного выходит за рамки этой статьи. Я её написал только для изучения команд package и import. Научной ценности она, естественно, не имеет. :-) Поэтому для каркаса своих java-программ вы можете придумать свою структуру. Главное, пожалуй оставить каталог mypackage (или свой вариант), поскольку хоть какой-то должен указываться в package исходных файлов.

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

(обязательно)