К сожалению, как сказано в вики Томката, порядок развертывания веб-приложений не определен, и задать его каким бы то ни было образом нельзя. Единственный способ обойти это - задать два различных сервиса в конфигурации, они при этом будут иметь различные порты, но веб-приложения следующего всегда будут разворачиваться позже веб-приложений предыдущего.
barbitoff programmer`s blog
Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
пятница, 26 октября 2012 г.
среда, 24 октября 2012 г.
away3d: скриншоты, или как отрисовать View3D на Bitmap
В away3d 4.0 делать скриншоты содержимого флешки простым:
myBitmap.draw(flashSprite);
не получится (здесь myBitmap - это объект BitmapData, в который запишется скриншот, а flashSprite - корневой спрайт флешки). Выходит это по той причине, что Stage3D не принадлежит списку отрисовки, и в битмапе мы получим все, кроме 3D-контента.
Однако, есть способ получить в битмап содержимое 3D-вида (объекта View3D):
_view.renderer.swapBackBuffer = false;Хитро, но работает, спасибо форуму away3d: http://away3d.com/forum/viewthread/1960/.
_view.render();
_view.stage3DProxy.context3D.drawToBitmapData(myBitmap);
_view.renderer.swapBackBuffer = true;
вторник, 23 октября 2012 г.
Ошибка "org.xml.sax.SAXParseException: The processing instruction target matching [xX][mM][lL] is not allowed" при парсинге XML
Проблема:
При разборе XML-документа валится исключение:
org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
Возможная причина:
Во входящем документе несколько раз присутствует XML Declaration (например, <?xml version="1.0" encoding="UTF-8" ?>).
суббота, 20 октября 2012 г.
"Invalid operation on closed cursor" при просмотре данных в таблице БД Transbase из Netbeans
Попытался посмотреть БД Transbase, используя из JDBC-драйвер и Netbeans. Подключился без проблем, список таблиц получил, а вот SELECT`ы не выполняются, валится ошибка:
Код ошибки 30004, положение SQL : TB Java Client error <30004>: Invalid operation on closed cursor
Строка 1, столбец 1
То ли дело в кривом драйвере, то ли в Netbeans`е. Пришлось искать другой способ полазить по БД, и я наткнулся на вполне годную программку JDBC Navigator: http://thomasokken.com/jdbcnav/. Она показывает данные таблиц без проблем, используя тот же драйвер.
среда, 17 октября 2012 г.
JAX-WS-клиент веб-сервиса: ошибка "com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class <xxx> is not found. Have you run APT to generate them?"
Проблема:
Веб-приложение, использующее JAX-WS-клиент к веб-сервису, отлично работало на машине разработчика, а при развертывании на Tomcat на промышленном сервере стало валиться с ошибкой:
com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class <xxx> is not found. Have you run APT to generate them?
Причина:
Вероятнее всего, старый JDK.
Решение:
Обновить JDK. Не знаю, до какой версии точно, но обновление до последнего JDK (1.6.0_26 в репозитории Debian Lenny) в моем случае решило проблему.
apt-get: обновление определенного пакета
Чтобы обновить один лишь пакет (а не все установленные пакеты, как это делает apt-get upgrade), нужно всего лишь воспользоваться командой install, которая в случае, если пакет уже установлен, обновляет его до последней доступной версии.
вторник, 16 октября 2012 г.
Orbeon: "java.io.IOException: PDF header signature not found." при печати формы
Проблема:
При попытке распечатать форму Orbeon Forms (имеющую собственный шаблон pdf-ки) валится исключение:
java.io.IOException: PDF header signature not found.Причина:
at com.lowagie.text.pdf.PRTokeniser.checkPdfHeader(Unknown Source)
at com.lowagie.text.pdf.PdfReader.readPdf(Unknown Source)
at com.lowagie.text.pdf.PdfReader.<init>(Unknown Source)
at com.lowagie.text.pdf.PdfReader.<init>(Unknown Source)
...
Вероятнее всего, pdf-ки просто нет там, куда ссылается соотв. элемент формы (instance('fr-form-attachments')/pdf).
среда, 10 октября 2012 г.
YUI2: динамическое изменение высоты виджета YAHOO.widget.Panel
Изменение высоты виджета YAHOO.widget.Panel после его создания выполняется вызовом:
panel.cfg.setProperty("height","<xxx>px")
, где panel - сам виджет, созданный с помощью new YAHOO.widget.Panel().
вторник, 9 октября 2012 г.
Spring Security: сброс сессии определенного пользователя
Чтобы сбросить сессию определенного пользователя, во-первых, нужно получить доступ к реестру сессий. Как это делается, я уже писал в прошлом посте. В конфигурации Spring Security отличие состоит лишь в том, что нам понадобится не только пометить определенную сессию как более не действительную, а ещё и разлогинить пользователя с недействительной сессией (само это не сделается). Для последнего нужен специальный фильтр, тот же, что используется для контроля множественного входа:
<http ...>
<custom-filter before="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
...
</http>
<!-- Создаем фильтр,ссылающий на реестр сессий. Задаем страницу,
-- на которую будет выкидывать разлогиненого пользователя
-->
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/login.jsp?invalidSessionError=1" />
</beans:bean>
Всё, теперь пользователь с недействительной сессией будет выкидываться на "/login.jsp?invalidSessionError=1", можно разлогинивать:
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
SessionRegistry sReg = (SessionRegistry) ac.getBean("sessionRegistry");
for(Object principal: sReg.getAllPrincipals())
{
UserDetails authentication = (UserDetails)principal;
if(authentication.getUsername().equals(username))
{
List<SessionInformation> userSessions = sReg.getAllSessions(principal, false);// получаем все сессии пользователя, кроме истекших
for(SessionInformation sessInfo: userSessions)
sessInfo.expireNow();
}
}
Этот код разлогинит пользователя, имя которого задано переменной username. Написанное выше верно для случая, когда принципал представлен объектом UserDetails.
в
14:25:00
0
коммент.
Отправить по электронной почтеНаписать об этом в блогеПоделиться в XОпубликовать в FacebookПоделиться в Pinterest
Ярлыки:
J2EE,
Java,
SessionRegistry,
Spring Security,
Spring Security разлогинить заданного пользователя,
Spring Security invalidate user session,
Spring Security Session Registry
Spring Security 3.1: получение списка залогиненных пользователей
Задача:
Получить список залогиненных пользователей (например, чтобы разлогинить некоторых из них).
Решение:
Для решения этой задачи можно воспользоваться реестром пользовательских сессий, который используется Spring Security, в частности, для контроля множественного входа под одним логином. Чтобы реестр заполнялся и к нему можно было получить доступ из собственного кода, нужно (если, конечно, у Вас уже не используется контроль множественного входа):
- В web.xml добавить слушателя:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener> - В конфигурацию Spring Security добавить:
<!-- Задаем точку входа и страницу запрета доступа, обязательно
-- отключаем auto-config, чтобы определить свой фильтр для входа
-- по логину/паролю
-->
<http auto-config="false" access-denied-page="/login.jsp?accessDeniedError=1"
entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="usernamePasswordFilter" />
<!-- Далее идут правила доступа -->
<intercept-url ... />
...
<!-- Указываем ссылку на бин для session-managment`а -->
<session-management session-authentication-strategy-ref="sas"/>
<!-- Конфигурация выхода обыкновенная -->
<logout delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout"/>
</http>
<!-- Конфигурируем точку входа в приложение -->
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<!-- Конфигурируем реестр сессий -->
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- Конфигурируем бин стратегии контроля сессий. Не ограничиваем
-- множественность входа (нам это сейчас не нужно, по этой же причине
-- мы не использовали фильтр ConcurrentSessionFilter)
-->
<beans:bean id="sas" class=
"org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg ref="sessionRegistry" />
<beans:property name="maximumSessions" value="-1" />
</beans:bean>
<!-- Конфигурируем фильтр входа по логину / паролю, задавая ссылку на стратегию,
-- а также ссылки на бины обработчиков успешного / неуспешного входа
-->
<beans:bean id="usernamePasswordFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureHandler" ref="loginFailureHandler"/>
<beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"/>
</beans:bean>
<!-- Менеджер аутентификации. Тут все стандартно, задается один какой-то провайдер
-- и для стандартного провайдера задается какой-то UserService
-->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="..."/>
<authentication-provider user-service-ref='...'>
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
<!-- Обработчики успешного / неуспешного логина. Стандартные -->
<beans:bean id="loginSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" >
<beans:property name="defaultTargetUrl" value="/index.jsp"/>
</beans:bean>
<beans:bean id="loginFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" >
<beans:property name="defaultFailureUrl" value="/login.jsp?loginError=1" />
</beans:bean>
-
Теперь получить реестр и список активных принципалов в коде можно так:
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.web.context.support.WebApplicationContextUtils;
...
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
SessionRegistry sReg = (SessionRegistry) ac.getBean("sessionRegistry");
for(Object principal: sReg.getAllPrincipals())
System.out.println("Principal: "+principal.toString());
PS Надо, пожалуй, озаботиться подсветкой синтаксиса в блоге =)
в
13:13:00
0
коммент.
Отправить по электронной почтеНаписать об этом в блогеПоделиться в XОпубликовать в FacebookПоделиться в Pinterest
Ярлыки:
J2EE,
Java,
SessionRegistry,
Spring Security,
Spring Security список пользователей,
Spring Security invalidate user session,
Spring Security Session Registry
Spring Security 3.1: AuthenticationProcessingFilterEntryPoint
В Spring Security 3.1 нет AuthenticationProcessingFilterEntryPoint, в отличие от версий 3.0.х, вместо него есть аналогичный класс org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint. Инициализируется через spring security namespace он совершенно также:
<beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
в
12:14:00
0
коммент.
Отправить по электронной почтеНаписать об этом в блогеПоделиться в XОпубликовать в FacebookПоделиться в Pinterest
Ярлыки:
AuthenticationProcessingFilterEntryPoint,
Java,
LoginUrlAuthenticationEntryPoint,
Spring Security,
Spring Security 3.1,
Spring Security 3.1 AuthenticationProcessingFilterEntryPoint
пятница, 5 октября 2012 г.
php: установка заголовков запроса при загрузке данных по http с помощью функции file_get_contents()
Чтобы установить какой-нибудь заголовок http-запроса при загрузке данных по http функцией file_get_contents(), нужно использовать третий параметр этой функции - $context. Например, чтобы установить User-Agent как у 15ого Firefox`а, нужно:
$opts = array('http'=>array('header' => "User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1\r\n"));
$context = stream_context_create($opts);
$html = file_get_contents($link,false,$context);
А то некоторые сайты, например, без этого плюются 500ой ошибкой и не дают себя по-человечески сграбить =)
Warning: file_get_contents(http://***.ru/***): failed to open stream: HTTP request failed! HTTP/1.1 500 Internal Server Error
в
20:47:00
0
коммент.
Отправить по электронной почтеНаписать об этом в блогеПоделиться в XОпубликовать в FacebookПоделиться в Pinterest
Ярлыки:
file_get_contents,
file_get_contents установка HTTP заголовка,
file_get_contents http error 500,
file_get_contents http set header,
grab,
HTTP,
HTTP Code 500,
HTTP header,
php
среда, 3 октября 2012 г.
cmd: смонтировать папку как локальный диск
Чтобы смонтировать, например, папку D:\a\b\c как диск Q:, нужно:
SUBST Q: D:\a\b\c
away3d: двусторонний материал и освещение
Установив у материала свойство bothSides=true, можно добиться, чтобы обе стороны граней, на которые материал наложен, были видимыми (в противном случае одна будет видимой, другая - прозрачной). Однако, если к материалу применено освещение (установлено свойство lightPicker), вторая сторона будет некорректно вести себя по отношению к свету. Т.е., например, если освещение падает только со стороны наблюдателя, одна сторона грани будет корректно освещена, в вот вторая будет казаться неосвещенной.
Дело в том, что освещение грани рассчитывается исходя из угла между нормалью к ней и направлением света. При этом нормаль у грани одна на обе стороны, и для одной стороны она оказывается "выходящей" навстречу наблюдателю, и, значит, освещению, а для второй - "входящей", сонаправленной с направлением света.
Варианта выхода из данной ситуации 2: либо научить away3d самостоятельно инвертировать нормаль при расчете освещенности обратной стороны, либо дублировать все грани фигуры, разворачивая их нормали в обратную сторону. Последнее делается просто, воспользовавшись away3d.tools.helpers.MeshHelper`ом:
Варианта выхода из данной ситуации 2: либо научить away3d самостоятельно инвертировать нормаль при расчете освещенности обратной стороны, либо дублировать все грани фигуры, разворачивая их нормали в обратную сторону. Последнее делается просто, воспользовавшись away3d.tools.helpers.MeshHelper`ом:
var mesh:Mesh = new Mesh(geometry, material);Первый вариант сложнее, я пока не копал в эту сторону, хотя с целью уменьшения числа граней и экономии ОП, пожалуй, стоит попробовать.
var duplicateMesh = new Mesh( geometry.clone(), material);
MeshHelper.invertFaces(duplicateMesh);
вторник, 2 октября 2012 г.
Mint с Mate: как убрать "Мой компьютер" и "Домашняя папка пользователя" с рабочего стола
Чтобы убрать значки "Мой компьютер" и "Домашняя папка пользователя" с рабочего стола, нужно:
- Открыть меню программ, зайти в "Параметры" -> "Внешний вид рабочего стола"
- Снять соответствующие галочки
понедельник, 1 октября 2012 г.
Xftp 4: кодировка имен файлов
Чтобы вместо русских букв в именах файлов при подключении к Linux-хостам не появлялись кракозябры, нужно:
File -> Properties -> Options -> Поставить галку "Use UTF-8 encoding"
Подписаться на:
Сообщения (Atom)