barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

среда, 4 декабря 2013 г.

WSO2 ESB: развертывание Message Store из CAR-ника

Проблема

WSO2 ESB 4.5.1. Пытаюсь развернуть CAR-ник, собранный WSO2 Developer Studio 3.2.0 и содержащий Message Store. Хранилище не деплоится.

Причина

Соответствующий артефакт распаковывается в папку
%WSO2_HOME%\repository\deployment\server\synapse-configs\default\message-store
вместо
 %WSO2_HOME%\repository\deployment\server\synapse-configs\default\message-stores
Причина - баг в Carbon'е (https://wso2.org/jira/browse/CARBON-14063), исправлен в версии 4.1.0, а, значит, исправление попало только в WSO2 ESB 4.7.0+.

Решение

Либо деплоить Message Store руками, либо пересобирать SynapseAppDeployerConstants.

Windows: установка атрибута "Accessed" ("Открыт") у файлов / папок

Лично у меня в винде по-умолчанию время последнего доступа к файлу/папке не обновляется, т.к. соответствующая настройка выключена. Проверяется это выполнением из-под администратора команды:
fsutil behavior query disablelastaccess
Если команда выводит: 
DisableLastAccess = 1
значит, обновление данного атрибута действительно выключено. 
Если его нужно включить (например, данный флаг используется каким-либо ПО), нужно выполнить (опять таки из-под админа):
fsutil behavior set disablelastaccess 0
и перезагрузиться.

вторник, 19 ноября 2013 г.

Maven: Compilation failure без объяснения причин

Проблема

При запуске компиляции с помощью mvn валится ошибка "Compilation failure", которой не предшествует какой бы то ни было ругани javac-а, как это обычно бывает при некомпилируемом коде. При использовании ключа -e валится stacktrace, не сильно информативнее:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.
0:compile (default-compile) on project project-core: Compilation failure -> [Help
1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal o
rg.apache.maven.plugins:maven-compiler-plugin:3.0:compile (default-compile) on p
roject project-core: Compilation failure
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:213)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProje
ct(LifecycleModuleBuilder.java:84)
        ...
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.jav
a:230)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(La
uncher.java:409)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:
352)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compila
tion failure
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(Abstrac
tCompilerMojo.java:749)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.ja
va:118)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(Default
BuildPluginManager.java:101)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:209)
        ... 19 more
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please rea
d the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureExc
eption
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
Причина

Пролить свет на причину ошибки помог анализ вывода запуска mvn с ключем -X, включающим вывод кучи отладочной информации. В частности, в выводе обнаружилась следующая строчка:
[DEBUG]   (f) executable = C:/Program Files (x86)/Java/jdk1.6.0_25/bin/javac.exe
Она привлекла внимание по той причине, что JAVA_HOME смотрит вовсе не туда, и вообще указанный путь не существует. Залез в settings.xml, и действительно, увидел там вот это:
<properties>
   <java.1.6.home>C:/Program Files (x86)/Java/jdk1.6.0_25</java.1.6.home>
   <java.1.6.compiler>${java.1.6.home}/bin/javac.exe</java.1.6.compiler>
</properties>
Исправление данного пути на корректный поправило компиляцию (впрочем, можно было бы и удалить этот блок вообще и понадеяться на переменные окружения).

понедельник, 18 ноября 2013 г.

Weblogic: использование зашифрованного пароля в конфигурации DataSource

Хранить пароль от БД в конфигурации DataSource можно и в открытом виде, т.е.:
    <properties>
      <property>
        <name>user</name>
        <value>user1</value>
      </property>
      <property>
        <name>password</name>
        <value>11111</value>
      </property>
    </properties>
Однако, порой это недопустимо из соображений безопасности. В таком случае подойдет хранение зашифрованного пароля, для этого предназначен специальный тег <password-encrypted>:
<properties>
<property>
<name>user</name>
<value>user1</value>
</property>
</properties>
<password-encrypted>{3DES}IQHx+vYPxQI5k1W1Dbwubw==</password-encrypted>
Чтобы поместить туда пароль, его сначала нужно зашифровать. Делается это так:
  1. Идем в DOMAIN_HOME
  2. Выполняем:
    setDomainEnv.cmd
    или
    . ./setDomainEnv.sh
    Наличие точки в начале команды для Unix важно, т.к. скрипт устанавливает переменные окружения, и без точки они не будут видны в вызывающем shell'е, из-за чего при выполнении следующего шага получим:
    Could not find or load main class weblogic.security.Encrypt
  3. Выполняем:
    java weblogic.security.Encrypt 11111
  4. Используем полученный зашифрованный пароль внутри <password-encrypted>
Спасибо http://middlewaremagic.com/weblogic/?p=1400. 

понедельник, 28 октября 2013 г.

Java 7: Comparison method violates its general contract

После перехода с Java 6 на 7 одна из используемых приложением библиотек стала валиться с:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
Причина кроется в том, что в семерке переработана имплементация алгоритма сортировки, используемая в java.util.Arrays.sort и java.util.Collections.sort, и в случае некорректной реализации интерфейса Comparable она может генерировать данное исключение. Под некорректной понимается реализация, неконсистентная с реализацией equals() (например, если для некоторых эквивалентных объектов она возвращает значение, отличное от 0). Найти эту информацию можно в заметках о совместимости Java 7. 
Выход - переписать реализацию Comparable (в моем случае - не вариант, т.к. библиотека сторонняя и закрытая) либо воспользоваться системным свойством "java.util.Arrays.useLegacyMergeSort", позволяющим переключиться на старую имплементацию сортировки (сказать по правде, не пробовал, т.к. просто вернулся на JDK 6).
ЗЫ Спасибо http://www.yossale.com/?p=355.

вторник, 15 октября 2013 г.

Windows: ошибка "Windows cannot access \\server\share"

Проблема

При попытке открыть сетевую папку на некотором сервере возникает ошибка:



Причем даже не происходит запроса логина / пароля, а сразу отображается ошибка об отсутствии прав.

Причина

Логин / пароль для доступа к данное сетевой папке сохранены, но они либо неверны, либо у соответствующего пользователя действительно нет прав на эту папку. 

Решение

Идем в Control Panel --> Credential Manager, удаляем сохраненные логин / пароль. Стучимся в шару еще раз, вводим верные логин / пароль от пользователя, имеющего права на шару. 

ЗЫ

Практически одновременно с этой проблемой наткнулся на еще одну. Пытаюсь примонтировать сетевой диск, используя некоторый логин / пароль. Винда выдает ошибку, что якобы данный диск уже смонтирован с системе, но с "different credentials". При это в "Моем компьютере" я этого диска не вижу (иначе я конечно не стал бы монтировать его еще раз). Однако, этот диск видно через команду "net use", поэтому нужно его предварительно отмонтировать (а также отмонтировать все шары на данном сервере, т.к. они вероятнее всего также смонтированы с теми же "different credentials", и без их отмонтирования получим ту же ошибку):
net use \\server\share1 /DELETE
net use \\server\share2 /DELETE
net use \\server\share3 /DELETE
После чего уже можно произвести монтирование нужного нам сетевого диска, хоть через UI, хоть через "net use".

воскресенье, 6 октября 2013 г.

WSO2 ESB: вызов sequence с игнорированием ошибок

Задача

Вызвать один sequence из другого так, чтобы ошибка внутри вложенного sequence (например, сетевая ошибка при выполнении callout-медиатора) не приводила к ошибке наружного.

Решение

Т.к. средствами sequence-медиатора такое поведение нереализуемо, пришлось вызывать sequence из groovy-кода. Данная операция требует некоторых манипуляций с axis-контекстом, передаваемым вызываемой sqeucence. Немного длинно, но работает:
  <script language="groovy"><![CDATA[ import org.apache.commons.logging.LogFactory; import org.apache.synapse.core.axis2.Axis2MessageContext; try { /* create Axis2MessageContext, as ScriptMessageContext often can't be used to call this sequence - for example callout mediator in it will fail */ def mc2 = new Axis2MessageContext(new org.apache.axis2.context.MessageContext(),mc.getConfiguration(), mc.getEnvironment()); // copy existing envelope def newEnvelope = org.apache.axiom.om.util.CopyUtils.copy(mc.getEnvelope()); mc2.setEnvelope(newEnvelope); // propagate some properties to child context mc2.setProperty("prop1", mc.getProperty("prop1")); // force child sequence to use proxy-service logger mc2.setServiceLog(LogFactory.getLog("SERVICE_LOGGER.ProxyServiceName")); // execute child sequence mc.getSequence("ChildSequenceName").mediate(mc2); // restore envelope mc.setEnvelope(mc2.getEnvelope()); // restore some properties mc.setProperty("prop2", mc2.getProperty("prop2")); } catch(Exception ex) { LogFactory.getLog("SERVICE_LOGGER.ProxyServiceName").warn("Child sequence failed, continuing",ex); } ]]></script>