$ CLASSPATH и -cp с Java - PullRequest
       6

$ CLASSPATH и -cp с Java

4 голосов
/ 04 августа 2010
  • В этой записи опция -jar игнорирует все -cp и $ CLASSPATH.
  • В этой записи использование опции -cp также игнорирует $ CLASSPATH.

Есть ли для них веская причина?

Ответы [ 6 ]

7 голосов
/ 04 августа 2010

Это предотвращает конфликты в пути к классам, когда вы распространяете свое приложение для запуска в разных средах.В большинстве случаев вы хотите, чтобы ваше приложение было независимым от конкретной конфигурации платформы.Если $CLASSPATH содержит ссылки на классы с (неосознанно или сознательно) одинаковыми пакетом и именем класса, он получит приоритет в загрузке классов перед классами, которые вы включили в путь к классам вашего приложения.Это может привести к неожиданному поведению приложения или потенциальным дырам в безопасности.

5 голосов
/ 04 августа 2010

jar должен быть автономной программой с автономными библиотеками. Если вы хотите включить другие пути к классам, вам может потребоваться сделать что-то вроде

java -cp jar1:jar2:$CLASSPATH some.class.with.main

BalusC ответил на другой вопрос.

2 голосов
/ 04 августа 2010

Если вы действительно хотите, чтобы приложение запускалось с помощью «-jar», а также выбираете классы через переменную среды пользователя $ CLASSPATH, вы можете сделать это, создав для приложения собственный загрузчик классов.(Вы могли бы даже заставить ваше приложение искать аргумент "-cp" после аргумента "-jar".)

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

Если вы хотите заниматься хакерскими делами с помощью пути к классу приложения, более простой подход - создать скрипт-обертку, который собирает эффективный путь к классу, как вы хотите, а затем запускает приложение с опцией -cp.Вы могли бы даже извлечь "Class-path" из манифестов различных файлов JAR и включить это ...

1 голос
/ 04 августа 2010

Правильно или нет, мне не хватает флага -jar-cp.Это было бы очевидным и достаточно прямым, чтобы не быть угрозой безопасности или нарушать текущее поведение.

С такими API, как java.util.ServiceLoader , вполне разумно желать добавлять / удалять службыиз класса.Вам не нужно терять эту функциональность, потому что вы использовали Main-Class в своем манифесте.

1 голос
/ 04 августа 2010

Существует несколько причин, по которым переменная среды CLASSPATH игнорируется (и должна игнорироваться):

  1. Глобальный CLASSPATH для всех проектов вообще не имеет смысла.Это не может быть одинаково для всех проектов, и вам не нужен один массивный, который будет повторно применяться ко всем проектам.
  2. Вы не можете рассчитывать на его установку, поэтому в зависимости от этого это плохая идея,Код, который работает на одной машине, внезапно не работает, когда он перемещается.Как вы сообщаете необходимые настройки среды?Лучше не использовать их.
  3. Все серверы приложений Java EE имеют свои собственные соглашения (например, все файлы JAR в WEB-INF / lib и все файлы .class в классах WEB-INF / автоматически помещаются в CLASSPATH длявеб-приложение).
  4. Все серверы приложений Java EE игнорируют глобальный CLASSPATH.Они не рассчитывают на это.
  5. Все IDE Java имеют свои собственные соглашения для настройки проекта CLASSPATH.Изучите их.
  6. Все Java IDE игнорируют глобальный CLASSPATH.Они не рассчитывают на это.

У меня нет глобальной CLASSPATH на любой машине, которую я использую.Это необязательно.Я бы рекомендовал узнать, как работает CLASSPATH, и перестать полагаться на переменные среды.

0 голосов
/ 04 августа 2010

Нет достаточной разумной причины, чтобы объяснить эту кажущуюся "нелепость", по моим словам. Из одной из ошибок в базе данных ошибок Sun можно только сделать вывод, что разработчик не учел тот факт, что classpath можно было указать с помощью переменной среды CLASSPATH или с помощью параметра -cp. К тому времени, когда проблема была обнаружена, релиз был более или менее общедоступным, и это исправление могло вызвать проблемы обратной совместимости.

...