01 января 2008

Classpath. Подключение сторонних библиотек

Иногда при написание программ на java необходимо подключать библиотеки сторонних разработчиков, которые не входят в Java SDK. В этом случае нам пригодится переменная окружения (параметр) classpath. Если в этой переменной прописать путь к какой либо, одной или нескольким, директориям, то все файл с расширением *.class этих директорий будут автоматически подключены к нашему проекту, и мы сможем импортировать классы из них.

Рассмотрим как добавить определённый каталог в эту переменную.

ОС Windows: Панель управления - Свойства системы - Дополнительно - Переменные среды - Системные переменные.
Находим переменную ClASSPATH, если нету, то создаём новую, значение переменной ClASSPATH : .;Z:\Dir1\Dir2\class_dir\ ,
первая точка указывает на текущую директорию, дальше через точку с запятой перечисляем нужные каталоги.

ОС Linux:
Достаточно в шеле указать значение переменной, с помощью команды:

export CLASSPATH=$CLASSPATH:/dir1/dir2/class_dir/

Существует другой способ, при запуске программы можно непосредственно указывать путь к jar файлам (или каталогам с файлами), делается это с помощью параметра cp (classpath) .

в Windows:
java -classpath .;"{путь к файлу}\имя_файла.jar" javaprogram
в Linux:
java -
classpath \{путь к каталогу c jar файлами} javaprogram

Есть ещё один не рекомендуемый способ, поэтому я про него ничего писать не буду.

И последнее, если вы используете какие то IDE (среды разработки) , то задача упрощается, поскольку они предоставят вам удобный графический интерфейс для управления переменной classpath и подключением библиотек. Думаю в будущем этот вопрос также будет рассмотрен.

4 комментария:

black zorro комментирует...

Важный момент, про который постоянно забывают новички (да и более продвинутые товарищи полагающиеся на генерацию classpath с помощью java ide и не проверяющие что же там она делает)

Для примера у нас есть есть следующий класс выполняющий некоторые действия (свой класс или библиотека написанная товарищами из Индии - не важно)


package pack1;

public class Foo {
public void makeFoo (){
System.out.println ("foo");
}

public static void main(String[] args) {
new Foo ().makeFoo();
}
}


Затем, спустя некоторое время была выпущена новая версия этой библиотеки. Так что теперь метод makeFoo выводит не слово "foo", а слово "bar".

package pack1;

public class Foo {
public void makeFoo (){
System.out.println ("bar");
}

public static void main(String[] args) {
new Foo ().makeFoo();
}
}


Эти библиотеки были помещены внутрь jar-архивов с именами test41.jar и test4.jar, соотвественно.
Посмотрите на результаты которые получаются при вызове:

java -cp test4.jar;test41.jar pack1.Foo
makeBar

java -cp test41.jar;test4.jar pack1.Foo
makeFoo

Порядок следования архивов jar в classpath является важным и он задает порядок приоритета. Меняя местами архивы мы получаем различное поведение. Часто это приводит к плоховыявляемым и непонятным ошибкам.


--- замечание к материалу ---
Указание к параметру -classpath и -cp есть и для windows и linux. По вашей цитате создается впечатление, что одна опция только в windows, а вторая - только для linux-a.
Также знака равно после "-cp=" нет. И там и там используется пробел для разделения команды от, собственно, имен архивов или каталогов (проверил под linux-ой и в sun java и в gnu java).

Rumoku комментирует...

интересный момент с порядком следования библиотек(я про такое не знал).
правда непонятно зачем включать в проект две одинаковых библиотеки разных версий?

black zorro комментирует...

Специально так делать не нужно, а вот неспециально так бывает часто.
Например, хостинг у которого в shared папке версия библиотеки X, а для работы приложения нужна библиотека Y.
Я даже помню хитрые алгоритмы в ряде книжек с переименованием файлов по правилу
A-foo.jar
Z-foo.jar
Так чтобы загрузчик (похоже это особенность его алгоритма) сначала грузил A (т.е. нужную версию).
--- цитата из прошлого поста ---
(да и более продвинутые товарищи полагающиеся на генерацию classpath с помощью java ide и не проверяющие что же там она делает)
--- ---

Dr.XaoS комментирует...

А что за ерунда в первом абзаце?
Насколько я знаю, подключение всех jar-файлов из каталога появилось только в 1.6 версии, и для этого в конце нужно ставить wildcard'ы типа звездочки.

Только что наткнулся на вопрос студента, который уже "обгуглился", но все еще пытается подключить библиотеки заданием пути к каталогу с jar'никами. Полез сам гуглить и вот статья, которая говорит, что так и надо делать. :-\

http://mindprod.com/jgloss/classpath.html