barbitoff programmer`s blog

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

суббота, 1 июня 2013 г.

Отладка конфигурации log4j

Включается системным свойством log4j.debug, например, при старте jvm:
-Dlog4j.debug
Бывает крайне полезна, чтобы, скажем, понять, откуда из classpath log4j цепляет свой log4j.properties.

понедельник, 11 марта 2013 г.

cmd: Скобки в значениях переменных и группировки в if

Проблема:

В bat-нике есть некоторая переменная, значение которой содержит скобки. В моем случае переменная эта была CLASSPATH, и содержала она строку "C:/Program Files (x86)/IBM/WebSphere MQ/Java/lib/com.ibm.mq.jar". В bat-нике эта переменная используется следующим образом (в моем случае батником был стартовый скрипт Oracle Weblogic 10.3.5):
if NOT "%PRE_CLASSPATH%"=="" (
set CLASSPATH=%PRE_CLASSPATH%;%CLASSPATH%
)
, т.е. для группировки используются круглые скобки.
При попытке выполнить bat-ник валится ошибка:
set CLASSPATH=;C:/Program Files (x86)/IBM/WebSphere MQ/Java/lib/com.ibm.mq.jar

/IBM/WebSphere was unexpected at this time.
Причина:

При раскрытии переменной присутствующая в ней закрывающая скобка воспринимается интерпретатором как закрытие группировки после "if", а остаток строки интерпретируется как следующая команда ("/IBM/WebSphere...").

Решение:

Использовать отложенное раскрытие проблемной переменной, заключив её в "!" вместо "%". В таком случае значение переменной будет подставляться в команду при непосредственном её выполнении и уже не будет приводить к ситнаксическим ошибкам:
if NOT "%PRE_CLASSPATH%"=="" (
set CLASSPATH=%PRE_CLASSPATH%;!CLASSPATH!
)
Правда, перед этим нужно это самое отложенное раскрытие разрешить:
setlocal enabledelayedexpansion
Спасибо http://stackoverflow.com/questions/2410501/parenthesis-in-windows-cmd-script-variable-values-not-allowed.

вторник, 5 февраля 2013 г.

Java: определение, из какого файла загружен класс

При решении проблем с CLASSPATH бывает очень полезно знать, откуда таки загрузился тот или иной класс. Делается это так:
MyCalss.class.getProtectionDomain().getCodeSource().getLocation().getFile() 

вторник, 17 июля 2012 г.

org.apache.commons.logging.LogConfigurationException: User-specified log class 'org.apache.commons.logging.impl.Log4JLogger' cannot be found or is not useable.

Часа полтора ушло на казалось бы простейшую проблему: использовать apache commons logging в связке с log4j. Проблема была в следующем: в веб-приложении, разворачиваемом на Tomcat 6, имеются файлы конфигурации commons-logging и log4j со следующим содержимым:

commons-logging.properties:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
log4j.properties:
log4j.debug=false
log4j.rootLogger=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=%-4r [%t] %-5p %c %x - %m%n 
Первый конфигурационный файл должен подхватываться commons-logging`ом самостоятельно как первый с таким именем в CLASSPATH, путь ко второму указывается явно в web.xml. Сами jar-ники commons-logging-1.1.1.jar и log4j-1.2.15.jar в /WEB-INF/lib приложения лежат. Однако при попытке чтобы то ни было залогировать в веб-приложении валится исключение:
org.apache.commons.logging.LogConfigurationException: User-specified log class 'org.apache.commons.logging.impl.Log4JLogger' cannot be found or is not useable.
Как оказалось, проблема была в следующем: commons-logging-1.1.1.jar лежал также и в %JAVA_HOME%/jre/lib/ext (так уж получилось, что он залетел туда при установке КриптоПРО JCP). Поэтому и загружался этот jar-ник не тем класслоадером, что и остальные либы веб-приложения, и jar-ника log4j в /WEB-INF/lib ему было не видно. Выход - либо закинуть jar-ник log4j туда же в %JAVA_HOME%/jre/lib/ext, либо - удалить оттуда commons-logging-1.1.1.jar (в моем случае - не вариант, т.к. нарушило бы работу JCP).

java.net.SocketException: Connection reset при парсинге Hibernate-конфига

После некоторых манипуляций с проектом, использующим hibernate, стало вылиться исключение при чтении конфигурационного файла Hibernate:
org.hibernate.HibernateException: Could not parse configuration: /hibernate.cfg.xml
...
Caused by: org.dom4j.DocumentException: Connection reset Nested exception: Connection reset
...
java.net.SocketException: Connection reset
Какой коннект был сброшен, не совсем ясно О_о, ведь парсится локальный конфиг. Оказывается, в CLASSPATH оказались jar-ники 3ей версии Hibernate, тогда как приложение использует Hibernate 4 и в конфигурационных файлах указаны его DTD. Не найдя новых DTD в jar-никах старого Hibernate, XML-парсер полез за ними в интернет (куда его не пустили уже из-за прокси).