Могу ли я использовать classpath для переопределения файла в запущенном банке? - PullRequest
15 голосов
/ 10 ноября 2009

У меня есть файл JAR, который содержит приложение, а также файлы конфигурации для этого приложения. Приложение загружает файлы конфигурации из пути к классам (используя ClassLoader.getResource()), и его зависимости полностью удовлетворяются с помощью файлов конфигурации, вставленных в файл JAR.

Иногда я хочу, чтобы приложение запускалось с несколько иной конфигурацией (в частности, я хочу переопределить URL JDBC, чтобы он указывал на другую базу данных), поэтому я создаю новый файл конфигурации, сохраняю его в правильной структуре каталогов (которая означает в каталоге /config записи classpath), и я хочу сделать что-то вроде этого:

java -cp new-config:. -jar application.jar

Но я не могу получить в classpath запись пути new-config перед содержимым JAR приложения. Это жестко запрограммировано, что содержание JAR всегда является первым на пути к классам?

Ответы [ 4 ]

20 голосов
/ 10 ноября 2009

Почему бы просто не вызвать приложение без указания -jar и вместо этого явно указать основной класс приложения? Это позволит вам поместить ваш new-config и application.jar в путь к классам в требуемом порядке:

например. (при условии, что «new-config» - это каталог, содержащий переопределенный файл свойств)

java -cp new-config:application.jar Application.Main.Class

Я считаю, что имя основного класса можно найти в файле MANIFEST.MF внутри банки ....

13 голосов
/ 10 ноября 2009

Когда вы используете опцию -jar для запуска приложения:

... файл JAR является источником всех пользовательские классы и другой пользовательский класс настройки пути игнорируются .

как описано здесь . Обходной путь должен был бы указать путь к классу в манифесте файла jar, чтобы включить дополнительный путь (описанный здесь ).

Однако, учитывая, что вы говорите только о внесении изменений в конфигурацию, вы можете выбрать другой подход, который не зависит от пути к классам. Например, я обычно настраиваю свои приложения через Spring, используя файлы свойств для определения местоположения баз данных и т. Д. Моя конфигурация Spring согласована в тестовой среде, в среде QA и в реальных средах, но я передаю другой файл свойств в качестве аргумента командной строки при запуске приложения .

Фрагмент конфигурации пружины

<bean id="MyDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
    <property name="url" value="jdbc:microsoft:sqlserver://${dbServer}:${dbPort};DatabaseName=${dbName}"/>
    <property name="username" value="${dbUserName}"/>
    <property name="password" value="${dbPassword}"/>
    <property name="suppressClose" value="false"/>
</bean>

Фрагмент файла свойств

dbServer=MyServer
dbPort=1433
dbName=MyDb
dbUserName=Me
dbPassword=foobar
3 голосов
/ 10 ноября 2009

Архив JAR, указанный в опции -jar, переопределяет все остальные значения.

Обычно вам нужно сделать это с помощью внешнего конфигурационного файла или создать собственное решение с ClassLoader.getResource().

Мы используем специальное решение для решения этой проблемы - мы загружаем внутренние свойства следующим образом:

final Properties p = new Properties();
p.load(DefaultConfiguration.class.getResourceAsStream("config.properties"));

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

Информацию о том, как работает загрузка классов, смотрите:

http://java.sun.com/javase/6/docs/technotes/tools/findingclasses.html

1 голос
/ 10 ноября 2009

Это может быть невозможно при использовании только CLASSPATH. Есть способы получить вызов ClassLoader.getResource(), используя статический путь для поиска ресурса. Если он это делает, он обходит CLASSPATH.

...