Throubleshooting: Tomcat Listener not found

Olá Pessoal, 

Mais um throubleshooting do dia. Não é muito difícil passar por essa quando estamos usando o eclipse. Se vc usa o maven ou adiciona as bibliotecas na mão, pode cair no contexto a seguir. Vamos ver. 

Contexto 

Tudo preparado já no seu projeto e vc resolve executar no servidor somente para ver o “hello world”. E daí, o que acontece? 

GRAVE: Error configuring application listener of class com.sun.faces.config.ConfigureListener

java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener 

 

Mas qual o motivo? 

Simples! Mesmo vc adicionando as dependências de lib ao seu projeto, quando vc faz um deploy o tomcat busca as libs na pasta lib do projeto, isso é o correto, certo? Mas o Eclipse não copia os arquivos automaticamente para o lib. E o tomcat, ao chegar lá não vai achar aquelas libs externas que precisa, como a do JSF, primefaces, richfaces etc. No caso dos componentes JSF, ele apenas não é exibido no browser, mas a do JSF por exemplo, ele da error 404 not found.

Solução

Essa é difícil. Copiar os .jars  para a pasta lib do projeto e pronto. Você pode fazer essa cópia automática, dizendo ao maven para colocar as libs já no diretório lib do projeto. Daí é só ver na documentação. 

Abracos, vou ficando por aqui. Espero que estejam curtindo os posts de thoubleshooting.

See ya!!

JNDI com Hibernate – Ambiente de Test

Olá Pessoal,

No post de hoje, vou apresentar como usar JNDI dentro do seu arquivo hibernate.cfg.xml dentro de um ambiente de teste. Em outro post falarei como usar em um ambiente de produção e ver que fica mais fácil realizar mudanças nas conexões de modo mais fácil, uma vez que normalmente o ambiente de teste possui configurações levemente diferente do ambiente de produção desde nome do usuário, até o path do BD.

Lets go…

Starting/Nosso Cenário

Eu já falei aqui no blog sobre pool de conexão no TomCat e JNDI, porém não falei como usar o JNDI dentro do Hibernate.

Aqui veremos isso com um framework bem utilizado no mercado que é o Hibernate.

Mas, a pergunta que você pode está fazendo: “Camilo, por que eu usaria isso?”, “Qual a diferença na pratica?”

Como sempre gostei de ser mais pratico e menos teorico, eu também tive essa dúvida rs. Porém, descobrir a grande produvidade quando tive 6 projetos diferentes para Produção e sempre quando tinhamos um release, era fato de esquecer de mudar o hibernate.cfg.xml, para as conexões de produção, fora que toda vez já era um saco, porque tinha que configurar sempre no ambiente de desenvolvimento antes de enviar para prod.

Enfim, na pratica você só vai configurar em um lugar as config de conexão, em um único arquivo e mais nada. E o melhor, quando for pra PRODUÇÃO, veremos que lá temos outro arquivo JNDI só para PROD, que normalmente não tem porque mudar com frequência. E nos desenvolvedores precisamos apenas saber o JNDI correto, e o administrador do Servidor que se vire lá com as configs, do arquivo de conexão em produção. Isso é extremamente importante, trabalhei em um projeto do qual nos desenvolvedores não tinhamos acesso as senhas, pw de produção, somente os administradores, para nos o que importava era apenas o path do JNDI e mais nada. Para quem trabalha fazendo todos os papeis (isso lembra meu tempo de freelance rs) desenvolvedor,administrador, DBA, isso parece ser estranho, mas em projetos grandes que participei na IBM , não é assim que funciona. Desenvolvedor é desenvolvedor,Testador é testador e por ai vai. E em ambiente teste você tem até acesso ao BD, PW etc. Mas, em produção. Not.

Hoje estarei limitado ao ambiente de teste, porque no ambiente de produção há algumas mudanças significativas e quero deixar o post focado à um assunto.

Nosso projeto

Criei um projeto muito simples, pois a funcionalidade está no uso de JNDI com Hibernate em teste. Não passa de um projeto com JSF + Hibernate. Porém,vc pode configurar isso em qualquer projeto com Hibernate para que ele funcione com JNDI.


Primeiro passo:

É configurar o arquivo web.xml do seu projeto com o nome do JNDI que deseja, pode ser o nome do seu cachorro, da sua namorada, o que você quiser.

<resource-ref>

<res-ref-name>jdbc/lpjava</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>

Segundo passo:

Após ter configurado o web.xml, informando que a conexão para o BD estará naquele path. Vamos configurar o nosso JNDI, com os dados de conexão. Em ambiente de teste, vamos configurar o arquivo context.xml que está na pasta Server do Eclipse. É nele que vai estar as config locais. Insira dentro da tag Context o Resource abaixo:

<Resource auth=“Container”

name=“jdbc/lpjava”

driverClassName=“com.mysql.jdbc.Driver”

maxActive=“20” maxIdle=“10” maxWait=“-1”

type=“javax.sql.DataSource”

url=“jdbc:mysql://localhost/apptestes”

password=“lpjava”

username=“camilolopes”

validationQuery=“SELECT 1”

testOnBorrow=“true”

testWhileIdle=“true”

timeBetweenEvictionRunsMillis=“10000”

minEvictableIdleTimeMillis=“60000” />

Observe que informamos o nome do JNDI, que este tem referencia.

Terceiro passo:

Feito isso, vamos informar ao Hibernate que ele vai usar uma conexão JNDI, para o Hibernate o que importa é o path, se amanha você muda a senha de conexão vai precisar alterar apenas o arquivo context.xml que está na pasta Server dentro do Eclipse, lembrando que isso em ambiente de teste. Abaixo como ficou meu arquivo hibernate.cfg.xml

<hibernate-configuration>

<session-factory name=“hibernate/SessionFactory”>

<property name=“hibernate.connection.datasource”>java:/comp/env/jdbc/lpjava</property>

<property name=“hibernate.current_session_context_class”>thread</property>

<property name=“hibernate.transaction.factory_class”>org.hibernate.transaction.JDBCTransactionFactory</property>

<property name=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</property>

<property name=“hibernate.jdbc.batch_size”>0</property>

<mapping class=“br.com.camilolopes.bean.TUsuario”/>

</session-factory>

</hibernate-configuration>

Quem usa o Hibernate ou está começando vai ver que não temos mais a property para o password ou user, uma vez que há uma referencia para um path, onde este tem referencia para um arquivo (context.xml) onde está de fato nossa conexão.

Finalizando

Teste sua aplicação, mande executar e faça uma persistencia, porem não deixe de verificar se já deu um start no banco de dados, se todos os .jars referente ao Hibernate estão no projeto e no caso do Eclipse olhe se está fisicamente na pasta lib do projeto.

Vou ficando por aqui, espero que tenham gostado do post.

Abracos, see ya guys!!! 🙂

Segurança JEE Realm FORM TomCat

olá Pessoal,

Hoje vou falar de um assunto que todos os desenvolvedores, arquitetos etc. tem que se preocupar ao desenvolver uma aplicação é a famosa segurança. Você como “profissional do software” tem que saber quem vai ter acesso a determinadas partes da sua aplicação e o que ele pode fazer após ter concedido o acesso.

Dizer  se o usuário “camilo” for um simples “user” ele só pode navegar nas seguintes pages: “index.jsp, faleconosco.jsp etc”. Agora vamos dizer que o usuário “lopes” é um dos administradores do sistema, então ele pode acessar as páginas “cadastrarprodutos.jsp, deletarusuario.jsp que estão em /admin” etc.

Como fazer isso Camilo?

Bem, o objetivo deste post é dar um suporte quem está entrando agora no mundo JEE, hoje temos frameworks que ajudam de forma mais eficiente que usar Realm do TomCat. Mas, não pretendo ir além do Realm. Só ele dar um big post.

Alguns iniciantes em JavaEE, tem essa dúvida consigo: como implementar regra de acesso sem precisar fazer um hard-code?”

Fazer isso dentro do seu servlet, controller etc. não é boa ideia pelo simples motivo: “as regras de segurança podem mudar com bastante frequência”. Como por exemplo amanha você precisa adicionar um novo nível de administrador (sênior, pleno) e cada um com permissões diferentes. Mas, também pode acontecer de um novo grupo fazer parte da administração os “gerente de projetos” ai lá vai o desenvolvedor atualizar o code e se amanhã deixar de existir algum dos citados? Já viu o prolema que temos ao implementar regras de segurança dentro do seu servlet, controller etc.

Os iniciantes em JEE, põe tudo que for restrito dentro de WEB-INF, isso não é boa prática.

As regras de segurança referente acesso é algo que pode ser simples, mas também complexo, vai depender da regra de negócios da aplicação. Por exemplo, já vi aplicações que tem vários tipos de administradores, usuários, com acessos completamente diferentes, porém no mesmo nível. Mas, colocar em WEB-INF todos as suas pages .jsp. Vc deve se perguntar: “é seguro a quem?”.

Vamos parar de conversa e veremos na prática…

lets go…

Realm

Realm é um depósito de informações de usuário que autentica e autoriza os usuários.Usando realms, você põe a responsabilidade no servidor Web por obrigar a implementar políticas de segurança. Isto significa que os desenvolvedores não precisam escrever código para usar autenticação e autorização (não que isso os impeçam de fazê-lo). Delegando autenticação e autorização ao servidor, os desenvolvedores podem escrever códigos de propósitos gerais, sem preocupação com as regras de autorização de acesso. (Livro – Tomcat – Guia Rápido do Administrador)

Para esse exemplo vamos usar um dos mais populares container JEE o TomCat (versão 6). Se você estiver usando um container diferente, terá que ler a documentação do fabricante e saber como implementar. Porém há poucas mudanças na maioria das vezes.

Posts Recomendado:

Requisitos:

  • Eclipse (usarei o Galileo)

  • TomCat 6 (se tiver a 5.x.x sem problemas, pode usar)

Aqui vamos implementar sem usar dados vindo do BD. Então veja como uma forma de praticar “Segurança” até porque sem BD, vc vai precisar sempre ficar atualizando o arquivo tomcat-users.xml e se você não usar criptografia, qualquer um pode abrir esse arquivo e saber as senhas de cada usuário.

Desenvolvendo

  1. Crie um dynamic web project no Eclipse e deixe ele conforme a imagem a seguir. O meu chama RealmCamilo no decorrer do post, estarei informado o que teremos em cada page .jsp.

  2. Na página acessonegado.jsp insira o código a seguir:

    E-mail/Senha inválido.Tente novamente  />
  3. Na página index.jsp deixe conforme abaixo

     Acessar minha conta
  4. agora na pagina index.jsp dentro de /admin deixe assim:

    Está é uma página de conteúdo restrito. 🙂

Até aqui nada de especial. Agora que começa a segurança.

  1. Primeiro ponto é você deixar o tomcat parado e ir no caminho a seguir (caso tenha instalado no modo default):

    C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf

  2. Abra o arquivo server.xml

    Precisamos dizer ao TomCat que vamos habilitar o Realm, a linha vem comentada, para isso tire o comentário da linha a seguir:

    <Realm className=”org.apache.catalina.realm.MemoryRealm”/>

  3. Salve e feche o arquivo

  4. Agora vá no arquivo tomcat-users.xml no mesmo diretório do arquivo server.xml.

    Nesse arquivo criamos os usuários que terão acesso aplicação e qual role ele pertence.

    rolecode

  5. Não é muito difícil de ler, veja:

    “lopes É-UM manager. Porém, admin e camilo são um manager e admin.”

  6. O relacionamento aqui é one-to-many, nao se esqueça disso. Ou seja, um usuário pode ter mais de um nível de acesso.

  7. Lembre-se isso ai só são strings. O poder deles está quando criamos as restrições no arquivo web.xml.

Criando as regras de acesso

Agora precisamos criar as regras de acesso, dizer o que um “manager” pode acessar e o que um “admin”pode acessar.

  1. Abra o arquivo web.xml da sua aplicação.

webxml

Antes do primeiro código você precisa saber disso:

  • <security-constraint>: Protege um recurso, ou seja, diz o que será protegido e quem pode acessar.

  • <auth-constraint>: Isto especifica os roles que são permitidos acessar recursos cobertos por esta limitação de segurança.

  • <web-resource-collection>: sub-elemento de <security-constraint> que diz o que será registro.

  • <login-config>: diz qual o tipo de autenticação. Há quatros tipos: BASIC, DIGEST, FORM, SSL.

Para o nosso exemplo usaremos o FORM. O BASIC ele usa a caixa de autenticação do browser.

  1. insira o código abaixo no seu arquivo web.xml


Atenção:

Agora tenha atenção com o código de <login-config> Muitos confundem, achando que se o login/senha estiver OK. Vá para a página que está em <form-login-page> , mas ali que temos nenhuma condição IF.

O segredo é que antes de ir para tela de login, vc precisa ter tentando acessar o conteúdo restrito(na realidade é isso que acontece, pense um pouquinho…), assim o servidor vai saber o que fazer com vc que acessar caso seu login/senha válido, ou seja, enviar você para a página que foi solicitada (requested).

Se você, tentar direto para página de login, sem tentar acessar um conteúdo restrito, como o servidor vai saber encaminha-lo? Já que no action do form não há nada que diz “vá para pagina XYZ”.

  1. veja o código do form login.jsp

    Login
    Usuario: Senha:
  2. O atributo name, action deve ser com os nomes acima. Caso contrário, nada funciona como esperado. E nao esqueça que o método deve ser post, pois é um FORM.

Eu tenho o hábito de dizer: “Primeiro erre, para depois acertar”. Ou seja, primeiro tente acessar se não conseguir use seu login/senha. O máximo que vai receber é dizer que você não tem permissão para acessar.

Testando

*não esqueça dos starts/stops que você deve dar sempre que atualizar os arquivos .xml do tomcat.

Para testar vamos fazer um deploy da nossa app. Vamos usar um arquivo WAR, se não sabe como exportar um projeto como WAR veja no post indicado no inicio do post.

Abaixo como ficou minha exportação:

Veja meus teste de acesso:

  1. Tentando com o usuário camilo


  2. Resultado:


  3. Tentando com o usuário lopes


  4. Resultado:


Agora é com você

Experimente testar acessando o conteúdo restrito direto, tente colocar usuário inexistente, ou usuário com roles diferentes ao acesso permitido. E para ficar uma mensagem de erro personalizada, crie suas proprias páginas de erro.

Bom ficando por aqui, acho que este foi um dos maiores posts que já escrevi e nao sou a favor de posts grandes, mas foi necessário. O assunto precisava ser detalhado e olha que nao fui tanto assim. Vi vários outros posts na internet porém os que encontrei estava resumido demais e para quem está dando os primeiros passos pode se tornar complicado o processo. Espero que tenham gostado.

Abraços, see you next post. :).

Undeploy e Deploy Tomcat Eclipse

Olá Pessoal,

Neste post veremos um video cedido pelo autor Edson Gonçalves mostrando como fazer um undeploy/deploy no TomCat dentro da IDE Eclipse, vejam é que bem simples e fácil. Confiram abaixo o video.

Se nao conseguir visualizar o video clique aqui.

Simples não?! abracos e até o próximo post!