Теперь быстренько разберемся classpath, так как это достаточно важная тема для разработки на Java. Естественно я тут не смогу разобрать все тонкости и хитрости, но постараюсь представить самое необходимое чтобы было понимание этой темы. Для желающих разобраться глубже приведу линки для самостоятельного изучения. Ну и как всегда гугль в помощь.
Чтобы понимать что происходит под капотом у любой Java IDE когда она собирает проект и запускает его надо хоть немного попрактиковаться в использовании компилятора javac, среды исполнения java и понять classpath.
По существу classpath указывает компилятору или виртуальной машине где искать классы необходимые для сборки проекта или же его запуска. Немного об этом мы уже узнали тут. Теперь разберемся с этим получше.
Указать где компилятору или виртуальной машине искать классы можно через ключ –classpath или же системную переменную окружения CLASSPATH. Мы рассмотрим оба этих варианта.
Начнем с простого. Вернемся к нашему проекту Hello World (00004E_HelloWorld), там где мы разделили его на два файла Hello.java и Word.java.
Теперь попробуем создать исполняемый (jar) файл этого проекта из среды Eclipse. Так как скомпилированные, читай готовые к исполнению, файлы в Java имеют расширение class, а классов в реальных программах, могут быть сотни и тысячи, то их собирают в один или несколько jar архивов и таким образом запускают. То есть уже существует не россыпь файлов с расширением class, а один или несколько jar файлов.
И так! Понеслась! Воспользуемся Export для создания jar
После этого мы получим файл HelloWorld.jar готовый к исполнению на виртуальной машине java. Запустим его из командной строки:
Запускать jar файлы надо с ключом –jar как показано на скрине выше. Если этот ключ не использовать то вылетит ошибка:
Нам сообщили что не знают где искать главный (main) класс для HelloWorld.jar. Но запустить все же можно и без ключа –jar, но уже воспользовавшись на ключом –classpath, для которого существует сокращенный вариант –cp. Вот как это можно сделать:
Почему строчка запуска выглядит именно так? Вспоминаем что именно класс Hello.java содержит у нас метод main.
Класс Word.java такого метода не имеет.
Как я уже говорил метод main – это точка входа в программу, то есть место от куда начинается ее выполнение и поэтому виртуальной машине java надо знать, от куда надо начинать выполнять программу. Если она не может найти метод main, то она начинает ругаться, как это было показано выше.
И так в нашей строчке
java -cp HelloWorld.jar Hello
мы указали что искать метод main надо в классе Hello (расширение .class опускается) по пути HelloWorld.jar. Jar и zip архивы рассматриваются виртуальной машиной как каталоги, поэтому их надо указывать по полному имени с расширением.
Теперь скомпилируем наши классы Hello.java и Word.java самостоятельно из командной строки без помощи Eclipse, чтобы еще глубже понять как все работает. Для чистоты эксперимента рекомендую удалить все файлы с расширением .class и .jar из каталога bin.
Для начал просто скомпилируем исходники в class файлы без упаковки их в jar, чтобы было понятнее.
Переходим в коневой каталог 00004E_HelloWorld и от туда даем команду компиляции
javac -encoding utf8 -d bin src\Hello.java src\Word.java
Поскольку у нас программа состоит из двух классов Hello и Word, то их обоих сразу надо указать компилятору. Кроме того так же надо указать и кодировочку исходников. Так же мы указали папку bin – это то куда будут складываться откомпилированные файлы.
Теперь у нас в каталоге bin два файла Hello.class и Word.class. Перейдем в него чтобы запустить программу.
Все работает. Но файлики у нас там лежат россыпью классво .class
Теперь упакуем эти файлики .class в jar архив командой
jar cf HelloWorld.jar Hello.class Word.class
и попробуем запустить HelloWorld.jar
И вылетела ошибочка. Почему так? Ведь у нас уже есть jar файл в который упакованы оба класса.
Но все равно не работает. Это происходит потому, что внутри jar файла мы не указали какой файл у нас имеет метод main.
Запустить наш jar файл все таки можно указав дополнительно, какой класс содержит метод main.
java -cp HelloWorld.jar Hello
Теперь все работает. Но согласитесь так запускать jar файл не удобно, так как всегда надо знать какой класс содержит метод main. Если вы смотрели внимательно, то видимо заметили внутри архива HelloWorld.jar папку META-INF. В ней содержится файл MANIFEST.MF
Вот в нем и должна содержаться информация о классе содержащем метод main, но пока в нем ее нет.
Исправим эту ошибочку. Удалим файлик HelloWorld.jar и создадим его заново, но уже с добавлением информации о классе содержащим метод main. Сделаем это следующей командой
jar cfe HelloWorld.jar Hello Hello.class Word.class
И запустим файл HelloWorld.jar уже как полагается без танцев с бубном.
Как видим все работает нормально. Это произошло потому, что файл MANIFEST.MF уже содержит информацию о классе содержащем метод main.
Ну вот теперь мы имеем хоть какое-то представление о том что происходит когда какая-либо IDE создает исполняемый jar файл, а так же получили представление о classpath. В следующей статье мы немного углубим его.
P.S. Так же стоит знать что по умолчанию для виртуальной машины java доступны все классы стандартной библиотеки java, а так же все классы в текущем каталоге от куда запускается главный класс содержащий метод main.
Ну и на последок ссылка где про classpath рассказано достаточно подробно. Правда я не знаю как долго она проживет.
Спасибо за статью
ОтветитьУдалитьПожалуйста
УдалитьСпасибо!!!
ОтветитьУдалитьИ вам пожалуйста :)
УдалитьПожалуйста
ОтветитьУдалитьСпасибо большое!
ОтветитьУдалитьПожалуйста!
УдалитьКруть! Если когда-нибудь решите создать курс (особенно по андроид), дайте знать!
ОтветитьУдалитьПожалуйста! В планах есть но кода будет время на это не знаю. Работе конца края нет
УдалитьСпасибо. Интересно и подробно.
ОтветитьУдалитьПожалуйста
УдалитьПризнателен за статью :)
ОтветитьУдалитьПожалуйста
УдалитьСпасибо, человечище
ОтветитьУдалитьПросто и понятно !! На примерах !! Душевное Спасибо!!!
ОтветитьУдалитьДушевное пожалуйста
Удалить