Progress28.ru

IT Новости


09ae9cb0
2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java console application

Работа с Java в командной строке

От простого к .

Каждая программа обычно содержится в отдельном каталоге. Я придерживаюсь правила создавать в этом каталоге по крайней мере две папки: src и bin. В первой содержатся исходные коды, во второй — результат компиляции. В данных папках будет структура каталогов, зависящая от пакетов.

Один файл

Можно сделать и без лишних папок.
Берем сам файл HelloWorld.java.
Переходим в каталог, где лежит данный файл, и выполняем команды.
В данной папке появится файл HelloWorld.class. Значит программа скомпилирована. Чтобы запустить

Отделяем бинарные файлы от исходников

Теперь сделаем тоже самое, но с каталогами. Создадим каталог HelloWorld и в нем две папки src и bin.
Компилируем
Здесь мы указали, что бинарные файлы будут сохраняться в отдельную папку bin и не путаться с исходниками.

Используем пакеты

А то, вдруг, программа перестанет быть просто HelloWorld-ом. Пакетам лучше давать понятное и уникальное имя. Это позволит добавить данную программу в другой проект без конфликта имен. Прочитав некоторые статьи, можно подумать, что для имени пакета обязательно нужен домен. Это не так. Домены — это удобный способ добиться уникальности. Если своего домена нет, воспользуйтесь аккаунтом на сайте (например, ru.habrahabr.mylogin). Он будет уникальным. Учтите, что имена пакетов должны быть в нижнем регистре. И избегайте использования спецсимволов. Проблемы возникают из-за разных платформ и файловых систем.

Поместим наш класс в пакет с именем com.qwertovsky.helloworld. Для этого добавим в начало файла строчку
В каталоге src создадим дополнительные каталоги, чтобы путь к файлу выглядел так: src/com/qwertovsky/helloworld/HelloWorld.java.
Компилируем
В каталоге bin автоматически создастся структура каталогов как и в src.

Если в программе несколько файлов

HelloWorld.java
Calculator.java
Adder.java

Ошибка возникла из-за того, что для компиляции нужны файлы с исходными кодами классов, которые используются (класс Calculator). Надо указать компилятору каталог с файлами с помощью ключа -sourcepath.
Компилируем

Если удивляет результат

Есть возможность запустить отладчик. Для этого существует jdb.
Сначала компилируем с ключом -g, чтобы у отладчика была информация.

Отладчик запускает свой внутренний терминал для ввода команд. Справку по последним можно вывести с помощью команды help.
Указываем точку прерывания на 9 строке в классе Calculator

Запускаем на выполнение.

Чтобы соориентироваться можно вывести кусок исходного кода, где в данный момент находится курссор.

Узнаем, что из себя представляет переменная а.

Выполним код в текущей строке и увидим, что sum стала равняться 2.

Поднимемся из класса Adder в вызвавший его класс Calculator.

Удаляем точку прерывания

Можно избежать захода в методы, используя команду next.

Проверяем значение выражения и завершаем выполнение.

Хорошо бы протестировать

Запускаем. В качестве разделителя нескольких путей в classpath в Windows используется ‘;’, в Linux — ‘:’. В консоли Cygwin не работают оба разделителя. Возможно, должен работать ‘;’, но он воспринимается как разделитель команд.

Создадим библиотеку

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

Измените также назавания пакетов в исходных текстах. В HelloWorld.java нужно будет добавить строку

Делаем архив jar

С помощью ключа -C мы запустили программу в каталоге bin.

Надо узнать, что у библиотеки внутри

Можно распаковать архив zip-распаковщиком и посмотреть, какие классы есть в библиотеке.
Информацию о любом классе можно получить с помощью дизассемблера javap.

Из результата видно, что класс содержит кроме пустого конструктора, ещё один метод sum, внутри которого в цикле вызывается метод add класса Adder. По завершении метода sum, вызывается Adder.getSum().
Без ключа -c программа выдаст только список переменных и методов (если использовать -private, то всех).

Лучше снабдить библиотеку документацией

Изменим для этого класс калькулятора.

Документацию можно создать следующей командой. При ошибке программа выдаст список возможных опций.

В результате получиться следующее

Можно подписать jar-архив

Если требуется подписать свою библиотеку цифровой подписью, на помощь придут keytool и jarsigner.
Генерируем подпись.

Генерируем Certificate Signing Request (CSR)

Содержимое полученного файла отправляем в центр сертификации. От центра сертификации получаем сертификат. Сохраняем его в файле (например, qwertokey.cer) и импортируем в хранилище

Файл qwertokey.cer отправляем всем, кто хочет проверить архив. Проверяется он так

Использование библиотеки

Есть программа HelloWorld, которая использует библиотечный класс Calculator. Чтобы скомпилировать и запустить программу, нужно присоединить библиотеку.
Компилируем

Собираем программу

Это можно сделать по-разному.

Первый способ

Здесь есть тонкости.
В строке

не должно быть пробелов в конце.
Вторая тонкость описана в [3]: в этой же строке должен стоять перенос на следующую строку. Это если манифест помещается в архив сторонним архиватором.
Программа jar не включит в манифест последнюю строку из манифеста, если в конце не стоит перенос строки.
Ещё момент: в манифесте не должно быть пустых строк между строками. Будет выдана ошибка «java.io.IOException: invalid manifest format».

При использовании команды echo надо следить только за пробелом в конце строки с main-class.

Второй способ

В данном способе избегаем ошибки с пробелом в main-class.

Третий способ

Включили код нужной библиотеки в исполняемый файл.

Запуск исполняемого jar-файла

Файл calculator.jar исполняемым не является. А вот helloworld.jar можно запустить.
Если архив был создан первыми двумя способами, то рядом с ним в одном каталоге должна находится папка lib с файлом calculator.jar. Такие ограничения из-за того, что в манифесте в class-path указан путь относительно исполняемого файла.

Читать еще:  Ошибка steam api dll скачать

При использовании третьего способа нужные библиотеки включаются в исполняемый файл. Держать рядом нужные библиотеки не требуется. Запускается аналогично.

Как быть с приложениями JavaEE

Аналогично. Только библиотеки для компиляции нужно брать у сервера приложений, который используется. Если я использую JBoss, то для компиляции сервлета мне нужно будет выполнить примерно следующее

Структура архива JavaEE-приложения должна соответствовать определенному формату. Например

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

Надеюсь, данная статья станет для кого-нибудь шпаргалкой для работы с Java в командной строке. Данные навыки помогут понять содержание и смысл Ant-скриптов и ответить на собеседовании на более каверзные вопросы, чем «Какая IDE Вам больше нравится?».

How to Create a Chat Console Application in Java using Socket

1. Overview of the Java Chat Application

There can be multiple clients connect to a server and they can chat to each other, just like in a chat room where everyone can see other users’ messages. There’s no private chat between two users, for simplicity.

After getting connected to the server, a user must provide his or her name to enter the chat. The server sends a list of currently online users to the new user.

Every user is notified when a new user arrives and when a user has gone. Each message is prefixed with the username to keep track who sent the message.

And finally, the user says ‘bye’ to quit the chat.

The application consists of two parts: server and client. Each part can run independently on separate computers.

Now, let’s see how to code this Java chat application in details.

2. Create the Chat Server Program

The ChatServer >UserThread is created to serve that client. Since each connection is processed in a separate thread, the server is able to handle multiple clients at the same time.

The following is source code of the ChatServer class:

As you can see, the ChatServer >Set collections to keep track the names and threads of the connected clients. Set is used because it doesn’t allow duplication and the order of elements does not matter:

An important method in the ChatServer >broadcast() which deliver a message from one client to all others clients:

The UserThread class is responsible for reading messages sent from the client and broadcasting messages to all other clients. First, it sends a list of online users to the new user. Then it reads the username and notifies other users about the new user.

The following code is of the UserThread class:

Then it enters a loop of reading message from the user and sending it to all other users, until the user sends ‘bye’ indicating he or she is going to quit. And finally it notifies other users about the disconnection of this user and closes the connection.

3. Create the Chat Client Program

The ChatClient starts the client program, connects to a server specified by hostname/IP address and port number. Once the connection is made, it creates and starts two threads ReadThread and WriteThread .

Here is source code of the ChatClient class:

The ReadThread is responsible for reading input from the server and printing it to the console repeatedly, until the client disconnects. This class is implemented as follows:

And the WriteThread is responsible for reading input from the user and sending it to the server, continuously until the user types ‘bye’ to end the chat. This class is implemented as follows:

The reasons for running these two threads simultaneously is that the reading operation always blocks the current thread (both reading user’s input from command line and reading server’s input via network). That means if the current thread is waiting for the user’s input, it can’t read input from the server.

Therefore, two separate threads are used to make the client responsive: it can display messages from other users while reading message from the current user.

That’s how the chat application is designed. For more details, you can read the comments in the source code provided. But there are no many comments because the code is self-explanatory.

4. How to Run the Chat Server

This starts the server listening on the port number 8989, and you see the following output in the server once it started:

The server is waiting for new clients forever, so you have to press Ctrl + C to terminate it.

5. How to Run a Chat Client

This tells the client to connect to the server at localhost on port 8989. Then you see the following message in the server’s console:

And in the client’s console:

You see, the server tells the client how many users are connected, but there’s no user at this time. Then the program asks for the username:

Enter a username, say John, and then you can start chatting:

Now, let’s start the second client with username is Peter. At this time, you see the server tells that there’s one online user is John:

The user John is notified about new user Peter:

Читать еще:  Arrays copyof java

Type some messages from John and Peter and you see each user sees other’s messages, just like talking in a chat room.

Now, John wants to quit so he types ‘bye’- the client program terminates, and you see the following output in the server’s console:

Peter also gets a message from the server:

That’s basically how the chat application is running. You can test it with more clients and the application is still running smoothly. The following screenshot illustrates a test with 4 clients:

Now, it’s your time to play around with this chat application with the source code attached.

Related Java Network Tutorials:

Other Java network tutorials:

About the Author:

Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook.

Interactive Console Applications in Java

Learn how to make your applications pay more attention to what users are telling them.

Join the DZone community and get the full member experience.

Console applications come in several different forms:

    Applications having a text user interface that prov >Examples include the file manager Midnight Commander, the Linux tool menuconfig, or the Lynx browser.

For developing such applications, you can use one of the following Java libraries: Lanterna, Charva, or Java Curses.

  • Programs that take all input as command-line arguments. Most commands in Unix-like operating systems belong to this category.

Many Java libraries for parsing command-line arguments exist: Apache Commons-CLI, JOpt Simple, args4j, JCommander, Jewel CLI, and many other.

  • Command-line interface shells, where the user issues commands to the program in the form of successive lines of text.

Examples include Unix shells such as bash, or REPL environments such as JShell, which is planned to be included in Java 9.

The Java libraries Spring Shell and Cliche help creating this kind of applications.

Interactive console applications that prompt the user to provide information. Instead of issuing commands as in the case of shell applications, the user controls the program in a more limited way, by specifying some parameter values or choosing an option from a list.

The last type of console applications in the above list is the typical choice when starting to learn a new programming language. However, people tend to switch to one of the other types when implementing «serious» console applications. If the number of input parameters is relatively small, programs taking the input as command-line arguments are preferred, in order to allow pipelining. Otherwise, a shell interface or a GUI-like text interface are usually more appropriate.

So, are interactive console applications that prompt for user input still relevant today, or are they on the brink of extinction? I assume that many such applications are still written, but they usually don’t end up being widely known, because they are mostly created for personal use or as prototypes.

If you decide to write such an application, you have to read user input in an interactive manner. What is the best way to do this in Java? Let’s look at the most frequently used approaches:

  • Wrapping the standard input stream in a BufferedReader and reading user input line by line:

It is your responsibility to parse the input.

  • Using a java.io.Console, which allows you to read not only ordinary text, but also passwords, by suppressing echoing:

Console does not provide methods for parsing the input.

All of the above methods have drawbacks. An ideal solution would allow both parsing the input and reading passwords. If your application needs to read sensitive data, you are forced to use a java.io.Console, because there is no easy way to suppress echoing for the standard input stream. Aside of the annoying fact that you have to parse yourself the input, there is another problem with this solution: your virtual machine may not have a Console. This happens if the virtual machine has not been started from an interactive command line or if the standard input and output streams have been redirected. When running your application in an IDE, System.console() usually returns null.

Console is a final class with a private constructor. A virtual machine has at most one instance of this class, which can be obtained by invoking System.console() . You cannot provide your own Console implementation. What you can do instead, is to introduce an abstraction layer that provides the same functionality. By writing code that interacts only with this abstraction layer and not directly with a Console instance, you can handle the case of System.console() returning null.

This is the approach I took to develop Text-IO, a library for creating interactive console applications. The abstraction layer, which in Text-IO is represented by the TextTerminal interface, is extremely simple: a text terminal is only required to provide methods for printing a line of text and for reading a line of text, optionally masking the input. By default, the Text-IO library tries to use a text terminal backed by the java.io.Console. If the virtual machine has no console device, a Swing-based terminal is used instead. (The mechanism for choosing a text terminal is actually more complex and provides a Service Provider Interface for configuring additional text terminals.)

Читать еще:  Java dfile encoding utf 8

Some other useful features of the Text-IO library include:

  • Support for reading values with various data types.
  • The ability to specify default values.
  • The ability to specify constraints on the input values (format patterns, value ranges, length constraints etc.).
  • The ability to select one or more values from a list.
  • The ability to customize the error messages.

The code fragment below illustrates the use of Text-IO:

An example session using the above code produces the following output:

Click here to see an animated image of this example session in a Swing-based console.

A further advantage of using Text-IO is that you can easily test your code by implementing a mock text terminal that provides the desired input for your test case.

Библиотека примеров приложений Java

Оглавление
Консольное приложение

Простейший аплет
Аплет с параметрами
Комбинированное приложение
Консольное с окном Frame
Аплет с окном Frame
Комбинированное с окном Frame
Библиотека классов
Аплет с обработкой событий
Консольное с обработкой событий

2.1. Простое консольное приложение

В примере показана структура простого консольного приложения Java. Это приложение вводит число с клавиатуры, а затем отображает его на консоли.

Немного теории

Главный класс консольного приложения должен называться точно так же, как и файл исходного текста этого класса.

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

В качестве стандартного потока вывода консольное приложение использует поток java.lang.System.out, а в качестве стандартного потока ввода — java.lang.System.in. Есть и стандартный поток для вывода сообщений об ошибках — java.lang.System.err.

Описание примера

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

В классе SimpleConsoleApp есть поле szAppName класса String, конструктор и один метод с именем main:

Статический метод main не возвращает никакого значения и потому имеет тип void. В качестве единственного аргумента этому методу передается массив строк параметров запуска приложения.

Конструктор класса SimpleConsoleApp вызывается при создании объекта данного класса. Заметим, что при запуске консольного приложения объект главного класса не создается. При необходимости вы можете создать такой объект в методе main.

В нашем приложении конструктор выполняет очень простую задачу — он инициализирует поле szAppName, записывая в него ссылку на строку названия приложения:

Рассмотрим теперь исходный текст метода main.

Внутри этого метода мы определили несколько переменных, которые будут использованы для ввода с консоли целого числа:

Далее метод main создает объект sc класса SimpleConsoleApp:

Это приводит к вызову конструктора, инициализирующего поле szAppName. Следующая строка выводит название приложения на консоль, обращаясь к указанному полю:

Для вывода в стандартный выходной поток мы применили метод println, добавляющий после выведенной строки символы возврата каретки и перевода строки. В результате приглашение для ввода числа, расположенное в исходном тексте строкой ниже, будет отображено с новой строки:

Здесь мы воспользовались методом print, не вызывающем при выводе перевод строки. Поэтому текстовый курсор остановится сразу за строкой «Enter number: «.

Теперь о вводе строки с клавиатуры.

Мы применили метод read, вызвав его для стандартного потока ввода java.lang.System.in. Заметим, что во время работы этого метода, а также в процессе преобразования полученного массива символов в целое число возможно возникновение исключений. Поэтому мы заключили фрагмент кода, выполняющий эти функции, в блок try-catch:

Метод read считывает символы с клавиатуры и записывает их в массив байт с именем bKbd. Этот метод возвращает управление, когда пользователь закончил ввод и нажал клавишу . При этом в переменную iCnt записывается количество прочитанных символов.

Далее мы должны преобразовать последовательность введенных символов в число (ожидается, что пользователь будет вводить цифры). Для этого мы выполняем промежуточное преобразование массива символов в текстовую строку класса String, удаляем из нее символы возврата каретки и перевода строки, а затем создаем на базе полученной строки объект класса Integer.

Создание строки выполняется так:

Строка String содержит 16-разрядные символы Unicode. Чтобы преобразовать массив байт в строку Unicode, мы задаем значение старшего байта во втором параметре конструктора, равное нулю.

Удаление символов возврата каретки и перевода строки выполняется при помощи класса StringTokenizer, предназначенного для разбора текстовых строк. Создавая объект этого класса, мы передаем конструктору через второй параметр список символов-разделителей:

Метод nextElement возвращает первый элемент строки до разделителя, то есть в нашем случае всю строку до символов возврата каретки и перевода строки.

Далее строка преобразуется в объект класса Integer (целое число):

В процессе этого преобразования возможно возникновение исключения java.lang.NumberFormatException (например, если пользователь ввел текстовую строку, которую невозможно преобразовать в численное значение). Блок catch выводит название исключения на консоль.

На следующем этапе мы преобразуем объект Integer к примитивному типу int, вызывая для этого метод intValue:

Таким образом мы воспользовались классом Integer для преобразования текстовой строки в значение типа int. Результат этого преобразования затем отображается на консоли:

Ссылка на основную публикацию