Macos — Запуск программ на Java в bash


Содержание

Запуск консольного приложения java в Mac Os по клику

Есть простое консольное приложение.
Скомпилировал, скачал jre для WIN, LINUX, MAC OS.
Написал простой файлик .bat для запуска в WIN и .sh для запуска в LINUX.
Пробую использовать .sh для запуска в MAC OS.
Из консоли работает как надо. По двойному клику не хочет.
Выставлял права, прописывал свойство executable, менял расширение на .command — не запускается по двойному клику.
В консоли ./run.command и ./ru.sh — срабатывает правильно.
Содержание ./run.command и ./ru.sh :
../jre/jre1.8.0_152.jre/Contents/Home/bin/java -cp .:commons-validator-1.4.0.jar:jsoup-1.11.2.jar Main

Но по клику на .sh и .command не работает, выдает ошибки

Last login: Wed Jan 17 10:26:27 on ttys001
Mac-pc:

pc$ /Users/pc/Desktop/urw/run.command ; exit;
Error: Could not find or load main class .Main
logout
Saving session.
. copying shared history.
. saving history. truncating history files.
. completed.

Last login: Wed Jan 17 17:36:09 on ttys000
Mac-pc:

pc$ /Users/pc/Desktop/urw/run.sh ; exit;
/Users/pc/Desktop/urw/run.sh: line 1: ../jre/jre1.8.0_152.jre/Contents/Home/bin/java: No such file or directory
logout
Saving session.
. copying shared history.
. saving history. truncating history files.
. completed.

Пожалуйста, помогите запустить по двойному клику. Спасибо.

Как создать AppleScript- или Command файл для запуска приложения Java в Mac OS?

Я создал приложение Java и должен подготовить его для запуска на любой ОС. Для Windows я создал пакетный файл, подобный этому launch-win32.bat :

Для linux я создал оболочку script, подобную этой launch-linux.sh :

Теперь я думал, что MacOS будет очень похож на Linux, поскольку оба они основаны на UNIX, и я попросил друга с Mac попытаться запустить shellscript для запуска моего приложения. Но это не удалось с помощью NoClassDefFoundError :

Похоже, что синтаксис java-команды неверен, поскольку путь к классам не добавлен в java-программу должным образом. Моя главная проблема заключается в следующем:

  • MacOS официально не поддерживается Sun/Oracle, поэтому трудно найти хорошую документацию. (Мне нужна последняя JRE 7).
  • Я никогда не использовал Mac или не имел возможности попробовать, как он может работать.

Итак, мои вопросы:

  • Как запустить java из командной строки в MacOS, какой правильный синтаксис? Или почему команда выше не работает? (Например, основное отличие между Windows и Linux заключается в использовании точки с запятой ; вместо разделителя двоеточия : для пути к классам.)
  • Как следует указывать файл MacOS script? .sh или .scpt или .command или это похоже на Linux, что окончание файла не имеет значения до тех пор, пока вы chmod +x файл script?

Управление Java classpath (UNIX и Mac OS X)

Classpath представляет собой связующее звено между исполняемым модулем Java и файловой системой. Он определяет, где интерпретатор ищет файлы класса для загрузки. Основная идея состоит в том, что иерархия файловой системы отражает иерархию пакета Java, а classpath определяет, какие директории в файловой системе служат корневыми каталогами для иерархии пакета Java.

К несчастью, файловые системы сложны, и сильно зависят от платформы, и они не точно соответствуют пакетам Java. Соответственно, classpath долгие годы является источником постоянного раздражения как для новых пользователей, так и для опытных Java-программистов. Он — далеко не самый приятный компонент Java-платформы. Он — раздражающая помеха, которая вынуждает вас задерживаться на работе в попытках устранить маленькую проблему, которая упорно не хочет решаться.

Хорошая IDE типа Eclipse может защитить вас от некоторых трудностей управления classpath, но только отчасти, и только если ничего не случится (а что-то постоянно случается). Следовательно, каждый Java-программист непременно должен полностью понимать classpath. Только при глубоком понимании вы можете надеяться на устранение сложных проблем, которые возникают из-за classpath.

В этой статье я излагаю все, что вам нужно знать о Java classpath (и соответствующем sourcepath) в UNIX, Linux, и Mac OS X. Следование методам, изложенным здесь, послужит вам руководством на этом пути и должно помочь в решении большинства проблем с classpath.

Структура пакета

Освоение classpath начинается с исходного кода. Каждый класс принадлежит пакету, и этот пакет программ должен следовать стандартным соглашениям по именованию. Сделаем краткий обзор: Имя пакета начинается с двухуровневого обратного имени домена, например com.example или edu.poly. За ним следует по крайней мере еще одно слово, которое описывает содержимое пакета программ. Например, так как я являюсь владельцем имени домена elharo.com, если бы я должен был написать класс Fraction, я мог бы расположить его в одном из следующих пакетов:

  • com.elharo.math
  • com.elharo.numbers
  • com.elharo.math.algebra.fields

После обратного имени домена используйте только имена подпакета, состоящие из одного слова. Не используйте сокращения и пишите все слова правильно. Используйте программу проверки орфографии, если вам это нужно. Большой процент проблем, связанных с classpath, вызван использованием одного слова в исходной программе и слегка измененного написания или сокращения этого слова в файловой системе. Единственный разумный выбор — всегда использовать правильно написанные, несокращенные имена.

Полное имя пакета должно быть написано строчными буквами, даже для имен собственных и аббревиатур, которые обычно пишутся заглавными буквами. Имя пакета должно быть составлено только из ASCII-символов. Хотя компилятор принимает имена пакета, записанные на иврите, кириллице, греческом, и других шрифтах, многие файловые системы не принимают их. Как вы скоро увидите, эти имена пакетов будут выполнять двойную задачу в качестве имен директорий. Следовательно, имена пакетов (и классов) должны быть ограничены ASCII. (В то время как в пакетах Java и именах классов используется юникод, многие файловые системы ещё его не понимают. Простое копирование файла в систему с другой кодировкой по умолчанию может помешать компилятору и интерпретатору найти правильные классы.)

Одноразовая программа

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

Не экономьте на имени вашего пакета! Это только приведет к катастрофе в конечном счете. Если вам нужно имя домена, купите его. Если имена слишком длинные, приобретите имя покороче. (Я однажды приобрел xom.nu, таким образом мой префикс пакета составлял только шесть символов.) Не располагайте ваши классы в пакете по умолчанию (пакете, который вы получаете, если не включаете оператор пакета в класс). Если доступ пакета мешает объектам посылать сообщения, добавьте больше общедоступных методов в классы. Каждый класс, который будет использоваться чаще, чем один раз, должен быть в пакете.

Структура директории

Следующий шаг — это организовать ваши исходные файлы так, чтобы они соответствовали структуре пакета. Создайте где-нибудь чистую, пустую директорию. Для целей этой статьи я назову ее project (проект). Внутри этой директории создайте еще две директории: bin и src. (Некоторые люди предпочитают называть их build и source соответственно.)

Затем внутри директории src создайте иерархию, которая зеркально отображает вашу иерархию пакета. Например, при классе с именем com.elharo.math.Fraction, я бы расположил директорию com в директории src. Затем я бы создал директорию elharo внутри директории com. Затем я бы поместил директорию math внутрь директории elharo. И наконец, я бы поместил Fraction.java внутри этой директории math, как показано на рисунке 1:

Рисунок 1. Структура директории отражает структуру пакета

Очень важно: никогда не помещайте ничего, кроме исходного кода в вашу директорию src. Обычно единственные файлы, которые вы помещаете туда, это .java-файлы. Иногда вы можете расположить .html-файлы (для Javadoc) или другие типы исходного кода в эту директорию. Тем не менее, вы не должны помещать .class-файлы или другие скомпилированные, сгенерированные артефакты в эту иерархию. Выполнение этого действия непременно приведет к катастрофе. К сожалению, компилятор javac сделает именно так, если вы не проявите осторожность. В следующем разделе я покажу вам, как наладить это.

Компилирование

Компилирование кода Java — коварная вещь, потому что вам нужно отслеживать несколько связанных, но разных вещей:


  • Целевой файл, который вы компилируете.
  • Директорию, где компилятор ищет .java-файлы, которые импортирует целевой файл.
  • Директорию, где компилятор ищет .class-файлы, которые импортирует целевой файл.
  • Директорию, куда компилятор помещает скомпилированный вывод.

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

Файл для компиляции

Первое, что вы определяете, — это .java-файл, который вы собираетесь компилировать. Это дается как путь к файлу из текущей рабочей директории. Например, предположим, что вы в директории project, как показывает Рисунок 1. Эта директория содержит директорию src. Директория src содержит директорию com, которая содержит директорию example, которая содержит файл Fraction.java. Следующая командная строка компилирует его:

Если путь неверен, вы получите сообщение об ошибке следующего рода:

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

Эта проблема обычно указывает на неверно набранный путь, но она также может означать, что вы не находитесь в той директории, в которой вы рассчитываете находиться. В этом примере вы должны убедиться, что текущая рабочая директория — это директория проекта. Здесь поможет команда pwd. Например, следующее сообщает мне, что на самом деле я в project/src, а не в директории project:

Мне нужно выполнить команду cd . перед компилированием.

Куда идет вывод

Предполагая, что синтаксические ошибки отсутствуют, javac располагает скомпилированный .class-файл в той же директории, где находится .java файл. Вам это не нужно. Смешивание файлов .class и .java затрудняет очистку скомпилированных файлов без случайного удаления .java-файлов, которые вы хотите сохранить. Это делает чистую сборку проблематичной и ведет к возникновению различных проблем. Это также затрудняет упаковку в jar только что скомпилированных .class-файлов при распространении двоичного файла. В связи с этим вам нужно велеть компилятору поместить скомпилированный вывод в совершенно другую директорию. Переключатель -d точно определяет директорию вывода (обычно называемую bin, build, или classes):

Сейчас вывод такой, как показано на рисунке 2. Обратите внимание, что javac создал полную иерархию директорий com/elharo/math. Вам не нужно делать это вручную.

Рисунок 2. Параллельные иерархии исходных и скомпилированных файлов

Путь к исходным файлам (sourcepath)

Директория, где Java ищет исходные файлы называется sourcepath. В схеме, намеченной здесь, это src директория. Это директория, которая содержит иерархию исходных файлов, организованных в их собственных директориях. Это не директория com или src/com/elharo/math.

Большинство проектов используют больше, чем один класс и больше, чем один пакет. Они связаны импортирующими операторами и полностью подготовленными для пакета именами класса. Например, предположим, что вы сейчас создаете новый класс MainFrame в пакете com.elharo.gui, как показано в листинге 1:

Листинг 1. Класс в одном пакете может импортировать класс в другом

Этот класс использует класс com.elharo.math.Fraction в другом пакете из класса MainFrame. Установка исходных файлов сейчас такова, как показано на рисунке 3. (Я удалил скомпилированный вывод из предыдущего шага. Я всегда смогу скомпилировать его снова.)

Рисунок 3. Структура исходных файлов для нескольких пакетов

Сейчас давайте посмотрим, что происходит, когда я пытаюсь скомпилировать MainFrame.java так, как я делал это ранее:

Листинг 2. Компилирование MainFrame.java

Ошибки в листинге 2 произошли, потому что хотя javac знал, где найти MainFrame.java, он не знал, где найти Fraction.java. (Вы подумаете, что будет достаточно разумно заметить соответствующие иерархии пакета, но это не так.) Раскрывая секрет, я должен указать sourcepath. Он указывает директории, где компилятор ищет иерархию исходных файлов. В листинге 2 это src. Итак, я использую опцию -sourcepath, например, так:

Сейчас программа компилируется без ошибок и производит вывод, показанный на рисунке 4. Обратите внимание, что javac также скомпилировал файл Fraction.java, на который ссылается файл, который я компилировал.

Рисунок 4. Многоклассовый вывод

Компилирование множественных директорий в sourcepath

На самом деле вы можете иметь более одной директории в вашем sourcepath (они разделяются двоеточиями), хотя это обычно не нужно. Например, если я хочу включить и локальную директорию src, и директорию /Users/elharo/Projects/XOM/src, где я храню исходный код для другого проекта, я могу компилировать следующим образом:

Эта команда не компилирует каждый файл, найденный в какой-либо из этих иерархий. Она компилирует только файлы, на который делается ссылка прямо или косвенно одним .java-файлом, который я явно прошу скомпилировать.

Гораздо чаще у вас будет одна директория source для .java файлов, но много директорий для классов или JAR-архивов, где расположены прекомпилированные библиотеки сторонних производителей. Такова роль classpath.

Установка classpath

В средних и больших проектах перекомпилирование каждого файла каждый раз может занимать очень много времени. Вы можете облегчить нагрузку, отдельно компилируя и храня независимые части одного и того же проекта в разных классах или директориях bin. Эти директории добавляются к classpath.

Есть несколько способов добавить класс к classpath. Переключатель командной строки -classpath, тем не менее, — единственное, что следует использовать. Например, предположим, что я хочу импортировать файлы из другого проекта, который я до этого скомпилировал в директорию /Users/elharo/classes. Затем я бы добавил -classpath /Users/elharo/classes к командной строке следующим образом:

Теперь предположим, что мне нужно добавить две директории, /Users/elharo/project1/classes и /Users/elharo/project2/classes. Тогда я бы включил обе, разделив их двоеточием, как показано далее:

Директории верхнего уровня

Обратите внимание, что директории, которые я указываю здесь, все являются директориями верхнего уровня, которые содержат иерархию, подобную com/elharo/foo/bar or nu/xom/util. Директории, имена которых соответствуют именам пакета (com, elharo, math, etc.) никогда не включаются прямо в sourcepath или classpath.

Цукерберг рекомендует:  Html - Оцените работу htmlcss

Конечно, вы можете использовать различные формы соответствующих путей, если вы предпочитаете. Например, если project1 и project2 — «братья» текущей рабочей директории (то есть, они имеют одну и ту же родительскую директорию), тогда я бы мог сделать на них ссылку на них следующим образом:

До сих пор я предполагал, что программа завершается сама и не использует никакие отдельно скомпилированные библиотеки сторонних производителей. Но если она использует их, вам нужно их также добавить к classpath. Библиотеки обычно размещаются как JAR-файлы, например junit.jar или icu4j.jar. В этом случае вы добавляете именно JAR-файл к classpath, а не директорию, которая содержит его. (По существу, JAR-файл действует как директория, которая содержит скомпилированные .class-файлы.) Например, следующая команда добавляет три вещи к classpath: директорию /Users/elharo/classes, файл icu4j.jar в текущей рабочей директории, и файл junit.jar в /Users/elharo/lib:

JAR-файлы используются только для .class-файлов и classpath, а не для .java-файлов и sourcepath.

Запуск программы


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

  • classpath.
  • Полностью классифицированное для пакета имя класса, которое содержит ваш main () method.

Вам не нужно указывать sourcepath.

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

и метод main () был в классе com.elharo.gui.MainFrame, тогда вы будете запускать программу следующим образом:

Обратите особое внимание, что последний элемент командной строки — это имя класса. Это не имя файла. Оно не заканчивается на .java или .class. Этот класс должен быть найден где-нибудь в classpath.

Другие места, где располагаются классы

Я настоятельно рекомендую вам точно указывать classpath, когда вы компилируете и когда запускаете программу. Есть другие места, куда вы можете помещать файлы так, что они добавляются к classpath и обнаруживаются и компилятором javac и интерпретатором java. Эти опции экономят лишь немного набора текста, и они делают это за счет большого количества отлаживания, когда — а не если — вы случайно располагаете старую версию класса в classpath.

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

Текущая рабочая директория

Компилятор всегда добавляет текущую рабочую директорию (.) к classpath, запрашиваете вы это явно или нет. Очень легко забыть, что находится или не находится в той же директории, где и вы. Таким образом, попытайтесь избежать размещения любых классов или иерархий в ваш проект или начальную директорию. Вместо этого всегда храните вещи аккуратно разделенными на src-директории для .java-файлов и директории bin для .class-файлов.

CLASSPATH

Через некоторое время вы можете устать от ручного добавления директорий bin и JAR-архивов к classpath. Тогда вы можете открыть для себя переменную среды classpath. Вы можете добавить директории и JAR-архивы к переменной среды classpath только один раз. Затем вам не придется набирать их пути каждый раз, когда вы запускаете javac или java.

Сопротивляйтесь соблазну. Это только вызовет новые проблемы, если вы загрузите неверный класс или неверную версию класса. Любое время, которое вы сэкономите на наборе текста, будет отнято у вас отладкой проблем, вызванных случайной загрузкой неверных классов, и оно будет в сотни раз больше. Есть более надежные способы автоматизировать classpath и избежать набора текста.

jre/lib/ext

JAR-архивы, расположенные в вашей jre/lib/ext директории, добавляются к classpath всех приложений, запущенных на данной виртуальной машине. Хотя это кажется удобным, эта ошибка даст о себе знать позже, она сродни добавлению директорий к переменной среды classpath. Рано или поздно (возможно рано), вы загрузите неверную версию класса из места, о котором вы даже и не думаете, и потеряете много времени на отладку.

Эта проблема особенно серьезна во время использования серверных приложений. Убедитесь, что сервер, который вы используете, не имеет никаких дополнительных JAR’ов в своей директории jre/lib/ext. Проблемы, вызванные неверной версией JAR-архива в classpath может быть чрезвычайно трудно устранить, если вы не распознаете признаки или не знаете, что конкретно искать. Чтобы избежать этих проблем, некоторые среды разработки зашли настолько далеко, что пишут свои собственные программы загрузки классов, которые обходят обычные загрузочные механизмы кода Java.

jre/lib/endorsed

JAR-файлы в директории jre/lib/endorsed также добавляются к classpath всех приложений, запущенных на данной виртуальной машине. Разница заключается в том, что эти файлы на самом деле добавляются скорее к bootclasspath, чем обычному classpath, и могут замещать стандартные классы, поставляющиеся с JDK. Этот подход особенно полезен для модернизации XML-анализатора и устранения ошибок в виртуальной машине.

Еще раз повторю, что хотя этот способ кажется удобным, это долговременная ошибка по той же самой причине. Если вам нужно переместить классы JDK, используйте опцию -Xbootclasspath/p во время запуска, чтобы избежать случайной загрузки неверной версии класса:

Автоматизация управления classpath

Вам следует научиться использовать молоток, прежде чем вы возьмете в руки «пистолет» для забивания гвоздей. Точно так же, вы сперва должны научится чувствовать себя уверенно при ручном управлении классами, прежде чем вы попытаетесь использовать более мощные инструменты. Тем не менее, существуют инструменты, разработанные для того, чтобы уменьшить мучения от операций с sourcepath и classpath. Чаще всего они делают это, организуя для вас файлы в соответствии с теми принципами, которые я изложил в этой статье.

Большинство интегрированных сред разработки, например Eclipse и NetBeans автоматизируют управление classpath и помогают в некоторых его аспектах. Например, когда вы меняете имя пакета, Eclipse предлагает передвинуть соответствующий .java-файл, чтобы он совпадал, как показано на рисунке 5:

Рисунок 5. Быстрое исправление classpath в Eclipse

Помните, однако, что эти IDE по-прежнему располагаются на вершине файловой системы, что должно быть должным образом настроено, особенно, если вам нужно осуществить интеграцию с другими инструментами и другими IDE. Главный вклад этих инструментов состоит в том, что переключатели командной строки заменяются графическими диалогами, древовидными списками и вкладками; основная же файловая структура остается прежней.

Ant — это, фактически, стандартный инструмент для автоматизации процесса сборки. В отличие от расположения директорий в jre/lib/ext или в переменной среды CLASSPATH, Ant на самом деле позволяет вам создать пошаговые процессы сборки. Вам все еще нужно настроить classpath в файле build.xml редактора Ant и вручную расположить исходные файлы в правильных директориях, но, по крайней мере, вам не нужно указывать их повторно каждый раз во время компиляции.

Maven

Maven идет еще дальше, чем Ant в организации и автоматизации процесса сборки и связанных с ним операций с classpath. Maven обеспечивает рациональную установку по умолчанию, которая помогает вам компоновать простые проекты лишь с несколькими строками кода, если вы располагает исходные файлы там, где Maven ожидает их найти. Вам все-таки придется координировать иерархию файловой системы и иерархию пакета. Maven особенно полезен при управлении зависимостями в библиотеках сторонних производителей, хотя его не так легко настраивать, как Ant.

В заключение

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

  • Располагайте каждый класс в пакете.
  • Точно следуйте стандартам называния пакета и класса и правилам использования прописных букв.
  • Убедитесь, что иерархия вашего пакета соответствует иерархии директории.
  • Всегда используйте опцию -d для javac.
  • Никогда ничего не помещайте в jre/lib/ext.
  • Никогда ничего не помещайте в jre/lib/endorsed.
  • Никогда не помещайте .java-файлы в ту же самую директорию, что и .class-файлы.
  • Никогда не помещайте никакие .java или .class-файлы в текущую рабочую директорию.

Один последний совет: много проблем с classpath, требующих большого расхода времени, вращаются вокруг простых ошибок, таких как неправильное написание имени директории или компилирование из неверной директории. Если вы не можете определить, что идет не так, попросите друга или коллегу взглянуть на вашу проблему. Часто я обнаруживаю, что нахожусь слишком близко к ошибке, чтобы её увидеть, а для кого-то ещё она сразу же очевидна. Еще одна пара глаз — это эффективный метод устранения ошибок.

Classpath не легок, но он управляем, и есть способ справиться с его сумасшествием. Немного осторожности и внимания к заданию имён, аргументам командной строки, и структуре директорий должны помочь вам скомпилировать и запустить программы с минимальными трудностями.

Читайте другие интересные статьи

Понравилась статья, расскажи о ней друзьям, нажми кнопку!

Launchd. Автозапуск программ при загрузке Mac OS X


В этот раз поговорим про автозапуск программ при загрузке Mac OS X. Статья рассчитана на продвинутых пользователей и тех кто стремится к этому уровню. В MacOS X имеется встроенное решение для выполнения автоматизации различных действий — Automator. Программа очень продвинутая в умелых руках, о которой можно писать целые книги, однако сегодня речь пойдет о другом.

Mac OS X, как и другие UNIX-подобные операционные системы, предоставляет просто потрясающие возможности по управлению процессами, демонами и запуском приложений по расписанию. К примеру, можно запустить собственный веб-сервер, выполнять скрипты или программы по расписанию, монтировать файловые системы и т.д. Применений на самом деле масса.

Не так давно, я писал про ограничение оборотов кулера на Mac, таким способом можно снизить шум на MacBook, Mac mini или iMac. Остался, правда, не раскрытым один достаточно важный вопрос, а именно, как автоматизировать запуск нашей утилиты, управляющей работой кулера? Согласитесь, не очень удобно всякий раз лезть в консоль и запускать её вручную. Так что, предлагаю на этом конкретном примере разобраться с Launchd и ознакомиться с сервисами и демонами в Mac OS X.

Services (сервисы) и Daemons (демоны) Mac OS X.

Для начала немного теории. «Сервисы» и «демоны» являются системными службами и обеспечивают работу системы, однако предназначены немного для разных целей, соответственно и работают тоже по-разному. Давайте разберемся, что конкретно делают эти «сервисы» и «демоны» и в чем разница между ними?

Начнем с того, что делают они практически всё, начиная с запуска WEB-сервера и заканчивая монтированием файловых систем и запуском графической оболочки. Разница же между ними в том, что «сервисы», как правило, запускаются после загрузки графического интерфейса и предназначены, в основном, для запуска графических приложений; «демоны» могут запускаться до загрузки графики, в фоновом режиме и предназначены запуска bash/shell скриптов, серверов (служб) и всевозможных консольных утилит.

Сервисы представляют из себя конфигурационные XML файлы с расширением .plist, которые во время загрузки Mac OS обрабатываются и запускаются фоновым процессом launchd. Файлы .plist находятся в директориях LaunchAgents или LaunchDaemons (в зависимости от их предназначения). В системе имеется несколько директорий LaunchAgents и LaunchDaemons. Это ключевой момент в понимании того как происходит работа системы и его стоит рассмотреть подробнее:

Все конфигурационные файлы, находящиеся в данной директории, выполняются при входе в систему (логине) КОНКРЕТНОГО пользователя (в каталоге которого они находятся) и с правами этого пользователя, не затрагивая при этом систему и других пользователей.

Системная директория. Все находящиеся в ней конфигурационные файлы исполняются при логине ЛЮБОГО пользователя с правами вошедшего пользователя.

Снова системная директория, но все конфиги исполняются от лица администратора (root) на уровне системы. Программа или сценарий будет исполнен вне зависимости от того, вошёл какой-либо пользователь в систему или нет. Это и есть нужный нам вариант.

Системная директория зарезервированная OS X. Все конфиги находящиеся в ней являются системными, запускаются при логине любого пользователя. Лучше сюда не лезть без нужды.

Системная директория зарезервированная OS X. Все конфиги, находящиеся в ней, являются системными и запускаются при загрузке системы с правами root. Сюда тоже не стоит лезть.

Как вы уже догадались, директории LaunchAgents используются для запуска «сервисов», а LaunchDaemons — для запуска «демонов».

Файлы конфигурации .plist

Как уже говорилось, все конфигурационные .plist-файлы запускаются фоновым процессом launchd во время загрузки OS X.

Сами по себе .plist-файлы всего лишь «сценарии», набор неких правил, для запуска других приложений и не являются самостоятельными программами, однако отличаются гибкостью и функциональностью в настройке. Пора рассмотреть пример, свой файл сценария я назвал my.fancontrol.plist:

Пока вообще ничего не понятно, ну это мы сейчас поправим. Напомню задачу — необходимо при запуске Mac OS X, до входа пользователя в систему (а то какая-то несправедливость получится) в терминале выполнить команду:

Тем самым мы запускаем утилиту smc и передаем ей два параметра — указываем кулер и выставляем ему максимальную частоту оборотов. Выше вы видите получившийся код нашего сценария со стандартной шапкой формата XML (для всех служб и демонов она одинакова).

Что я тут понаписал? Итак, основные ключи и параметры .plist-файла:

Ключ «Label» задаёт название сервиса, которое будет отображаться в Мониторинге системы или логах утилиты Консоль.

Ключ «ProgramArguments» содержит массив, в котором указаны путь к исполняемому файлу (или bash/shell скрипту) и параметры его запуска. Заметьте, что каждый параметр необходимо записывать отдельно.

Ключ «RunAtLoad» указывает системе, что правило нужно исполнить при загрузке ОС. Есть еще много всяких ключей и параметров, например для запуска приложения по расписанию или через определенные промежутки времени. Этой статьёй я даю лишь толчок для понимания дальнейшего изучения Launchd в OS X и не ставлю целью создать полноценное руководство.

файл создан. Осталось переместить его в папку-назначение (/Library/LaunchDaemons), поправить права доступа и атрибуты, и перезагрузиться. В терминале пишем:

Активировать или дезактивировать работающий сценарии можно выполнив команды:

Если считаете статью полезной,
не ленитесь ставить лайки и делиться с друзьями.

Где Java установлен на Mac OS X?

Я только что загрузил Java 7u17 на Mac OS 10.7.5 из здесь и затем успешно установил его. Чтобы выполнить Программирование JNI, мне нужно знать, где Java установлена на моем Mac.

Я думал, что внутри /Library/Java/JavaVirtualMachines/ папка, будет папка с именем 1.7.0.jdk или что-то, но потом я обнаружил, что папка пуста. Это было подтверждено управлением ls /Library/Java/JavaVirtualMachines/ в терминале. Я попытался найти его, чтобы узнать, был ли он установлен где-то еще, но похоже, это ничего не дает.

может кто-нибудь сказать мне, где Java установлен на моем Mac?

14 ответов

использовать /usr/libexec/java_home -v 1.7 команда на оболочке терминала, чтобы выяснить, где находится ваш домашний каталог java 1.7

Если вы просто хотите узнать домашний каталог вашей последней версии java, опустите версию. например, /usr/libexec/java_home -v

оказывается, что у меня на самом деле был установлен Java 7 JRE, а не JDK. Правильная ссылка для скачивания -здесь. После его установки, jdk1.7.0jdk отображается в каталоге JavaVirtualMachines.

Цукерберг рекомендует:  RxJava и основы реактивной разработки

можно использовать echo $(/usr/libexec/java_home) команда в вашем терминале, чтобы узнать путь, где устанавливается Java.

Если вы устанавливаете только JRE, он, кажется, помещается в:

используйте функцию поиска unix для поиска установленных javas.


структура пакетов Java Mac OS немного отличается от Windows. Не расстраивайтесь из-за этого, так как разработчику просто нужно установить PATH и JAVA_HOME .

так .bash_profile set JAVA_HOME и PATH Как ниже. Этот пример для Java 6:

попробуйте это, это простой способ найти java установлен путь в Mac OS X,

1 ) /библиотека i.e Macintosh HD / библиотека

2) нажмите на библиотеку, в которой мы найдем папку Java.

3) таким образом, окончательный путь

надеюсь, что это помощь для кого-то .

просто писать /Library/Java/JavaVirtualMachines/
в Go To Folder перейти в Finder

отредактировано: псевдоним текущей версии java — /Library/Java/Home

Я только что установил JDK для версии 21 Java SE 7 и обнаружил, что он установлен в другом каталоге от Java 6 от Apple. Он находится в /Library / Java. вместо этого в /System/Library / Java. Запуск /usr/libexec / java_home-V 1.7 против-V 1.6 подтвердит это.

я попробовал решение serkan, он нашел местоположение java 7 в OS X Mavericks. он находится в «/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/» но чтобы сделать его JDK по умолчанию, мне пришлось установить системную переменную JAVA_HOME .файл в домашнем каталоге на адрес «/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/» так что его и работает Теперь благодаря идее Серкана

Загрузка Java для компьютера Mac

Загружайте Java для ОС OS X непосредственно с веб-сайта компании Oracle.

Загрузка последней версии

Если для работы с программой или веб-страницей требуется установить программное обеспечение Java, можно загрузить текущую версию Java для ОС OS X непосредственно с веб-сайта компании Oracle.

Примечание. Можно также загрузить устаревшую версию Java SE 6 компании Apple, если вы используете программу, для работы которой требуется неподдерживаемая устаревшая версия.

Информация о продуктах, произведенных не компанией Apple, или о независимых веб-сайтах, неподконтрольных и не тестируемых компанией Apple, не носит рекомендательного характера и не рекламируются компанией. Компания Apple не несет никакой ответственности за выбор, функциональность и использование веб-сайтов или продукции сторонних производителей. Компания Apple также не несет ответственности за точность или достоверность данных, размещенных на веб-сайтах сторонних производителей. Помните, что использование любых сведений или продуктов, размещенных в Интернете, сопровождается риском. За дополнительной информацией обращайтесь к поставщику. Другие названия компаний или продуктов могут быть товарными знаками соответствующих владельцев.

Как компилировать и запускать программу Java с помощью командной строки

Хотя многие среды программирования позволяют компилировать и запускать программы, их также можно скомпилировать и запустить с помощью командной строки. У Windows и Mac есть свои собственные версии командной строки, на Mac OS она называется Терминал. Процесс компиляции и запуска для Windows и для Mac практически идентичен.

/.bash_profile и нажмите ↵ Enter . После этого перезапустите терминал.

Как скомпилировать Java код на Mac OS

Как скомпилировать Java код на Mac OS один из самых популярных вопросов. После этой статьи у Вас не останется никаких вопросов. Обещаю Вам, это элементарно.

Данный урок и последующие направлен для людей, которые хотят изучать Java (не путайте с JavaScript) на Mac OS, это совершенно разные языки программирования. Идею создать данную статью я почерпнул из учебников по изучению Java, где работа с консолью представлена так, что Вы чуть ли не гуру должны быть в этом направлении – и авторы искренне удивляются, почему Вы это не понимаете. Особенно это актуально для людей, которые только что начинают изучать Java или для тех, кто переходит с веб языков, например, PHP на данный язык и хочет постичь его основы и сразу же с первых минут попадает в полный просак.

Люди выполняют те задания, которые выдаются в учебниках, но консоль упрямо не понимает, что от нее хотят. Итак. Давайте разберемся по-порядку, в этой статье мы создадим самую элементарную, самую первую нашу программу “Hello World”, которая будет собственно, выводить данные слова в нашу консоль. Мы создадим файл, скопмилируем его и запустим, чтобы посмотреть, как работает наша новоиспеченная программа.

Первый шаг

Первое, что нужно сразу понять, это то, что Java уже установлена на Ваш комп (Apple). И Mac OS уже все понимает и знает, что к чему. Следовательно ограничимся только важными знаниями. И первое, что мы должны сделать, это создать любую папку на рабочем столе. И в этой папке создать любой файл с разрешением .java, в любом текстовом редакторе, я советую использовать Sublime Text 2 – скачайте в нете абсолютно бесплатно. В этой статье мы не будем вникать в код, просто тупо скопируйте это и вставьте в свой файл.

Управление Java classpath (UNIX и Mac OS X)

Classpath представляет собой связующее звено между исполняемым модулем Java и файловой системой. Он определяет, где интерпретатор ищет файлы класса для загрузки. Основная идея состоит в том, что иерархия файловой системы отражает иерархию пакета Java, а classpath определяет, какие директории в файловой системе служат корневыми каталогами для иерархии пакета Java.

К несчастью, файловые системы сложны, и сильно зависят от платформы, и они не точно соответствуют пакетам Java. Соответственно, classpath долгие годы является источником постоянного раздражения как для новых пользователей, так и для опытных Java-программистов. Он — далеко не самый приятный компонент Java-платформы. Он — раздражающая помеха, которая вынуждает вас задерживаться на работе в попытках устранить маленькую проблему, которая упорно не хочет решаться.

Хорошая IDE типа Eclipse может защитить вас от некоторых трудностей управления classpath, но только отчасти, и только если ничего не случится (а что-то постоянно случается). Следовательно, каждый Java-программист непременно должен полностью понимать classpath. Только при глубоком понимании вы можете надеяться на устранение сложных проблем, которые возникают из-за classpath.

В этой статье я излагаю все, что вам нужно знать о Java classpath (и соответствующем sourcepath) в UNIX, Linux, и Mac OS X. Следование методам, изложенным здесь, послужит вам руководством на этом пути и должно помочь в решении большинства проблем с classpath.

Структура пакета

Освоение classpath начинается с исходного кода. Каждый класс принадлежит пакету, и этот пакет программ должен следовать стандартным соглашениям по именованию. Сделаем краткий обзор: Имя пакета начинается с двухуровневого обратного имени домена, например com.example или edu.poly. За ним следует по крайней мере еще одно слово, которое описывает содержимое пакета программ. Например, так как я являюсь владельцем имени домена elharo.com, если бы я должен был написать класс Fraction, я мог бы расположить его в одном из следующих пакетов:

  • com.elharo.math
  • com.elharo.numbers
  • com.elharo.math.algebra.fields

После обратного имени домена используйте только имена подпакета, состоящие из одного слова. Не используйте сокращения и пишите все слова правильно. Используйте программу проверки орфографии, если вам это нужно. Большой процент проблем, связанных с classpath, вызван использованием одного слова в исходной программе и слегка измененного написания или сокращения этого слова в файловой системе. Единственный разумный выбор — всегда использовать правильно написанные, несокращенные имена.


Полное имя пакета должно быть написано строчными буквами, даже для имен собственных и аббревиатур, которые обычно пишутся заглавными буквами. Имя пакета должно быть составлено только из ASCII-символов. Хотя компилятор принимает имена пакета, записанные на иврите, кириллице, греческом, и других шрифтах, многие файловые системы не принимают их. Как вы скоро увидите, эти имена пакетов будут выполнять двойную задачу в качестве имен директорий. Следовательно, имена пакетов (и классов) должны быть ограничены ASCII. (В то время как в пакетах Java и именах классов используется юникод, многие файловые системы ещё его не понимают. Простое копирование файла в систему с другой кодировкой по умолчанию может помешать компилятору и интерпретатору найти правильные классы.)

Одноразовая программа

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

Не экономьте на имени вашего пакета! Это только приведет к катастрофе в конечном счете. Если вам нужно имя домена, купите его. Если имена слишком длинные, приобретите имя покороче. (Я однажды приобрел xom.nu, таким образом мой префикс пакета составлял только шесть символов.) Не располагайте ваши классы в пакете по умолчанию (пакете, который вы получаете, если не включаете оператор пакета в класс). Если доступ пакета мешает объектам посылать сообщения, добавьте больше общедоступных методов в классы. Каждый класс, который будет использоваться чаще, чем один раз, должен быть в пакете.

Структура директории

Следующий шаг — это организовать ваши исходные файлы так, чтобы они соответствовали структуре пакета. Создайте где-нибудь чистую, пустую директорию. Для целей этой статьи я назову ее project (проект). Внутри этой директории создайте еще две директории: bin и src. (Некоторые люди предпочитают называть их build и source соответственно.)

Затем внутри директории src создайте иерархию, которая зеркально отображает вашу иерархию пакета. Например, при классе с именем com.elharo.math.Fraction, я бы расположил директорию com в директории src. Затем я бы создал директорию elharo внутри директории com. Затем я бы поместил директорию math внутрь директории elharo. И наконец, я бы поместил Fraction.java внутри этой директории math, как показано на рисунке 1:

Рисунок 1. Структура директории отражает структуру пакета

Очень важно: никогда не помещайте ничего, кроме исходного кода в вашу директорию src. Обычно единственные файлы, которые вы помещаете туда, это .java-файлы. Иногда вы можете расположить .html-файлы (для Javadoc) или другие типы исходного кода в эту директорию. Тем не менее, вы не должны помещать .class-файлы или другие скомпилированные, сгенерированные артефакты в эту иерархию. Выполнение этого действия непременно приведет к катастрофе. К сожалению, компилятор javac сделает именно так, если вы не проявите осторожность. В следующем разделе я покажу вам, как наладить это.

Компилирование

Компилирование кода Java — коварная вещь, потому что вам нужно отслеживать несколько связанных, но разных вещей:

  • Целевой файл, который вы компилируете.
  • Директорию, где компилятор ищет .java-файлы, которые импортирует целевой файл.
  • Директорию, где компилятор ищет .class-файлы, которые импортирует целевой файл.
  • Директорию, куда компилятор помещает скомпилированный вывод.

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

Файл для компиляции

Первое, что вы определяете, — это .java-файл, который вы собираетесь компилировать. Это дается как путь к файлу из текущей рабочей директории. Например, предположим, что вы в директории project, как показывает Рисунок 1. Эта директория содержит директорию src. Директория src содержит директорию com, которая содержит директорию example, которая содержит файл Fraction.java. Следующая командная строка компилирует его:

Если путь неверен, вы получите сообщение об ошибке следующего рода:

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

Эта проблема обычно указывает на неверно набранный путь, но она также может означать, что вы не находитесь в той директории, в которой вы рассчитываете находиться. В этом примере вы должны убедиться, что текущая рабочая директория — это директория проекта. Здесь поможет команда pwd. Например, следующее сообщает мне, что на самом деле я в project/src, а не в директории project:

Мне нужно выполнить команду cd . перед компилированием.

Куда идет вывод

Предполагая, что синтаксические ошибки отсутствуют, javac располагает скомпилированный .class-файл в той же директории, где находится .java файл. Вам это не нужно. Смешивание файлов .class и .java затрудняет очистку скомпилированных файлов без случайного удаления .java-файлов, которые вы хотите сохранить. Это делает чистую сборку проблематичной и ведет к возникновению различных проблем. Это также затрудняет упаковку в jar только что скомпилированных .class-файлов при распространении двоичного файла. В связи с этим вам нужно велеть компилятору поместить скомпилированный вывод в совершенно другую директорию. Переключатель -d точно определяет директорию вывода (обычно называемую bin, build, или classes):

Сейчас вывод такой, как показано на рисунке 2. Обратите внимание, что javac создал полную иерархию директорий com/elharo/math. Вам не нужно делать это вручную.

Рисунок 2. Параллельные иерархии исходных и скомпилированных файлов

Путь к исходным файлам (sourcepath)

Директория, где Java ищет исходные файлы называется sourcepath. В схеме, намеченной здесь, это src директория. Это директория, которая содержит иерархию исходных файлов, организованных в их собственных директориях. Это не директория com или src/com/elharo/math.

Большинство проектов используют больше, чем один класс и больше, чем один пакет. Они связаны импортирующими операторами и полностью подготовленными для пакета именами класса. Например, предположим, что вы сейчас создаете новый класс MainFrame в пакете com.elharo.gui, как показано в листинге 1:

Листинг 1. Класс в одном пакете может импортировать класс в другом

Этот класс использует класс com.elharo.math.Fraction в другом пакете из класса MainFrame. Установка исходных файлов сейчас такова, как показано на рисунке 3. (Я удалил скомпилированный вывод из предыдущего шага. Я всегда смогу скомпилировать его снова.)

Рисунок 3. Структура исходных файлов для нескольких пакетов

Сейчас давайте посмотрим, что происходит, когда я пытаюсь скомпилировать MainFrame.java так, как я делал это ранее:

Листинг 2. Компилирование MainFrame.java

Ошибки в листинге 2 произошли, потому что хотя javac знал, где найти MainFrame.java, он не знал, где найти Fraction.java. (Вы подумаете, что будет достаточно разумно заметить соответствующие иерархии пакета, но это не так.) Раскрывая секрет, я должен указать sourcepath. Он указывает директории, где компилятор ищет иерархию исходных файлов. В листинге 2 это src. Итак, я использую опцию -sourcepath, например, так:

Сейчас программа компилируется без ошибок и производит вывод, показанный на рисунке 4. Обратите внимание, что javac также скомпилировал файл Fraction.java, на который ссылается файл, который я компилировал.

Рисунок 4. Многоклассовый вывод

Компилирование множественных директорий в sourcepath

На самом деле вы можете иметь более одной директории в вашем sourcepath (они разделяются двоеточиями), хотя это обычно не нужно. Например, если я хочу включить и локальную директорию src, и директорию /Users/elharo/Projects/XOM/src, где я храню исходный код для другого проекта, я могу компилировать следующим образом:

Эта команда не компилирует каждый файл, найденный в какой-либо из этих иерархий. Она компилирует только файлы, на который делается ссылка прямо или косвенно одним .java-файлом, который я явно прошу скомпилировать.


Гораздо чаще у вас будет одна директория source для .java файлов, но много директорий для классов или JAR-архивов, где расположены прекомпилированные библиотеки сторонних производителей. Такова роль classpath.

Цукерберг рекомендует:  Подсказка обработка нескольких событий одной функцией

Установка classpath

В средних и больших проектах перекомпилирование каждого файла каждый раз может занимать очень много времени. Вы можете облегчить нагрузку, отдельно компилируя и храня независимые части одного и того же проекта в разных классах или директориях bin. Эти директории добавляются к classpath.

Есть несколько способов добавить класс к classpath. Переключатель командной строки -classpath, тем не менее, — единственное, что следует использовать. Например, предположим, что я хочу импортировать файлы из другого проекта, который я до этого скомпилировал в директорию /Users/elharo/classes. Затем я бы добавил -classpath /Users/elharo/classes к командной строке следующим образом:

Теперь предположим, что мне нужно добавить две директории, /Users/elharo/project1/classes и /Users/elharo/project2/classes. Тогда я бы включил обе, разделив их двоеточием, как показано далее:

Директории верхнего уровня

Обратите внимание, что директории, которые я указываю здесь, все являются директориями верхнего уровня, которые содержат иерархию, подобную com/elharo/foo/bar or nu/xom/util. Директории, имена которых соответствуют именам пакета (com, elharo, math, etc.) никогда не включаются прямо в sourcepath или classpath.

Конечно, вы можете использовать различные формы соответствующих путей, если вы предпочитаете. Например, если project1 и project2 — «братья» текущей рабочей директории (то есть, они имеют одну и ту же родительскую директорию), тогда я бы мог сделать на них ссылку на них следующим образом:

До сих пор я предполагал, что программа завершается сама и не использует никакие отдельно скомпилированные библиотеки сторонних производителей. Но если она использует их, вам нужно их также добавить к classpath. Библиотеки обычно размещаются как JAR-файлы, например junit.jar или icu4j.jar. В этом случае вы добавляете именно JAR-файл к classpath, а не директорию, которая содержит его. (По существу, JAR-файл действует как директория, которая содержит скомпилированные .class-файлы.) Например, следующая команда добавляет три вещи к classpath: директорию /Users/elharo/classes, файл icu4j.jar в текущей рабочей директории, и файл junit.jar в /Users/elharo/lib:

JAR-файлы используются только для .class-файлов и classpath, а не для .java-файлов и sourcepath.

Запуск программы

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

  • classpath.
  • Полностью классифицированное для пакета имя класса, которое содержит ваш main () method.

Вам не нужно указывать sourcepath.

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

и метод main () был в классе com.elharo.gui.MainFrame, тогда вы будете запускать программу следующим образом:

Обратите особое внимание, что последний элемент командной строки — это имя класса. Это не имя файла. Оно не заканчивается на .java или .class. Этот класс должен быть найден где-нибудь в classpath.

Другие места, где располагаются классы

Я настоятельно рекомендую вам точно указывать classpath, когда вы компилируете и когда запускаете программу. Есть другие места, куда вы можете помещать файлы так, что они добавляются к classpath и обнаруживаются и компилятором javac и интерпретатором java. Эти опции экономят лишь немного набора текста, и они делают это за счет большого количества отлаживания, когда — а не если — вы случайно располагаете старую версию класса в classpath.

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

Текущая рабочая директория

Компилятор всегда добавляет текущую рабочую директорию (.) к classpath, запрашиваете вы это явно или нет. Очень легко забыть, что находится или не находится в той же директории, где и вы. Таким образом, попытайтесь избежать размещения любых классов или иерархий в ваш проект или начальную директорию. Вместо этого всегда храните вещи аккуратно разделенными на src-директории для .java-файлов и директории bin для .class-файлов.

CLASSPATH

Через некоторое время вы можете устать от ручного добавления директорий bin и JAR-архивов к classpath. Тогда вы можете открыть для себя переменную среды classpath. Вы можете добавить директории и JAR-архивы к переменной среды classpath только один раз. Затем вам не придется набирать их пути каждый раз, когда вы запускаете javac или java.

Сопротивляйтесь соблазну. Это только вызовет новые проблемы, если вы загрузите неверный класс или неверную версию класса. Любое время, которое вы сэкономите на наборе текста, будет отнято у вас отладкой проблем, вызванных случайной загрузкой неверных классов, и оно будет в сотни раз больше. Есть более надежные способы автоматизировать classpath и избежать набора текста.

jre/lib/ext

JAR-архивы, расположенные в вашей jre/lib/ext директории, добавляются к classpath всех приложений, запущенных на данной виртуальной машине. Хотя это кажется удобным, эта ошибка даст о себе знать позже, она сродни добавлению директорий к переменной среды classpath. Рано или поздно (возможно рано), вы загрузите неверную версию класса из места, о котором вы даже и не думаете, и потеряете много времени на отладку.

Эта проблема особенно серьезна во время использования серверных приложений. Убедитесь, что сервер, который вы используете, не имеет никаких дополнительных JAR’ов в своей директории jre/lib/ext. Проблемы, вызванные неверной версией JAR-архива в classpath может быть чрезвычайно трудно устранить, если вы не распознаете признаки или не знаете, что конкретно искать. Чтобы избежать этих проблем, некоторые среды разработки зашли настолько далеко, что пишут свои собственные программы загрузки классов, которые обходят обычные загрузочные механизмы кода Java.

jre/lib/endorsed

JAR-файлы в директории jre/lib/endorsed также добавляются к classpath всех приложений, запущенных на данной виртуальной машине. Разница заключается в том, что эти файлы на самом деле добавляются скорее к bootclasspath, чем обычному classpath, и могут замещать стандартные классы, поставляющиеся с JDK. Этот подход особенно полезен для модернизации XML-анализатора и устранения ошибок в виртуальной машине.

Еще раз повторю, что хотя этот способ кажется удобным, это долговременная ошибка по той же самой причине. Если вам нужно переместить классы JDK, используйте опцию -Xbootclasspath/p во время запуска, чтобы избежать случайной загрузки неверной версии класса:

Автоматизация управления classpath

Вам следует научиться использовать молоток, прежде чем вы возьмете в руки «пистолет» для забивания гвоздей. Точно так же, вы сперва должны научится чувствовать себя уверенно при ручном управлении классами, прежде чем вы попытаетесь использовать более мощные инструменты. Тем не менее, существуют инструменты, разработанные для того, чтобы уменьшить мучения от операций с sourcepath и classpath. Чаще всего они делают это, организуя для вас файлы в соответствии с теми принципами, которые я изложил в этой статье.

Большинство интегрированных сред разработки, например Eclipse и NetBeans автоматизируют управление classpath и помогают в некоторых его аспектах. Например, когда вы меняете имя пакета, Eclipse предлагает передвинуть соответствующий .java-файл, чтобы он совпадал, как показано на рисунке 5:

Рисунок 5. Быстрое исправление classpath в Eclipse

Помните, однако, что эти IDE по-прежнему располагаются на вершине файловой системы, что должно быть должным образом настроено, особенно, если вам нужно осуществить интеграцию с другими инструментами и другими IDE. Главный вклад этих инструментов состоит в том, что переключатели командной строки заменяются графическими диалогами, древовидными списками и вкладками; основная же файловая структура остается прежней.

Ant — это, фактически, стандартный инструмент для автоматизации процесса сборки. В отличие от расположения директорий в jre/lib/ext или в переменной среды CLASSPATH, Ant на самом деле позволяет вам создать пошаговые процессы сборки. Вам все еще нужно настроить classpath в файле build.xml редактора Ant и вручную расположить исходные файлы в правильных директориях, но, по крайней мере, вам не нужно указывать их повторно каждый раз во время компиляции.


Maven

Maven идет еще дальше, чем Ant в организации и автоматизации процесса сборки и связанных с ним операций с classpath. Maven обеспечивает рациональную установку по умолчанию, которая помогает вам компоновать простые проекты лишь с несколькими строками кода, если вы располагает исходные файлы там, где Maven ожидает их найти. Вам все-таки придется координировать иерархию файловой системы и иерархию пакета. Maven особенно полезен при управлении зависимостями в библиотеках сторонних производителей, хотя его не так легко настраивать, как Ant.

В заключение

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

  • Располагайте каждый класс в пакете.
  • Точно следуйте стандартам называния пакета и класса и правилам использования прописных букв.
  • Убедитесь, что иерархия вашего пакета соответствует иерархии директории.
  • Всегда используйте опцию -d для javac.
  • Никогда ничего не помещайте в jre/lib/ext.
  • Никогда ничего не помещайте в jre/lib/endorsed.
  • Никогда не помещайте .java-файлы в ту же самую директорию, что и .class-файлы.
  • Никогда не помещайте никакие .java или .class-файлы в текущую рабочую директорию.

Один последний совет: много проблем с classpath, требующих большого расхода времени, вращаются вокруг простых ошибок, таких как неправильное написание имени директории или компилирование из неверной директории. Если вы не можете определить, что идет не так, попросите друга или коллегу взглянуть на вашу проблему. Часто я обнаруживаю, что нахожусь слишком близко к ошибке, чтобы её увидеть, а для кого-то ещё она сразу же очевидна. Еще одна пара глаз — это эффективный метод устранения ошибок.

Classpath не легок, но он управляем, и есть способ справиться с его сумасшествием. Немного осторожности и внимания к заданию имён, аргументам командной строки, и структуре директорий должны помочь вам скомпилировать и запустить программы с минимальными трудностями.

Читайте другие интересные статьи

Понравилась статья, расскажи о ней друзьям, нажми кнопку!

Launchd. Автозапуск программ при загрузке Mac OS X

В этот раз поговорим про автозапуск программ при загрузке Mac OS X. Статья рассчитана на продвинутых пользователей и тех кто стремится к этому уровню. В MacOS X имеется встроенное решение для выполнения автоматизации различных действий — Automator. Программа очень продвинутая в умелых руках, о которой можно писать целые книги, однако сегодня речь пойдет о другом.

Mac OS X, как и другие UNIX-подобные операционные системы, предоставляет просто потрясающие возможности по управлению процессами, демонами и запуском приложений по расписанию. К примеру, можно запустить собственный веб-сервер, выполнять скрипты или программы по расписанию, монтировать файловые системы и т.д. Применений на самом деле масса.

Не так давно, я писал про ограничение оборотов кулера на Mac, таким способом можно снизить шум на MacBook, Mac mini или iMac. Остался, правда, не раскрытым один достаточно важный вопрос, а именно, как автоматизировать запуск нашей утилиты, управляющей работой кулера? Согласитесь, не очень удобно всякий раз лезть в консоль и запускать её вручную. Так что, предлагаю на этом конкретном примере разобраться с Launchd и ознакомиться с сервисами и демонами в Mac OS X.

Services (сервисы) и Daemons (демоны) Mac OS X.

Для начала немного теории. «Сервисы» и «демоны» являются системными службами и обеспечивают работу системы, однако предназначены немного для разных целей, соответственно и работают тоже по-разному. Давайте разберемся, что конкретно делают эти «сервисы» и «демоны» и в чем разница между ними?

Начнем с того, что делают они практически всё, начиная с запуска WEB-сервера и заканчивая монтированием файловых систем и запуском графической оболочки. Разница же между ними в том, что «сервисы», как правило, запускаются после загрузки графического интерфейса и предназначены, в основном, для запуска графических приложений; «демоны» могут запускаться до загрузки графики, в фоновом режиме и предназначены запуска bash/shell скриптов, серверов (служб) и всевозможных консольных утилит.

Сервисы представляют из себя конфигурационные XML файлы с расширением .plist, которые во время загрузки Mac OS обрабатываются и запускаются фоновым процессом launchd. Файлы .plist находятся в директориях LaunchAgents или LaunchDaemons (в зависимости от их предназначения). В системе имеется несколько директорий LaunchAgents и LaunchDaemons. Это ключевой момент в понимании того как происходит работа системы и его стоит рассмотреть подробнее:

Все конфигурационные файлы, находящиеся в данной директории, выполняются при входе в систему (логине) КОНКРЕТНОГО пользователя (в каталоге которого они находятся) и с правами этого пользователя, не затрагивая при этом систему и других пользователей.

Системная директория. Все находящиеся в ней конфигурационные файлы исполняются при логине ЛЮБОГО пользователя с правами вошедшего пользователя.

Снова системная директория, но все конфиги исполняются от лица администратора (root) на уровне системы. Программа или сценарий будет исполнен вне зависимости от того, вошёл какой-либо пользователь в систему или нет. Это и есть нужный нам вариант.

Системная директория зарезервированная OS X. Все конфиги находящиеся в ней являются системными, запускаются при логине любого пользователя. Лучше сюда не лезть без нужды.

Системная директория зарезервированная OS X. Все конфиги, находящиеся в ней, являются системными и запускаются при загрузке системы с правами root. Сюда тоже не стоит лезть.

Как вы уже догадались, директории LaunchAgents используются для запуска «сервисов», а LaunchDaemons — для запуска «демонов».

Файлы конфигурации .plist

Как уже говорилось, все конфигурационные .plist-файлы запускаются фоновым процессом launchd во время загрузки OS X.

Сами по себе .plist-файлы всего лишь «сценарии», набор неких правил, для запуска других приложений и не являются самостоятельными программами, однако отличаются гибкостью и функциональностью в настройке. Пора рассмотреть пример, свой файл сценария я назвал my.fancontrol.plist:

Пока вообще ничего не понятно, ну это мы сейчас поправим. Напомню задачу — необходимо при запуске Mac OS X, до входа пользователя в систему (а то какая-то несправедливость получится) в терминале выполнить команду:

Тем самым мы запускаем утилиту smc и передаем ей два параметра — указываем кулер и выставляем ему максимальную частоту оборотов. Выше вы видите получившийся код нашего сценария со стандартной шапкой формата XML (для всех служб и демонов она одинакова).

Что я тут понаписал? Итак, основные ключи и параметры .plist-файла:

Ключ «Label» задаёт название сервиса, которое будет отображаться в Мониторинге системы или логах утилиты Консоль.

Ключ «ProgramArguments» содержит массив, в котором указаны путь к исполняемому файлу (или bash/shell скрипту) и параметры его запуска. Заметьте, что каждый параметр необходимо записывать отдельно.

Ключ «RunAtLoad» указывает системе, что правило нужно исполнить при загрузке ОС. Есть еще много всяких ключей и параметров, например для запуска приложения по расписанию или через определенные промежутки времени. Этой статьёй я даю лишь толчок для понимания дальнейшего изучения Launchd в OS X и не ставлю целью создать полноценное руководство.

файл создан. Осталось переместить его в папку-назначение (/Library/LaunchDaemons), поправить права доступа и атрибуты, и перезагрузиться. В терминале пишем:

Активировать или дезактивировать работающий сценарии можно выполнив команды:

Если считаете статью полезной,
не ленитесь ставить лайки и делиться с друзьями.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих