2009-11-10 5 views
15

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

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

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

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

+0

Вы пробовали положить конфиг вне де баночке, в его собственном файле фляги в пути относительно application.jar (../conf/config.jar)? Если вы это сделаете, я думаю, вы можете установить classpath, указывающий на это jar config в манифесте приложения, и вы можете установить новую конфигурацию, изменяя config.jar. Хотелось бы, чтобы у меня было больше времени, чтобы сделать демоверсию, чтобы подтвердить мой ответ, но я не могу ... поэтому я написал это как комментарий – JuanZe

+0

Вы имеете в виду, а не внутри JAR? – Guss

+0

да, а не внутри той же банки, что и приложение, помещая конфигурацию внутри второй банки ... – JuanZe

ответ

20

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

например. (Предполагается, что «новая-конфигурация» представляет собой каталог, содержащий файл переопределенном свойства)

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

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

+2

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

1

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

3

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

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

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

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

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

Для получения информации о том, как класс погрузочные работы см:

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

+0

Это действительно проблема. Я понимаю, что нет никакого способа обойти это, кроме запуска приложения по-другому - как было предложено alasdairg, или написания некоторого пользовательского кода загрузки. Благодарю. – Guss

13

При использовании -jar опции для запуска приложения:

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

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

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

Spring Конфигурация Отрывок

<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 
+0

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

+0

Как запустить приложение? Я бы подумал, что переданные параметры будут скрыты для пользователя, запустив приложение через скрипт Webstart, .bat или .sh и т. Д. – Adamski

+0

Нет - пользователи запускают приложение из командной строки, передавая требуемые параметры - даты , файлы для обработки и т. д. – Guss

 Смежные вопросы

  • Нет связанных вопросов^_^