Среда консольного программирования 3F-lab

Java + Console

Для разработки программ на языке Java используются мощные IDE, оснащенные развитыми графическими интерфейсами: Eclipse, NetBeans, VisualStudio и другие. Их преимущества несомненны. И все-таки бывают ситуации, когда целесообразнее обойтись более простыми средствами. Во-первых, перечисленные программные продукты весьма требовательны к ресурсам и на компьютерах со скромными возможностями работать просто не будут. Во-вторых, они не пригодны в случаях, когда нужно отредактировать и откомпилировать код на удаленном хосте, к которому имеется лишь терминальный доступ. Ну и, наконец, каждая IDE создает в автоматическом режиме много обвязочного кода, комментариев, вспомогательных файлов, которые пользователь не всегда полностью контролирует. При этом переучивание с одной IDE на другую происходит достаточно болезненно, если программист не владеет принципами написания, компиляции и упаковки кода в "ручном режиме".

Предлагаемая среда разработки Java-приложений - 3f-lab - пердназначена для создания программ исключительно средствами консоли. Для ее использования достаточно ssh доступа к компьютеру. Когда программа пишется непосредственно на хосте, для которого предназначена, существенно сокращается время на отладку, т.к. происходит постоянная "подгонка по месту". Кроме того, удаленные "сервера" зачастую обладают в разы большей мощностью, чем десктопы, ноутбуки и нетбуки программистов-фрилансеров. Поэтому при удаленной консольной работе снижаются еще и затраты времени на компиляцию. Впрочем, 3f-lab прекрасно работает и на маломощных компьютерах, т.е. не требует никаких зависимостей кроме JDK. В 3f-lab осуществляется полный контроль над кодом. Один из ее принципов - устранение любой избыточной информации.

3f-lab - это не программный продукт, а набор четко соблюдаемых правил, каталогов и скриптов. В небольшом скринкасте вы можете увидеть, как в соответствии с принципами 3f-lab написать, откомпилировать и запустить простейшую программу. Это занимает порядка 10 минут, включая установку (JDK). Для начала просмотра нажмите на картинку.

Данный скринкаст можно также просмотреть в pdf-формате.

При организации среды 3f-lab следует прежде всего определиться с тем, где она будет находиться. Оптимально разместить ее в домашнем каталоге. В этом случае всегда есть уверенность, что хватит полномочий на создание, изменение, удаление и запуск файлов и не понадобятся права администратора. Понятие домашней директории (каталога, папки) существует и в Linux и в Windows.

Рассмотрим процесс организации среды 3f-lab на примере платформы Linux. Для создания ее основных каталогов следует выполнить:

		cd ~
		mkdir -p .3f-lab/_bin/java
		mkdir -p .3f-lab/_classes/{lib,raw}
		mkdir -p .3f-lab/{_reusable,_projects}

То же самое можно сделать множеством других способов (клавишей F7 в Midnight Commander'e, правой кнопкой мыши в оконном режиме и т.п.). Названия каталогов имеют некоторые особенности. Во-первых, В начале имени коренного каталога .3f-lab присутствует точка. Благодаря этому он оказывается в верхней части списка поддиректорий домашнего каталога, где его быстро можно найти. Во-вторых, все названия подкаталогов внутри .3f-lab содержат в начале нижнее подчеркивание. Сделано это с той же целью - чтобы они всегда находились в верхней части списка, если в каталоге 3f-lab окажутся какие-нибудь посторонние файлы (что крайне нежелательно).

Рассмотрим назначение созданных подкаталогов:

  1. _bin - здесь хранятся бинарные утилиты, программы, сложные программные пакеты, всевозможные SDK (в том числе JDK);
  2. _classes - здесь будут лежать откомпилированные классы и библиотеки (.jar-файлы);
  3. _projects - каталог проектов, т.е. конечных продуктов, разработанных, например, для сторонних заказчиков;
  4. _reusable - каталог для исходников, созданных для удобства и активно использующихся в различных проектах (многократно используемый код);

Познакомиться с этими и другими каталогами подробнее вы можете, перемещаясь по вкладкам данной странички.



Каталог _bin

В каталоге _bin, как уже сказано ранее, хранятся бинарные файлы. Если среда 3f-lab организуется под Windows - этот каталог может быть наполнен консольными архиваторовами, компиляторами, сетевыми утилитами, средств криптографии и т.п. В случае же с Linux все эти программы находится в системных папках, поэтому в каталоге _bin оказывается зачастую всего одна, но очень важная вещь: JDK (Java Developer Kit). Это комплект утилит и библиотек, с помощью которого можно не прибегая к прочим средствам писать программы на языке Java. Проанализируйте структуру любой IDE, и вы обязательно в центре ее найдете именно JDK, вокруг которого просто "обернут" красивый интерфейс.

В большинстве современных Linux-систем среда Java установлена по умолчанию. Однако, во-первых, среда для выполнения Java-программ - это еще не среда для разработки Java программ. Во-вторых, Java постоянно совершенствуется. "Свежесть" ее версии - не просто дань моде. Программист, который игнорирует последние достижения языка, рискует много потерять в эффективности как написания, так и исполнения кода. Поэтому желательно использовать самую свежую версию JDK.

Каждая новая версия JDK распаковывается автоматически в каталог со своим номером. Добиться устойчивости относительных путей к компилятору внутри 3f-lab можно с помощью символической ссылки. Скачав дистрибутив JDK с сайта oracle.com, его следует поместить в ~/.3f-lab/_bin/java. Дистрибутив для Linux представляет собой самораспаковывающийся скрипт, выкладывающий всё свое содержимое в каталог, из которого его запустили. То есть файлы JDK после распаковки могут оказаться, например, в _bin/java/jdk1.5.0_08, что неудобно и некрасиво. Если выполнить команду

		ln -s jdk1.5.0_08 sun

то компилятор javac, например, всегда можно вызвать командой ~/.3f-lab/_bin/java/sun/bin/javac. При выходе новой версии достаточно подправить линк после распаковки дистрибутива.

Почему было не сделать путь к компилятору проще, например: ~/.3f-lab/_bin/jdk/bin/javac? Дело в том, что существует множество jdk-подобных продуктов. Есть, например, очень специфическая java от Microsoft (ее при необходимости можно установить в каталог ~/.3f-lab/_bin/java/ms). Есть java для мобильных телефонов, которая хранится в отдельном каталоге ~/.3f-lab/_bin/java/wtk. В ~/.3f-lab/_bin/java/ant - хранятся каталоги и файлы сборщика, в OpenDS - служба каталогов и много еще есть программ на Java, имеющих сложную файловую структуру и требующих своего "дома", организуемого с помощью системных переменных со словом HOME (ANT_HOME, JAXE_HOME, TOMCAT_HOME и т.п.).

Как быть, если на одном и том же компьютере работают два программиста, каждый в своей домашней директории? Нужно ли каждому распаковывать по дистрибутиву JDK? В этом случае JDK устанавливается, например, в каталог /opt/java и на него делаются символические ссылки в соответствующие каталоги "лабораторий", размещенных в домашних каталогах программистов.

Общее правило таково: переменная окружения JAVA_HOME (она часто используется при запуске java-программ) всегда в рамках лаборатории должна указываться как

		JAVA_HOME=~/.3f-lab/_bin/java/sun

Несколько слов о сборщике ant. Устанавливать его нужно с учетом только что описанной особенности. Скрипт ant нужно поправить, дописав в его начало строки

		JAVA_HOME=~/.3f-lab/_bin/java/sun 
		ANT_HOME=~/.3f-lab/_bin/java/ant

Затем следует скопировать этот скрипт в /usr/bin, после чего команда ant вызывается из любой поддиректории домашнего каталога, как любая другая команда Linux.



Каталог _classes

Каталог _classes предназначен для хранения откомпилированных классов и библиотек. Но прежде, чем описать его специфику, необходимо сказать о такой проблеме программирования, как "кошмар зависимостей". В мире Windows она известна как dll-hell, в мире open source как dependences hell, в Java - как jar-hell. Она заключается в том, что фрагменты программ с одинаковыми именами, но разным содержимым (классы, функции, библиотеки) могут конфликтовать, т.к. загружаются из разных, иногда неожиданных мест. Например, исполняемый байт-код Java может находиться в следующих местах:

  1. в одном из каталогов, указанных в переменной CLASSPATH;
  2. в jar-архиве, передаваемом интерпретатору ключом -jar;
  3. в стандартном каталоге $JAVA_HOME/jre/lib/ext (jar-архивы);
  4. в случае срвлетов это еще и каталог WEB-INF/lib (в WEB-INF также могут быть размещены и незапакованные классы-файлы);
  5. можно написать собственные загрузчики классов.

В качестве примера jar-hell можно привести ситуацию, когда программист меняет код класса и не может добиться изменения в поведении программы. Причиной может быть то, что Java загружает не изменяемую, а какую-то старую версию класса, когда-то помещенную, в $JAVA_HOME/jre/ext/lib и забытую там.

Хотя порядок загрузки байт-кода в Java хорошо документирован, чтобы свести к минимуму проблему jar-hell в рамках 3f-lab следует хранить классы (как в виде файлов, так и в виде архивов) в строго определенном месте - каталоге ~/.3f-lab/_classes. Библиотеки (jar-архивы) помещаются в _classes/lib (можно создавать символические ссылки, если это части каких-то фреймворков). Файлы классов, хранящиеся "россыпью", следует помещать в каталог _classes/raw. Запаковывать их в jar-библиотеки до окончания работы над проектом нет смысла, т.к. такой код часто меняется в процессе разработки.

Для преодоления проблем, связанных с именами классов, в Java существует соглашение о пакетах (пространствах имен). Например, два человека, не подозревая о существовании друг друга, пишут классы с одинаковым названием - Element. Но один из них - химик и подразумевает химический элемент, а другой связан с кинематографом и подразумевает фильм "5-й элемент". Если бы не было пакетов, при попытке одновременного использования этих классов возникла бы путаница. Поэтому классы помещают в пакеты. В первом случае полное имя класса могло бы выглядеть как ru.mendeleev.Element, а во втором - us.besson.Element.

В качестве имени для пакетов, создаваемых программистом или организацией, рекомендуется использовать прочтенное в обратной последовательности имя своего веб-сайта. Например те, кто имеет аккаунт в сервисе sourceforge.net, могут использовать имена типа net.sf.lab3f.util.

В рамках лаборатории 3f-lab, в соответствии с правилами маппинга, файл класса Element (название условное), принадлежащий пакету net.sf.lab3f.util, должен храниться в файле _classes/raw/net/sf/lab3f/util/Element.class. Необходимые подкаталоги сборщик ant создаст автоматически.



Каталог _projects

В каталоге _projects размещаются файлы, связанные с реализацией конкретных проектов. Это то, что потом превращается в готовые программы, передаваемые заказчикам или используемые для собственного удовольствия. Проекты, написанные на языке Java, могут быть реализованы в различных формах:

  1. как отдельная консольная утилита;
  2. как GUI-приложение;
  3. как клиент-серверное приложение;
  4. как веб-приложение;
  5. как приложение для мобильного устройства.

Начиная работу над новым проектом, следует создать в каталоге _projects подкаталог с каким-нибудь подходящим именем. Имена таких подкаталогов пишутся заглавными буквами. Например,

	mkdir ~/.3f-lab/_projects/MPG123

Заглавные буквы позволяют четче отличать пакеты и каталоги проектов от пакетов для многократного использования (см. _reusable).

В зависимости от выбранной формы реализации, структура подкаталогов внутри каталога _projects/${PROJECTNAME} может быть разной. Для утилиты или простого приложения достаточно создать единственный подкаталог src. Для клиент-серверных приложений - подкаталоги client и server. Если предполагается работа с базами данных, то можно создать подкаталог sql. Для работы с xml/xsl/xsd/dtd - подкаталог xml и т.д.

В ходе работы над проектом целесообразно создавать также такие каталоги, как .tmp для черновиков, .design для графических макетов. После написания кода и его отладки получается какой-то результат. В случае веб-приложения - это war-архив. Если создается приложение для мобильного телефона - файлы jar и jad. Для Windows это может быть исполняемый файл типа setup.exe. Для таких результирующих файлов в каждом проекте создается каталог .output. В начале имен перечисленных каталогов присутствует точка. Делается это для того, чтобы при использовании системы контроля версий не помещать их в репозиторий. В противном случае его объем неоправданно увеличится. Для того, чтобы каталги с точкой не попали в репозиторий git можно добавить в каталог проекта файл .gitignore со следующим содержимым:

 
		.*/**

Сам репозиторий git управляется следующими командами (находиться при этом нужно в корне каталога проекта):

 
		git init   # создать пустой репозиторий
		git add .  # добавить все файлы проекта 
		git commit -a -m "какой-нибудь комментарий" 
			   # зафиксировать текущее состояние проекта

Классы, генерируемые в ходе работы над проектом, хранятся в каталоге _classes/raw в соответствии с правилами маппинга, описанными на вкладке _classes. То есть если проект называется MPG123, а имена пакетов принято начинать с com.example, то откомпилированные классы должны попадать в _classes/raw/com/example/MPG123.

Для быстроты нахождения текущего проекта (того, над которым идет интенсивная работа в данное время) в каталоге _projects на него можно сделать символическую ссылку:

		ln -s MPG123 .CURRENT

В этом случае благодаря точке в начале названия каталог (точнее ссылка на него) окажется в верхней строке списка.



Каталог _reusable

Каталог _reusable предназначен для хранения исходных текстов многократно используемых классов, выполняющих какие-либо вспомогательные "библиотечные" функции. Например, для конвертации бинарных массивов в формат base64 можно создать класс com.example.util.B64:

		package com.example.util;

		public class B64{
			public String encode(byte[] ba){
				// ... код метода
			}
			public byte[] decode(String s){
				// ... код метода
			}
		}

Файл в котором хранится этот код, называется B64.java и хранится в каталоге _reusable/util. После компиляции соответствующий файл-класс оказывается по адресу ~/.3f-lab/_classes/raw/com/example/util/B64.class. Со временем в каталоге _reusable может сформироваться примерно такая подборка:

  1. util - здесь хранятся разнообразные вспомогательные классы, помогающие обратиться к часто используемым возможностям языка;
  2. gui - классы для быстрого создания GUI-приложений;
  3. xml - классы для работы с xml (SAX, XSL, DOM);
  4. servlet - специфические многократно используемые сервлеты.

В каждом из этих каталогов есть файл build.xml, помогающий откомпилировать классы и поместить их в каталог _classes/raw. Он может выглядеть следующим образом:

 
	<?xml version="1.0" encoding="utf-8"?>
		<project name="Test" default="jc" basedir=".">
		
		<property name="classes.raw"  value="../../_classes/raw"/>
		<property name="classes.lib"  value="../../_classes/lib"/>

		<taskdef resource="aQute/bnd/ant/taskdef.properties" 
				classpath="${classes.lib}/task-bnd.jar"/>
		<taskdef name="ipojo" classname="org.apache.felix.ipojo.task.IPojoTask" 
				classpath="${classes.lib}/task-ipojo.jar"/>

		<target name="jc">
			<javac srcdir="." destdir="${classes.raw}" 
				 includeAntRuntime="false">
				<classpath>
					<pathelement path="${classes.raw}"/>
					<pathelement path="${classes.lib}/groovy.jar"/>
				</classpath>
			  </javac>
		</target>

	</project>

Этот файл хорошо иллюстрирует одну из основных идей 3f-lab: обращения к каталогам следует записывать в относительных величинах. То есть сборщик работает вне зависимости от того, куда поместили всю "лабораторию". Поднявшись на два уровня вверх, он попадает в директорию _classes/raw и находит там всё необходимое.



Прочие каталоги

Четыре описанных каталога 3f-lab - _bin, _classes, _reusable и _projects - достаточны для решения большинства задач, связанных с программированием в среде 3f-lab. Однако на практике используется еще несколько.

В каталог _backup можно помещать архивы проектов и каталога _reusable. Частично роль механизма резервного копирования выполняют репозитории git, но иногда можно использовать и более традиционный способ:

		tar cvfz ../_backup/SOME_PROJECT.tgz SOME_PROJECT/

(Команда выполняется из каталога _projects).

Каталог _tmp предназначен для хранения временных файлов. Его, например, удобно использовать при ревизии кода: переместить файлы проекта в _tmp и по одному возвращать, попутно перетряхивая, объединяя, переименовывая и удаляя фрагменты кода и файлы.

Каталог _web - для развернутых веб-приложений. Может быть оформлен как символическая ссылка на каталог webapps сервера Tomcat. Удобно помещать сразу в _web результаты сборки проектов, связанных с http-технологиями (war-архивы). Там их автоматически находит, вебсервер, что позволяет быстро видеть измененный результат в браузере.

Наконец каталог _install. Здесь могут храниться дистрибутивы ПО, которое используется в рамках 3f-lab: JDK, WTK, Tomcat, Ant и т.п.



Загрузка необходимых файлов

Для работы в среде 3f-lab необходимы следующие приложения и пакеты:

Для Windows подготовлена сборка, включающая в себя Vim и Apache Ant.

Support This Project

Для отправки комментариев и связи с автором можно воспользоваться электронной почтой bigbelk@users.sf.net. Поддержать проект материально Вы можете перечислив денежные средства через приведенные здесь кнопки PayPal и Яндекс.Деньги.

С уважением,
Михаил Беляков.

Поделиться
Яндекс Яндекс. Деньги Хочу такую же кнопку