Skip navigation

Há vários meses que venho recebendo o alerta getOutputStream() has already been called for this response no meu log do JBoss AS 7 quando envio um relatório PDF (gerado pelo iText) do servidor para o cliente.

 

Após pesquisas realizadas no passado concluí que eu poderia ignorar o alerta, pois ele não representava nenhum risco aparente. Apesar disso não havia encontrado uma solução para ao menos evitar que esta mensagem incoveniente desaparecesse dos meus logs.

 

Entretanto em uma nova pesquisa encontrei a solução. Segundo o Ramki Java Blog, depois que o pdf é escrito na resposta HTTP, o próprio servlet JSF tenta "re-abrir" a resposta para escrever o HTML renderizado do estágio de renderização do ciclo de vida do JSF. Portanto a solução é dizer ao JSF que a resposta está completa e para pular o resto do ciclo. Para isso é necessário apenas inserir o seguinte código ao final do método que escreve o PDF:

 

 

FacesContext.getCurrentInstance().responseComplete();  

De acordo com Remy Maucherat na requisição do suporte à compressão gzip aberta por mim na JBoss Issues (https://issues.jboss.org/browse/AS7-2991) a funcionalidade solicitada já foi incluída na próxima versão do JBoss AS, 7.1.1, que deve ser lançada em breve (acredito que nas próximas semanas).

 

De acordo com a documentação oficial, para habilitar o suporte é necessário adicionar a propriedade org.apache.coyote.http11.Http11Protocol.COMPRESSION dentro da tag system-properties, como demonstrado no exemplo abaixo:

 

<server name="xyz.home" xmlns="urn:jboss:domain:1.0">
    <extensions>
        <extension module="org.jboss.as.clustering.infinispan"/>
        <extension module="org.jboss.as.clustering.jgroups"/>
        <extension module="org.jboss.as.connector"/> 
        ....
        <extension module="org.torquebox.web"/>
    </extensions>
    <system-properties>
        <property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION" value="true"/>
</system-properties>

 

Assim que eu tiver acesso à versão 7.1.1 postarei minhas primeiras impressões.

Localize o seguinte trecho do arquivo standalone.xml (acredito que o processo seja o mesmo para o modules.xml):

 

<interfaces>
     <interface name="management">
          <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
     </interface>
     <interface name="public">
          <inet-address value="${jboss.bind.address:127.0.0.1}"/>
     </interface>
</interfaces>

 

Modifique o IP localizado após jboss.bind.address para o IP da sua máquina. Isso tornará as aplicações implantadas no servidor disponíveis para acesso externo.

 

Para liberar também a interface de gerenciamento do servidor para acesso externo, o processo é o mesmo, entretanto o IP modificado é aquele que vem após jboss.bind.address.management. Isso porém não é recomendável por questão de segurança, pois  qualquer pessoa com más intenções que tenha acesso à rede poderá reconfigurar o servidor, portanto o servidor estaria desprotegido (o único bloqueio seria a senha).

Após o lançamento do JBoss Tools 3.3 M5 no final do ano passado, já foi disponibilizada a mesma versão do JBoss Developer Studio (JBDS). O JBDS nada mais é do que a IDE Eclipse com o plugin JBoss Tools embutido, pronto para ser instalado e diretamente utilizado.

 

O maior destaque dessa versão, além da correção de bugs, foi a inclusão do suporte ao JBoss AS 7.1, que está atualmente na versão CR1.

 

Outra novidade é a possibilidade de escolher entre as versões 3.5 e 4 do hibernate, embora o suporte à versão 4 ainda esteja em fase experimental.

 

O JBoss Tools 3.3 ainda está em versão milestone, portanto não é recomendável para produção por enquanto, apesar disso ele já está bem estável.

 

Outras novidades dessa versão podem ser encontradas no blog oficial do JBoss Tools e o download pode ser efetuado aqui.

Este erro foi identificado na versão 3-RC2 do Primefaces. O problema ocorre quando a propriedade match do componente password é utilizada para confirmar a senha, comparando o valor dos dois campos de texto, como no seguinte exemplo:

 

<h:outputText value="Informe sua nova senha:" />
 <p:password id="pw1" value="#{alterarSenhaController.senhaNova}" required="true" label="nova senha"/>
 <h:outputText value="Confirme sua nova senha:" />
 <p:password id="pw2" value="#{alterarSenhaController.repeticaoNovaSenha}" feedback="false" required="true" label="repetição da senha" match="pw1"/>

 

No caso acima a propriedade match no segundo password (pw2) referencia o primeiro (pw1). Quando utilizado, entretanto, ocorre erro de validação mesmo quando o valor de ambos são iguais.

 

Solução

Para solucionar o problema é necessário fazer com que o primeiro password (pw1) referencie o segundo (pw2), como demonstrado abaixo.

 

<h:outputText value="Informe sua nova senha:" />
 <p:password id="pw1" value="#{alterarSenhaController.senhaNova}" required="true" label="nova senha" match="pw2"/>
 <h:outputText value="Confirme sua nova senha:" />
 <p:password id="pw2" value="#{alterarSenhaController.repeticaoNovaSenha}" feedback="false" required="true" label="repetição da senha" />

 

Desse modo a validação ocorrerá normalmente e só será disparada quando os valores forem divergentes.

hfluz

Atalhos úteis do Eclipse

Posted by hfluz Dec 21, 2011

O Eclipse disponibiliza diversos atalhos que podem melhorar, e muito, nossa produtividade ao programar sistemas de software. Eu destaco abaixo aqueles que mais utilizo:

 

  • ctrl+shift+o: organiza todo os imports da classe. Ordena e agrupa os imports, remove aqueles que estão inutilizados e adiciona outros que estão faltando;
  • ctrl+shift+f: formata o código do arquivo que estiver em foco. Para mudar as regras de formatação, acesse as preferências do Eclipse e clique em Code Style->formatter;
  • ctrl+3: Este atalho praticamente inutiliza a barra de ferramentas. Quando pressionado, este atalho apresenta uma caixa de text. Se você digitar qualquer palavra, serão apresentadas as opções de menu e de criação de projetos, classes, entre outros (por exemplo, digitando EJB serão apresentadas as opções de criar projetos e outros arquivos e operações relacionados a ele). O melhor é que a partir da segunda vez nem é necessário digitar, pois ao pressionar o atalho, as escolhas mais frequentes são diretamente exibidas.

 

Se alguém tiver outras boas sugestões de atalhos do eclipse, por favor registrem-as nos comentários.

Artigos relacionados:

Como criar um projeto J2EE no JBoss Tools

Como criar um projeto EJB

 

Para criar um projeto Web com suporte ao CDI, JSF e Primefaces no JBoss Tools siga os passos abaixo:

 

  1. Na barra de ferramentas, clique em File->New->Dynamic Web Project
  2. Dê um nome para o projeto (por exemplo, Tutorial-web)
  3. Marque Add project to an EAR para adicioná-lo como módulo de um projeto enterprise criado anteriormente (projeto TutorialEE, caso tenha seguido este tutorial)
  4. Clique em Next duas vezes
  5. Marque a opção Generate web.xml deployment descriptor
  6. Modifique o Context_root, seu valor será aquele que aparecerá na URL para acessar o projeto pelo navegador. Por exemplo se seu valor for Tutorial-web, a URL do projeto será ip:porta/Tutorial-web
  7. Clique em Finish e o projeto estará criado

 

Adicionar Facets

Assim como no projeto EJB é necessário adicionar facets ao projeto Web (nesse caso facets do JSF e do CDI):

  1. Acesse as propriedades do projeto e selecione Project's facets
  2. Marque as opções CDI e JSF
  3. Clique em Apply e OK;
  4. Serão criados os arquivos faces-config.xml e beans.xml

 

Adicionar libs ao Projeto

É necessário adicionar as seguintes libs no diretório WEB-INF/lib do projeto Web:

  • jdom-1.1.jar e rome-0.9.jar (para utilizar o componente feedReader do primefaces);
  • Primefaces-3.0.M4.jar
  • sam-1.0.2.jar (tema do primefaces)
  • Seam-faces-3.0.0.Final.jar (para utilizar o ViewScope nos CDI beans)

 

Configuração do web.xml

Configure o padrão de URL do JSF como *.xhtml e defina o tema do primefaces com o código abaixo:

 

<servlet-mapping>
     <servlet-name>Faces Servlet</servlet-name>
     <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
     <param-name>primefaces.THEME</param-name>
     <param-value>sam</param-value>
</context-param>

 

O arquivo web.xml também deve ser modificado para definir as restrições de segurança, porém isso é abordado na Configuração da Aplicação Web com security-domain.

Artigos relacionados:

Como criar um projeto J2EE no JBoss Tools

Como criar um projeto WEB com suporte ao CDI, JSF e Primefaces no JBoss Tools

 

Para criar um módulo EJB com suporte a CDI e JPA e adicioná-lo a um projeto enterprise criado previamente, siga os seguintes passos:

 

  1. Na barra de ferramentas clique em File->New->EJB Project
  2. Dê um nome ao projeto, por exemplo, Tutorial-ejb e marque para adicioná-lo como módulo de um projeto enterprise (se você seguiu este tutorial para criar um projeto J2EE, adicione o módulo EJB ao projeto TutorialEE)
  3. Clique em Next duas vezes
  4. Desmarque a opção Create an EJB Client JAR module to hold the client interfaces and classes e marque a opção Generate ejb-jar.xml deployment descriptor

 

Adicionar Facets

O projeto terá sido criado, porém ainda não suportará JPA nem CDI. Para isso siga os seguintes passos:


  1. Clique com o botão direito do mouse sobre o projeto EJB e acesse as propriedades do projeto (properties)
  2. No campo de texto na parte de cima da janela que foi aberta digite facet e clique em Project Facets
  3. Marque as opções JPA e CDI
  4. Clique em Apply (neste momento serão criados os arquivos persistence.xml e beans.xml)

 

Engenharia Reversa JPA (tabelas -> entidades)

O JBoss Tools é capaz de mapear todas as tabelas do seu banco de dados e gerar automaticamente todas as entidades de persistência. Para isso siga os seguintes passos:

 

Passos:

  1. Utilize o atalho ctrl+3 do Eclipse, digite tables no campo que aparecer e selecione JPA Entities From Tables
    1. Neste momento será necessário criar uma conexão com o banco de dados, portanto clique no botão Add conections (ao lado do combo box)

    2. Selecione Oracle (no meu caso), dê um nome qualquer para a conexão e clique em next
    3. Na próxima tela adicione o driver jdbc da oracle clicando no botão New driver definition (ao lado do combo box)
      1. Selecione o Oracle Thin Driver 11

      2. Vá para a aba Jar List e exclua o ojdbc14.jar da lista
      3. Clique em Adicionar jar/zip e selecione o driver ojdbc6.jar que está na sua máquina
      4. Na aba properties modifique a Connection URL (que segue o modelo jdbc:oracle:thin:@ip:porta:sid no caso do dese), preencha o Database Name, digite a senha em password e o nome do usuário em User ID
      5. Clique em OK
    4. Marque save_password (opcional) e clique em Test Conection para verificar se está tudo correto
    5. Caso ocorra algum erro verifique novamente suas configurações de conexão, caso contrário clique em Finish
  2. De volta à tela para gerar as entidades selecione o schema que possui as tabelas desejadas
  3. Selecione as tabelas desejadas ou clique nos botões ao lado para selecionar ou desmarcar todas elas
  4. Clique em Next duas vezes
  5. Na próxima tela preencha o pacote de destino
  6. Marque a opção Always generate optional JPA annotations and DDL parameters
  7. É possível selecionar em Collection properties type se você que que o retorno das buscas venha como Set ou List
  8. Clique em Next e depois em Finish

 

Após serem criadas, as entidades podem apontar alguns erros. Por exemplo, no caso de views será necessário anotar algum(ns) campos como ID. No caso de projetos que referenciam entidades de diversos schemas será necessário adicionar schema="nome_do_schema" na anotação Table das entidades (recomendável para qualquer projeto)

 

Criar Session Beans (Facades)

Os session beans contêm os métodos que realizam as operações de persistência, utilizando JPA, além de fornecer outros serviços que podem ser acessados por diversos outros projetos. Para criar um session bean, siga os passos abaixo:

 

  1. Use o atalho ctrl+3 e digite session e selecione Session Bean (EJB 3.x) – Create new EJB session bean
  2. Preencha o nome do pacote e marque para gerar a interface local
  3. Dê um nome ao facade
  4. Clique em Next e Finish
  5. Adicione a anotação @Named para transformá-lo em um CDI bean
  6. Ao implementar os métodos adicione a anotação @Override a eles, desse modo o eclipse fornecerá a opção de adicioná-los automaticamente à sua interface local

 

Após os passos executados acima, o projeto EJB estará pronto para ser utilizado.

 

Em breve será disponibilizado um vídeo que demonstra os passos descritos acima para criar um projeto EJB.

Artigos relacionados:

Como criar um projeto EJB com suporte a JPA e CDI no JBoss Tools

Como criar um projeto WEB com suporte ao CDI, JSF e Primefaces no JBoss Tools

 

Para criar um projeto java enterprise (J2EE) no Eclipse com o plugin do JBoss Tools siga os seguintes passos:

 

  1. Na barra de ferramentas clique em File->New->Enterprise Application Project
  2. Você será apresentado ao wizard de criação do projeto
  3. Dê um nome ao projeto, por exemplo, TutorialEE
    1. É necessário especificar a target runtime do servidor, entretanto, como ainda não há nenhuma runtime, é preciso criá-la. Para isso clique em New Runtime
    2. Na seção JBoss Community, selecione JBoss 7.x Runtime
    3. Dê um nome ao runtime e coloque o endereço do servidor
    4. Clique em Finish
  4. Clique em Next e marque para gerar o application.xml
  5. Clique em Next novamente e, em seguida, em Finish
  6. O projeto enterprise será criado

 

Configurações Adicionais

Caso a aplicação utilize bibliotecas como o itext ou seam é necessário criar a pasta lib dentro de EarContent/META-INF e adicionar as seguintes bibliotecas para que sejam reconhecidas pelo JBoss AS 7:

  • itext
  • joda-time (requisito do seam-international)
  • seam-international (requisito do seam-faces)
  • seam-solder (requisito do seam-faces)

 

Neste momento, o Eclipse apontará um erro no arquivo application.xml. Este aviso pode ser ignorado, pois quando o primeiro módulo for adicionado a ele (tanto o EJB, quanto o Web), o aviso desaparecerá.

 

Vídeo que demonstra os passos descritos acima:

Artigo relacionado:

Como criar um projeto WEB com suporte ao CDI, JSF e Primefaces no JBoss Tools

 

Quando configurado o security-domain no JBoss AS 7, precisamos configurar também nossa aplicação web para utilizá-lo.

 

Primeiramente é necessário criar o arquivo jboss-web.xml dentro da pasta WEB-INF do projeto WEB e adicionar o seguinte conteúdo a ele:

 

 <?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
     <security-domain>java:/jaas/portalRealm</security-domain>
</jboss-web>

 

É importante observar que o nome do security-domain é portalRealm, entretanto é necessário concatenar java:/jaas/ antes de seu nome para que o domínio de segurança seja acessado corretamente.

 

Para finalizar é preciso simplesmente definir o método de autenticação e as restrições de segurança, que define os padrões de URL da aplicação que terão suas páginas protegidas e que grupos de usuários podem acessá-las. Segue um exemplo abaixo:

 

 

<security-constraint>
     <web-resource-collection>
          <web-resource-name>All resources</web-resource-name>
          <description>Protects all resources</description>
          <url-pattern>/private/*</url-pattern>
     </web-resource-collection>

     <auth-constraint>
          <role-name>professor</role-name>
     </auth-constraint>
</security-constraint>

<security-role>
     <role-name>professor</role-name>
</security-role>

<login-config>
     <auth-method>FORM</auth-method>
     <form-login-config>
          <form-login-page>/Login.xhtml</form-login-page>
          <form-error-page>/LoginError.xhtml</form-error-page>
     </form-login-config>
</login-config>

 

Observações:

  • url-pattern contém o padrão de URL que será restrito (nesse caso, qualquer página que estiver dentro de /private será protegida e poderá ser acessada apenas por usuários que pertencem ao grupo professor)
  • auth-constraint especifica que grupo tem acesso às páginas restritas
  • security-role especifica um grupo
  • E login-config determina qual o método de autenticação (basic ou form, por exemplo)

 

Faça o deploy da aplicação web e tente acessar uma página protegida. Você será, então, redirecionado para a página Login.xhtml e terá que se autenticar antes de acessar a página.

Do mesmo modo que o Glassfish configura a autenticação de suas aplicações através do realm, o JBoss AS 7 faz uso do security-domain para executar esta tarefa.

 

Do lado do servidor é necessário apenas editar o arquivo standalone.xml e adicionar o seguinte código dentro de <security-domains> </security-domains>:

 

 

<security-domains>
      <security-domain name="portalRealm">
           <authentication>
                <login-module code="Database" flag="required">
                     <module-option name="dsJndiName" value="java:jboss/datasources/portal"/>
                     <module-option name="principalsQuery" value="SELECT senha FROM usuario WHERE username=?"/>
                     <module-option name="rolesQuery" value="select grupo,'Roles' FROM usuario WHERE username=?"/>
                     <module-option name="hashAlgorithm" value="SHA-256"/>
                     <module-option name="hashEncoding" value="base64"/>
                </login-module>
           </authentication>
      </security-domain>
 </security-domains>

 

Considerações:

  • Adeque as queries para suas respectivas tabelas que armazenam os dados do usuário
  • portalRealm é o nome do domínio de segurança e que fará parte da URL de conexão JAAS
  • A module-option dsJndiName define a URL JDBC que será utilizada para executar as queries
  • A module-option principalsQuery define a SQL que faz a busca da senha do usuário
  • A module-option rolesQuery define a SQL que busca o grupo do usuário
  • A module-option hashAlgorithm define o algoritmo hash utilizado na senha (esse valor pode ser SHA-256 ou MD5 por exemplo)
  • A module-option hashEncoding define a codificação hash utilizada na senha

 

Caso hashAlgorithm e hashEncoding não sejam especificadas, será considerado que a senha está armazenada sem nenhum tipo de criptografia ou codificação.

 

Para instruções de como configurar a aplicação para utilizar o security-domain, clique aqui.

Artigos relacionados:

Configuração do Driver Oracle (ojdbc) como módulo no JBoss AS 7

Como criar um projeto EJB com suporte a JPA e CDI no JBoss Tools

 

Há diversos meios para criar um datasource para a conexão com o banco de dados, como, por exemplo, através da edição de arquivos de configuração ou por intermédio da linha de comando.

O meio abordado neste artigo é a que faz uso do console gráfico.

 

Passos:

  1. Acesse o console gráfico por meio de um browser de internet com a URL localhost:9990/console
  2. A página inicial já apresenta a interface para editar as configurações de datasource7A2A.tmp.jpg
  3. Clique no botão Add para adicionar uma nova datasource4048.tmp.jpg
  4. Digite o nome da datasource e o nome jndi que será referenciado pelo persistence.xml da aplicação e clique em Next
  5. Selecione o driver jdbc que será utilizado (no meu caso oracle, para configurá-lo clique aqui)6346.tmp.jpg
  6. Digite o nome do usuário, a senha e a URL de conexão com o banco de dados e clique no botão Done

 

Após seguidos estes passos o datasource estará disponível para ser acessado por qualquer aplicação implantada no servidor e também para ser acessado pelo security-domain.

Artigos relacionados:

Criação de Datasource no JBoss AS 7

Como criar um projeto EJB com suporte a JPA e CDI no JBoss Tools

 

Há duas formas de se configurar um driver JDBC no JBoss Application Server 7. A primeira é por intermédio do deploy do driver ojdbc6.jar no servidor e a outra é configurá-lo como módulo.

Vou apresentar apenas a segunda solução, visto que ela é a mais recomendada pela própria documentação do JBoss AS, pois o driver só é inicializado com o servidor quando for requisitado por alguma aplicação implantada.

 

Passos:

  1. Vá ao diretório [JBOSS_AS_HOME]/modules/com
  2. Crie o diretório odbc6 e dentro dele outra pasta chamada main
  3. Coloque o driver JDBC (ojdbc6.jar) dentro do diretório main e dentro desta mesma pasta crie o arquivo module.xml

 

O arquivo module.xml deverá ter o seguinte conteúdo:

 

 <module xmlns="urn:jboss:module:1.0" name="com.oracle.ojdbc6">
 <resources>
 <resource-root path="ojdbc6.jar"/>
 </resources>
 <dependencies>
 <module name="javax.api"/>
 </dependencies>
</module>

 

Ao final, a estrutura dos diretórios deverá ser a seguinte:

  • [JBoss_AS_HOME]/
    • -modules/
      • com/
        • oracle/
          • jdbc/
            • main/
              • module.xml
              • ojdbc6.jar

 

Seguidos os passos acima, será necessário reiniciar o servidor caso ele esteja iniciado e o driver estará adequadamente configurado e pronto para ser utilizado pelas aplicações.