Social Icons


Pages

terça-feira, 2 de outubro de 2012

Eclipse 4.2 SR1 é lançado silenciosamente

Silenciosamente, a organização Eclipse lançou a 2 dias atrás a primeira versão de manutenção do Eclipse 4.2: Eclipse 4.2.1, nomeada Eclipse Juno SR1.

Surpreendentemente, esse evento não foi notificado na homepage principal - eclipse.org - ou mesmo no RSS de atividades recentes. Também não se vê qualquer nota de versão, como houve com o lançamento da versão 4.2.

Buscando no Bugzilla, encontramos uma listagem com 80 bugs que foram fixados nesta versão da plataforma.

Desta vez, o projeto WTP (Web Tools Platform) se sentiu obrigado a postar sobre este evento em sua página inicial. Seguindo a versão do Eclipse 4.2.1, o WTP foi atualizado de 3.4.0 para 3.4.1. O link "Novidades interessantes" do WTP 3.4.1, infelizmente, ainda aponta para a liberação 3.4.0 anterior, mas há uma lista de bugs corrigidos disponíveis, que felizmente aponta para a versão correta.

A comunidade reporta que o 4.2 SR1 tem sido igualmente criticado, embora só hoje Steffen Schäfer postou sobre esta versão focando o novo JGit / Git 2.1 versões. Além dele, há um post chinês sobre o 4.2.1, que apenas diz o seguinte:
Para melhorar a performance, foram corrigidos muitos bugs e a exportação de war com codigo java também foram corrigidos!
Parece que, com o aumento do tamanho, complexidade e enorme número de plug-ins e projetos sobre a eclipse.org, a única coisa que todos nós simplesmente chamávamos de "Eclipse", se torna cada vez mais e mais difícil de identificar como um produto específico no site e, como tal, mais difícil de relatar sobre.

E sobre a adoção da plataforma de 4.2 do Eclipse? Tem havido muito debate recentemente sobre o péssimo desempenho da nova plataforma. Será o SR1 um passo na direção certa, ou vamos ter que esperar pela 4.2 SR2, ou possivelmente até mesmo 4.3?  

* Traduzido de http://jdevelopment.nl/eclipse-42-sr1-silently-released

quinta-feira, 23 de agosto de 2012

Como exibir um PDF numa página JSF quando o arquivo está fora do container web

Confesso: tentei encontrar um título menor pra descrever esta situação, mas não encontrei... Resumindo, o problema é este: se uma página JSF tivesse que exibir um documento PDF que já estivesse dentro do WebContent, era moleza: bastava criar um link apontando pra ele e ponto final. Mas, e se o arquivo estiver, por exemplo, em um servidor da rede cujo o usuário final não tenha acesso?

Uma solução é: importar o conteúdo deste arquivo PDF em um array de bytes e, com isto, enviá-lo para o Response do JSF.

Vamos simular esta solução: criaremos uma aplicação simples, onde o usuário indica em qual caminho está o arquivo PDF, importa e visualiza o PDF no navegador. Ficará assim:

Para isto, basta um ManagedBean e uma página JSF. Sem mais delongas, eis o código, devidamente comentado:

index.xhtml:
<html
 xmlns="http://www.w3.org/1999/xhtml"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html">
<h:head />

<h:body>
 <h:form>
  <h:panelGrid columns="2">
   <h:outputText value="Arquivo:" />
   <h:inputText value="#{control.arquivo}" />
   <h:commandButton
    value="Importar Arquivo"
    action="#{control.importarArquivo}" />
   <h:commandLink
    value="Visualizar PDF"
    action="#{control.visualizarPdf}"
    target="_blank" />
  </h:panelGrid>
 </h:form>
</h:body>
</html>

Control.java:
@ManagedBean
@SessionScoped
public class Control implements Serializable {

   // Array de bytes que armazenará o conteúdo do arquivo PDF
   private byte[] conteudoPdf;

   // Caminho completo do arquivo informado pelo usuário.
   // Ex: C:\Meus Documentos\boletim.pdf
   private String arquivo;

   public String getArquivo() {
      return arquivo;
   }

   public void setArquivo(String arquivo) {
      this.arquivo = arquivo;
   }

   public void importarArquivo() {
      try {
         // Cria um objeto File a partir do caminho especificado
         File file = new File(arquivo);

         // Inicializa o array bytes com o tamanho do arquivo especificado.
         // Note a conversao para int, restringindo a capacidade maxima do
         // arquivo em 2 GB
         conteudoPdf = new byte[(int) file.length()];

         // Cria um InputStream a partir do objeto File
         InputStream is = new FileInputStream(file);

         // Aqui o InputStream faz a leitura do arquivo, transformando em um
         // array de bytes
         is.read(conteudoPdf);

         // Fecha o InputStream, liberando seus recursos
         is.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   public void visualizarPdf() {

      FacesContext fc = FacesContext.getCurrentInstance();

      // Obtem o HttpServletResponse, objeto responsável pela resposta do
      // servidor ao browser
      HttpServletResponse response = (HttpServletResponse) fc
            .getExternalContext().getResponse();

      // Limpa o buffer do response
      response.reset();

      // Seta o tipo de conteudo no cabecalho da resposta. No caso, indica que o
      // conteudo sera um documento pdf.
      response.setContentType("application/pdf");

      // Seta o tamanho do conteudo no cabecalho da resposta. No caso, o tamanho
      // em bytes do pdf
      response.setContentLength(conteudoPdf.length);

      // Seta o nome do arquivo e a disposição: "inline" abre no próprio
      // navegador.
      // Mude para "attachment" para indicar que deve ser feito um download
      response.setHeader("Content-disposition", "inline; filename=arquivo.pdf");
      try {

         // Envia o conteudo do arquivo PDF para o response
         response.getOutputStream().write(conteudoPdf);

         // Descarrega o conteudo do stream, forçando a escrita de qualquer byte
         // ainda em buffer
         response.getOutputStream().flush();

         // Fecha o stream, liberando seus recursos
         response.getOutputStream().close();

         // Sinaliza ao JSF que a resposta HTTP para este pedido já foi gerada
         fc.responseComplete();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Leia Também:

Como exibir um PDF numa página JSF a partir de um campo BLOB/CLOB

Eis o cenário: Uma aplicação JSF, onde numa determinada página seja necessário exibir documentos PDF. Estes ficam armazenados em banco de dados, num campo BLOB/CLOB de uma tabela. A pergunta: Como implemento isto?

Vamos lá, hora da diversão. Começamos criando uma Entity para mapear a tabela que armazena o documento PDF:

DocumentoPdf.java:
@Entity
public class DocumentoPdf implements Serializable {

   @Id
   private int id;
 
   //Este atributo corresponde ao campo BLOB/CLOB que armazena 
   //o conteudo do documento PDF (Note a anotação @Lob)
   @Lob
   @Column
   private byte[] conteudo;
 
   //... Gets e Sets ...
}

Agora, precisamos de uma forma de buscar os objetos desta Entity no banco de dados. Vamos criar um DAO, deixando o código de acesso ao banco fora do escopo do nosso exemplo:

Dao.java:
public class Dao {

   public DocumentoPdf buscarDocumento() {
      //Implemente aqui para retornar o objeto DocumentoPdf do Banco de Dados
   }
}

Com o DAO pronto, vamos para o principal: um método no ManagedBean que pegue o array de bytes e envie para o navegador como um arquivo de documento PDF:

Control.java:
@ManagedBean
public class Control implements Serializable {

   //Apenas para simplificar: carrega automaticamente a Entity através do DAO
   private DocumentoPdf documentoPdf = new Dao().buscarDocumento();

   public void visualizarPdf() {

      FacesContext fc = FacesContext.getCurrentInstance();

      // Obtem o HttpServletResponse, objeto responsável pela resposta do
      // servidor ao browser
      HttpServletResponse response = (HttpServletResponse) fc
            .getExternalContext().getResponse();

      // Limpa o buffer do response
      response.reset();

      // Seta o tipo de conteudo no cabecalho da resposta. No caso, indica que o
      // conteudo sera um documento pdf.
      response.setContentType("application/pdf");

      // Seta o tamanho do conteudo no cabecalho da resposta. No caso, o tamanho
      // em bytes do pdf
      response.setContentLength(documentoPdf.getConteudo().length);

      // Seta o nome do arquivo e a disposição: "inline" abre no próprio navegador
      // Mude para "attachment" para indicar que deve ser feito um download
      response.setHeader("Content-disposition",
            "inline; filename=arquivo.pdf");
      try {

         // Envia o conteudo do arquivo PDF para o response
         response.getOutputStream().write(documentoPdf.getConteudo());

         // Descarrega o conteudo do stream, forçando a escrita de qualquer byte
         // ainda em buffer
         response.getOutputStream().flush();

         // Fecha o stream, liberando seus recursos
         response.getOutputStream().close();

         // Sinaliza ao JSF que a resposta HTTP para este pedido já foi gerada
         fc.responseComplete();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Por fim, vamos criar a página JSF para testar. O atributo target="_blank" no h:commandLink indica ao browser que o PDF deve ser aberto em uma nova aba. Retire este atributo caso queira exibir na aba atual:

index.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<h:body>
  <h:form>
    <h:commandLink value="Visualizar PDF" action="#{control.visualizarPdf}" 
          target="_blank" />
  </h:form>
</h:body>
</html>

Leia também:

terça-feira, 21 de agosto de 2012

Como instalar o Oracle JavaSE 6 no Ubuntu

Em dezembro de 2012, a Oracle decidiu retirar a licença para distribuições do Java em sistemas operacionais. Desde então, não foi mais possível instalar a JVM da Oracle a partir dos repositórios oficiais do Ubuntu.

Para facilitar a nossa mera vida de usuários mortais, a comunidade Ubuntu criou alguns PPAs (Pacotes de Arquivos Pessoais) com os fontes e binários da Oracle JVM. Desta forma, bastaria adicionar um PPA ao repositório do Ubuntu, para ser possível instalar via Central de Programas ou Synaptic. O problema é que a maioria destes PPAs foram removidos pela Canonical; e os que ainda restam; mantém uma versão do Java desatualizada - e tendem a serem removidos também.

Para agravar ainda mais a situação, o Mozilla Firefox recentemente desativou todos os plugins Java 6 com updates inferiores ao 33. Ou seja, sites que utilizam applets - como o Banco do Brasil, por exemplo - pararam de funcionar nestes computadores. Então, qual é a saída?

Resta-nos a instalação manual. Daí vem a última surpresa: no site da Oracle, só existem instaladores para distribuições Linux baseadas no RedHat (pacotes RPM), ou um executável binário para instalação via shell...

Felizmente, existe uma solução elegante, que é basicamente: Baixar o pacote em formato RPM, convertê-lo para DEB (formato aceito pelo Ubuntu e outras distribuições baseadas no Debian) e... instalar! Como extra, também iremos instalar o plugin do Java para o Mozilla Firefox. Então vamos lá:

  • Passo 1: Baixe o instalador no site da Oracle.  Logo abaixo na página você verá: "Java SE 6 Update XX". Ao lado, escolha download do JRE (para quem só quer rodar uma aplicação em java) ou JDK (para desenvolvedores). Em seguida, atente-se em quantos bits é o seu Ubuntu: "Linux x86" corresponde a 32 bits, enquanto "Linux x64" corresponde a 64 bits. Para este passo-a-passo, vou considerar o arquivo jdk-6u34-linux-x64-rpm.bin, que corresponde ao JDK para 64 bits. Salve o arquivo na sua pasta pessoal.

  • Passo 2: Tornar o binário executável. Para isto, abra uma janela do terminal e digite:
    chmod +x jdk-6u34-linux-x64-rpm.bin

  • Passo 3: Execute o binário para extrair os pacotes .RPM:
    ./jdk-6u34-linux-x64-rpm.bin 

  • Passo 4: Para converter o pacote .RPM em .DEB, vamos precisar de um utilitário chamado Alien (isto mesmo, de alienígena). Como ele não vem instalado por padrão no Ubuntu, vamos instalá-lo via apt-get:
    sudo apt-get install alien

  • Passo 5: Agora, vamos usar o Alien para converter o pacote .RPM para .DEB e finalmente instalar a JVM:
    sudo alien -c -i jdk-6u34-linux-amd64.rpm

Pronto, a JVM já está instalada em sua máquina. Porém, para a utilização de applets no Mozilla Firefox, é necessário a instalação do plug-in Java. Faremos isto criando um link simbólico da libnpjp2.so na pasta de plug-ins do Firefox, com o seguinte comando:

- Para Ubuntu 64 bits:
sudo ln -s /usr/java/default/jre/lib/amd64/libnpjp2.so /usr/lib/firefox/plugins
- ou para Ubuntu 32 bits:
sudo ln -s /usr/java/default/jre/lib/i386/libnpjp2.so /usr/lib/firefox/plugins
Este passo-a-passo foi testado no Ubuntu. Mas deve funcionar também em outras distribuições Linux baseadas no Debian.