Pull to refresh

Comments 53

Когда-то еще давно сам реализовал для своего проекта подобную систему
Скриншот

И к слову о недостатках, разве при помощи рефлексии нельзя изменить значение финализированного поля?

   static void setFinalStatic(Field field, Object newValue) throws Exception {
      field.setAccessible(true);

      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, newValue);
   }
Если прочитать подробнее о таких методах (например, в первоисточнике приведенного хака: stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection), то можно сделать вывод, что такой подход может работать нестабильно, в частности из-за SecurityManager, не говоря уже о Android.
Библиотеке этого не нужно.
Ооо, не обратил внимания на автора :) Привет-привет) Но я бы и не относил это к недостаткам, эти переменные и незачем финализировать.
Привет-привет) Спасибо за замечание — подправил.
Основная причина вовсе не security manager — final-поля (и особенно static final) очень агрессивно инлайнятся. И, согласно спецификации, компилятор вовсе не обязан следить за их последующими изменениями. То есть даже если у вас получится поле изменить — вы не можете быть уверенным, что ваш код будет видеть новое значение
Библиотека интересная. А исходники будут?
Думаю да, если в этом есть необходимость. Так же постараемся сделан залив в maven репозиторий.
Ждем maven, А там будем посмотреть :)
Для использования не только в домашних поделках исходники лучше закинуть на github, а артифакты — в центральный репозиторий. Что бы была гарантия сборки проекта через год и через два. Даже при потере интереса авторами.
Библиотека должна быть представлена в Maven, иначе никакие промо статьи ей не помогут.
И, конечно, исходник должен быть в паблике.

Это самые верные доказательства, что библиотека готова к реальным проектам.
Спасибо за ссылку! Судя по описанию, действительно очень мощный фреймворк конфигурации, пока что самое мощное и удобное решение из всех, что я видел.

P.S. думаю вот эта ссылка лучше покажет все его преимущества: owner.aeonbits.org/docs/usage/
Несколько из другой степи этот фреймворк + тянуть 3 доп. библы для его работы это не айс.
В больших Java приложениях обычно уже используются библиотеки apache-commons и ничего дополнительного не нужно.
Судя по приведенной ссылке, не только commons
image

Так или иначе, я никому ничего не навязываю — естественно, что каждый будет использовать то, к чему привык.
Все приведенные выше библиотеки принадлежат к apache-commons.
Тем не менее, это три физически отдельных библиотеки
Вы написали:
Судя по приведенной ссылке, не только commons

Вам ответили, что все они принадлежат к apache-commons (или являются apache-commons, что по сути одно, т. к. apache-commons — собирательное название группы библиотек от Apache Software Foundation).

Id est ваше утверждение неверно. Там только commons.

Вы пишите дальше:
Тем не менее, это три физически отдельных библиотеки

И? О чём вы спорите? Никто не отрицал, что это три библиотеки.

Вы начали спорить не с тем, что там не три библиотеки, а с тем что они не входят в apache-commons. Не меняйте тезисы по ходу спора.
Не вижу больших преимуществ над .xml + JAXB (XStream, etc).

Кода будет столько же (аннотации + пару строк вызова маршала), а вот такие плюшки как schema (для валидации формата без запуска), xslt (конвертирование старых конфигов, когда формат меняется; отображение конфига в более привлекательнои виде для менеджеров), xpath (полноценые запросы по конфигу) делают XML — куда более интересным вариантом для больших конфигов (для мальеньких и Properties хватит).
По скольку в таких фишках не было надобности — их, пока, нет.
XML out-of-the-box предлогает все тоже, что и nProperties и даже больше. В чем полезность этой библиотеки?
Например, в lazy-инициализации полей конфигуратора.
+1
Или JSON (если в проекте используется то и для конфига можно)
В дополнение,
Json почти такой же:
Списки, массивы. В том числе и из объектов.
Кому нужно засилие скобок в конфигах, которые собственно всем своим нутром должны быть как можно более читабельны для человека? Где Вы вообще видели, чтобы конфигурацию для приложения хранили в JSON?
Еще раз повторяюсь — данная библиотека расчитана на замену стандартного Properties Java — никакие XML, JSON файлы приводить тут вообще ни к месту. Это лишь альтернатива, которую мы успешно используем в своих проектах. Как там говорили? «Не нравится — не ешь» ©
Json — это нечто среднее между бинарным форматом и текстовым, что вполне удобно для использования.
Если вы спрашиваете о программах c конфигами на нём— то это например новый minecraft лаунчер.
P.S. я не имею ничего против вашего конфига, выглядит вполне рабочим.
Я вообще люблю библиотеки делающие рутину за меня. :)
Это Scala библиотека. Мы говорим о Java.
> Configuration library for JVM languages.

> implemented in plain Java with no dependencies
В самом деле, извиняюсь. Поставили в тупик билд файлы scala.
Использую свою обвеску к apache commons-configuration для использования в IoC-контейнере.

Аннотация следующего вида:
import javax.enterprise.util.Nonbinding;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({FIELD, PARAMETER, METHOD})
@Retention(RUNTIME)
@Qualifier
@Inherited
@Documented
public @interface Configuration {
  @Nonbinding String value();
  @Nonbinding String config() default "default";
  @Nonbinding boolean secret() default false;
  @Nonbinding String defaultValue() default "";
}


Позволяет указать, какое поле читать, из какого конфига (если их несколько), писать ли его значение в отладочном логе и значение по умолчанию.
Как это работает? Расскажите подробнее пожалуйста.
Данное решение заточено под CDI (JSR-299).

В managed bean:
@ApplicationScoped
class SomeBean {
  @Inject
  @Configuration(value = "some.property.name", defaultValue = "10")
  private int propertyName;
}


Тогда IoC-framework ищет источник для инжекции, который описан в библиотеке:
class ConfigurationInjector {
// ...
  @Produces
  @Configuration("")
  public Integer integerConfig(InjectionPoint point) {
    Configuration configAnnotation = point.getAnnotated().getAnnotation(Configuration.class);
    // вытаскиваем configAnnotation.value и используем в кач-ве ключа для поиска в конфигурационных файлах
  }
// ...
}

где из аннотации вытаскивается имя ключа, значение по умолчанию, имя конфига. С помощью commons-configuration происходит вытаскивание нужного из конфига (с учетом подстановок и include-деклараций) и дальше через Reflections API запись в аннотированное поле.
IPropertyListener

Меня одного напрягает, когда в Java добавляют «I» к имени интерфейса?..
Как бы это — общепринятая практика.
Это не является общепринятой практикой: зависит от конвенции.

Часто напоминает iNumbers, sName и прочие прелести «венгерской» нотации в Java.

Возможно, что это наследие C++ (особенно, под win у них это чаще проскакивает).
В C++, наверное, да — общепринятая. В Java интерфейсы, обычно, отличаются окончанием -able, либо вообще ни чем не отличаются. Впрочем, это и не нужно.
В наше время важнее семантика — типизацию давно берет на себя IDE.
Поэтому от префиксов типов избавляются.
Вы уж извините, что я все критикую, однако…
Разработка библиотеки не преследовала коммерческих целей и преследовать не будет.

Вряд ли эту строку можно считать лицензионным соглашением. Если вы действительно хотите, чтобы Вашу библиотеку могли легально использовать, есть смысл задуматься над указанием полноценной лицензии, которая разграничивает сферы ответственности и явно указывать все ограничения, сопряженные с использованием Вашего ПО.
Спасибо за замечание.
Прописали лицензию Apache 2.0
Фиг знает. Обычно у меня куча конфигурируемых компонентов, но всего один конфигурационный файл на все, где свойства для каждого компонента прописываются с неким префиксом. Неплохо бы уметь вытаскивать только эти свойства из одного и того же файла в зависимости от указанного префикса: Cfg(prefix=«db»)…

db.driver=aaa
db.url=bbb
db.user=XXX
db.password=YYY

ws.url=…
ws.user=…
ws.passwd=…

component1.prop1=…
component1.prop2=…
Спасибо, будет добавлено в новой версии ) Пока готовим залив на maven
Всем спасибо за комментарии.

Библиотека и ее исходники опубликованы на Google Code под лицензией Apache 2.0
code.google.com/p/jfork/

Залив в Maven будет сразу же, как появится свободное для этого действа время :)
У nProperty возможностей столько же. Спасибо за спецификацию от плея, включим в nProperty того, чего нет (например, инициализацию поля File из пути в конфиге)
Отличная вещь, судя по описанию.
Опробую в каком-нибудь мелко-среднем проекте.
Подкину идею: задание одних свойств через другие.
Часто требуется для путей.
Например

base.path=/my/path
other.path=${base.path}/relative/path
Спасибо за идею, будет учтено :)
Sign up to leave a comment.

Articles