Skip to content

RichFaces, modalPanel and developer (that’s me in this case) stupidity

Ever since I started using RichFaces as my core JSF web component framework (that is, almost a year by now) I faced a recurring issue.

There’s a typical patter in applications where there’s some sort of data whose details are shown inside a rich:modalPanel. Usually this comes from a list of entries, where some command (Link or Button, for instance):

  • fires an actionListener (receiving some parameters to identify the selected entry, load it from a database, for instance, and populate a bean that will feed the said modalPanel);
  • contains an <rich:componentControl … operation=”show”> for that modalPanel.

Pretty simple and works great except for a rathar obnoxious problem: the componentControl with event=”onclick” displays the modalPanel immediately, but it’s data is not yet available. Depending on how loaded your system is or your client latency, there can be a relatively long time before any correct data might be shown. Anything beyond a a few hundred milliseconds can get the user very confused (think of old data showing up first then being ‘magically’ replaced with other data, or an empty form suddendly being populated).

What happend actually makes perfect sense, that is: your modalPanel got displayed, but your data is not yet available. It gets displayed when ready.

This always bugged me and I though of many arcane solutions for this, with lots of components with rendered conditions and reRender attributes. Never a decent solutioin.

Turns out, and I can’t think how this never ocurred me, that the problem wasn’t really with the processing, but with WHEN I was displaying the modalPanel. Solution:

  • Instead of having rich:componentControl firing an operation with event=”onclick” (instant display of modalPanel, delayed display of correct data), it should fire with event=”oncomplete”, thus displaying the modalPanel when the data is already available (assuming the actionListener populates the data).
  • This fixes the problem of data replacement, but not of delay for itself (if your actionListener takes a long time to process, for instance). Simple fix: have a componentControl display some sort of “wait, loading” message with event=”onclick” and another, with event=”oncomplete” display your data and get rid of your message.

I’m really glad I sorted this out.

Oracle ESB - automating build and deploy

One important charactersistic for the success of any software development project is the ability to be built with the same structure and order no matther when and on which environment. Several approaches exist, such as build servers and such. I like to use ant to handle my build requirements (never really got the handle of maven yet; someday, maybe) and, as needed, be called from a build server (hudson, in my case). A easy coroallry of this assumption is the need to get rid of IDE based build.

This all gets even more relevant on projects composed of different and separated modules which have interdepencies and need to be built on some specific order.

Lately I’ve been dealing with an integration project based on Oracle SOA Suite, composed of severam BPEL processes and ESB components. Of course I saw the need to have a coordinated build among all of these.

BPEL subprojects have a neat default build.xml (which actually needs to be run with Oracle’s distributed ant, not your regular one, but this is just a path change). ESB projects, on the other hand, don’t come with such handy feature. It gets worse: they only have as option to be deployed to a server directly from JDeveloper. In fact, there ins’t even a way to deploy some sort of file through Oracle ESB’s administration interface, which sounds to me like it was actually designed to be deployed through tools. Not quite what I’d call amateur, but a far cry from what I’d call an “enterprise approach” (to begin with, how would one have a release package delivered containing all components of a solution? Configuration Management hell, anyone?).

(JDeveloper actually just compiles any needed classes and zips them along with any *esbsvc files. The deployment procedure executed from JDeveloper is a simple POST to <SERVER>/esb/jdevConfiguration/deployment, where SERVER is the selected Integration Server Connection configured in JDeveloper. What is sent? The above mentioned zip file. Sounds very dirty in my book.)

Digging a little deeper I found that:

On the first forum thread above, there’s a reference to http://meslie.blogspot.com/2009/01/oracle-esb-deploy-script.html which points to some things that I agreed with: the approach of using Export/Import has the drawback of isolating the only information that actually changes between different staging environments, namely, the referenced endpoits (in case of Adapters, this is a non-issue due to the fact that JNDI references are used, already decoupling the actual servers from the ESB). Fortunatelly he provides a script that accomplished just that.

On theory everything should be ok, but we all face “that kind” of problems. In this case, the solution is based upon the ant tasks developed for SOA Suite release 10.1.3.3 (which I never found on the distribution). This is referenced as http://www.oracle.com/technology/products/integration/esb/files/esbdeploymentautomation.zip in one of the forum posts above. The solution from meslie tries to find a class named  oracle.tip.esb.console.util.DOMUtil (extended on oracle.tip.esb.client.tobeintegrated.DOMUtils) (I resign from making any comments on the later package naming). An up-to-date ESBDeploymentAutomation.jar can be found on SOA Suite SERVER, as well as oraesb.jar, needed to find the DOMUtil class. Updating the jar file resolved this issue. (Why isn’t it available within JDeveloper 10.1.3.4 is beyond my compreension.)

After all of that when I tought everything would be working nicely, I got the familiar problem with Oracle’s XML parser:

[java] Caused by: javax.xml.parsers.FactoryConfigurationError: Provider oracle.xml.jaxp.JXDocumentBuilderFactory not found

This time I wasn’t able to figure out (probably related to being called from ant and not used within the application server which has support for libraries).

As I have further things to do today, this will be left for tomorrow. I’ll update this when I find a solution.

Intrepid fail; ou tirando a poeira do blog

Não ando escrevendo muito por aqui. De agosto pra cá andei ocupado saindo do emprego antigo (sem a oportunidade de testar ssh sobre http, infelizmente), principiando coisas mais concretas com a AlphaObject (sala, projetos, etc) e, obviamente, deixando às moscas isto aqui.

Desde algumas poucas semanas eu tenho aguardado para postar aqui sobre minhas desventuras com o Ubuntu cuja nova versão saiu recentemente, chamada Intrepid Ibex. Como ando usando Ubuntu no note desde que o note ainda estava em sua encarnação retrasada (acho que pelos tempos do Breezy), sempre realizando upgrades através das ferramentas da própria distribuição sem grandes problemas (exceto, claro, quando trocava de computador), dei uma semana de prudência para corrigirem qualquer coisa mais crítica que encontrassem e me meti a fazer o upgrade.

O resultado foi no mínimo frustrante: imediatamente deixaram de funcionar o som, restricted-drivers da nvidia (o que fritava ~30% de CPU com o processo do Xorg, constantemente) e retornar do suspend. Lendo um pouco sobre esses problemas, comecei a suspeitar que o problema dos drivers da nvidia estivesse causando o problema do suspend.

Isso foi há cerca de 3 semanas. Eu que já cansei de bater cabeça pra resolver problemas nas minhas máquinas de uso normal (nelas eu quero trabalhar; bater cabeça eu bato nas que eu trabalho), deixei por isso e fiquei monitorando se alguém que tinha esses problemas conseguia uma solução.

Hoje, de súbito (acho que o último update foi ontem), o som funcionava. Me motivei e fui atrás, novamente, de alguma solução pro problema do vídeo. Acabei encontrando solução neste link. Apesar de todos os passos e detalhes que ele descreve, o que precisei foi fazer o que é descrito a respeito de lrm-video (editar, comentando a instalação de “nvidia").

Aparentemente isto não causou melhora no problema do suspend.

Resultado disso é que tenho novamente o notebook quase completamente funcional e que me decepcionei um pouco com o processo de upgrade do Ubuntu nesta última versão, mas isto não deve me tirar desse rumo posto que, mesmo quando outros sofriam problemas graves com upgrades enquanto eu realizava os upgrades mais tranqüilos. São só coisas que acontecem…

Posto isto tudo, fica mais forte minha certeza de que preciso de um computador desktop novo pois o que eu tinha em casa foi para a firma (saudade do tempo em que eu tinha 3 computadores e algo tipo 1TB em HDs) e ando somente com o notebook como máquina de trabalho e pessoal. Tenho medo de que aconteça com essa máquina. Com o HD dela especificamente (sim, backups foram feitos recentemente).

Também anoto aqui que preciso registrar novo domínio para este blog que é pessoal e não subordinado à Alpha Object. Assim eu posso ser esquizofrênico e falar mal da minha própria empresa no blog. :)

Notas sobre mod_jk; ou Brincando com clusters de apache e tomcat

Então parti para a construção de um cluster para uma aplicação em tomcat.

A idéia seria oferecer alta disponibilidade e balanceamento de garga com 4 instâncias de tomcat (idealmente em máquinas separadas) formando 2 clusters. À frente disso tudo, um apache com mod_jk distribuindo as requisições entre as instâncias do tomcat em round robin.

Primeiramente, a parte simples: balanceamento de carga.

Há algumas coisas que gostaria de entender melhor:

  • Servlets não conhecem mais seu localAddr quando atendendo a uma requisição vinda do mod_jk (retorna null). se acessando direto responde corretamente seu ip. imaginei que JkOptions +ForwardLocalAddress resolveria isto, mas aparentemente é para que o tomcat reconheça a requisição como vindo do host do mod_jk ao invés do do cliente.
  • Não descobri forma de o mod_jk logar para qual worker node está encaminhando cada requisição.

Quanto à replicação de sessões:

É importante lembrar que o JSESSIONID é dependente do host do cliente e do host do servidor. Acessar cada um dos worker nodes vai gerar sessões específicas para eles. Assim, se se quer testar mesmo a replicação os acessos têm de ser feitos pelo load balancer.

Posto isto, fazendo alguns testes (baixando nodos e deixando que o mod_jk reencaminhasse para outro worker) verifiquei que a replicação às vezes não funcionava 100%: às vezes, ao encaminhar para outro nodo a sessão não voltava para o estado desejado consistente todas as vezes, me dando a entender que a sessão não tinha sido replicada corretamente antes da falha simulada.

Creio ser caminho para solução verificar o atributo channelSendOptions do elemento Cluster do server.xml dos tomcats. Este elemento controla a replicação das sessões entre os nodos do cluster e seu valor default é 8, o qual corresponde a comunicação assíncrona. Em http://tomcat.apache.org/tomcat-6.0-doc/config/cluster.html encontra-se uma referência com os possíveis valores para este atributo.

Testei alguns valores de channelSendOptions com os seguintes resultados:

  • Testado com 10 (async + use ack), não resolveu.
  • Testado com 6 (sync + use ack) deixou a coisa ainda pior, sem replicar direito a sessão at all.
  • Testando com 4 (sync) manteve o mesmo comportamento estranho.

Retornei ao padrão (8, async) assumindo gerar o menor overhead e me voltei à estratégia informada aqui: http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html, onde se lê:

If you are using mod_jk and not using sticky sessions or for some reasons sticky session don’t work, or you are simply failing over, the session id will need to be modified as it previously contained the worker id of the previous tomcat (as defined by jvmRoute in the Engine element). To solve this, we will use the JvmRouteBinderValve.

The JvmRouteBinderValve rewrites the session id to ensure that the next request will remain sticky (and not fall back to go to random nodes since the worker is no longer available) after a fail over. [...] By default, if no valves are configured, the JvmRouteBinderValve is added on. The cluster message listener called JvmRouteSessionIDBinderListener is also defined by default and is used to actually rewrite the session id on the other nodes in the cluster once a fail over has occurred.

Teoricamente, portanto, já tenho esta configuração e, de fato, devo concluir que ela está fazendo seu trabalho.

Continuo com o problema de desalinhamento de sessões. não consegui isolar exatamente a situação em que causa o problema (nem sempre ocorre).

Observei também que, no caso de falha em um dos nodos, às vezes o mod_jk assumia timout e retornava service unavailable, com log dizendo que todas as instâncias estavam ocupadas ou em erro. Certamente uma delas estava muito bem obrigado mas ainda assim ocorria essa situação.

Por acaso, encontrei um post de 2004 na [tomcat-users] em que um usuário descreve exatamente a mesma situação e a mesma preocupação que tenho: http://markmail.org/message/vr3dcxwlsc27itvv.

Minha resposta para ele sugeriria que verificasse os valores de timeouts como descritos em http://tomcat.apache.org/connectors-doc/generic_howto/timeouts.html e http://tomcat.apache.org/connectors-doc/reference/workers.html. Devo seguir meu próprio conselho e tentar isto.

Tenho que retomar esta questão toda ainda para ver como deixar com o comportamento ideal, funcionando 100% o balanceamento de carga e a replicação de sessões. Mas já é um começo.

Notas sobre uso de ubuntu como servidor de vídeo em flash

Para não esquecer e facilitar a vida de quem interessar possa:

  • Wikipedia é uma boa fonte de informações sobre Flash video.
  • Para converter o vídeo, o pacote php5-ffmpeg não dá conta do recado (não tenho muitos detalhes). Melhor usar esta “classe” php que delega ao ffmpeg via shell as conversões.
  • O ffmpeg que vem com o ubuntu não tem compilado suporte a encoding de mp3, de forma que os vídeos em flash não podem ser feitos (o áudio deles é mp3).
  • Para adicionar suporte é preciso recompilar o ffmpeg, seguindo os passos descritos aqui ou aqui, lembrando de verificar que os parâmetros estão corretos: --enable-libmp3lame --enable-libfaad --enable-libfaac.
  • O player do jeroenwijering funciona bastante bem e é livre.

E o Pedro é o cara (ele quem descobriu tudo isso) ;)

Tagged

Aos usuários de bugzilla em debian unstable

Nota sincera àqueles que usam bugzilla em um debian unstable: não atualizem perl para 5.10. Simplesmente vai quebrar o bugzilla. Como a atualização do perl puxa outra penca de upgrades (perl-base, perl-modules, libdbi-perl, libdbd-mysql-perl, liblocale-perl e um libtemplate-perl que eu nunca tinha ouvido falar são os que eu me lembro) e as voltar dependências para as versões adequadas vai ser uma chatíssima perda de tempo (e um grande vai e vem no http://packages.debian.org/stable/).

O problema não existe em debian stable (versão do perl é 5.8.8 que funciona que é uma maravilha)

Não faço idéia de por que eu inventei de usar unstable; talvez porque eu tinha a esperança de não precisar usar versões de um software de 3 anos atrás sem risco de quebrar tudo. Me enganei.

Como lidar com redes bloqueadas

Então meu caro novo empregador possui uma rede com políticas de segurança questionáveis (como por exemplo impedir que desenvolvedores baixem .exe e outras coisas). Entre as práticas implementadas está o bloqueio de emails externos, ssh (no nível de pacote) e permitir acesso ao mundo exterior somente através de um proxy http.

Considerando que a coisa é tão bem organizada a ponto de um ping para máquina X (que resolve para o ip Y) me dar respostas de umas 4 máquinas diferentes com o mesmo ip, eu não me dignei a respeitar tal política obtusa. Especialmente considerando que eu preciso dos meus emails e eventualmente acessar meu servidor por ssh.

Normalmente um túnel ssh (ssh -L yadda yadda) resolveria o problema do email, mas isto não dá (veja acima: ssh bloqueado). Então, out of the blue me ocorreu o pensamento: “E se eu pudesse passar ssh pelo proxy http? Alguém tem que ter passado por este problema”.

Enter google. Pesquiso por “ssh over http”, algo que, se tivessem me dito em qualquer outro contexto, eu perguntaria “mas tu não tá falando de http sobre ssh?” e, para meu leve espanto, não só encontro menções a isto, como um que outro link com guias decentes.

Basicamente, diz a teoria, preciso criar um vhost no meu apache com um certo módulo lá que faz o binding com o sshd e, no lado cliente, configurar meu ssh para usar um certo proxy para encaminhar as coisas pelo http. Parece promissor e relativamente razoável (considerando o nivel de voodoo necessário para algumas coisas em redes). Provavelmente vou usar https. Indireção por indireção, uma camada a mais é o de menos.

Parece promissor. Dou um retorno daqui a uns 2 dias (só pretendo testar isso amanhã).

Tagged

RSS bobo

Sim, meu feed está viajando na batatinha feio como claramente visível no planet ndi.

Não me perguntem. Vou botar a culpa no Wordpress.

Update: sim, eu estou ciente de que os links diretos para os posts estão baleados; algo com o mod_rewrite ou algo que o valha. Outra hora vejo isso; por enquanto fica nos permalinks feios.

Lazyweb FTW!

Então, eis que descubro a solução para minas mazelas que me afligiam no VMWare.

Contexto: uso direto o VMWare server para diversos fins. Muitas vezes o bagunçava alguma coisa com o teclado e, fora do VMWare, nunca mais funcionava o shift. Not good. At all.

Resolvi tomar vergonha na cara e pesquisar e eis que aqui encontro a solução: basta rodar `setxkbmap` que tudo volta ao normal.

Tagged

Atualização de Wordpress para 2.6 “perde” categorias

Atualizei hoje o Wordpress para a versão 2.6 e me deparei com o fato de que as categorias haviam “sumido”. Isto, é, ainda estavam lá, aparentemente; os posts ainda estavam associados às categorais das quais faziam parte, mas os nomes das categorias simplesmente não apareciam em lugar algum: nem ao editar o post, nem ao verificar no site público ou qualquer lugar.

Olhando um pouco, me parece que há diversas mudanças na estrutura do banco do wordpress. Antigamente havia um wp_categories que, ao que me parece não existe mais.

Verifica o que outros fizeram a respeito, comecei a lastimar não tem um backup para comparar o que havia na base antiga. Acabei tendo que corrigir na mão: alterando os valores em wp_terms para nomes falsos de categorais, vi em que posts elas apareciam e inferi qual era qual das poucas categorias que eu tinha. Não deve estar exatamente igual, mas não é como se eu estivesse perdendo muito a respeito.

Fica é minha decepção com o procedimento de upgrade do Wordpress que não trata corretamente algo simples e tão utilizado.