Сейчас уже никто не создает программы в консоли. Используя любимую IDE, разработчик чувствует себя неуютно за чужим компьютером, где её нет.
Решив разобраться в работе Ant и Maven, я поймал себя на том, что не смогу собрать приложение без них в консоли.
В данной статье я постарался уместить все этапы проектирования демонстрационного приложения, чтобы не искать справку по каждой команде на просторах Интернета.
От простого к .
Каждая программа обычно содержится в отдельном каталоге. Я придерживаюсь правила создавать в этом каталоге по крайней мере две папки: src и bin. В первой содержатся исходные коды, во второй — результат компиляции. В данных папках будет структура каталогов, зависящая от пакетов.
Один файл
Можно сделать и без лишних папок.
Берем сам файл.
publicclassHelloWorld < publicstaticvoidmain(String[] args) < System.out.println(«Hello World!»); Calculator calc=newCalculator(); System.out.println(«2+2 Hello World!»); System.out.println(a+»+»+b+» thread=main», com.qwertovsky.helloworld.Calculator.sum(), line=9 bci=0 9 Adder adder=new Adder();
Чтобы соориентироваться можно вывести кусок исходного кода, где в данный момент находится курссор.
main[1] list 5 public class Calculator 6 < 7 public int sum(int. a) 8 < 9 =>Adder adder=new Adder(); 10 for(int i:a) 11 < 12 adder.add(i); 13 >14 return adder.getSum();
Узнаем, что из себя представляет переменная а.
main[1] print a a = instance of int[2] (id=340) main[1] dump a a = < 2, 3 >main[1] stop at com.qwertovsky.helloworld.operation.Adder:19 Deferring breakpoint com.qwertovsky.helloworld.operation.Adder:19. It will be set after the class is loaded.
Продолжим исполнение.
Урок 2. Часть 3. Компиляция и запуск Java приложения из командной строки
main[1] cont > Set deferred breakpoint com.qwertovsky.helloworld.operation.Adder:19 Breakpoint hit: «thread=main», com.qwertovsky.helloworld.operation.Adder.add(), line=19 bci=0 19 sum+=b; main[1] list 15 > 16 17 public void add(int b) 18 < 19 =>sum+=b; 20 > 21 22 public int getSum() 23 < 24 return sum; main[1] print sum sum = 0 main[1] print b b = 2
Выполним код в текущей строке и увидим, что sum стала равняться 2.
main[1] step > Step completed: «thread=main», com.qwertovsky.helloworld.operation.Adder.add(), line=20 bci=10 20 > main[1] print sum sum = 2
Поднимемся из класса Adder в вызвавший его класс Calculator.
main[1] step up > Step completed: «thread=main», com.qwertovsky.helloworld.Calculator.sum(), line=10 bci=36 10 for(int i:a)
Удаляем точку прерывания
main[1] clear com.qwertovsky.helloworld.operation.Adder:19 Removed: breakpoint com.qwertovsky.helloworld.operation.Adder:19 main[1] step > Step completed: «thread=main», com.qwertovsky.helloworld.Calculator.sum(), line=12 bci=30 12 adder.add(i);
Можно избежать захода в методы, используя команду next.
main[1] next > Step completed: «thread=main», com.qwertovsky.helloworld.Calculator.sum(), line=10 bci=36 10 for(int i:a) main[1] next > Step completed: «thread=main», com.qwertovsky.helloworld.Calculator.sum(), line=14 bci=42 14 return adder.getSum();
Проверяем значение выражения и завершаем выполнение.
main[1] eval adder.getSum() adder.getSum() = 5 main[1] cont > 2+3=5 The application exited
Хорошо бы протестировать
Используем JUnit.
Java SE 18 Как скомпилировать и запустить класс через консоль
Компилируем
mkdir test_bin javac -classpath lib/path/junit-4.8.2.jar -sourcepath ./src -d test_bin test/com/qwertovsky/helloworld/TestCalculator.java
Запускаем. В качестве разделителя нескольких путей в classpath в Windows используется ‘;’, в Linux — ‘:’. В консоли Cygwin не работают оба разделителя.
Возможно, должен работать ‘;’, но он воспринимается как разделитель команд.
java -classpath lib/path/junit-4.8.2.jar:./test_bin org.junit.runner.JUnitCore com.qwertovsky.helloworld.TestCalculator JUnit version 4.8.2 . Time: 0,031 OK (4 tests)
Создадим библиотеку
Класс Calculator оказался полезным и может быть использован во многих проектах. Перенесем всё, что касается класса Calculator в отдельный проект.
HelloWorld ‘—bin ‘—src ‘—com ‘—qwertovsky ‘—helloworld ‘—HelloWorld.java Сalculator ‘—bin ‘—src ‘ ‘—com ‘ ‘—qwertovsky ‘ ‘—calculator ‘ ‘—Calculator.java ‘ ‘—operation ‘ ‘—Adder.java ‘—test ‘—com ‘—qwertovsky ‘—calculator ‘—TestCalculator.java
Измените также назавания пакетов в исходных текстах. В HelloWorld.java нужно будет добавить строку
importcom.qwertovsky.calculator.Calculator;
Компилируем.
cd Calculator javac -sourcepath src -d bin src/com/qwertovsky/calculator/Calculator.java
Делаем архив jar
jar cvf calculator.jar -C bin . added manifest adding: com/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/Calculator.class(in = 497) (out= 373)(deflated 24%) adding: com/qwertovsky/calculator/operation/(in = 0) (out= 0)(stored 0%) adding: com/qwertovsky/calculator/operation/Adder.class(in = 441) (out= 299)(deflated 32%)
С помощью ключа -C мы запустили программу в каталоге bin.
Надо узнать, что у библиотеки внутри
Можно распаковать архив zip-распаковщиком и посмотреть, какие классы есть в библиотеке.
Информацию о любом классе можно получить с помощью дизассемблера javap.
javap -c -classpath calculator.jar com.qwertovsky.calculator.Calculator Compiled from «Calculator.java» public class com.qwertovsky.calculator.Calculator extends java.lang.Object< public com.qwertovsky.calculator.Calculator(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object.»»:()V 4: return public int sum(int[]); Code: 0: new #2; //class com/qwertovsky/calculator/operation/Adder 3: dup 4: invokespecial #3; //Method com/qwertovsky/calculator/operation/Adder.»»:()V 7: astore_2 8: aload_1 9: astore_3 10: aload_3 11: arraylength 12: istore 4 14: iconst_0 15: istore 5 17: iload 5 19: iload 4 21: if_icmpge 42 24: aload_3 25: iload 5 27: iaload 28: istore 6 30: aload_2 31: iload 6 33: invokevirtual #4; //Method com/qwertovsky/calculator/operation/Adder.add:(I)V 36: iinc 5, 1 39: goto 17 42: aload_2 43: invokevirtual #5; //Method com/qwertovsky/calculator/operation/Adder.getSum:()I 46: ireturn >
Из результата видно, что класс содержит кроме пустого конструктора, ещё один метод sum, внутри которого в цикле вызывается метод add класса Adder. По завершении метода sum, вызывается Adder.getSum ().
Без ключа -c программа выдаст только список переменных и методов (если использовать -private, то всех).
javap -private -classpath calculator.jar com.qwertovsky.calculator.operation.Adder Compiled from «Adder.java» public class com.qwertovsky.calculator.operation.Adder extends java.lang.Object
Лучше снабдить библиотеку документацией
Изменим для этого класс калькулятора.
Документацию можно создать следующей командой. При ошибке программа выдаст список возможных опций.
mkdir doc javadoc -d doc -charset utf-8 -sourcepath src -author -subpackages com.qwertovsky.calculator
В результате получиться следующее
Можно подписать jar-архив
Если требуется подписать свою библиотеку цифровой подписью, на помощь придут keytool и jarsigner.
Генерируем подпись.
keytool -genkey -keyalg rsa -keysize 2048 -alias qwertokey -keystore path/to/qwerto.keystore Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: Valery Qwertovsky What is the name of your organizational unit? [Unknown]: Qwertovsky What is the name of your organization? [Unknown]: Qwertovsky What is the name of your City or Locality? [Unknown]: Tver What is the name of your State or Province? [Unknown]: Tverskaya obl. What is the two-letter country code for this unit? [Unknown]: RU Is CN=Valery Qwertovsky, OU=Qwertovsky, O=Qwertovsky, L=Tver, ST=Tverskaya obl., C=RU correct? [no]: y Enter key password for (RETURN if same as keystore password): Re-enter new password:
Генерируем Certificate Signing Request (CSR)
keytool -certreq -file path/to/qwertokey.crt -alias qwertokey -keystore path/to/qwerto.keystore
Содержимое полученного файла отправляем в центр сертификации. От центра сертификации получаем сертификат. Сохраняем его в файле (например, qwertokey.cer) и импортируем в хранилище
keytool -import -trustcacerts -keystore path/to/qwert.keystore -alias qwertokey -file path/to/qwertokey.cer
Подписываем jar-архив
jarsigner -keystore path/to/qwerto.keystore calculator.jar qwertokey
Файл qwertokey.cer отправляем всем, кто хочет проверить архив. Проверяется он так
jarsigner -verify -verbose -certs -keystore path/to/qwerto.keystore calculator.jar
Использование библиотеки
Есть программа HelloWorld, которая использует библиотечный класс Calculator. Чтобы скомпилировать и запустить программу, нужно присоединить библиотеку.
Компилируем
cd HelloWorld javac -sourcepath src -d bin -classpath path/to/calculator.jar src/com/qwertovsky/helloworld/HelloWorld.java
java -classpath bin:path/to/calculator.jar com.qwertovsky.helloworld.HelloWorld
Собираем программу
Это можно сделать по-разному.
Первый способ
cd HelloWorld echo main-class: com.qwertovsky.helloworld.HelloWorld>manifest.mf echo class-path: lib/calculator.jar >>manifest.mf mkdir lib cp path/to/calculator.jar lib/calculator.jar jar -cmf manifest.mf helloworld.jar -C bin .
Здесь есть тонкости.
В строке
main-class: com.qwertovsky.helloworld.HelloWorld
не должно быть пробелов в конце.
Вторая тонкость описана в [3]: в этой же строке должен стоять перенос на следующую строку. Это если манифест помещается в архив сторонним архиватором.
Программа jar не включит в манифест последнюю строку из манифеста, если в конце не стоит перенос строки.
Ещё момент: в манифесте не должно быть пустых строк между строками. Будет выдана ошибка «java.io.IOException: invalid manifest format». При использовании команды echo надо следить только за пробелом в конце строки с main-class.
Второй способ
cd HelloWorld echo class-path: lib/calculator.jar >manifest.mf mkdir lib cp path/to/calculator.jar lib/calculator.jar jar -cmef manifest.mf com.qwertovsky.helloworld.HelloWorld helloworld.jar -C bin .
В данном способе избегаем ошибки с пробелом в main-class.
Третий способ
cd HelloWorld mkdir lib cd lib jar -xvf path/to/calculator.jar com/ created: com/ created: com/qwertovsky/ created: com/qwertovsky/calculator/ inflated: com/qwertovsky/calculator/Calculator.class created: com/qwertovsky/calculator/operation/ inflated: com/qwertovsky/calculator/operation/Adder.class cd .. cp -r bin/* lib/ jar -cef com.qwertovsky.helloworld.HelloWorld helloworld.jar -C lib . rm -r lib
Включили код нужной библиотеки в исполняемый файл.
Запуск исполняемого jar-файла
Файл calculator.jar исполняемым не является. А вот helloworld.jar можно запустить.
Если архив был создан первыми двумя способами, то рядом с ним в одном каталоге должна находится папка lib с файлом calculator.jar. Такие ограничения из-за того, что в манифесте в class-path указан путь относительно исполняемого файла.
cd Calculator ls ../HelloWorld/lib calculator.jar java -jar ../HelloWorld/helloworld.jar
При использовании третьего способа нужные библиотеки включаются в исполняемый файл. Держать рядом нужные библиотеки не требуется. Запускается аналогично.
java -jar ../HelloWorld/helloworld.jar
Как быть с приложениями JavaEE
Аналогично. Только библиотеки для компиляции нужно брать у сервера приложений, который используется. Если я использую JBoss, то для компиляции сервлета мне нужно будет выполнить примерно следующее
javac -classpath path/to/jboss/common/lib/jboss-servlet*.jar -d ./classes src/com/qwertovsky/app/servlets/MenuSt.java
Структура архива JavaEE-приложения должна соответствовать определенному формату. Например
my.ear `—META-INF | `—manifest.mf `—lib | `—mylib.jar `—my.war | `—META-INF | | `—manifest.mf | `—WEB-INF | | `—lib | | | `—myweblib.jar | | `—classes | | | `—com | | | `—. | | `—web.xml | `—index.html | `— `—myejb.jar
Читайте другие интересные статьи
Понравилась статья, расскажи о ней друзьям, нажми кнопку!
Источник: adminunix.ru
Скомпилируйте несколько исходных файлов Java с помощью командной строки
В этом руководстве мы узнаем, как мы можем взаимодействовать с компилятором Java через интерфейс командной строки.
В качестве предварительного условия нам необходимо загрузить Java и настроить переменную среды JAVA_HOME на нашем компьютере.
2. Компиляция одного файла исходного кода Java
Java предоставляет простой инструмент — javac для компиляции файлов исходного кода Java. Начнем с компиляции небольшого класса Car.java :
public class Car private String make; private String model; // standard setters and getters >
Как скомпилировать несколько исходных файлов Java в командной строке
Я знаю бегать javac file1.java производит file1.class if file1.java это единственный исходный файл, то я могу просто сказать java file1 для запуска.
Однако, если у меня есть 2 исходных файла, file1.java и file2.java , то как мне собрать программу?
Означает ли это, что оба файла имеют основной метод или есть 2 точки входа приложения? — Pradeep Singh
5 ответы
Попробуйте сделать следующее:
javac file1.java file2.java
это жестко запрограммировано, как мы можем использовать результаты $(find .) так далее? — Александр Миллс
или вы можете использовать следующее для компиляции всех исходных файлов Java в текущем каталоге.
javac *.java
Нет, это не рекурсия. — Сагар Раут
* является символом подстановочного знака. Это означает, что все вещи в этом каталоге заканчиваются на «.java» — user3735633
Вот еще один пример компиляции java-файла во вложенном каталоге.
Я пытался построить это из командной строки. Это пример из «gradle», который имеет зависимость «commons-collection.jar». Для получения дополнительной информации см. ‘gradle: быстрое начало работы с Java’ пример. — конечно, вы бы использовали инструменты «градации» для его создания. Но я подумал расширить этот пример для вложенного Java-проекта с зависимой банкой.
Примечание: Для этого вам понадобится дистрибутив «бинарный или исходный код gradle», пример кода находится в: «samples/java/quickstart»
% mkdir -p temp/classes % curl —get http://central.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar —output commons-collections-3.2.2.jar % javac -g -classpath commons-collections-3.2.2.jar -sourcepath src/main/java -d temp/classes src/main/java/org/gradle/Person.java % jar cf my_example.jar -C temp/classes org/gradle/Person.class % jar tvf my_example.jar 0 Wed Jun 07 14:11:56 CEST 2017 META-INF/ 69 Wed Jun 07 14:11:56 CEST 2017 META-INF/MANIFEST.MF 519 Wed Jun 07 13:58:06 CEST 2017 org/gradle/Person.class
Источник: stackovergo.com