Monitorando a temperatura no Macbook

Macbook White
Macbook White, ou frigideira

A temperatura no Macbook pode aumentar com o uso, principalmente quando há um processamento mais pesado. O meu chegou Macbooke chega a 103 graus e permanece assim enquanto faço processamento pesado, em geral, rotinas em Java para análise de texto com arquivos grandes.

Tenho uma boa experiência com produtos da Apple. Desde 2007 trabalho diariamente com Macbook, iPhone, iPod Touch e agora minha preferida: Apple TV.

Para monitorar a temperatura no Macbook você pode usar o iStat Pro, que mostra informações da CPU, memória, discos, rede, bateria, ventoinhas, etc… É o widget que mais uso e bem que poderia ter uma versão para Linux.

Temperatura máxima no Macbook
Temperatura máxima no Macbook

Até hoje está funcionando muitíssimo bem, então acho que isso é normal. Fritar ovo também deve ser normal. Dá uma olhada aqui na idéia.

Criando um projeto Java EE 6 com Eclipse, JBoss e Maven

Nesse artigo vamos criar um projeto Java EE 6 de forma rápida e simples utilizando o Apache Maven. O servidor de aplicação será o JBoss 7.1.1, versão certificada para Java EE 6.

O Maven é um software para construção e gerenciamento de projetos utilizado principalmente em Java. A manutenção das dependências em um projeto é um processo complicado e o Maven pode facilitar e agilizar a vida do programador nesse sentido.

O primeiro passo é fazer o download do Eclipse IDE for Java EE Developers. Dentro do Eclipse, precisamos instalar o JBoss Tools. Clique em Help – Eclipse Market Place.

projeto java ee 6
Com o Eclipse instalado, podemos fazer o download do JBoss 7.1.1.

Em seguida, precisamos criar o Maven Project de acordo com a sequência abaixo.

  • Crie um novo projeto Maven
  • Novo projeto Maven
    Novo projeto Maven
  • Localização do projeto
  • Simple project
    Localização do projeto
  • Selecione o arquétipo: jboss-javaee6-webapp-ear-archetype
  • Arquétipo
    Arquétipo
  • Parâmetros do arquétipo
  • Parâmetros
    Parâmetros
  • Projeto Java EE 6 criados

  • Projetos
    Projetos
  • Adicione o servidor, nesse caso, o JBoss 7.1.1, que acaba de mudar de nome e agora se chama Wildfly
  • Novo servidor
    Novo servidor
  • Selecione o tipo de servidor (JBoss AS 7.1)
  • Tipo de servidor
    Tipo de servidor
  • Informe o diretório onde está o JBoss
  • Diretório do servidor
    Diretório do servidor
  • Adicione o projeto
  • Projetos
    Projetos
  • Inicie o servidor (debug)
  • Servidor
    Servidor
  • Para acessar o site, clique aqui. Nosso projeto Java EE 6 está pronto.

Novidades do Java EE 6

Utilizando Maven a gente economiza tempo na criação de projetos. Acho que vale a pena inclusive para projetos antigos, já que a gente ganha muito tempo com o gerenciamento de dependências e o build.

Agora, é só adicionar novas funcionalidades na aplicação web. Algumas novidades do JavaEE 6 que valem lembrança:

  1. Servlets 3.0 – declaração via anotações e chamadas assíncrona
  2. CDI 1.0 – Facelets nativo
  3. JPA 2.0 com Criteria Queries e cache de segundo nível
  4. JAX-RS 1.1, API para RESTful
  5. JSF 2.0 com Facelets nativo
  6. EJB 3.1, agora com interfaces opcionais e EJB Lite
  7. Bean Validation 1.0 com Validadores personalizados

Instalação e configuração do Hadoop (single node)

O Hadoop tem se tornado uma importante ferramenta para Big Data. Neste post vamos fazer a instalação e configuração do Hadoop em single node. Nos próximos posts veremos alguns programas Hadoop de exemplo para processamento de arquivos, importação de dados de um banco relacional e outras possibilidades.

Apache Hadoop

logo-hadoop
hadoop
Framework para processamento paralelo e distribuído.
Principais características:
– implementação do MapReduce
– Hadoop Distributed File System (HDFS)
– roda no hardware atual, sem a necessidade de adquirir novos servidores
– tolerância a falhas
– replicação de dados

Download

A última versão estável é a 1.0.4, disponível aqui.

Instalação e configuração do Hadoop

Alterar os arquivos de configuração que estão no diretório do Hadoop:


$ cd ${diretório-do-hadoop}

– conf/hadoop-env.sh


export JAVA_HOME=${diretório-do-jdk}

– conf/core-site.xml


<configuration>
     <property>
         <name>fs.default.name</name>
         <value>hdfs://localhost:54310</value>
     </property>
     <property>
         <name>hadoop.tmp.dir</name>
         <value>${user.home}/hadoop/hadoop-tmp-dir</value>
     </property>
</configuration>

– conf/hdfs-site.xml


<configuration>
     <property>
         <name>dfs.replication</name>
         <value>1</value>
     </property>
     <property>
         <name>dfs.name.dir</name>
         <value>${user.home}/hadoop/dfs-name-dir</value>
     </property>
     <property>
         <name>dfs.data.dir</name>
         <value>${user.home}/hadoop/dfs-data-dir</value>
     </property>
</configuration>

– conf/mapred-site.xml


<configuration>
   <property>
       <name>mapred.job.tracker</name>
       <value>localhost:54311</value>
  </property>
</configuration>

ssh

O Hadoop utiliza ssh para comunicação. Para tanto, verifique se o serviço está ativo:


$ sudo /sbin/service sshd status

Caso não tenha o ssh server instalado:


    $ sudo apt-get install ssh
    $ sudo apt-get install rsync

ou

    $ sudo yum install openssh-server
    $ sudo yum install rsync

ssh inativo:


Active: inactive (dead) since...

ssh ativo:

Active: active (running) since...

Para iniciar o serviço:

$ sudo /sbin/service sshd start

Geração de chaves

Se você não consegue acessar o localhost sem o passphrase, gere as chaves:


    $ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
    $ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys


Tente acessar o localhost:

    $ ssh localhost

Dica: caso ainda precise do passphrase, altere as permissões conforme abaixo:

    $ chmod 600 ~/.ssh/authorized_keys

HDFS


$ cd ${diretório-do-hadoop}/bin


$ ./hadoop namenode -format

Iniciando o Hadoop

Para iniciar o daemon do Hadoop:


$ ./start-all.sh

Durante a inicialização do serviço, deve ser mostrado o log:


starting namenode, logging to /home/marco/Software/hadoop/libexec/../logs/hadoop-marco-namenode-marcoreis-ultrabook.out
localhost: starting datanode, logging to /home/marco/Software/hadoop/libexec/../logs/hadoop-marco-datanode-marcoreis-ultrabook.out
localhost: starting secondarynamenode, logging to /home/marco/Software/hadoop/libexec/../logs/hadoop-marco-secondarynamenode-marcoreis-ultrabook.out
starting jobtracker, logging to /home/marco/Software/hadoop/libexec/../logs/hadoop-marco-jobtracker-marcoreis-ultrabook.out
localhost: starting tasktracker, logging to /home/marco/Software/hadoop/libexec/../logs/hadoop-marco-tasktracker-marcoreis-ultrabook.out

Interface web

Para testar a instalação do Hadoop e verificar se está funcionando, acesso os serviços através das urls:
Namenode
JobTracker
TaskTracker

Parando o Hadoop


$ ./stop-all.sh

Palestra: Big Data e a era da informação

No próximo dia 27/04, 10h, estarei falando sobre Big Data no IESB. Essa palestra vai ser para o Flisol 2013 (Festival Latino Americano de Instalação de Software Livre), onde vou abordar os principais conceitos e mostrar uma solução utilizando a tecnologia.

O Flisol é um evento internacional e descentralizado, realizado pelas comunidades para promover o software livre e sua filosofia. Acontece, além do Brasil, na Argentina, Uruguai, México, Chile e por aí vai.

Haverá diversas atividades entre palestras, mini-cursos, workshops, hackerlab e install fest. Confira aqui a agenda.

Tópicos da minha palestra

  • A era da informação
  • Information Retrieval
  • Relevância
  • Tipos de consulta (frase, wildcard, proximidade, intervalos)
  • Busca em tempo real
  • Oportunidades e possibilidades

[photopress:cartaz_flisol.jpg,full,centered]

Banner de divulgação do evento

A difícil tarefa de chegar no horário

Acordei cedo, mesmo sem o despertador, porque não gosto de chegar atrasado nos compromissos. “10h da manhã, vou conseguir chegar no horário”, pensa ele. Não que chegar atrasado tenha grandes consequências, mas é questão de honra chegar em algum lugar na hora marcada.

Partindo da crença popular de que o homem se arruma rápido, o que no meu caso é totalmente verídico, em questão de minutos está tudo pronto. Banho tomado, dente escovado, cama arrumada, chave do carro e a mochila do material em cima da mesa.

Agora começa a aventura. Acordar duas crianças no sábado de manhã, depois de terem passado a noite assistindo televisão. Diego nem se mexe. Mariana quase se mexeu, mas desistiu. E agora? Empurra, chama, pede, clama, implora. Nada. E o relógio lá, contando as horas.

Puxa o cobertor de um, pega a outra no colo (arrebenta com a coluna) e, devagar, os olhos se abrem. Agora é fácil. Só dar banho, vestir roupa, pentear o cabelo, café da manhã e chego no horário. Nada mais ilusório. Incrível como a teoria e prática não se encontram quando se trata de crianças.

Banho da Mariana. A receita é simples: liga o chuveiro, molha, sabão + esponja + espuma, toalha, veste a roupa. 10 minutos. Acabou? Tá bom, vai pensando. Creme para pentear, enquanto penteio, ouço as reclamações:
– Tá doendo meu cabelo!
– Filha, cabelo não dói.
– Tá sim.
– Ok, vou pentear mais devagar (mais 10 minutos, e o relógio…).

Enquanto isso eu ouço o outro tomando banho. Depois de terminar de arrumá-la, vou vê-lo e descubro que está brincando na banheira.
– Filho, eu pedi para você tomar banho rápido.
– Tá bom, pai. Já estou saindo.

Consigo terminar de arrumar Mariana. Agora é fácil, Diego já deve estar pronto. Não, na verdade ele estava brincando na banheira esse tempo todo, nem tinha tocado no sabonete.

Café da manhã. Teoria: levar na padaria que fica embaixo da minha casa, pedir alguns pães e leite, pagar e sair. Acontece exatamente assim, mas será normal demorar 30 minutos para comer um pão e tomar um copo de leite? Com duas crianças sim. Ao menos com duas crianças e um pai solo.

As mães que conseguem fazer isso de forma organizada e sequencial estão de parabéns. Aliás, todas devem conseguir.

10:15 entro no carro. 10:25 chego na escola de desenho do Diego. Mas da próxima vez eu consigo chegar no horário.

Como visualizar pastas e arquivos ocultos no Mac

Visualizar pastas e arquivos ocultos no Mac não é tão simples como no Windows. A gente precisa executar uma linha de comando no terminal.

Pastas e arquivos ocultos no Mac

Para visualizar as pastas e arquivos ocultos no Mac, abra uma janela no terminal (Aplicações -> Utilidades -> Terminal) e digite:

defaults write com.apple.finder AppleShowAllFiles TRUE

Após o comando, reinicie o Finder:

killall Finder

Para ocultar novamente:

defaults write com.apple.finder AppleShowAllFiles FALSE

pastas e arquivos ocultos no Mac
Finder

Error occurred during initialization of VM Could not reserve enough space for object heap

O “Error occurred during initialization of VM Could not reserve enough space for object heap” é comum na inicialização do Tomcat 7 com JDK 7 no Linux 64 bits.
No console pode-se conferir a mensagem:

Error occurred during initialization of VM
Could not reserve enough space for object heap

Para resolver o problema com a alocação de memória, execute o comando:

export _JAVA_OPTIONS=”-Xms20m -Xmx64m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:NewSize=10m -XX:MaxNewSize=10m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled”

Tutorial do Lucene: como indexar arquivos

Apache Lucene

Tutorial Lucene
Lucene
O Lucene é um framework para busca textual de alta performance escrito totalmente em Java e bastante fácil de usar. Neste tutorial do Lucene vamos ver as funcionalidades de busca e indexação que podemos adicionar em qualquer aplicação, web ou desktop, uma vez que o framework conta com uma API bastante completa e plugável. A biblioteca é bastante famosa, sendo utilizada em muitos portais da internet.

Há uma versão para .Net, o Lucene.Net, e ports para outras linguagens. Uma alternativa bastante interessante é o Solr (pronuncía-se ‘sólar’), um servidor corporativo de buscas já otimizado para aplicações web, que é um subprojeto do Lucene. No Solr, as operações podem ser feitas através de JSON, XML, HTTP, CSV, etc, o que permite a integração com virtualmente todas as plataformas.

Tanto Windows quanto o Mac OS X têm mecanismo de busca nativo, encontrar um arquivo qualquer é muito fácil. No Mac, o Spotlight procura em todo o sistema de arquivo em busca de aplicativos, e-mails, documentos, definição no vocabulário, diretórios, etc.

Spotlight
Spotlight

Nos dois casos (Windows e Mac) estamos limitados ao sistema de arquivos da máquina do usuário. Neste artigo vamos implementar um buscador utilizando Lucene que pode indexar vários formatos de documento, até mesmo através da rede, e disponibilizar essa informação para todos os usuários de uma corporação.

Em artigos posteriores veremos como indexar bancos de dados relacionais e discutiremos as vantagens, desvantagens, possibilidades e limitações deste tipo de solução.

As funcionalidades de um buscador: indexação e busca

A indexação consiste em recuperar o texto contido em um documento e adicioná-lo ao índice, tornando essa informação disponível para o usuário. Imaginando que hoje estamos acostumados a ter qualquer informação imediatamente, o fator velocidade é essencial. Essa operação é lenta, pois envolve muito processamento e gravação em disco. Indexar grandes volumes de dados demora bastante tempo e para isso há ferramentas específicas.

Para o Lucene, cada item indexado é um Document e contém uma coleção de campos. Um campo deve ter nome e valor textual. A busca pode ser feita em qualquer um desses campos.

Google, Bing, Yahoo!, Ask, etc funcionam assim. Além da página de busca, há um webcrawler visitando todos os sites da internet e indexando seu conteúdo. Esse processo é constante, até porque a internet é dinâmica. Sem contar que hoje temos conteúdo multimídia, não é apenas texto ou HTML como foi no começo da internet, há décadas atrás. Hoje a internet tem muito mais que apenas texto. Temos imagem, som, vídeo, portais verticais, Wolpham Alpha, web semântica e mídias sociais. E tudo isso deve estar disponível em tempo real.

A busca consite em recuperar os documentos que contém um termo informado pelo usuário. No Lucene essa operação é extremamente rápida. Mesmo uma consulta complexa, feita em um índice com milhões de documento, dura menos de 1 segundo. Além disso, o resultado da busca pode vir ordenado ou classificado (melhores resultados aparecem primeiro). E são muitas as opções de consulta fornecidas pelo Lucene:
– busca por palavra-chave ou frase
– busca em campos específicos
– busca com wildcard (* e ?)
– busca aproximada, utilizando a Distância de Levenshtein
– busca por proximidade entre palavras
– busca por intervalos de valores (datas, números ou letras)

Vale notar que o Lucene indexa apenas texto. Para indexar documentos binários (MS Office, PDF, RTF, etc) temos que utilizar alguma biblioteca de extração de texto, como o Apache Tika, que consegue recuperar texto em diversos formatos de arquivo.

Tutorial do Lucene

Composto por duas classes (Indexador e Buscador), o projeto proposto indexa um diretório informado pelo programador. Pode ser um diretório local, um compartilhamento Windows ou um diretório NFS.

Indexador



package net.marcoreis.util;

import java.io.*;
import java.text.*;

import org.apache.log4j.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.store.*;
import org.apache.lucene.util.*;
import org.apache.tika.*;

public class Indexador {
  private static Logger logger = Logger.getLogger(Indexador.class);
  //{1}
  private String diretorioDosIndices = System.getProperty("user.home")
      + "/indice-lucene";
  //{2}
  private String diretorioParaIndexar = System.getProperty("user.home")
      + "/Dropbox/MaterialDeEstudo/big-data";
  //{3}
  private IndexWriter writer;
  //{4}
  private Tika tika;

  public static void main(String[] args) {
    Indexador indexador = new Indexador();
    indexador.indexaArquivosDoDiretorio();
  }

  public void indexaArquivosDoDiretorio() {
    try {
      File diretorio = new File(diretorioDosIndices);
      apagaIndices(diretorio);
      //{5}
      Directory d = new SimpleFSDirectory(diretorio);
      logger.info("Diretório do índice: " + diretorioDosIndices);
      //{6}
      Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
      //{7}
      IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36,
          analyzer);
      //{8}
      writer = new IndexWriter(d, config);
      long inicio = System.currentTimeMillis();
      indexaArquivosDoDiretorio(new File(diretorioParaIndexar));
      //{12}
      writer.commit();
      writer.close();
      long fim = System.currentTimeMillis();
      logger.info("Tempo para indexar: " + ((fim - inicio) / 1000) + "s");
    } catch (IOException e) {
      logger.error(e);
    }
  }

  private void apagaIndices(File diretorio) {
    if (diretorio.exists()) {
      File arquivos[] = diretorio.listFiles();
      for (File arquivo : arquivos) {
        arquivo.delete();
      }
    }
  }

  public void indexaArquivosDoDiretorio(File raiz) {
    FilenameFilter filtro = new FilenameFilter() {
      public boolean accept(File arquivo, String nome) {
        if (nome.toLowerCase().endsWith(".pdf")
            || nome.toLowerCase().endsWith(".odt")
            || nome.toLowerCase().endsWith(".doc")
            || nome.toLowerCase().endsWith(".docx")
            || nome.toLowerCase().endsWith(".ppt")
            || nome.toLowerCase().endsWith(".pptx")
            || nome.toLowerCase().endsWith(".xls")
            || nome.toLowerCase().endsWith(".txt")
            || nome.toLowerCase().endsWith(".rtf")) {
          return true;
        }
        return false;
      }
    };
    for (File arquivo : raiz.listFiles(filtro)) {
      if (arquivo.isFile()) {
        StringBuffer msg = new StringBuffer();
        msg.append("Indexando o arquivo ");
        msg.append(arquivo.getAbsoluteFile());
        msg.append(", ");
        msg.append(arquivo.length() / 1000);
        msg.append("kb");
        logger.info(msg);
        try {
          //{9}
          String textoExtraido = getTika().parseToString(arquivo);
          indexaArquivo(arquivo, textoExtraido);
        } catch (Exception e) {
          logger.error(e);
        }
      } else {
        indexaArquivosDoDiretorio(arquivo);
      }
    }
  }

  private void indexaArquivo(File arquivo, String textoExtraido) {
    SimpleDateFormat formatador = new SimpleDateFormat("yyyyMMdd");
    String ultimaModificacao = formatador.format(arquivo.lastModified());
    //{10}
    Document documento = new Document();
    documento.add(new Field("UltimaModificacao", ultimaModificacao,
        Field.Store.YES, Field.Index.NOT_ANALYZED));
    documento.add(new Field("Caminho", arquivo.getAbsolutePath(),
        Field.Store.YES, Field.Index.NOT_ANALYZED));
    documento.add(new Field("Texto", textoExtraido, Field.Store.YES,
        Field.Index.ANALYZED));
    try {
      //{11}
      getWriter().addDocument(documento);
    } catch (IOException e) {
      logger.error(e);
    }
  }

  public Tika getTika() {
    if (tika == null) {
      tika = new Tika();
    }
    return tika;
  }

  public IndexWriter getWriter() {
    return writer;
  }
}

1. Diretório que irá guardar o índice.
2. Diretório que contém os documentos que serão indexados.
3. IndexWriter: cria e mantém o índice.
4. Biblioteca que extrai texto de diversos formatos conhecidos.
5. Directory: representa o diretório do índice.
6. Analyser/StandardAnalyser: fazem o pré-processamento do texto. Existem analisadores inclusive em português.
7. IndexWriterConfig: configurações para criação do índice. No projeto serão utilizados os valores padrão.
8. Inicializa o IndexWriter para gravação.
9. Extrai o conteúdo do arquivo com o Tika.
10. Monta um Document para indexação.
Field.Store.YES: armazena uma cópia do texto no índice, aumentando muito o seu tamanho.
Field.Index.ANALYZED: utilizado quando o campo é de texto livre.
Field.Index.NOT_ANALYZED: utilizado quando o campo é um ID, data ou númerico.
11. Adiciona o Document no índice, mas este só estará disponível para consulta após o commit.

Buscador



package net.marcoreis.util;

import java.io.*;

import javax.swing.*;

import org.apache.log4j.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.*;
import org.apache.lucene.util.*;

public class Buscador {
  private static Logger logger = Logger.getLogger(Buscador.class);
  private String diretorioDoIndice = System.getProperty("user.home")
      + "/indice-lucene";

  public void buscaComParser(String parametro) {
    try {
      Directory diretorio = new SimpleFSDirectory(new File(diretorioDoIndice));
      //{1}
      IndexReader leitor = IndexReader.open(diretorio);
      //{2}
      IndexSearcher buscador = new IndexSearcher(leitor);
      Analyzer analisador = new StandardAnalyzer(Version.LUCENE_36);
      //{3}
      QueryParser parser = new QueryParser(Version.LUCENE_36, "Texto",
          analisador);
      Query consulta = parser.parse(parametro);
      long inicio = System.currentTimeMillis();
      //{4}
      TopDocs resultado = buscador.search(consulta, 100);
      long fim = System.currentTimeMillis();
      int totalDeOcorrencias = resultado.totalHits;
      logger.info("Total de documentos encontrados:" + totalDeOcorrencias);
      logger.info("Tempo total para busca: " + (fim - inicio) + "ms");
      //{5}
      for (ScoreDoc sd : resultado.scoreDocs) {
        Document documento = buscador.doc(sd.doc);
        logger.info("Caminho:" + documento.get("Caminho"));
        logger.info("Última modificação:" + documento.get("UltimaModificacao"));
        logger.info("Score:" + sd.score);
        logger.info("--------");
      }
      buscador.close();
    } catch (Exception e) {
      logger.error(e);
    }
  }

  public static void main(String[] args) {
    Buscador b = new Buscador();
    String parametro = JOptionPane.showInputDialog("Consulta");
    b.buscaComParser(parametro);
  }
}

1. IndexReader: classe abstrata responsável por acessar o índice.
2. IndexSearcher: implementa os métodos necessários para realizar buscas em um índice.
3. QueryParser/Query: representa a consulta do usuário. Outros exemplos de query podem ser vistos no Javadoc.
4. Realiza a busca e armazena o resultado em um TopDocs.
5. ScoreDoc: representa cada um dos documentos retornados na busca.

Exemplos de busca

Busca por palavra-chave

Rode o Buscador e digite “java” como termo de consulta. Será mostrado o resultado com vários documentos contendo essa palavra. Em seguida, busque por “java -ejb”, ou seja, documentos que contém o termo “java” e não “ejb”.

Intervalos

Para pesquisar um intervalo utilize a consulta “UltimaModificacao:[20110101 TO 20110606]”. Funciona também para intervalo de letras.

Busca aproximada

Digite “servlet~” ou “servlet~0.7” e compare os resultados. O resultado mostra documentos que contenham algum termo parecido com “servlet”, usando a Distância de Levenshtein. O padrão é 0.5, ou seja, “servlet~” e “servlet~0.5” são iguais para o Lucene. Podemos aumentar a precisão, como é o caso de servlet~0.7

Código

O código-fonte do aplicativo está disponível aqui.

Palavras-chave: tika, lucene, solr, indexação, buscador, java, distância de levenshtein, big data