barbitoff programmer`s blog

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

пятница, 12 апреля 2019 г.

Консольная утилита для тестирования JMS-брокеров Apache ActiveMQ

Если нужно протестировать работу брокера или кластера Apache ActiveMQ (обычного или Artemis), т.е. отправить / получить сообщения, посмотреть содержимое очереди и пр., подойдёт консольная утилита amqutil: http://kevinboone.net/README_amqutil.html.

Пример отправки и получения сообщений:
java -jar amqutil-0.1.3.jar produce 1 -d TEST.Q -url tcp://localhost:61616
java -jar amqutil-0.1.3.jar consume 1 -d TEST.Q -url tcp://localhost:61616

понедельник, 13 ноября 2017 г.

ORA-02020: используется слишком много каналов связи БД

Проблема

Есть ADF-приложение, в нем некоторые Entity смотрят на вьюхи, которые, в свою очередь, смотрят на удаленные таблицы через DATABASE LINK. При работе с этими Entity падает ошибка:
ORA-02020: используется слишком много каналов связи БД

Решение

Срабатывает ограничение OPEN_LINKS (ограничение на число link-ов в рамках одной сессии, см. https://docs.oracle.com/cd/B19306_01/server.102/b14237/initparams139.htm#REFRN10138) или OPEN_LINKS_PER_INSTANCE (тоже самое, но не на уровне сессии, а глобально, актуально при использовании SHARED-линков и распределенных транзакций, см. https://docs.oracle.com/cd/B19306_01/server.102/b14237/initparams140.htm#REFRN10139). Оба по-умолчанию равны 4. Посмотреть текущие значения можно SQL-запросом:
show parameter OPEN_LINKS
Необходимо поменять значения командами:
ALTER SYSTEM SET OPEN_LINKS=255 SCOPE=SPFILE;
ALTER SYSTEM SET OPEN_LINKS_PER_INSTANCE=255 SCOPE=SPFILE; 
(для применения потребуется рестартануть БД)

воскресенье, 12 ноября 2017 г.

ORA-24777: использование непереносимых ссылок на базы данных недопустимо

Проблема

Есть ADF-приложение, работающее на weblogic. Приложение использует Data source, предоставляемый weblogic'ом, для соединения с БД. Некоторые Entity приложения смотрят на вьюхи, которые, в свою очередь, смотрят на удаленные таблицы через DATABASE LINK.
При попытке приложения обратиться к данным в удаленной БД падает ошибка:
ORA-24777: использование непереносимых ссылок на базы данных недопустимо
Решение

Data source на weblogic использует JDBC-драйвер "oracle.jdbc.xa.client.OracleXADataSource, либо обычный (non-XA) драйвер oracle.jdbc.OracleDriver, но в настройках датасорса стоит галочка "Supports Global Transactions" (которая, кстати, установлена там по-умолчанию). При этом DATABASE LINK создан не как SHARED.
Соответственно, варианта 2:
  1. Использовать oracle.jdbc.OracleDriver со снятой галочкой "Supports Global Transactions", если распределенные транзакции по факту приложению не нужны
  2. Пересоздать DATABASE LINK с использованием SHARED-опции (подробнее см. https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_5005.htm#i2061693).  Например:
CREATE SHARED PUBLIC DATABASE LINK MY_DBLINK
CONNECT TO "USR1" IDENTIFIED BY "PSWRD1"
AUTHENTICATED BY "USR1" IDENTIFIED BY "PSWRD1"
USING 'MYRMTORCL';

воскресенье, 18 декабря 2016 г.

WSO2 ESB: как отключить динамическую регулировку числа потоков, слушающих JMS-очередь

Есть прокси-сервис, слушающий JMS-очередь. Работа в несколько потоков для него настроена параметрами transport.jms.ConcurrentConsumers и transport.jms.MaxConcurrentConsumers (см. http://axis.apache.org/axis2/java/transports/jms.html). Однако, каким бы ни было значение transport.jms.ConcurrentConsumers, в "состоянии покоя", т.е. когда в очереди-источнике сообщений нет, на очереди висит только 1 получатель. По мере появления сообщений в очереди число получателей растет вплоть до указанного в transport.jms.MaxConcurrentConsumers ограничения. Затем, после опустошения очереди, получатели начинают отключаться, пока снова не остается только 1 получатель.
Объясняется такое поведение вот чем. Изначально шина создает для очереди столько слушателей, сколько указано в параметре transport.jms.ConcurrentConsumers. Каждый получатель начинает цикл опроса очереди, при этом на каждой итерации он ожидает получения сообщения в течение некоторого промежутка времени, заданного параметром transport.jms.ReceiveTimeout (по-умолчанию 1000мс). После определенного числа "холостых" итераций, в результате которых таймаут вышел, а сообщение так и не было получено, слушатель самозавершается. Число итерацией определяется параметром transport.jms.IdleTaskLimit и по-умолчанию равно 10. В итоге, через примерно 10 секунд завершаются все слушатели кроме одного "дежурного", который не завершается ни при каких обстоятельствах.
Данная ситуация не во всех случаях может устраивать, иногда нужно, чтобы очередь всегда слушало фиксированное число слушателей (например, при использовании группировки сообщеий). Тут варианта 2:
  1. Устанавливаем очень большое значение параметра transport.jms.IdleTaskLimit (т.к. бесконечное значение установить нельзя, можно поставить, к примеру, 2147483647)
  2. Устанавливаем бесконечный таймаут ожидания получателем сообщения путем установки параметра transport.jms.ReceiveTimeout в -1

четверг, 20 ноября 2014 г.

ActiveMQ 5.7.0: настройка Dead Letter Queue и числа попыток повторной доставки для отдельной очереди

Задача

Есть некая очередь MyQueue. Для нее нужно настроить (независимо от общих настроек JMS-сервера):

  • Отдельную очередь, куда будут складываться недоставленные сообщения из этой очереди (Dead Letter Queue, или сокращённо DLQ), т.к. по-умолчанию в качестве DQL для всех очередей используется очередь с именем ActiveMQ.DLQ
  • Число попыток повторной доставки, по истечению которого сообщение будет помещаться в эту самую DLQ
Решение

Настройки выполняются в conf/activemq.xml. Первый шаг - отдельная DQL, настраивается она с помощью блока policyEntry со вложенным deadLetterStrategy:
<destinationPolicy>
<policyMap>
 <policyEntries>
<!-- -->
<policyEntry queue="MyQueue">
 <deadLetterStrategy>
<individualDeadLetterStrategy
 queuePrefix="DLQ." useQueueForQueueMessages="true" />
 </deadLetterStrategy>
</policyEntry>
 </policyEntries>
</policyMap>
</destinationPolicy>
Данная конфигурация указывает использовать в качестве DQL очередь с именем DQL.MyQueue. Помимо префикса, можно также задать постфикс (http://activemq.apache.org/maven/apidocs/org/apache/activemq/broker/region/policy/IndividualDeadLetterStrategy.html). Задать целиком имя очереди, насколько я понял, нельзя. Впрочем, меня устроил и вариант с префиксом.
Теперь про число повторных доставок. Настраиваться она может различными способами (https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_A-MQ/6.0/html/Client_Connectivity_Guide/files/AMQClientConnectRedelivery.html), но server-side способ один - с помощью redeliveryPlugin. Выполняется такая настройка помещением в тот же activemq.xml внутрь блока <broker>:
<plugins>
<redeliveryPlugin>
 <redeliveryPolicyMap>
<redeliveryPolicyMap>
 <redeliveryPolicyEntries>
<!-- a destination specific policy -->
<redeliveryPolicy queue="MyQueue"
 maximumRedeliveries="1" />
 </redeliveryPolicyEntries>
 <!-- the fallback policy for all other destinations -->
 <defaultEntry>
<redeliveryPolicy maximumRedeliveries="10" />
 </defaultEntry>
</redeliveryPolicyMap>
 </redeliveryPolicyMap>
</redeliveryPlugin>
  </plugins>
Особенность заключается в том, что для того, чтобы такая настройка отрабатывала как ожидается, клиент должен при подключении к брокеру указывать jms.redeliveryPolicy.maximumRedeliveries=0.

четверг, 2 октября 2014 г.

WSO2 ESB 4.5.1: реализация Splitter-паттерна с JMS-endpoint'ами и транзакицонностью

Задача

Реализовать прокси-сервис, который:

  • принимает по http входящее сообщение, являющееся "пакетным", т.е. состоящим из составных частей, которые должны обрабатываться отдельно друг от друга (Splitter EIP)
  • разбивает "пакет" на отдельные сообщения, складывает их по одному в JMS-очедерь
  • если все сообщения положились успешно, отвечает на входящий запрос успехом
  • если при помещении в JMS хотя бы одного из сообщений возникла ошибка, вся jms-транзакция должны быть откачена и в ответ на входящий запрос должен быть отправлен soapFault
Проблема

Вроде бы, реализация очевидна: iterate-медиатор для итерации по отдельным частям "пакета" и отправка этих "частей" на jms-endpoint посредством send-медиатора. Но проблема заключается в том, что JMSSender (входит в axis2-transport-jms) не умеет работать с jms-транзакциями. Т.е., если посмотреть в исходники, видим:
session = ((QueueConnection) connection).
            createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
, где false говорит об отсутствии поддержки транзакций. Т.е. не то что распределенные транзакции, а даже локальные транзакции не поддерживаются при записи в jms с помощью send-медиатора.
Другой вариант - использовать store-медиатор и JMSMessageStore. Однако, открыв исходники JMSMessageStore, видимо практически тоже самое:
return connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Т.о., для реализации указанных требований придется что-то пилить руками, используя напрямую JMS-API.

пятница, 22 августа 2014 г.

Ошибка java.lang.NullPointerException в классе ClassFinderMetaDataEnumaration при старте веб-приложения на weblogic

Проблема

При старте веб-приложения на weblogic 10.3.5 падает ошибка:
weblogic.application.ModuleException: Failed to load webapp: 'xxx'
at weblogic.servlet.internal.WebAppModule.prepare(WebAppModule.java:393)
at weblogic.application.internal.flow.ScopedModuleDriver.prepare(ScopedModuleDriver.java:176)
at weblogic.application.internal.flow.ModuleListenerInvoker.prepare(ModuleListenerInvoker.java:199)
at weblogic.application.internal.flow.DeploymentCallbackFlow$1.next(DeploymentCallbackFlow.java:517)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
Truncated. see log file for complete stacktrace
Caused By: java.lang.NullPointerException at weblogic.application.utils.ClassFinderMetaDataEnumaration.hasMoreElements(ClassFinderMetaDataEnumaration.java:32)
at weblogic.servlet.internal.WebAnnotationProcessorImpl.getAnnotatedClasses(WebAnnotationProcessorImpl.java:139)
at weblogic.servlet.internal.War.getAnnotatedClasses(War.java:1038)
at weblogic.servlet.internal.WebAppServletContext$ServletContextWebAppHelper.getAnnotatedClasses(WebAppServletContext.java:3833)
at weblogic.servlet.internal.WebAnnotationProcessorImpl.processAnnotations(WebAnnotationProcessorImpl.java:84)
Truncated. see log file for complete stacktrace
Причина

В приложении был класс класс Settings с вложенным статическим приватным классом Settings.PropertyNames. Не было времени разбираться, что именно мешало weblogic'у, имя класса PropertyNames или же приватный доступ вложенного статического класса, но после того, как я убрал этот класс, приложение начало стартовать.

понедельник, 21 апреля 2014 г.

ActiveMQ 5.7.0 и JMX

Самый простой способ: идем в bin/activemq.bat, комментим:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote
и раскомменчиваем:
set SUNJMX=-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
Получаем JMX на порту 1099 без аутентификации.
Если нужна аутентификация, то настройка следующая:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.access.file=%ACTIVEMQ_HOME%\conf\jmx.access -Dcom.sun.management.jmxremote.password.file=%ACTIVEMQ_HOME%\conf\jmx.password -Dcom.sun.management.jmxremote.ssl=false
Для файла %ACTIVEMQ_HOME%\conf\jmx.password нужно зайти в настройки безопасности и сделать так, чтобы единственным пользователем, имеющим доступ к этому файлу, был тот, из-под кого стартует ActiveMQ, иначе будет валится ошибка:
Password file read access must be restricted
(см. http://docs.oracle.com/javase/6/docs/technotes/guides/management/security-windows.html). 

среда, 26 марта 2014 г.

axis2 1.6.2 на weblogic и "Weblogic's StAX implementation is unsupported and some Axiom features will not work as expected! Please use Woodstox instead"

Проблема

Приложение, публикующее веб-сервис, построенный на axis2 (версия 1.6.2) отлично работает на Tomcat, однако на Weblogic выдает некорректный xml в ответ на запросы, например:
<ns1:Response xmlns:ns1="http://my.ns/get">
     <ns1:http://my.ns/get extension="pdf">
          <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:1.339fa79a76e9c28c028457f6d5d2336291c1c2c768ddde02@apache.org"></xop:Include>
     </ns1:http://my.ns/get>
</ns1:Response>
Т.е. вместо наименования тега (это должен был быть тег "Content") почему-то идет URL пространства имен.
При этом при старте приложения в лог пишется настораживающее:
Weblogic's StAX implementation is unsupported and some Axiom features will not work as expected! Please use Woodstox instead.
Решение

В weblogic.xml указать:
<weblogic-web-app>
 <container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
  </container-descriptor>
</weblogic-web-app> 
Также нужно убедиться в наличии в библиотеках приложения xercesImp и xml-apis.

вторник, 25 марта 2014 г.

Weblogic: password-encrypted в конфиге jdbc-data-source и ошибка "Could not perform unpadding: invalid pad byte"

Проблема:

Есть некий EAR-ник, содержащий jdbc-data-source. В нем пароль задан с помощью password-encrypted:
<password-encrypted>{AES}q+rhp78+7777woah7777JW7777S+0p7777djmw7777c=</password-encrypted>
При старте приложения в лог валится ошибка:
####<Mar 19, 2014 4:44:21 PM MSK> <Error> <Console> <xxx> <AdminServer> <[ACTIVE] ExecuteThread: '21' for queue: 'weblogic.kernel.Default (self-tuning)'> <weblogic> <> <> <1395233061606> <BEA-240003> <Console encountered the following error weblogic.application.WrappedDeploymentException: Could not perform unpadding: invalid pad byte.
at com.rsa.jsafe.c.a(Unknown Source)
at com.rsa.jsafe.JSAFE_SymmetricCipher.decryptFinal(Unknown Source)
at weblogic.security.internal.encryption.JSafeEncryptionServiceImpl.decryptBytes(JSafeEncryptionServiceImpl.java:124)
at weblogic.security.internal.encryption.JSafeEncryptionServiceImpl.decryptString(JSafeEncryptionServiceImpl.java:184)
at weblogic.security.internal.encryption.ClearOrEncryptedService.decrypt(ClearOrEncryptedService.java:96)
at sun.reflect.GeneratedMethodAccessor378.invoke(Unknown Source)
... at weblogic.deploy.service.internal.targetserver.DeploymentReceiverCallbackDeliverer$1.run(DeploymentReceiverCallbackDeliverer.java:46)
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:528)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
При этом само приложение не стартует.

Причина


Конфиг datasource'а был перевезен с другого инстанса weblogic (соответственно, и сам зашифрованный пароль был создан именно для того инстанса). Как оказалось, шифрование пароля привязано к домену сервера Weblogic (о чем, кстати, и сказано в документации: http://docs.oracle.com/cd/E11035_01/wls100/admin_ref/utils.html#encrypt). Так что при копировании конфигурации в другой домен Weblogic требуется повторить процедуру шифрования пароля (как это делается, я писал тут: http://barbitoff.blogspot.ru/2013/11/weblogic-datasource.html).

среда, 5 февраля 2014 г.

JavaMail: кодировка по-умолчанию, используемая в заголовках писем

Вообще, не-ascii заголовки в почтовых сообщениях кодируются в соответствии с RFC 2047 (http://www.faqs.org/rfcs/rfc2047/). При отправке почты с помощью Javamail столкнулся со следующей проблемой: формируется заголовок письма, имеющий вид:
=?UTF8?B?0J3QsNC/0YDQsNCy0LvQtdC9INC00L7QutGD0LzQtdC9?= =?UTF8?B?0YI6INC+0YjQuNCx0LrQuCDQsiBlbWFpbA==?=
Не совсем корректным здесь является имя используемой кодировки - "UTF8", в то время как IANA предписывает использовать имя "UTF-8", т.е. с дефисом (http://www.iana.org/assignments/character-sets/character-sets.xhtml). Такие заголовки "съедаются" Outlook'ом, веб-клиентами mail.ru и gmail.com, однако, например, SquirrelMail выводит такой заголовок "как есть", не выполняя декодирование. 
Для установки заголовка мой код (вернее не мой, а код open-source проекта, но не суть) испольует javax.​mail.​internet.​MimeMessage.setSubject(java.lang.String subject). В документации сказано, что данный метод использует "platform's default charset" (http://docs.oracle.com/javaee/6/api/javax/mail/internet/MimeMessage.html#setSubject(java.lang.String)), по факту - системное свойство file.encoding.
Посмотрев в стартовые скрипты приложения, я обнаружил, что там действительно указана опция jvm "-Dfile.encoding=UTF8". Поменяв ее на "-Dfile.encoding=UTF-8" я решил проблему с некорректным именем кодировки в заголовках отправляемых почтовых сообщений.

суббота, 25 января 2014 г.

Как я сдавал 1Z0-897 "Oracle Certified Expert, Java EE 6 Web Services Developer"

Сразу оговорюсь, сдал я не особо - 68% при проходном 64%. Сказалась, как обычно, нехватка времени на подготовку, да еще и отсутствие в свободном доступе внятной информации о том, что конкретно будет на экзамене, а также более ли менее близких к составу экзаменационных вопросов книг и mock-экзаменов.
Собственно на подготовку ушла ровно неделя, точнее целиком я готовился только 2 выходных дня, а в остальные 5 дней в среднем по 3-4 часа. Опыт в разработке SOAP веб-сервисов у меня около 2 лет, но на момент начала подготовки я не мог похвастаться особо глубокими знаниями JAX-WS, т.к. разрабатываемые мной веб-сервисы в основном были достаточно тривиальными, и я довольствовался "обязательным минимумом" знаний. Что такое XML Schema и WSDL я знал, но в последнем также не был большим знатоком. REST же для меня был вообще практически новым словом, что это такое, я конечно представлял, но на практике никогда применять не приходилось. Собственно это все и стало предпосылкой к сдаче экзамена, т.к. экзамен - отличный повод "прибраться" в своих знаниях, систематизировать их, а также узнать что-то новое, что потом можно использовать на практике.
При подготовке я в основном ориентировался на содержимое вот этой странички на код-ранче: http://www.coderanch.com/how-to/java/ScdjwsLinks, поэтому первое, с чего я начал подготовку - прочитал книжку "Java Web Services: Up and Running" под авторством Martin Kalin (2009). Книжка по объему достаточно скромная - всего 318 страниц (+ некоторые разделы, например про историю веб-сервисов, можно смело пропускать), поэтому осилить ее можно достаточно быстро. По ходу чтения делал заметки, чтобы перед экзаменом была возможность быстро освежить в памяти полученные из нее знания. Из книги узнал для себя много нового, многие вещи, казавшиеся раньше загадочными, теперь стали очевидными. Не могу сказать, что книга дает исчерпывающие значения по теме, но она определенно показывает, в какую сторону копать при наличии той или иной задачи. Сказать, что этой книги достаточно для успешной сдачи экзамена, тоже с полной уверенностью нельзя. Но об этом немного позже.
После прочтения книги у меня закрались сомнения в том, что полученных знаний хватит для получения сертификата, и я начал судорожно искать, где бы еще что-нибудь почитать по теме. Для начала просмотрел вот этот гайд: http://java.boot.by/ocewsd6-guide/, - там многое пересекается с книгой (даже возникает впечатление, что оно оттуда и скопировано), но в тоже время есть и новая информация, в частности, по REST и JAX-RS. Чтобы окончательно удостовериться в том, что полученные мной знания по REST и JAX-RS достаточно полны, я также прочитал статью на сайте IBM: http://www.ibm.com/developerworks/ru/library/wa-jaxrs/.
В довершение, уже вечером перед экзамен, я пробежался по тестам тут:  http://www.examclouds.com/ (в разделе "WS Quiz"). Тесты меня несколько испугали, т.к. ответы на многие вопросы я не знал. Но как оказалось, это и не нужно - на экзамене ничего подобного не было.
Собственно вот и вся подготовка. Выспаться перед экзаменом не получилось, но свежесваренный кофе сделал свое дело =)
Сдавал я в Unix Education Center, там же, где 10 месяцами ранее я экзаменовался на OCJP. На экзамен дается 1.5 часа, вопросов в тесте - 60. В общем-то, расслабляться нельзя, времени не много. Я успел ответить на все вопросы за 1:15, потом просмотрел еще раз те вопросы, по которым были сомнения. Была пара вопросов, отображавшихся некорректно из-за того видимо, что xml, входящий в текст вопроса, забыли экранировать, и он попросту не показывался. Написал жалобу в pearsonvue, через которых заказывал экзамен, обещали разобраться.
Теперь про вопросы на экзамене. Их уровень не запредельный, обойтись одной только книжкой "Java Web Services: Up and Running" было бы сложно, но в целом, запомни я все прочитанное получше, сдать можно было бы на более высокий балл. Единственная тема, к которой я был совершенно не готов (а на которую, однако, было не менее 4-5 вопросов) - это WS-I.

пятница, 30 августа 2013 г.

Acegi Security на Weblogic 10: постоянный редирект на страницу логина

Проблема

В приложении используется Acegi Security 1.0.7 (приложение построено с помощью Wavemaker 6.5.3), приложение разворачивается на Weblogic 10.3.5. При попытке залогиниться пользователь постоянно редиректится на страницу входа (но без сообщения о неуспешной авторизации, т.е. ситуация отличается от таковой при неверном логине/пароле).

Причина

В браузере хранится 2 cookie с именем JSESSIONID.

Решение 

Удалить все куки с именем JSESSIONID и снова попробовать зайти.

четверг, 22 августа 2013 г.

Oracle + Weblogic connection pool: задание схемы по-умолчанию

Недавно писал про организацию пула соединения с БД в приложении, развертываемом на Weblogic (http://barbitoff.blogspot.ru/2013/07/weblogic-1035-connection-pooling.html). Xml-конфигурация пула позволяет задать все параметры соединения, кроме имени используемой схемы. Хардкодить имя схемы в SQL-запросах не хочется, как и изобретать велосипед с подтягиванием имени схемы из какого-то своего отдельного конфига. Выход - использовать в SQL схему по-умолчанию (т.е. не задавать имя схемы вообще) и воспользоваться таким параметром пула, как "init-sql". В этом параметре нужно указать SQL-запрос, который при инициализации соединения с БД поменяет схему по-умолчанию на необходимую нам. Этот SQL зависит от используемой СУБД, для Oracle он выглядит так:
  <jdbc-connection-pool-params>
    <max-capacity>20</max-capacity>
    <connection-reserve-timeout-seconds>25</connection-reserve-timeout-seconds>
    <test-table-name>SQL SELECT 1 FROM DUAL</test-table-name>
    <init-sql>SQL ALTER SESSION SET CURRENT_SCHEMA = USR</init-sql>  </jdbc-connection-pool-params>

суббота, 6 июля 2013 г.

Weblogic 10.3.5: connection pooling в веб-приложении

Когда-то давно писал об организации connection pool'а в веб-приложении, разворачиваемом на Tomcat 6, на этот же раз возникла необходимость в аналогичном решении для Weblogic 10.3.5.
Ниже описан случай, когда WAR-ник деплоится в составе EAR-ника.
Во-первых, необходимо создать в EAR-нике xml-файл с конфигурацией пула. Поместить его в принципе можно где угодно, я разместил в META-INF/datasources/ и назвал mydb-jdbc.xml. Содержимое у него примерно следующее (на примере Oracle):
<jdbc-data-source xsi:schemaLocation="http://www.bea.com/ns/weblogic/90/domain.xsd"
 xmlns="http://xmlns.oracle.com/weblogic/jdbc-data-source"
 xmlns:sec="http://www.bea.com/ns/weblogic/90/security"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:wls="http://www.bea.com/ns/weblogic/90/security/wls">
  <name>mydb-datasource</name>
  <jdbc-driver-params>
    <url>jdbc:oracle:thin:@//db_host:db_port/db_servicename</url>
    <driver-name>oracle.jdbc.OracleDriver</driver-name>
    <properties>
      <property>
        <name>user</name>
        <value>*****</value>
      </property>
      <property>
        <name>password</name>
        <value>*****</value>
      </property>
    </properties>
  </jdbc-driver-params>
  <jdbc-connection-pool-params>
    <max-capacity>20</max-capacity>
    <connection-reserve-timeout-seconds>25</connection-reserve-timeout-seconds>
    <test-table-name>SQL SELECT 1 FROM DUAL</test-table-name>
  </jdbc-connection-pool-params>
</jdbc-data-source>
Тут в целом все достаточно очевидно. 
После создания данного файла нужно добавить ссылку на него в дескриптор приложения (META-INF/weblogic-application.xml в EAR-нике):
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.0/weblogic-application.xsd">
  <module>
    <name>mydb-datasource-module</name>
    <type>JDBC</type>
    <path>META-INF/datasources/mydb-jdbc.xml</path>
  </module>
</weblogic-application>
Теперь осталось лишь в web.xml WAR-ника, входящего в EAR, добавить ссылку на соотв. ресурс:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <!-... -->
  <resource-ref>
    <res-ref-name>mydb-datasource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</web-app>
Все, теперь в коде WAR-ника коннекты к БД получаются так:
    InitialContext ctx = new InitialContext();
    javax.sql.DataSource ds =
            (javax.sql.DataSource) ctx.lookup("java:comp/env/mydb-datasource");
    conn = ds.getConnection();


Деплой EAR на Weblogic 10.3.5: Filtering class loader configuration ignored for web module

Проблема

Есть enterprise-приложение, содержащее внутри WAR-ник. При деплое EAR-ника на Weblogic 10.3.5 в логах появляется warning:
<Warning> <HTTP> <BEA-101377> <Filtering class loader configuration ignored for web module ***.war of application ***>
Помимо этого, почему-то игнорируются <prefer-application-packages> из weblogic.xml, размещенного в /WEB-INF WAR-ника.

Причина

Конфигурация фильтрующего загрузчика классов должна размещаться в дескрипторе основного  развертываемого артефакта (weblogic-application.xml в EAR-нике), а не в weblogic.xml WAR-ника (http://docs.oracle.com/cd/E24329_01/doc.1211/e26117/chapter_bea_messages.htm).

Решение

Перенести настройку фильтрации классов в weblogic-application.xml EAR-ника.


Weblogic 10.3.5 + Netbeans 7.3: WSP_1018_POLICY_EXCEPTION_WHILE_FINISHING_PARSING_WSDL

Проблема:

В Netbeans 7.3 создано веб-приложение, содержащее веб-сервис (который создавался с помощью соотв. мастера) и собираемое maven-ом. При развертывании приложения на Wevlogic 10.3.5 валится исключение:
weblogic.application.ModuleException: ...
...
javax.xml.ws.WebServiceException: [failed to localize] WSP_1018_POLICY_EXCEPTION_WHILE_FINISHING_PARSING_WSDL()
...
Caused by: com.sun.xml.ws.policy.PolicyException:[failed to localize] WSP_1014_POLICY_REFERENCE_DOES_NOT_EXIST
...
Причина:

Netbeans включил в pom-ку приложения зависимость webservices-rt как compile, в то время как Weblogic имеет свою имплеменацию jax-ws. Именно наличие в CLASSPATH двух имплементаций приводит к данной ошибке (я правда не понял почему именно, но не суть).

Решение:

Изменить scope зависимости webservices-rt на provided:
    <dependency>
      <groupId>com.sun.xml.ws</groupId>
      <artifactId>webservices-rt</artifactId>
      <version>1.4</version>
      <scope>provided</scope>
    </dependency>
Спасибо http://relativelyprime.blogspot.ru/2010/05/netbeans-68-weblogic-1033-and-jax-ws.html


вторник, 25 июня 2013 г.

Развертывание Birt Runtime 4.2.2 на Weblogic 10.3.5

Если просто задеплоить birt.war на Weblogic , получаем при старте:
weblogic.application.ModuleException:
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1510)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:482)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
Truncated. see log file for complete stacktrace
Caused By: java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.apache.xerces.dom.ElementImpl.getSchemaTypeInfo()Lorg/w3c/dom/TypeInfo;" the class loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader) of the current class, org/apache/xerces/dom/ElementImpl, and the class loader (instance of <bootloader>) for interface org/w3c/dom/Element have different Class objects for the type org/w3c/dom/TypeInfo used in the signature
at org.apache.xerces.dom.DeferredDocumentImpl.getNodeObject(Unknown Source)
at org.apache.xerces.dom.DeferredDocumentImpl.synchronizeChildren(Unknown Source)
at org.apache.xerces.dom.CoreDocumentImpl.getDocumentElement(Unknown Source)
at org.eclipse.birt.core.framework.jar.BundleLoader.loadExtensions(BundleLoader.java:151)
at org.eclipse.birt.core.framework.jar.BundleLoader.load(BundleLoader.java:63)
Решение данной проблемы - закомментировать в weblogic.xml тег <prefer-web-inf-classes>:
<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE weblogic-web-app
    PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
    "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd" >
<weblogic-web-app>
<container-descriptor>
     <!--prefer-web-inf-classes>true</prefer-web-inf-classes-->
</container-descriptor>
</weblogic-web-app>
После этого приложение стартует, однако при попытке сгенерировать отчет валится:
org.eclipse.birt.report.engine.api.EngineException: Error happened while running the report.
   at org.eclipse.birt.report.engine.api.impl.EngineTask.handleFatalExceptions(EngineTask.java:2346)
...
Caused by: java.lang.NoSuchMethodError: org.mozilla.javascript.Context.initStandardObjects()Lorg/mozilla/javascript/ScriptableObject;
   at org.eclipse.birt.report.engine.javascript.JavascriptEngineFactory.createRootScope(JavascriptEngineFactory.java:74)
...
Проблема исправляется также через weblogic.xml, который в итоге принимает вид:
<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE weblogic-web-app
    PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
    "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd" >
<weblogic-web-app>
<container-descriptor>
<!--prefer-web-inf-classes>true</prefer-web-inf-classes-->
<prefer-application-packages>        
            <package-name>org.mozilla.*</package-name>
        </prefer-application-packages> </container-descriptor>
</weblogic-web-app>



среда, 19 июня 2013 г.

Развертывание war-ника из Wavemaker на Weblogic 10.3.5

Развертывание WAR-ников, созданных Wavemaker'ом, на Weblogic имеет некоторые особенности, которые, впрочем, связаны не с самим Wavemaker'ом, а с используемыми в создаваемых приложениях библиотеками.
Первая ошибка, возникающая при работе Grid-виджета, связана с библиотекой Apache Commons Lang:
java.lang.NoSuchMethodError: org.apache.commons.lang.StringUtils.join(Ljava/util/Collection;C)Ljava/lang/String;
Проблема знакомая (Commons Lang цепляется не из приложения, а из weblogic'а), лечится добавлением в war-ник в папку WEB-INF дескриптора weblogic.xml со следующим содержимым:
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
  <description>Weblogic Webapp</description>
      <container-descriptor>
        <prefer-application-packages>      
            <package-name>org.apache.commons.*</package-name>
        </prefer-application-packages>
    </container-descriptor>
</weblogic-web-app>
Однако после этого вылезает другая проблема, на этот раз уже из-за Hibernate:
ClassNotFoundException: org.hibernate.hql.ast.HqlToken
Тут уже пришлось немного погуглить, и, спасибо http://blog.inflinx.com/2007/09/05/classnotfoundexception-orghibernatehqlasthqltoken-in-weblogic/, решение отыскалось, на этот раз не совсем очевидное. Заключается оно также в модификации weblogic.xml, который в итоге принял вид:
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
  <description>Weblogic Webapp</description>
      <container-descriptor>
        <prefer-application-packages>      
            <package-name>org.apache.commons.*</package-name>
            <package-name>antlr.*</package-name>
        </prefer-application-packages>
    </container-descriptor>
</weblogic-web-app>
Чтобы каждый раз не добавлять weblogic.xml в war-ник руками перед развертыванием, можно его вшить в проект Wavemaker с помощью вкладки "Source" -> "Resources", добавив его в папку webapproot/WEB-INF:


воскресенье, 16 июня 2013 г.

Развертывание war-ников на Weblogic 10.3.5 из Netbeans 7.3

Проблема

Netbeans 7.3 при развертывании war-ника на Weblogic 10.3.5 висит по пять минут на "Waiting for server to start the module...". При этом, приложение уже реально стартануло (видно через console, отвечает на запросы). 

Причина

Соотв. баг заведен в багтрекере NB (https://netbeans.org/bugzilla/show_bug.cgi?id=228419) и будет исправлен в 7.4. Проявляется он только при отсутствии в war-нике index.jsp в корне. Отсюда и workaround для проблемы - добавить index.jsp с любым содержимым в корень приложения.