Evitar log de LoginException quando usuário errra senha

Passamos a conviver com um número excessivo de exceções de login do JAAS no Jboss EAP 6.0.1 quando algum usuário errava a senha. Essas exceções não indicam erros do sistema propriamente ditos, e estavam enchendo o log e tornando difícil a análise de outros problemas de produção.

Login failure: javax.security.auth.login.LoginException: Login Failure: all modules ignored
	at javax.security.auth.login.LoginContext.invoke(LoginContext.java:921) [rt.jar:1.6.0_45]
	at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186) [rt.jar:1.6.0_45]
	at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683) [rt.jar:1.6.0_45]
	at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.6.0_45]
	at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) [rt.jar:1.6.0_45]
	at javax.security.auth.login.LoginContext.login(LoginContext.java:579) [rt.jar:1.6.0_45]
	...

A opção foi abaixar o nível de log do pacote org.jboss.security para FATAL para todo o Jboss. Isso pode ser feito no standalone.xml seguinte na seção de logging:

<subsystem xmlns="urn:jboss:domain:logging:1.1">
    ...
    <logger category="org.jboss.security">
        <level name="FATAL"/>
    </logger>
    ...
</subsystem>

Kanban

Kanban

Tenho trabalhado num projeto de um kanban simples para tarefas pessoais baseado em JavaScript e HTML5 com local storage. Tenho utilizado no dia a dia para gerenciar minhas tarefas no trabalho, tarefas de casa, além de tarefas relativas ao desenvolvimento do próprio aplicativo. Está sendo útil para mim, e creio que pode ser para outros.

Não busco concorrer com KanbanFlow, Trello e outros kanbans que são online e compartilhados por times. Se trata apenas de um kanban local, armazenado no cache do navegador, para pequenas gestões de pequenas atividades, sem burocracia.

A quem interessar: http://github.com/rafaelodon/kanban

Feedbacks são bem vindos!

Desabilitando a execução do maven-javadoc-plugin herdado do Parent

Aconteceu comigo de vários componentes maven de um projeto herdarem um POM Parent que configura a utilização do Plugin maven-javadoc-plugin. Esse plugin varre todo o código do componente e gera os HTMLs da documentação estilo JavaDoc. No entanto, esse plugin parece demandar muitos recursos para ser executado, onerando o tempo de build. No caso de projetos com muitos componentes, isso pode inclusive significar um tempo muito grande de fila de builds para integração contínua. Para desabilitar a execução do plugin adicionei a entrada project/build/pluginManagement abaixo ao pom.xml dos componentes em questão:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  	 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
             http://maven.apache.org/xsd/maven-4.0.0.xsd">

        ...

	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<artifactId>maven-javadoc-plugin</artifactId>
					<configuration>
						<skip>true</skip>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>

        ...

</project>

Se você desejar ainda desabilitar esse plugin por padrão mas eventualmente gerar o JavaDoc quando for necessário, é possível colocar essa configuração de build acima dentro de um profile do Maven, bastando assim escolhê-lo no momento da execução.

Criando Applets para os Painéis do Gnome 3

Qual não foi minha surpresa quando fui para o Gnome 3 e soube que o applet Giplet que podia ser adicionado aos paineis Gnome para mostrar o seu IP local, só funcionava para Gnome 2. Resolvi verificar como estava o estado-da-arte da fabricação de applets para Gnome 3. Vou relatar aqui os passos mais fáceis que encontrei.

Baixe o Panel Applet Generator, que adianta muito sua vida e permite criar applets compatíveis com Gnome 2 e 3. A forma mais fácil de fazer isso é via Git:

git clone https://github.com/palfrey/panel-applet-generator

No diretório do panel-applet-generator, execute o comando abaixo, que no caso está parametrizado para criar um Applet chamado “showmyip” com uma descrição correspondente. Para quem interessar, há outras opções disponíveis, tais como definir ícone, categoria, etc.

python panel-applet-generator.py -n showmyip -d "Displays your local IP address on the panel."

Depois disso basta entrar na pasta showmyip que será criada. Lá estará toda a estrutura básica de um Applet Gnome tanto para a versão 2 quanto para o 3. O que você precisa fazer é continuar implementando o arquivo .py principal criado, que vai ter o nome do seu applet seguido da palavra “Applet”, no caso acima showmyipApplet.py. Para quem não sabe é basicamente um programinha python baseado em Gtk. No meu caso, simplesmente adicionei um import ao socket para obter o IP e adicionei um label com o IP ao applet:

try:
    from gi.repository import Gtk
except: # Can't use ImportError, as gi.repository isn't quite that nice...
    import gtk as Gtk

import socket

def applet_factory(applet, iid, data = None):
    hostname = socket.gethostname()
    ip = socket.gethostbyname("%s.local" % hostname)
    label = Gtk.Label("IP: "+ip)
    applet.add(label)
    applet.show_all()
    return True

O passo final é gerar o .deb e instalar nosso Applet para adicionar ao painel. Nesse ponto o panel-applet-generator não ajuda muito (sugestão de pull request, hein?).

Vá até o diretório do applet e compacte-o com Tarball e Gzip e adicione o prefixo “0.1.orig.tar.gz” (o 0.1 vem do controle de versão que está descrito na estrutura do pacote DEBIAN). Dê um debuild para gerar o .deb. Em seguida basta instalar via dpkg.

cd showmyip/
tar -czf ../showmyip_0.1.orig.tar.gz .
debuild -us -uc
sudo dpkg -i ../showmyip_0.1-1_i386.deb

Para adicionar o applet criado ao painel, segure a tecla Windows + Alt clique com botão direito sobre o painel, acione “Add to Panel”, e você verá na lista de applets o seu applet querido.

Serializando e Deserializando Classes de Entidade do Hibernate/JPA para XML com XStream

Em um projeto que trabalhei tivemos a necessidade de representar em XML a nossa principal entidade de banco de dados, com [quase] todas as suas relações diretas e indiretas (uma grande árvore). A opção que se mostrou mais fácil foi o uso da biblioteca XStream. No entanto, esbarramos em alguns problemas uma vez que o Hibernate trabalha com Proxies e implementações próprias das Collections do Java, afim de promover a abordagem Lazy para a obtenção de entidades relacionadas. Nesse post demonstro como resolvemos esse problema.

Se estiver usando maven, adicione ao pom.xml da sua aplicação a dependência xstream-hibernate:

<dependency>
	<groupId>com.thoughtworks.xstream</groupId>
	<artifactId>xstream-hibernate</artifactId>
	<version>1.4.7</version>
</dependency>	

É muito importante que você crie e configure uma única instância de XStream que deverá ser usada tanto na serializaçaõ quanto na deserialização, para que tudo funcione. Configure-a da seguinte forma:

	
import org.hibernate.collection.internal.PersistentBag;
import org.hibernate.collection.internal.PersistentList;
import org.hibernate.collection.internal.PersistentMap;
import org.hibernate.collection.internal.PersistentSet;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentCollectionConverter;
import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentMapConverter;
import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentSortedMapConverter;
import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentSortedSetConverter;
import com.thoughtworks.xstream.hibernate.converter.HibernateProxyConverter;
import com.thoughtworks.xstream.hibernate.mapper.HibernateMapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;

public class MeuXStream {

    public static XStream xs;

    static {

        xs = new XStream() {
	    @Override
	    protected MapperWrapper wrapMapper(final MapperWrapper next) {
	        return new HibernateMapper(next);
	    }
        };

        xs.registerConverter(new HibernateProxyConverter());
        xs.registerConverter(new HibernatePersistentCollectionConverter(xs.getMapper()));
        xs.registerConverter(new HibernatePersistentMapConverter(xs.getMapper()));
        xs.registerConverter(new HibernatePersistentSortedMapConverter(xs.getMapper()));
        xs.registerConverter(new HibernatePersistentSortedSetConverter(xs.getMapper()));

        xs.alias("Bag", PersistentBag.class);
        xs.alias("Map", PersistentMap.class);
        xs.alias("List", PersistentList.class);
        xs.alias("Set", PersistentSet.class);

        xs.autodetectAnnotations(true);
    }
    ...
}

A maior parte das linhas acimas é para tratar a conversão de coleções para XML. Suas Classes de Entidades podem conter coleções, e estas vão estar com os tipos abstratos das Collections (Ex: Set, List, Map). Em tempo de execução, o Hibernate instanciará essas propriedades com suas próprias implementações dessas Collections (ex: org.hibernate.collection.PersistentList para o caso de List). No entanto você não vai querer que no seu XML final conste detalhes dessas coleções específicas do hibernate. Para isso, defina o HibernateMapper como o MapperWrapper do seu XStream. Além disso, registre os conversores do Hibernate fornecidos pela biblioteca xstream-hibernate. Por fim, é interessante definir alias para as 4 coleções do hibernate, pois, mesmo depois de convertidas, o XML final utiliza no atributo class o nome da classe do Hibernate, o que é irrelevante, mas fica poluído e verboso.

Caso você tenha mapeado alguma herança, certifique-se também de colocar a anotação @Proxy com lazy=false na super-classe. Isso evita que o Hibernate utilize Proxies nas instâncias dessa classe, o que leva ao XStream a serializar essas Proxies como se fossem instancias apenas da super-classe, gerando conflitos quando ele esbarra com uma propriedade da sub-classe e causando erros de de conversão (ConversionException). Lembrando que mesmo que você coloque essa anotação, isso não impedirá que carregamento das propriedades do tipo anotado seja Lazy, pois ainda há a configuração de cada propriedade nas próprias entidades (FetchType), apenas evitará a confusão com Proxies da super-classe.

	
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Proxy(lazy = false)
public class MinhaSuperClasse implements Serializable {
    ...
}

Provavelmente você não desejará representar toda sua cadeia de classes no XML, podando alguns pontos. Para isso, anote as propriedades que não desejar serializar com a anotação @XStreamOmitField. Para que essas anotações sejam reconhecidas, foi preciso aquele ultimo comando do bloco estático de inicialização do XStream.

Por fim, para serializar, o mais importante é carregar a sua entidade logo antes de transformar em XML, pois dessa forma, com a sessão ainda aberta, o próprio XStream irá percorrer todos os getters das propriedades, forçando o carregamento de tudo que foi configurado com a abordagem Lazy.

	
...
MinhaEntidade entidade = minhaEntidadeDAO.carregarPeloId(id);
String xml = xs.toXML(entidade)
...

Para deserializar, obtenha de volta o mesmo XStream usado na serialização e faça:

	
...
String xml = lerXmlDeAlgumLugar();
MinhaEntidade entidade = (MinhaEntidade) xs.fromXML(xml);
...

Atente para a limitação de que o XML gerado em um momento só poderá ser deserializado em um outro momento se a mesma estrutura de classes e propriedades se mantiver. Qualquer mudança de nome de classe ou de propriedade, ou mesmo alteração de pacote, resultará em um erro de conversão. Para contornar esse problema pode-se definir alias para todas as propriedades e classes com as anotações @XStreamAlias e @XStreamAliasType, ou fazendo chamadas à xs.alias(…) ou xs.aliasType(…). Pode-se ainda criar Converters customizados para definir como serializar/deserializar uma classe específica, ou no caso de um comportamento geral para todas a classes, o ideal é escrever um Mapper customizado. Detalhes sobre esse processo de customização você encontra nessa ajuda do XStream.

10 anos com Java. Relembrando…

Hoje me dei conta que há exatos 10 anos atrás, em agosto de 2004, tive meu primeiro contato real com o Java. Apesar de nesses 10 anos não ter trabalhado apenas com Java, ela foi meu principal “ganha-pão”. Nesse post faço uma volta ao passado para relembrar como eram as coisas nessa época.

Começei a programar muito novo, ainda criança, brincando de mover a tartaruguinha do Micromundos com Linguagem Logo. Na pré-adolescência e início da adolescência brincava muito com Basic e Pascal, tudo console, e mais pra frente Visual Basic, Delphi já no Win 32. E foi no ensino-médio técnico que a coisa ficou séria, quando aprendí C/C++ e o bom e velho PHP com pacotão Web (HTML+CSS+JavaScript), garantindo meus primeiros freelances. Mas foi só em agosto de 2004, quando inciei a graduação em Ciência da Computação, que me enfiaram o Java goela abaixo pela primeira vez. Era uma recomendação da SBC na época. As universidades todas seguiam tal tendência, já que era uma plataforma livre e o mercado de Java na época estava quente.

E assim, durante a graduação usei Java para tudo: construir aplicativos console, desktop, web e mobile; exercitar o conceito de cliente/servidor e técnicas de arquitetura paralela e distribuída; estudar algoritmos, estruturas de dados, grafos, orientação por objeto e quase todas os assuntos que envolviam programação no curso. E apesar de diversos trabalhos enquanto estudante, foi só em 2007 que tive meu primeiro contato realmente profissional com Java em uma empresa de desenvolvimento.

Em 2004 Java era um terreno ainda em exploração. Estávamos na JDK 1.4, mas muita gente ainda usava a 1.3. Ainda falava-se muito em Java applets como uma grande vantagem, mas ele já havia definitivamente perdido espaço para o Flash. De fato muito sites corajosos (não eram só os sites de banco) usavam applets para alguns propósitos, principalmente interativos. Java Desktop também era muito bem visto, mas ainda havia muita referência baseada em AWT ao invés do SWING. Java FX nem sonhava em existir! E como essa história de levar tudo para a Web ainda estava acontecendo (e o Java EE teve papel importante no patrocínio dessa transição), teve muito manolo que optou por fazer sistemas desktop cliente/servidor enormes, com muito RMI (o RCP do Java), ao invés de partir para o uso de EJBs. Aliás, EJB foi um recurso arquitetural nobre que o Java incentivou desde muito cedo e que até hoje é sub-utilizado, dando lugar para soluções com desenhos vergonhosamente pouco sofisticados.

Lembro-me também da hype sobre Java ME e das promessas sobre o Mobile, muito antes dessa realidade dos Smartphones atuais. Os professores e evangelizadores da tecnologia falavam muito sobre a questão do Java ser multi-plataforma e de poder ser usado em aplicações embarcadas de hardwares específicos. Mas acho que pouca gente teve contato com essa parte. Quem carregou o Java pra frente no Mobile foi a Nokia em sua época de ouro. Suporte ao Java era uma feature a ser observada na compra de um aparelho novo. Cheguei a ver inúmeras vagas de emprego de empresas que faziam aplicativos para celular, e tenho ainda conhecimento de alguns colegas que participaram de soluções de software corporativas baseada em outros Handhelds que usavam Java, como os Palm.

Pra fechar, destaco o Java EE, que julgo ter sido a perna do Java que mais cresceu. Em 2004 quem soubesse Servlet e JSP básico já era disputado pelo mercado. O conceito de MVC ou o simples conceito de divisão em camadas despontava como tendência, e quem diria que iria durar tanto tempo. Mas pouco se falava de JSF e muito menos de Spring. O que alguns usavam era o Struts para ajudar com o vai-e-vem dos servlets. A efervescência dos frameworks ainda iria começar: muitos surgiram e muitos desapareceram. E alguns viraram especificação! Algumas soluções de ORM existiam, e o Hibernate ainda não era unanimidade (muito menos existia JPA). Lembro de dar manutenção em um projeto que usava Apache IBatis p/ ORM (nunca mais ouví falar). Aliás, unanimidade mesmo era que precisávamos de muito XML pra fazer qualquer coisa em projetos web. Annotations só vieram na JDK 1.5…

Fica a saudade dessa época onde o Java era uma terra de oportunidades e uma grande novidade. O legado deixado é enorme, o que me leva a crer que vamos demorar a deixar de escutar o nome “Java” por aí (seria o novo Mainframe?). Há ainda quem diga que se tornou uma ferramenta implacável no cinto-de-utilidades do programador, ao lado do C/C++ por exemplo (todos anos a fio no Top 5 do Ranking TIOBE). Por fazer parte da minha história, torço para que a plataforma continue se adequando aos novos ventos e gerando oportunidades!

Compartilhando recursos estáticos entre webapps JEE6 através de um JAR

Na API Servlet 3.0 é possível colocar recursos estáticos dentro de um JAR para serem acessados pelos webapps que dependem desse JAR. Para tanto, basta empacotar os recursos desejados na pasta META-INF/resources do JAR. Os arquivos aí colocados estarão disponíveis para os WAR como se estivessem na raíz do webapp. Ex:

O arquivo:

MeuWebApp.war/WEB-INF/lib/WebCommons.jar/META-INF/resources/public/img/logo.png

Estará disponível no servidor como:

http://localhost:8080/MeuWebApp/public/img/logo.png

No caso de um projeto Maven, essa pasta pode ser contemplada no código fonte em [PASTA DO PROJETO]/src/main/resources/META-INF/resources

Isso é bastante útil para compartilhar html, xhtml, jsp, css, js, imagens, arquivos de properties, dentre outros, entre diferentes WAR. Para obter o mesmo resultado nas versões anteriores da API era necessário bolar algum mecanismo que acessasse recursos programaticamente via ServletContext, ou mesmo utilizando bibliotecas de terceiros específicas para esse propósito, como é o caso da Weblets.

No caso de se tratar de um projeto JSF, pode ser desejado compartilhar entre os WAR não somente recursos estáticos como também ManagedBeans, Converters e outros beans gerenciados pelo framework. Para isso, crie no JAR também o arquivo META-INF/faces-config.xml.

Forçando o uso de Hibernate 3.x com JPA no Jboss AS 7 / EAP 6

O Jboss AS 7 já provê a biblioteca do Hibernate 4 para os projetos, não sendo necessário incluí-la na lib de seu WAR. No entanto, pode acontecer de você querer usar uma versão mais antiga do Hibernate, como por exemplo a versão 3. Além de incluí-la como lib, você precisa avisar para o Jboss para deixar de prover o Hibernate dele, no caso a versão 4. Para tanto, alguns passos sesão necessários.

Você precisa adicionar ao WAR final o arquivo META-INF/jboss-deploy-structure.xml com o segunte conteúdo:

<jboss-deployment-structure>
	<deployment>
		<exclusions>
			<module name="org.hibernate" />
		</exclusions>		
	</deployment>
</jboss-deployment-structure>

Você também vai precisar adicionar uma propriedade a mais na sua Persistence Unit declarada no persistence.xml:

...
	<property name="jboss.as.jpa.providerModule" value="hibernate3-bundled" />
...

E por fim, certifique-se de fornecer o JAR do hibernate ao compilar o pacote final. Para quem usa Maven, basta adicionar o seguinte:

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>3.6.10-Final</version>
</dependency>

Não se esqueça de verificar a árvore de dependências do Maven para saber se alguma dependência indireta está requerendo alguma biblioteca específica do Hiberante também na versão 4. Se houver, o downgrade pode não ser possível ou pelo menos será não-trivial. Boa sorte!

Abandonando o antigo formulário j_security_check através de JSF 2 e Servlet 3

Muitas são as aplicações web em Java que utilizam o Serviço de Autenticação e Autorização do Java (JAAS) para fazer a segurança. E um elemento famoso no JAAS é o JSP/HTML de login que possui um formulário mágico que faz um POST para a URL “j_security_check“, enviando o password e a senha através dos inputs de nome “j_password” e “j_username” respectivamente. Muitos torcem o nariz para esse tipo de coisa, já que a plataforma está de certa forma engessando a tela de login.

As vantagens de querer fazer um formulário de login JSF 2 são muitas! Primeiramente você pode querer herdar o layout de um template via Facelets. Você pode também querer utilizar componentes ricos de bibliotecas como PrimeFaces ao invés de simples inputs HTML padrão. O JSF também dá um bom suporte para validação de campos e mensagens de erro/sucesso. Mas dadas as restrições impostas pelo j_security_check e seus amigos, como unir os dois mundos então?

Com a chegada do JEE 6 e a nova Servlet API 3.0, foi previsto um método bem óbvio na interface HttpServletRequest chamado request.login(String username, String password). O resto você provavelmente já imagina: pode-se acionar o JAAS programaticamente dentro de um ManagedBean do JSF por exemplo, unindo o melhor dos dois mundos.

A idéia então é fazer um XHTML de login e fazer um ManagedBean que cuide do comportamento dessa tela. Veja como fica a configuração de segurança do web.xml:

<?xml version="1.0"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
           http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">

	...
	
	<security-constraint>
		<web-resource-collection>
			<web-resource-name>private</web-resource-name>
			<description>private resources</description>
			<url-pattern>/private/*</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<role-name>*</role-name>
		</auth-constraint>
	</security-constraint>
	
	<login-config>
		<auth-method>FORM</auth-method>	
		<form-login-config>
			<form-login-page>/public/pages/security/login.jsf</form-login-page>
			<form-error-page>/public/pages/security/login.jsf</form-error-page>
		</form-login-config>
	</login-config>
	
	<security-role>
		<role-name>*</role-name>
	</security-role>

</web-app>

Perceba que no web.xml a página de login é tanto o formulário quanto a página de erro, ou seja, em caso de login inválido a aplicação retornará para a página de login, permitindo continuar interagindo com o formulário para exibir mensagens por exemplo. A página /public/pages/security/login.xhtml pode ser algo assim (observe que ela herda um template via Facelets):

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:p="http://primefaces.org/ui"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	template="/WEB-INF/template/main.xhtml">
	<ui:define name="body">
		<p:messages id="messages" globalOnly="true" />
		<h:form id="form">			
			<h:panelGrid columns="3">
				<p:outputLabel value="Usuário" for="inputUsuario" />
				<p:inputText id="inputUsuario" required="true"
					value="#{loginMB.usuario}" />
				<p:message for="inputUsuario" />

				<p:outputLabel value="Senha" for="inputSenha" />
				<p:password id="inputSenha" required="true"
					value="#{loginMB.senha}" />
				<p:message for="inputSenha" />
			</h:panelGrid>

			<p:commandButton id="btEntrar" value="Entrar" ajax="false"
				action="#{loginMB.onClickLogar()}"
				icon="ui-icon-check" />
		</h:form>
	</ui:define>
</ui:composition>

E um exemplo de ManagedBean para tal página pode ser (os imports estão omitidos):

...

@ManagedBean
@ViewScoped
public class LoginMB {

    private static final String PAGINA_INDEX = "/private/pages/index.xhtml";

    private String usuario;
    private String senha;

    public String onClickLogar() {
        try {
	    HttpServletRequest request = (HttpServletRequest) FacesContext.
                getCurrentInstance().getExternalContext().getRequest();
            request.login(this.usuario, this.senha);
            return PAGINA_INDEX;
        } catch (ServletException e) {
	    //se houver erro no Login Module vai cair aqui... 
            //Você pode fazer log por exemplo!
        } finally {
            //tratar aqui mensagens de segurança que possam ter vindo 
            //do Login Module exibindo-as na forma de FacesMessage
	}

        return null;
    }

    public String getUsuario() {
        return usuario;
    }

    public void setUsuario(String usuario) {
        this.usuario = usuario;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }
}

Não se esqueça de que para esse recurso de login programático estar disponível, sua aplicação deve adicionar a dependência provida a API do Servlet 3.0 no pom.xml:

<dependency>
	<groupId>javax</groupId>
	<artifactId>javaee-web-api</artifactId>
	<version>6.0</version>
	<scope>provided</scope>
</dependency>            

Vale ressaltar que o exemplo do post cobre apenas o essencial. Para atingir a excelência num esquema de login JAAS é preciso cuidar de vários outros aspectos. Um deles é definir um bom mecanismo de troca de mensagens do Login Module para com a Aplicação. Uma opção é adicionar a mensagem como atributo no Request, podendo capturá-la no ManagedBean e tranformá-la em uma FacesMessage. Outra questão que deve ser observada é o comportamento da aplicação quando a página de login é acessada por um usuário já logado, podendo redirecioná-lo ou retirá-lo da sessão, o que pode ser feito via JSF adicionando no seu XHTML de login um event listener na fase de Pre-Render View e implementando um listener correspondente:

...
   <f:event listener="#{loginMB.verificaSeUsuarioJaLogado}" type="preRenderView" />
...

Tenho certeza que partindo dessa solução base você poderá buscar várias sofisticações, fugindo do tradicional JSP de login para o JAAS.