Desabilitando um producer de terceiros no CDI

Entrei um problema no Jboss 7 AS / 6 EAP onde o WELD reclamou ainda no deploy da aplicão que existiam ambiguidade em uma injeção, devido a presença de dois produtores capazes de instanciar a mesma classe (no meu caso o FacesContext do JSF). Veja abaixo o erro:

org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies for type 
     [FacesContext] with qualifiers [@Default] at injection point...

Para resolver precisei desativar um dos produtores. Isso foi feito criando uma Extension que veta o funcionamento de um produtor, no caso abaixo, do produtor org.apache.myfaces.extensions.cdi.jsf.impl.util.FacesInformationProducer do Apache MyFaces. Veja abaixo:

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;

import org.apache.myfaces.extensions.cdi.jsf.impl.util.FacesInformationProducer;

public class FacesProducerSolverExtension implements Extension {

	public void observe(@Observes ProcessAnnotatedType p){
		if(p.getAnnotatedType().getJavaClass()
                    .equals(FacesInformationProducer.class)){
			p.veto();			
		}
	}
}

Para que esse extension funcione, ele deve ser registrado no arquivo de texto WEB-INF/classes/META-INF/services/javax.enterprise.inject.spi.Extension no seu WAR que ficará com o seguinte conteúdo:

br.gov.demoiselle.destdemoiselle.cgpolact.cdi.extension.FacesProducerSolverExtension

Resolvendo falta de classes para SSL do JDK no Jboss 7 AS / 6 EAP

No Jboss AS 7 / EAP 6 enfrentei uma situação onde quando a aplicação tentava estabelecer uma conexão segura via HTTPS (no caso era um webservice), acontecia o seguinte erro:

java.lang.NoClassDefFoundError: com/sun/net/ssl/internal/ssl/Provider

Pesquisando, percebí que essa classe fazia parte da própria JRE, mas no entanto, o Jboss não estava dando visibilidade dela para o ClassLoader da aplicação.

Para resolver, basta adicionar os seguintes path no arquivo XML do módulo da JDK localizado em JBOSS_HOME/modules/sun/jdk/main/module.xml:

...   
     <path name="com/sun/net/ssl/internal"/>
     <path name="com/sun/net/ssl/internal/ssl"/>
... 

Suprindo a falta do @KeepAlive no JSF 2

Para quem programa em JSF 1.2 com RichFaces + A4j, um recurso muito popular é o @KeepAlive. Anotando um ManagedBean dessa forma ele fica com um escopo maior que o de Request e menor que o de Sessão, sobrevivendo na memória enquando o usuário navegar entre páginas que façam uso de um mesmo ManagedBean. Exemplos clássicos: 1. Páginas de listagem e edição; 2. Formulários preênchidos em etapas.

Ao pisar no terreno do JSF 2.0 essa tag deixa de existir. Ainda que existisse, você pode não querer usar o RichFaces e escolher outra biblioteca, como por exemplo a PrimeFaces. A ausência do @KeepAlive no JSF 2.0 parece não ser vista como algo grave já que existem novas possibilidades de controle de escopo tais como as anotações próprio JSF e a as anotações do CDI. O JSF 2.0 fornece por exemplo a @ViewScoped, usada para páginas recheadas de Ajax, mantendo o ManagedBean vivo enquanto existem requests para a mesma página, ou seja, quando não há navegação (métodos acionados devem ser void ou retornar String null). Já o CDI fornece o @ConversationScoped que permite dizer quando a “conversação” com o ManagedBean inicia e termina de forma programática.

Para quem ainda sente falta do simples e preciso @KeepAlive, uma solução é recorrer ao pacote CDI Extensions (CODI) do projeto Apache MyFaces, que fornece a notação @ViewAcessScoped que nos dá exatamente o comportamente desejado. Para instalá-lo via Maven, adicione as seguintes dependências ao projeto:

<dependency>
	<groupId>org.apache.myfaces.extensions.cdi.modules</groupId>
	<artifactId>myfaces-extcdi-jsf20-module-api</artifactId>
	<version>1.0.3</version>
	<scope>compile</scope>
</dependency>

<dependency>
	<groupId>org.apache.myfaces.extensions.cdi.modules</groupId>
	<artifactId>myfaces-extcdi-jsf20-module-impl</artifactId>
	<version>1.0.3</version>
	<scope>compile</scope>
</dependency>

<dependency>
	<groupId>org.apache.myfaces.extensions.cdi.core</groupId>
	<artifactId>myfaces-extcdi-core-api</artifactId>
	<version>1.0.3</version>
	<scope>compile</scope>
</dependency>

<dependency>
	<groupId>org.apache.myfaces.extensions.cdi.core</groupId>
	<artifactId>myfaces-extcdi-core-impl</artifactId>
	<version>1.0.3</version>
	<scope>compile</scope>
</dependency>

Para usar a anotação no seu ManagedBean, faça como segue:

import br.gov.frameworkdemoiselle.stereotype.ViewController;

@ViewAccessScoped
public class MeuMB {
    ...
}

JSF 1.2: Forçando a recriação de um Managed Bean

A configuração do escopo de ManagedBeans no JSF 1.2 é um tópico que gera bastante confusão. Além de poder definir se o ManagedBean vai ter um ciclo de vida atrelado do Request, Sessão ou Aplicação, existem outros modificadores como o @KeepAlive do RichFaces.

O fato é que essa farofa de escopos misturados com recursos de outras bibliotecas trazem algumas situações indesejadas. Seja em sistemas legados ou seja quando estamos em equipes muito heterogêneas, onde não dá pra garantir um bom planejamento do escopo correto de um MB, pode acontecer de você desenvolver uma solução considerando que o ManagedBean vai ser criado e inicializado ao acessar uma determianda tela, mas ao executar a aplicação, descobre erros que advém do fato do ManagedBean estar sobrevivendo na memória, sendo difícil perceber seu real ciclo de vida. Nesse instante, pode surgir a necessidade da recriação de um Managed Bean, evitando vários problemas.

A dica é implementar um método que será acionado por um commandButton ou commandLink da sua aplicação e que, ao invés de navegar diretamente para uma tela, obterá o ManagedBean via EL (no exemplo abaixo a classe DestinoMB), criará ele novamente, e em seguida chamará a tela desejada:

public class OrigemMB(){
	...
	public String onClickMeuBotao(){				
		FacesContext context = FacesContext.getCurrentInstance();
		ELContext elContext = context.getELContext();
		String elMB = "#{destinoMB}"; // Você deve conhecer a EL do seu MB
		
		ValueExpression expression = context.getApplication().getExpressionFactory()
			.createValueExpression(elContext, elMB, DestinoMB.class);
		expression.setValue(elContext, null);

		//Se necessário é possível ainda obter o MB para incializações
		DestinoMB destinoMB = (DestinoMB) context.getApplication().getExpressionFactory()
			.createValueExpression(elContext, elMB, DestinoMB.class).getValue(elContext);
                destinoMB.inicializar();
			
		return "outcomeDaTelaDesejada";
	}
	...
}

Resolvendo problemas com caracteres especiais UTF-8 no JSF 2

As aplicações JSF 2 que crio e faço deploy no Jboss 7 AS / 6 EAP sempre apresentam problemas de encoding no envio de campos de formulários. Forçar o encoding do XHTML, do form, e outros truques parece não resolver pois alguém no meio do caminho entrega os caracteres especiais já estragados para o servidor.

Pesquisando, descobri que se trata de uma configuração do Servidor de Aplicações, no meu caso o Jboss. Uma maneira mais garantida de resolver o problema, sem apelar para configurações do próprio servidor, é garantindo que todo request que chega para a aplição está com o encoding correto, no meu caso UTF-8. Para tanto, um bom e velho filtro resolve, como segue:

...
@WebFilter("*.jsf")
public class CharacterEncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

O perigo da Deep Web

Após ouvir falar da Deep Web resolví verificar do que se tratava. O conceito é simples: existe uma parte da web que pode ser visualizada, já que foi indexada por importantes sites de buscas ou pode ser alcançada a partir de links de sites populares e é chamada de Surface Web (Web da Superfície); existe também uma parte da web que não pode, ou não deseja, ser alcançada, e é chamada de Deep Web (Web Profunda). Teoricamente um site da Deep Web nunca deveria ser alcançado, senão por alguem que guarde seu endereço “desconhecido” e não dependa de terceiros para chegar até ele.

Associado a esse conceito simples, há todo um movimento por navegar de forma anônima na web e acessar sites com conteúdo ofensivo ou proibido. Mas o que uma coisa tem a ver com a outra? Esse tipo de site não sobrevive na Surface Web. Os mecanismos de busca penalizam tais sites e deixam de listá-los, geralmente por questões legais ou denúncias. Da mesma forma, sites de hospedagem, plataformas de blog e outros meios de divulgação de conteúdo na Web deixam bem claro em seus termos de compromisso que não se pode veicular nenhum tipo de conteúdo ilegal ao utilizar o serviço. Sendo assim, um site que por exemplo se propõe a ensinar a fabricar bombas, cometer suicídio ou promover a pedofilia, naturalmente não tem vez na Surface Web e acaba sendo banido rapidamente. Isso se dá pois alguém tem que se responsabilizar pela ilegalidade.

É justamente aí que entra o lance do anonimato na rede. Havendo uma forma de utilizar a web sem que ninguem saiba quem são os donos e os visitantes dos sites, abre-se caminho para uma Web sem-lei, onde é difícil incriminar alguém. Dessa forma, esses sites tentam existir em uma outra Web, onde é bem mais difícil saber quem são os “culpados” pelos atos ilícitos. Curiosamente, os usuários assumiram que essa outra Web, anônima, seja também a Deep Web. Mas há diversas discussões filosóficos em torno do assunto, pois anonimato e alcance de sites são conceitos disintos, mas que parecem andar juntos. Percebam uma tendência estranha: existe uma web visível, e existe uma web invisível. De certa forma, os fatos mostram que tudo que é “legal”, acaba sendo visível, pois as pessoas podem acessar, podem referenciar, os buscadores podem listar, sem problemas com a lei. Naturalmente, o que sobra na parte “invisível”, são as coisas ilegais. E para “ver” essa parte “invisível”, as pessoas preferem navegar de forma anônima, já que o risco de esbarrarem em algo ilegal é grande. Eis o elo!

Um dos pilares tecnologicos que faz essa Deep Web (ou a Web Anônima) existir é o projeto TOR (https://www.torproject.org/). TOR é uma tecnologia que faz com que toda sua ação na web seja mascarada por camadas e mais camadas de criptografia. Fica praticamente impossível computacionalmente falando descobrir a origem de um acesso feito a um site. O projeto é mantido com intuito de promover a navegação anônima, com um tom de “protesto”, alegando que não deveriamos ser rastreados e defendendo a liberdade.  Naturalmente, a tecnologia caiu nos braços de malfeitores que a utilizam para criar uma Web paralela, anônima, que tem sido associada ao conceito de Deep Web por permitir acesso a conteúdos bizarros, onfensivos, ilegais, que nunca seriam encontrados por vias comuns como Google.

Afim de verificar a “propaganda” (nada boa) dessa Deep Web, baixei o navegador do TOR e acessei alguns sites com listagens de links da Deep Web (perceba que nesse momento, deixou de ser Deep, pois está escancarada). Infelizmente, não se vê muita coisa útil, e, para piorar, ao visitar os links você acaba esbarrando em muita coisas ruins como: venda de drogas, contratação de crimes, pornografia, bizarrices, coleções de fotos de atrocidades, auto-mutiliação, e muitos outros assuntos que, francamente, não precisariam ser acessados por ninguém que deseja se manter dentro da lei e em bom estado de sanidade mental.

Se por um lado achei a tal Deep Web apenas um conceito teórico simples, na prática concluí que não se trata de coisa boa. O tal discurso da liberdade e do anonimato acaba sendo uma ferramenta que permite que crimes como a pedofilia sejam incentivados. Que liberdade é essa que envolve a vida de inocentes? Se algo nao é bom para ser feito/dito na vida real, porque ela deve ser publicada no mundo virtual? Enfim, discussões mil podem ser feitos em cima dessa tal “liberdade” que acaba sempre sendo utilizada de forma errada…

Pra começar…

Em tempos onde ser indexado por um bom mecanismo de busca (atualmente, leia-se Google) vale ouro, melhor reservar meu espaço aqui no WordPress. Espantei-me por ver que não havia ainda o blog de prefixo odon. Bom, já que o espaço é meu agora, melhor utilizar eventualmente se pintar motivação. Mas já adianto que não curto muito falar de coisas pessoais, acho que vou acabar escrevendo algo sobre computação, música ou postar desenhos, como sempre.

Se você chegou aqui de alguma forma estranha, senão por um link que eu próprio te indiquei, por favor, deixe ao menos um comentário para eu saber que pessoas têm alcançado esse blog por meios curiosos.

Até+