Pesquisar

quarta-feira, 23 de dezembro de 2009

Jpcsp - v0.4 lançado - Castelvania Dracula X Chronicles

JPCSP - O emulador do PSP feito em Java

A muito tempo não dou mais nenhuma contribuição no projeto Jpcsp mas não deixo de acompanhar o progresso do projeto. (Pra quem não sabe o que é o Jpcsp!) A última notícia foi mesmo um presente de natal, a versão 0.4 do Jpcsp foi lançada e já está disponível para download.

Sinto um pouco de orgulho por ter conseguido participar, efetivamente, e realizar um dos meus sonhos de moleque. (Criar um emulador :) )... agora deixando de conversa fiada segue alguns screenshots!

Castlevania - Dracula X Chronicles


Heatseeker


God of war (In menu)



Feliz Natal! ho ho ho - Veja mais notícias do Jpcsp ou os meus posts antigos sobre Jpcsp.

quinta-feira, 3 de dezembro de 2009

Adicione o recurso "você quis dizer" nas suas aplicações Java

SpellChecker - Uma extensão no Lucene

Continuando brincando com Lucene, no novo Lucene 3.0.0 encontrei uma pasta contrib na qual há libs diversas. Uma delas é o SpellChecker que lhe oferece recursos para que você implemente em suas aplicações java (web ou desktop) recursos como "Você quis dizer".

Recurso Você quis dizer

Imagine : Você é dono de uma loja virtual na qual é oferecido DVDs para venda. Um fanático pelo ator Arnold Schwarzenegger entra no sua loja e tem em mente comprar todos os DVDs desse ator (hoje, governador) a primeira ação do usuário é digitar o nome do ator no campo busca. Facilmente ele irá errar a digitação do nome, por exemplo digitando "arnold swuazeneger", e isso não deveria ser algo impeditivo para compra dos DVDs. Para esse problema bastaria a solução do tipo "Você quis dizer foo" implementada pelo Google Inc. no seu motor de busca. Você consegue esse mesmo, ou próximo, efeito em suas buscas utilizando uma das extensões do Lucene, chamada de SpellChecker. O exemplo-código abaixo é simples e demonstra como fazer isso.

Código


     Directory diretorioDicionario = new RAMDirectory();
//criação do diretório
SpellChecker sp = new SpellChecker(diretorioDicionario);
//instânciação do objeto SpellChecker
sp.indexDictionary(new PlainTextDictionary(new File("dicionario.txt")));
//indexação do Dictionary (há duas implementações).
String pesquisa = "arnold swuazeneger";
//seu termo pesquiado
int numeroDeSugestoes = 5;
//número de sugestões similares
String[] similares = sp.suggestSimilar(pesquisa, numeroDeSugestoes);
//as sugestões em si.

System.out.println("Seu Termo : " + pesquisa);
for (String palavra : similares) {
System.out.println("Você quis dizer: " + palavra);
}

pesquisa = "bava";
similares = sp.suggestSimilar(pesquisa, numeroDeSugestoes);
System.out.println("Seu Termo : " + pesquisa);
for (String palavra : similares) {
System.out.println("Você quis dizer: " + palavra);
}

Saída


Seu Termo : arnold swuazeneger
Você quis dizer: arnold schwarzenegger

Seu Termo : bava
Você quis dizer: java
Você quis dizer: lava
Você quis dizer: bala


Arquivo dicionario.txt:
arnold schwarzenegger
jean claude van damme
java
lava
bala

Conclusão

Nem sempre é tão difícil quanto parece, sempre há uma roda já pronta para seu problema. Você ainda pode ajustar a acurácia da pesquisa pelo método setAccuracy do SpellChecker. Claro que o uso do recurso em produção requer mais e mais atenção quanto ao diretório e o dicionário de busca. Baseado nos códigos acima, facilmente você consegue levar essa características para seus sistemas Java Web ( JSF - JavaServer Faces, Struts, JSP).

terça-feira, 1 de dezembro de 2009

Tutorial Apache Lucene 3.0.0 - motor de busca textual


Lucene um motor de busca textual

No dia 25 de novembro foi lançado a nova versão do motor de busca Lucene, a versão 3.0.0. Lucene é um framework de alta performance para busca textual feito em java. (há versões para php e .net também) Uma das características marcantes dele é a integração com Hadoop. (um framework para computação distribuida - que possui, dentre outros, um MapReduce e um sistema de arquivos distribuido HDFS)

Porque usar Lucene?

Imagine o seguinte cenário: Seu usuário deseja criar um modulo de gerenciamento de artigos e também expó-los na Internet. As informações do artigo são: título, autor e o contéudo. Normalmente cada artigo desse contém cerca de 1500 palavras e o usuário poderá buscar pelo conteudo desses artigos. Suponha que há 1 milhão e meio de artigos para serem cadastrados, o simples uso de um banco de dados e o operador LIKE '%palavra%' é inviável. E aí que entra um bom framework de busca textual, usá-lo passa ser a solução mais tranquila e viável. Além de trazer velocidade, também traz outras características nas buscas que dificilmente fariamos codificando tudo do zero.

Domain-Specific Language | Ubiquitous Language

Há vários termos usados na terminologia do framework, os principais são: Documento, Campo, Diretório, Indexador, Pesquisador, Analisador e Termo.

  • Documento - é o conjunto de dados que você deseja indexar, por ex. título, conteudo e autor formam o documento artigo, pode ser visto como um objeto no lucene é visto como Document.
  • Campo - é o dado, identificado, que pode ser analogo a um campo de uma tabela ou uma propriedade de um objeto no lucene é visto como Field.
  • Diretório - conceito abstrato que denota um local para guardar os índices no lucene é visto como uma interface Directory, que possui diversas implementações DbDirectory, FSDirectory, JEDirectory, RAMDirectory.
  • Indexador - é o responsável por indexar os documentos num diretorio no lucene é visto, geralmente, como IndexWriter.
  • Pesquisador - responsável por pesquisar uma Query no diretorio de índices, no lucene é visto como Searcher.
  • Analisador - atua como um filtro e faz uma pré-avaliação do que pode ser indexado ou não, no lucene há uma lista de vários analisadores.
  • Termo - pode ser visto como objeto que pode ser usado como parametro da pesquisa, composto pelo nome do campo e o valor a ser pesquisado, no lucene é visto como Term.

Como isso funciona?

A descrição a seguir é um resumo bem simplificado sobre o funcionamento de um motor de busca textual. A primeira fase, geralmente, é a indexação do documento, nessa fase o documento é analizado (por um Analizer que também já retira as stopwords) para posteriomente ser indexado.

Set stopWords = new HashSet();
stopWords.add("the");
stopWords.add("it");
stopWords.add("is");
IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR),
new StandardAnalyzer(Version.LUCENE_CURRENT,
stopWords),
false,
IndexWriter.MaxFieldLength.LIMITED);


No Lucene você pode criar um índice usando o IndexWriter, a criação desse objeto envolve dizer onde será (ou está) o diretório dos índices, qual analizador você irá utilizar, se irá criar o indice e qual a quantidade máxima de campos.

O objetivo do indexador é indexar documentos, para tanto é necessário que haja documentos para serem indexados.
Document doc = new Document();
doc.add(new Field("nomedocampo", "valores a serem guardados", Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("camp1","valores a serem analisados tokenizados",Field.Store.YES, Field.Index.toIndex(true, true)));
writer.addDocument(doc);
É o objetivo final de todo processo de busca textual é mesmo a busca em si.
String valueToBeSearched = "red";
String index = "indexDir"; //dirotorio base do indice
IndexReader reader = IndexReader.open(FSDirectory.open(new File(index)), true); //indexador
Searcher searcher = new IndexSearcher(reader); //pesquisador
QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, field, analyzer); //transoformador do texto em uma query
Query query = parser.parse(valueToBeSearched); //a consulta (query) em si
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, false); //os melhores resultados
searcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs; //o conjunto de melhores documentos para a consulta

int maximo = hits.length;
Document doc = searcher.doc(hits[index].doc);
String valor = doc.get("nomeDoCampo");

Recursos na busca de documentos

Quando se faz uma pesquisa por documentos no Lucene podemos utilizar de alguns operadores (+, -, AND, NOT, OR, * e etc.) juntamente com o termo pesquisado ou apenas pesquisar uma frase completa.

Exemplo : termo
Consequência: Irá pesquisar a palavra "termo" nos documentos indexados.

Exemplo : termo OR palavra ( == termo palavra)
Consequência: Irá pesquisar "termo" ou "palavra" nos documentos indexados.

Exemplo : +termo +palavra ( == termo AND palavra)
Consequência: Irá pesquisar "termo" e "palavra" nos documentos indexados.

Exemplo : campo:termo
Consequência: Irá pesquisar "termo" no campo "campo" nos documentos indexados.

Exemplo : +homer +simpsons -house
Consequência: Irá pesquisar documentos que contenham homer e simpsons e não tenha house.

Exemplo : "termo exato"
Consequência: Irá pesquisar documentos que contenham exatamente "termo exato".

Exemplo :
java*
Consequência: Irá pesquisar documentos que contenham palavras que começem com java (javadb, javanet...).

Exemplo : java~
Consequência: Irá pesquisar documentos que contenham palavras similares a java como por ex. lava, jaba...

Finalizando tive as seguintes impressões sobre essa nova versão do Lucene.

Prós:
  • Maior facilidade para uso do framework, ex: criações de Fields estão bem mais fluentes.
  • Sensível otimização nos tempos de busca e indexação.

Contras:
  • Otimas ferramentas como luke ainda não tem suporte para a versão 3.0.0. (mas já há uma solicitação aberta para tal mudança.)
  • Muitas mudanças no core do framework; o que fez livros mais antigos quase perderem seu valor.

Referências

terça-feira, 24 de novembro de 2009

quinta-feira, 29 de outubro de 2009

JPA - lock otimista e pessimista, concorrência e afins

JPA - Java Persistence API

JPA é especificação para mapeamento ORM e persistência de dados inspiradíssima no famoso framework Hibernate.

A especificação JPA (1.0) já é amplamente usada e aceita na comunidade de desenvolvedores Java. Há vários provedores de implementação para o padrão ( Hibernate , EclipseLink, TopLink ...)

Um assunto pouco explorado, quando se trata de tutoriais de jpa, é sobre locks (otimista e pessimista). E é sobre esse assunto que tento escrever um pouco aqui.

Tratamento de concorrência em bancos de dados

Há basicamente três tipos de tratamento para concorrência em banco de dados:
  1. Otimista - Quando é criado mecanismos para versionar o dado, no momento em que o banco vai efetivar sua operação sua versão é checada para garantir que você está com um dado que não foi alterado.
  2. Pessimista - O banco simplesmente trava o dado e só aquele que tem a trava consegue trabalhar com os dados.
  3. Ostrich - Quando não há tratamento nenhum pra concorrência :) , ou seja, a maioria dos casos atuais.

O exemplo básico

Começaremos com os perigos do modo Ostrich de agir. Para exemplificar criaremos uma simples classe.
@Entity
public class Produto implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String nome;
private double quantidade;
//getters and setters omitidos
}
Agora considere dois usuários A e B trabalhando sobre o Produto com id = 1( Nintendo Wii) ambos usuários têm o mesmo produto na tela de edição, o usuário A modifica quantidade e salva antes do usuário B, já o usuário B modifica o nome e salva depois. Note que há incosistência, o usuário A acredita (porque ele editou e salvou) que alterou a quantidade de nintendos wii, porém o usuario B (ainda com a quantidade antiga) mudou o nome e salvou o objeto. O que acontece? Depende do seu provedor de JPA, há casos em que o update só é feito para a coluna modificada mas há casos em que o objeto todo é modificado, o que causa claramente inconsistência. Escrever, escrever e escrever pode não ajudar então veja o código abaixo exemplificando esse cenário.
            Produto nintendoWiiA = em.find(Produto.class,1L);
Produto nintendoWiiB = em.find(Produto.class,1L);
/*Usuário A*/
em.getTransaction().begin();
nintendoWiiA.setQuantidade(45.0D);
em.getTransaction().commit();

/*Usuário B*/
em.getTransaction().begin();
nintendoWiiB.setNome("Nintendo WII");
em.getTransaction().commit();

System.out.println(em.find(Produto.class,1L));
ps: O código é apenas para demonstrar como isso é feito, não é funcional.

Agora para mudar esse exemplo para o modo otimista de ser basta criarmos uma propriedade no objeto com a anotação @Version para denotar que este campo será usado para o fim da implementação otimista. Esse campo deve ser int, long ou timestamp.

Com a adição do lock otimista quando o usuário B fosse tentar salvar suas modificações ele receberia a execeção OptimisticLockException. Isso já garantiria ao menos a notificação ao usuário que alguém estava trabalhando sobre o mesmo dado e ( lembra das canseiras que o IDE nos livra no versionamento de código) apartir dai você poderia mostrar o que foi mudado para o usuário tomar a decisão de salvar ou não suas alterações.

A parte chocante fica por conta do modo pessimista de ser, a JPA 1.0 não suporta diretamente o modo pessimista de ser (O JPA 2.0 prevê esse modo a mais :)

Então o que fazer?

Imaginem duas contas bancárias: (sempre esse exemplo) aMinhaConta (com saldo de R$ 150,00) e a suaConta (com saldo de R$ 25.000,00) e você quer me presentear com um Wii mas não tem como mandá-lo pelo correio, logo acha mais conviniente realizar uma transferência para que eu compre. O processo (bem simplificado) se resume a isso:

#0 quantiaASerDoada = R$ 1390,00;
#1 se suaConta.saldo > quantiaASerDoada então
#2 suaConta.transerePara(minhaConta, quantiaASerDoada);
#3 fim se

Se entre a linha 1 e 2 você fizer um saque de R$ 25.000,00 (isso pode ocorrer) a transferência não deveria ser realizada. Um modo para que isso ocorra é travar (lock) o dado que pode sofrer com essas concorrências. No JPA 1.0 você pode travar um objeto em dois passos (ai reside el peligro).

#0 Conta suaConta = em.find(Conta.class, 175789);
#1 em.lock(suaConta,LockMode.Write);

Mais uma vez entre a linha 0 e a 1 pode ocorrer um problema de concorrência. (tanto que a especificação JPA 2.0 já prêve um modo similar ao session do hibernate, o travamento no momento da leitura, em.find(Conta.class, 175789, LockMode.PESSIMISTIC);)

Solução fácil para o problema acima

Basta (se estiver usando Hibernate as your JPA provider) :

((Session) ((EntityManagerImpl) em.getDelegate()).getSession())

O session já tem um jeito de select for update session.get(SuaClasse.class, seuId, tipoDeTravamento). ( já perceberam que pra cada problema que você encontra na JPA 1.0 o hibernate quase sempre tem a solução?!)

Referências

http://en.wikibooks.org/wiki/Java_Persistence/Locking
http://www.javaworld.com/jw-07-2001/jw-0713-optimism.html

quinta-feira, 22 de outubro de 2009

Organizacao é tudo

Para as pessoas que moram no Rio de Janeiro ou que tenham disponibilidade para verem o evento Caelum Day | in Rio já bastaria dizer que o evento será no mínimo bom. Mas dessa notícia o que gostaria de destacar não é só o evento ( se puder ir, vá :) ) e sim a organização do site do evento... algo que deveria ser copiado, isso mesmo ctrl+c ctrl+v! Vejam o site do evento Caelum Day, ele possui as características padrões como : Programação do Evento , grandes nomes para palestrar (Philip Calçado), inscrições e etc. porém dentro dessas características comuns ele traz informações IMPORTANTÍSSIMAS como dicas de restaurantes, hotéis e até mesmo estacionamentos (dicas com valores :) ). Ahh1 o evento ocorrerá no dia 7 de Novembro de 2009 das 8h às 18h. Parabéns pela organização do evento.

Ahh2 : só pra complementar no final do evento será sorteado um Nintendo Wii. :)

sábado, 17 de outubro de 2009

Quer pagar quanto?

O portal de notícias da Record o R7 foi lançado a alguns dias atrás... até ai nada de anormal, certo?! Pois bem, fui verificar quanto valia o portal de acordo com o BizInformation. Se você ainda não conhece, se trata de um site que baseado em diversos parametros informa quanto seu site vale. Logo a primeira reação foi me assustar com o resultado para o site R7.com :

R$2.692,79

Somente isso! Imaginem meu site alternativo the empyrean foi cotado ao valor de :

$3,946.8

Outro detalhe é que para o site the empyrean foi usado (dolar americano) U$ ,ou seja, meu blog vale mais do que o portal R7 :-) brincadeira....
ps: penso que está claro o fato de que, o BizInformation, nesse caso do portal R7, falhou nas suas estátisticas.

quarta-feira, 7 de outubro de 2009

Livro DSL In Action

A friend of mine enviou-me um email informando sobre o livro DSL In Action (ainda não pronto) para uma possível pré-leitura. Há até mesmo um capítulo no site. Pelo capítulo grátis pra degustação, penso que o livro pode ser um grande amigão, gostei da forma com que o autor trata o assunto domain-specific language - dsl - e por isso fica a dica aqui de uma boa leitura. C0m certeza mais um livro a se somar na pilha de livros sobre dsl.

sexta-feira, 25 de setembro de 2009

Usar sempre a interface mais genérica possível

Se você precisa somente iterar sobre uma coleção de um tipo de objeto...
Faça seuMetodoReceber(Collection colecao); e não uma List ou Set... (ou ainda uma Iterable)


Se você vai trabalhar num nível muito baixo com Stream...
Faça seuMetodoReceber(InputStream is); e não um FileInputStream...


Essa lista segue sem fim...

Porque sempre usar a interface mais genérica possível?

Você pode simplesmente mudar sua coleção que retornava uma List pra retortar uma TreeSet. Mudar o comportamento esperado, mudar o Stream para outro tipo e outras coisas que são comuns, sem sofrer tanto. Se você nunca enfrentou o inferno das manutenções não entenderá completamente a dor.

Se você está pensando em criar uma biblioteca então essa consideração deve ser ter atenção redobrada.

Opte sempre pelo mais GENÉRICO possível.

quarta-feira, 23 de setembro de 2009

Aprendendo com seu IDE

Estou trabalhando em um projeto que utiliza Swing e o Netbeans. Ate aí nenhuma novidade... mas no decorrer da criação e do uso dos JComponents notei que o netbeans cria algumas coisas bizarras e outras legais... Tudo pra deixar o usuário (eu) feliz com as pedras no sapato da JTable. Bem o interessante não é nada disso... vou ao exemplo que facilitará.

Suponha que você tenha uma classe:

public class ClasseA{
public void fazNada(){
System.out.println("nada");
}
}

E uma classe de teste:

public class TestClasseA{
public static void main(String[] args){
ClasseA a = new ClasseA();

a.fazNada();

}

}



O resultado será simples um nada
Bem e se eu quisesse alterar o comportamento do método fazNada... normalmente o que as pessoas fazem é (além de seguir um dos Patterns do GOF... esqueci o nome :S ) criar uma outra classe herdando da ClasseA e sobreescrevendo o comportamento para o método fazNada.

O que notei que o netbeans faz é o seguinte:



public class TestClasseA{
public static void main(String[] args){
ClasseA a = new ClasseA(){
public void fazNada(){
System.out.println("tudo");
}

};

a.fazNada();

}

}

Isso mesmo sobreescrevendo-a na própria "instanciação"... a essa técnica, ou jeito, penso que o nome correto é classe anónima... (já vi vários usos para classes anónimas, mas esse foi novo.)

terça-feira, 15 de setembro de 2009

Ajuda fútil com progress bar ou outro componente que registre o progresso

Suponha que você tenha um progress bar que vai de UM_VALOR_MIN até UM_VALOR_MAX em unidades inteiras. Agora suponha que você tenha uma LISTA_DE_ARQUIVOS e deseja fazer um processamento(com_cada_um_dos_arquivos). E também quer deixar visível ao usuário esse progresso.
Agora veja o algoritmo mais (f)útil pra isso.

ps: esse é mais um daqueles posts que você pode se arrepender, tanto de ler quanto de escrever no futuro.




LISTA_DE_ARQUIVOS = listFilesAt("/home/myuser/myfolder/movies/")
UM_VALOR_MAX = 100
TOTAL_DE_ITENS =
LISTA_DE_ARQUIVOS .tamanho
QTD_POR_ITEM = UM_VALOR_MAX / TOTAL_DE_ITENS
UM_VALOR_MIN = QTD_POR_ITEM

for (String item : LISTA_DE_ARQUIVOS) {
File file = new File(item)
processar(file)
marcarProgresso(round( UM_VALOR_MIN+ 0.059))
UM_VALOR_MIN+= QTD_POR_ITEM
}

quinta-feira, 3 de setembro de 2009

Cache encurtando viagens


Cache é importante?

Me lembro quando comprei meu processador Atlhon XP 2400, na época tinha o maior cache maior da categoria. Tinha um cache L1 para dados e instruções de 64KB (cada) e L2 com 256KB. Hoje um E8400 tem cache L1 de 32KB pra dados e 32KB para instruções e um L2 com 6MB (compartilhado entre os núcleos) indo além disso um Core i7 adiciona mais um nível (LEVEL) o L3. ( ele tem L1 = 32KB pra dados e 32KB pra instruções, L2 = 4 x 256KB e L3 = 8MB compartilhada com todos núcleos). Bem, se os projetistas de hardware já se preocuparam com isso pra que eu vou fazer cache?

O que é um Cache?

O processo de armazenamento temporário de informações recentemente acessadas em um subsistema de memória especial para acesso mais rápido. (Windows Vista Center Help)
É um dispositivo de acesso rápido, interno a um sistema, que serve de intermediário entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador acede. A vantagem principal na utilização de uma cache consiste em evitar o acesso ao dispositivo de armazenamento - que pode ser demorado -, armazenando os dados em meios de acesso mais rápidos. (Wikipedia)

Exemplo (ridículo) do uso de Cache (sun.misc.Cache)

Cache cache = MCache.get(); //singleton, session, jndi, cache distributed server...
if (cache.get("homePageNews")==null){
//busco no banco
//quando busco no banco
//atualizo também o cache.
}else{
//salvei tempo
Set news = (Set)cache.get("homePageNews");
}
Senta que lá vem história, experiência quase-real

Numa consultoria 0800 à um amigo Php-Ense; ele me retratava que apesar de ser um servidor não tão parrudo o sistema estava apresentando lentidão (demora de 0,5 a 1,8 segundos), as telas estavam demorando muito a serem carregadas... Já cheguei pensando que seria uma batalha(tanto pelo pouco conhecimento em PHP, quanto pela descrição do problema). Se tratava de uma aplicação simples com poucos 'Gruds' (cerca de 30). Na demonstração percebi que algumas telas demoravam mais do que outras para carregar , e uma demorava quase 2 segundos (essa que encomodava-o) que era a gestão de clientes, nela havia três combos: países, estados e cidades. Uma outra era a página inicial que carregava : últimas notícias, o perfil de três clientes (randômicos), três serviços prestados (randômicos), um texto sobre a "empresa" e uma mensagem. Tudo isso era carregado do banco a cada requisição, se 100 pessoas abrissem o browser naquele site seriam enviados 100 equisições ao banco (que provavelmente por se tratar do mesmo dado os teria em cache, ôoo o banco também tem cache, todo mundo têm eu também quero... será? ) mesmo que o banco lhe salve um pouco de processamento, você continua enviando e recebendo dados pela rede e isso é danoso. Sugeri a ele usar um framework de Cache ou criar um simples e sincronizá-lo com a base de N minutos a N minutos. Depois que ele seguiu meus conselhos ele disse ter uma melhora bem melhor do que esperava. Isso, claro, não significa que todos os problemas de performance serão sanados com uso de cache, alias o uso indiscriminado de tal recurso pode também afetar a performance negativamente. Agora imagine que uma aplicação esteja distribuída em vários servidores em clustes um único sistema de Cache não irá ajudar muito, para tanto já existem sistemas de Cache distribuidos (acredite que isso é mais simples do que minha mente temerosa de computação distribuída possa imaginar).

terça-feira, 1 de setembro de 2009

Lista de bons programas open-source.

Soa como clichê mas vai ai minha lista:

Media Center - http://www.moovida.com/screenshots/
Playstation 2 - http://code.google.com/p/pcsx2/
Wii / Dolphin Emulator - http://code.google.com/p/dolphin-emu/
JDowloader - http://jdownloader.org/

ps: só citei os que estou usando e aproveitando (muito) ultimamente.

sexta-feira, 14 de agosto de 2009

Minhas::Commons::Lib::Utils > Apache::Commons

Por mais que existam frameworks como Jpa, Jsf, Ruby On Rails, Lucene, Spring e outros, provavelmente sempre existirá uma característica ou um pedaço de código que nós desenvolvedores iremos criar e guarda-los em um modulo (pacote...) de utils. Há alguns desenvolvedores que mesmo conscientes de que já existem frameworks de ORM, criam seus próprios produtos. Acredite ainda existem.

Se você é aquele que segue a idéia de não reinventar a roda tente sempre, antes de criar essas "libs", verificar se já há algum código criado pra tal problema.

Pensando nesses problemas a grande Apache criou vários projetos com um subnome de Commons. (tanto para plataforma Java quanto .NET) E são esses projetos (não todos, só alguns) que vou resumir aqui seus usos, a idéia não é dar um guideline de uso dos projetos mas apenas mostrar que para quase toda "vontade" de criar uma lib, já existe uma pronta. Então a use...

Tenho um problema de desempenho que acho que resolveria se mantivesse alguns objetos pesados no pool..

Primeiro tenha certeza de onde está o seu real problema de desempenho, isso você só consegue medindo... dá-lhe profiler. Às vezes não são os poucos objetos pesados, mas a grande quantidade de pequenos repetidos! Bem para esse problema a Apache já criou projeto :) Apache Commons Pool.

Trabalho numa empresa que desenvolveu um sistema para o TRE-XX e lá nos temos que validar títulos de eleitor, isso eu dúvido que apache tenha...

Realmente a apache (eu acho que não, vai saber?!...) parece não ter, mas a Caelum desenvolveu (e está evoluindo) um Framework chamado Stella (http://stella.caelum.com.br/core-formatters.html), justamente para prover soluções para problemas que nós desenvolvedores Brasileiros enfrentamos diariamente, tais como: validar cpf, boletos de bancos nacionais, formatar cnpj e etc.

Pô, uso a API padrão do Java (6) no que tange ao assunto de coleções mas não consigo encontrar várias operações que gostaria de fazer com essas coleções... e ai?

Aqui o conselho seria primeiro dar uma boa olhada nas classes Collections (não a Interface Collection) e a Arrays, elas já provem bastantes características mas se mesmo assim não se der por satisfeito pesquise e irá econtrar uma Collection-Commons (http://commons.apache.org/collections/userguide.html) da Apache.

Tô trabalhando num sistema legado e aqui, por questões de performance, uso o JDBC e tenho que criar, mapear e fazer n coisas de banco, tudo na "mão"...

Performance ... sempre deve ser medida pra ser confirmada. A Apache (novamente) tem um projeto DBUtils (http://commons.apache.org/dbutils/examples.html) que têm várias funcionalidades para manuseio de banco de dados.

Nem sempre as utils vem para só para resolver problemas, às vezes criamos utils para facilitar nosso código.

Pensando assim a Apache também criou uma outra Commons (http://commons.apache.org/io/description.html) para IO, o que torna uma tarefa entediante de ler os bytes de um InputStream numa simples tarefa.

Tarefas como mandar email, realizar operação matemáticas complexas, usar recursos e protocolos das redes de computadores, já estão implementadas, testadas e sendo usadas em produção por várias pessoas.

Por último, pare e pense: porque será que grandes projetos, tais como Hibernate Core ou Search, Spring e outros, tem dependências de grande parte dos projetos xyz-commons-kwq.zip da apache? será mesmo necessário criar aquela util ou mesmo criar uma exceção para dizer que o argumento passado à um método veio nulo?

quarta-feira, 12 de agosto de 2009

Tiny Types não são desperdícios

Tiny Types são importantes por diversos fatores dos quais me lembro de: enriquecimento do domínio, forçagem de tipagem, clientes das classes perdem o poder de errar no uso incorreto da ordem dos parâmetros de algum método.

O que é um tiny type?

Sabe aquelas propriedades que costumamos definir como simplesmente String (nome, sobrenome, cpf, cep) , alguns desses atributos podem acabar se transformando em um tipo próprio.... os tiny types.
Definição: São objetos pequeninos (dahhh) que normalmente são imutáveis e seguem o padrão VO (de Martin Fowler), podem parecer chatos no inícios para alguns mas se mostram poderosos com o passar do tempo.

E as vantagens??

Enriquecimento do domínio: new Pessoa(new Nome("Luiz"), new Sobrenome("Inacio"))
Diminuição de erros: tendo uma classe qualquer Pessoa com atributos nome e sobrenome como String poderia nos permitir fazer coisas como: new Pessoa("Inacio","Luiz")

E as desvantagens???

Claramente você terá mais trabalho para definir e até mesmo mapear (seja o @Embebbed do padrão JPA ou seu mapeador próprio ou seu framework predileto para mapeamento ORM) esses mini-tipos que serão incorporados a um objeto maior.

ps: inspirado (entre outros...) pelo post da caelum.

terça-feira, 11 de agosto de 2009

JRuby, Abobrinhas e DDD

Programação funcional, linguagem dinâmica, duck typing, closures, fluência, dsl, behavior, tipagem inferida... são assuntos recorrentes das rodas dos desenvolvedores mais cool. Em uma dessas rodas ouvi a seguinte afirmação sobre o JRuby:
"Eu não gosto do JRuby... gosto do Ruby puro, JRuby é apenas os problemas do Java no Ruby"
Isso foi numa roda de "experientes em Java"... claro que tentei explicar que a frase não fazia muito sentido e que deveriamos pensar em Plataforma... e que JRuby é uma implementação para o interpretador de Ruby e não uma linguagem, que era até mesmo mais rápido do que o MRI (ou CRuby para os mais intimos), dai que eles se renderam e entenderam o que era o JRuby e MRI. Eu ainda curioso, perguntei como tinham chegado aquela conclusão, e para minha surpresa um me disse que foi porque veio com NetBeans e por isso não deveria ser coisa boa... (pode? rsrsrsrsr)

Hoje também li um post (ótimo por sinal) do Rodrigo Yoshima (AsperCom) no qual ele discorre o já batido (mas nunca esgotado) assunto Repositories... ele escreveu uma frase ("Não é uma opção arquitetural, somente estou transparecendo o domínio.") que me fez lembrar mais uma vez da falta de cautela dos desenvolvedores ao se preocuparem muito mais em tecnologia do que com a realidade. Certa vez estava realizando um projeto (não UML, na definição das classes mesmo) no qual dividi uma entidade em dois conceitos mas que tinha somente uma tabela no banco, quase 100% das pessoas me criticaram por estar sendo muito purista, naquele momento não sabia exatamente o que dizer à eles mas lembro que o sentimento era que eu estava apenas transcrevendo o que houvi dos usuários.

quarta-feira, 29 de julho de 2009

Aprenda o TInés para se dar bem

"Com a governança dos processos de negocios facilitada pelo uso de SOA, o alinhamento dos negocios com a T.I. se tornou mais ágil. Nossa empresa também está pensando em levar para as nuvens nossa infra-estrutura de armazenamento."

Escutei, exatamente, isso numa palestra que um CIO apresentava e acredito que ele sabia exatamente o que estava falando. O fato não é se ele sabia ou não o que dizia e sim que todos prestavam com atenção e respeito pelas palavras do homem bem vestido.

Não quero, de jeito algum, diminuir os substantivos (e seus livros, teorias...) mas apenas alertar que usar palavras "corretas" numa entrevista pode te dar vantagens em relação aos outros entrevistados.
Deixe pra discutir se essas buzzwords são modas ou vieram pra ficar com seus amigos ou no seu blog.

sexta-feira, 17 de julho de 2009

Arquitetura e Design de Software Uma visão sobre a plataforma Java drafts....

No mês de maio de 2009, postei aqui sobre um investimento que você iria fazer que era certeza de ROI!
( pra quem não se lembra clique aqui)

O livro (ainda WIP - Work In Progress) Arquitetura e Design de Software Uma visão sobre a plataforma Java já mostra um pouco da sua cara, o pessoal liberou alguns PDFs iniciais com um pouco do conteúdo do livro (que mais uma vez sai em Novembro desse ano (2009), se tudo correr bem claro!)!

Pra quem deseja fazer o download desses rascunhos iniciais do livro Arquitetura e Design de Software Uma visão sobre a plataforma Java clique aqui.

fonte original: http://blog.caelum.com.br/2009/07/17/livro-arquitetura-e-design-de-software-4-topicos-do-draft-liberados/

quarta-feira, 1 de julho de 2009

JSF 2.0 na prática - Navegação implicíta

Novas características do JSF 2.0 na prática - Navegação implicíta

Depois do primeiro exemplo (primeiro exemplo), vamos tentar explorar as novas características. A primeira delas, a anotação @ManagedBean, já foi usada no primeiro exemplo.

Navegação padrão...

Cansado ou triste por ter que escrever navigation-rules pra coisas muito obvias... O padrão JSF 2 trouxe dos já-bem-conhecidos frameworks a idéia de só ter que criar uma regra de navegação na exceção, nos casos comuns prevalece o "bom senso"...
Bem o seu bom senso pode ser diferente do meu que pode ser diferente do Super Mario que por sua vez também pode ser diferente do Senhor Abravanel. Leia sobre essa regra em http://blog.gilliard.eti.br/2009/05/implicit-navigation-jsf-2/

De volta ao exemplo

Para demonstrar como essa característica funciona na prática, adicione o seguinte componente a nossa página index.xhtml.

[br /][h:commandButton value="Navegação implícita!" action="login"/]

Além disso crie uma página com nome login.xhtml
[?xml version="1.0" encoding="ISO-8859-1" ?]
[!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"]
[html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"]
[head]
[title]ArchSoftyJSF2[/title]
[/head]
[body]
[h:form]
[h:outputText value="Login!"/]
[/h:form]
[/body]
[/html]

Pronto agora quando clicar no botão [Navegação implícita!] a página que será mostrada será a login.xhtml.

Ainda sem o faces-config.xml!

Exemplo simples usando JavaServer Faces 2.0 (BETA1) JSF 2 + Eclipse Galileo + Tomcat 6x

O que necessito?
  1. 1. Tomcat: http://tomcat.apache.org/download-60.cgi (ou algo que "rode" a espec. JSP2.5)
  2. 2. JSF 2.0 BETA1: https://javaserverfaces.dev.java.net/files/documents/1866/135560/mojarra-2.0.0-Beta1-binary.zip
  3. 3. Eclispe Galileo: http://www.eclipse.org/downloads/ (ou Netbeans 6.7, gnome-editor, vi, notepad...)
  4. 4. JDK 6.0: http://java.sun.com/javase/downloads/index.jsp


Primeiro passo.

Crie um projeto java web. No caso especifico do Eclipse essa categoria se chama: "Dynamic Web Project", nomei o projeto como desejar, eu usarei o nome "ArchSoftyJSF2"; ainda no Eclipse escolhi como "Target runtime" o Apache Tomcat v6.0 e já cliquei em Finish.

Segundo passo.

Coloque os dois jars - jsf-api.jar e jsf-impl.jar - no classpath da aplicação.

Terceiro passo.

Modifique o arquivo web.xml, adicionando um Servlet.
[servlet]
[servlet-name]Faces Servlet[/servlet-name]
[servlet-class]javax.faces.webapp.FacesServlet[/servlet-class]
[/servlet]

[servlet-mapping]
[servlet-name]Faces Servlet[/servlet-name]
[url-pattern]*.jsf[/url-pattern]
[/servlet-mapping]

Quarto passo.

Crie um arquivo (index.xhtml) com o seguinte conteúdo.

[?xml version="1.0" encoding="ISO-8859-1" ?]
[!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"]
[html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"]
[head]
[title]ArchSoftyJSF2[/title]
[/head]
[body]
[h:form]
[h:outputText value="Alô, Mundão!"/]
[/h:form]
[/body]
[/html]

Quinto passo.

Rode e verá sua primeira aplicação usando Jsf 2.0 funcionando. Claro que se trata de um exemplo bem simples, pra deixar mais interessante vamos adicionar um botão e usar o novo modelo de managed bean (digo modelo no sentido de criação por meio de annotations).


Sexto passo.

Crie uma classe Java:

package presentation;

import javax.faces.bean.ManagedBean;

@ManagedBean(name="primeiroBean")
public class PrimeiroBeanMB {
private String texto;

public String getTexto() {
return texto;
}

public void setTexto(String texto) {
this.texto = texto;
}

public void mudeOTexto(){
texto = "Texto modificado!";
System.out.println(texto);
}
}


Sétimo passo.

Altere o index.xhtml mais precisamente mude o interior de ...

[h:form]
[h:outputText value="Alô, Mundão!"/]
[h:commandButton value="Mudar o texto" action="#{primeiroBean.mudeOTexto}"/]
[h:outputText value="#{primeiroBean.texto}"/]
[/h:form]

Agora é só rodar... Sentiu a ausência do faces-config.xml?

ps: desculpe a preguiça de apenas mudar <<>> por ]

quinta-feira, 28 de maio de 2009

Investimento Certo em Novembro de 2009 Arquitetura e Design de Software - Uma visão sobre a plataforma Java

Em novembro de 2009 você tem um grande investimento para fazer, desta vez não se trata de aplicações na Poupança ou mesmo CDB e sim num livro que a editora Elsevier irá publicar.

O livro intitulado: Arquitetura e Design de Software - Uma visão sobre a plataforma Java (que já possui um site http://www.arquiteturajava.com.br/) foi escrito por "nada mais nada menos" que: Fábio Kung, Guilherme Moreira, Nico Steppat, Paulo Silveira e Sérgio Lopes (Caelum não lhe veio a cabeça?).

"O prefácio de Phillip Calçado já deixa bem claro que não há uma arquitetura de caixinha, e de que cada caso deve ser estudado a fundo."

Não é preciso dizer mais nada...
O draft inicial dos conteúdos:
  1. Arquitetura pré-pronta de caixinha? Prefácio de Phillip Calçado
  2. Introdução
  3. Plataforma Java
    1. Java como plataforma, não como linguagem
    2. Gerenciar memória não é simples
    3. Otimizacao prematura é a raiz de todo mal
    4. Tome cuidado com o ciclo de vida de objetos caros
    5. A comunidade Java - do JCP aos fóruns
    6. A burocracia e o lado ruim das especificações
    7. A linguagem certa para cada tarefa
  4. Tópicos de Orientação a Objetos
    1. Evite herança, favoreça composição
    2. Programe voltado a interface, não a implementação
    3. Prefira a imutabilidade
    4. Cuidado com a criação indiscriminada de getters e setters
    5. Modelo anêmico
    6. Domain-Driven Design
    7. O Código e a Linguagem Ubíqua
  5. Java avançado
    1. Refletindo seu código
    2. Configurando: anotações e XML
    3. Entendendo o NoSuchMethodError e o ClassLoader hell
    4. Manipulação de bytecode
  6. Design
    1. Baixo acoplamento, alta coesão
    2. Inversão de Controle: Cadê a minha chave de fenda?
    3. Fábricas e o mito do baixo acoplamento
    4. O que preciso para ser IoC-based?
  7. Arquitetura
    1. Camadas e Camadas: a confusão de tiers e layers
    2. Granularidade correta: Minimize a comunicação entre tiers
    3. Model View Controller
    4. Dois tiers
    5. Tres tiers
    6. N-tiers
    7. Mensageria assíncrona
  8. Frameworks e especificações Java EE
    1. Enterprise Java Beans
    2. JavaServer Faces facilita a criação de interfaces?
    3. Considere usar uma ferramente de mapeamento objeto relacional
    4. Logar é melhor que debugar
    5. Evite escrever seu proprio framework
    6. Injeção de dependência
  9. SOA - Same Old Architecture?
    1. A burocratização do SOAP vale a pena?
    2. Não escreva XML dentro de XML: não veja XML
    3. Considere um outro protocolo leve
    4. SOA: Same Old Architecture?
  10. Web 2.0
  11. Segurança
Mais sobre o livro Arquitetura e Design de Software - Uma visão sobre a plataforma Java no site http://www.arquiteturajava.com.br/

segunda-feira, 11 de maio de 2009

Tutorial Jogl - Desenhando em Java com Jogl 2D

Depois te fazer sua primeira tela usando o Jogl agora iremos para parte final desse tutorial.

Para desenharmos no Jogl iremos usar seus eventos. Há uma interface (GLEventListener) que devemos implementar se quisermos desenhar. Uma implementação nula (ou mock) pode ser vista abaixo:
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;


public class OuvinteJogl implements GLEventListener {
public void init(GLAutoDrawable arg0) {
}

public void display(GLAutoDrawable arg0) {
}

public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}

public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
}
}
Se concentre em dois métodos, o init e o display ambos recebem um GLAutoDrawable. Esse GLAutoDrawable será o nosso GLCanvas, assim as mudanças que faremos em GLAutoDrawable irão refletir diretamente no nosso GLCanvas.

Método init

Começemos então pelo método init que irá inicializar nosso desenho.
public void init(GLAutoDrawable drawable) {
int width = 512, height = 256;
GL gl = drawable.getGL();
GLU glu = new GLU();
gl.glClearColor(.0f, .0f, .0f, 1.0f);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, width, 0.0, height);
}
Aqui basicamente defini uma resolução (largura x altura). A segunda linha do méotodo é importantissíma veja como extrai o objeto GL (que na verdade é a API da OpenGl) e nele que iremos trabalhar diretamente com "a linguagem opengl". Esse GLU é uma biblioteca que nos ajuda nas tarefas rotineiras do opengl.

Depois de ter o contexto da opengl (gl) o código foi basicamente de inicialazação de um plano 2D (sem profundidade) na resolução dada.

Método display

Agora sim, nesse método que iremos criar o código para desenharmos a tv desintonizada usando o jogl.
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);

gl.glBegin(GL.GL_POINTS);
for (int x = 0; x < y =" 0;">
Simples. Aqui da mesma forma o primeiro passo é adiquirir o contexto da OpenGL (representado pelo objeto GL no java), limpar as cores gl.glClear(GL.GL_COLOR_BUFFER_BIT) e começar a desenhar pontos na tela. A logica é simples percorre-se dois for's uma para x e outro para y, a cada ponto uma cor é setada usando o método random da biblioteca Math (padrão do Java).

Agora pra juntar isso ao nosso JFrame anterior... ?
Simples basta ligar o nosso Listener ao Canvas.
super("OpenGl 2D - Java 2D com opengl Jogl");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(514, 258);
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new OuvinteJogl());
add(canvas);

Simples, não?
Execute e veja o resultado!


Mas perai... alguém me enganou! Isso não é animado...
É ai que entra o 3º Componente o FPSAnimator.
Ainda no construtor... escreva após a última linha de código existente nele.
FPSAnimator animator = new FPSAnimator(canvas, 50);
animator.start();
Agora execute e veja. (aquel 50 é o número de fps) Pronto igualzinho aquele tempo que a TV te dava canseira com o Super Nintendo e o Video Cassete.


Links:
  1. http://archsofty.blogspot.com/2009/05/jogl-java-bindings-for-opengl-api-with.html
  2. http://archsofty.blogspot.com/2009/05/tutorial-jogl-configuracao-do-ambiente.html
  3. http://archsofty.blogspot.com/2009/05/tutorial-jogl-desenhando-em-java-com.html

Código Final Completo.
import com.sun.opengl.util.FPSAnimator;
import javax.media.opengl.GLCanvas;
import javax.swing.JFrame;

public class FrameJogl extends JFrame {

public static void main(String[] args) {
new FrameJogl().setVisible(true);
}

public FrameJogl() {
super("OpenGl 2D - Java 2D com opengl Jogl");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(514, 258);
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new OuvinteJogl());
add(canvas);
FPSAnimator animator = new FPSAnimator(canvas, 50);
animator.start();
}
}

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

public class OuvinteJogl implements GLEventListener {

public void init(GLAutoDrawable drawable) {
int width = 512, height = 256;
GL gl = drawable.getGL();
GLU glu = new GLU();
gl.glClearColor(.0f, .0f, .0f, 1.0f);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, width, 0.0, height);
}

public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);

gl.glBegin(GL.GL_POINTS);
for (int x = 0; x < 512; x++) {
for (int y = 0; y < 256; y++) {
gl.glColor3f((float)Math.random(), (float)Math.random(), (float)Math.random());
gl.glVertex2i(x, y);
}
}
gl.glEnd();
}

public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int arg3, int arg4) {
}

public void displayChanged(GLAutoDrawable drawable, boolean arg1, boolean arg2) {
}
}

Tutorial JOGL - Configuração do ambiente

Primeira Parte - Configurando Jogl no Netbeans

O primeiro passo é ir ao site do jogl e baixar a versão correspondente ao seu sistema operacional. No meu exemplo estou usando o Windows portando baixei desse link http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1/jogl-1.1.1-windows-i586.zip . Dentro do arquivo comprimido haverá uma pasta lib vário arquivos:
  • gluegen-rt.dll
  • gluegen-rt.jar
  • jogl.dll
  • jogl.jar
  • jogl_awt.dll
  • jogl_cg.dll
Note que se você estiver usando linux ao invés de *.dll terá os arquivos *.so.

Como em qualquer outro desenvolvimento uma IDE poderá te ajudar e muito, escolha a sua preferida. Estou usando o NetBeans 6.5. (Que não necessariamente é minha IDE preferida ;) )

Conceitos sobre Jogl

Quando você está criando uma aplicação que irá lançar mão de recursos providos pelo OpenGL há básicamente três componentes que poderão facilitar e muito sua vida. São eles:

GLCanvas (ou GLPanel) - Um componente (que extend de Component do AWT).
GLEventListener - O modelo de listener para os eventos comuns do opengl.
FPSAnimator - Uma classe que irá lhe ajudar a efetivamente fazer seus desenhos (ou jogos) animarem.

Criando um projeto...

Crie um projeto e adicione à ele as bibliotecas (gluegen-rt.jar e jogl.jar), copie também para pasta raiz do projeto todas as *.dll que estavam na pasta lib (do arquivo baixado anteriormente).

Para simplicar bastante as coisas (assim deixando de mais fácil entendimento para todos) iremos criar um JFrame e mostraremos nesse JFrame nossa animação.

O código pode ser visto abaixo:
import javax.swing.JFrame;
public class FrameJogl extends JFrame {

public static void main(String[] args) {
new FrameJogl().setVisible(true);
}

public FrameJogl() {
super("OpenGl 2D - Java 2D com opengl Jogl");
setSize(514, 258);
}
}
Simples ao extremo. Apenas cria um JFrame atribuindo o tamanho de 514 pixels de comprimento por 258 pixels de altura.

O próximo passo é escrever o componente que irá mostrar a tela opengl dentro desse JFrame. Para tal tarefa apenas escrevemos:
GLCanvas canvas = new GLCanvas();
add(canvas);

Isso, claro, no construtor abaixo de setSize. Agora se executarmos a aplicação teremos algo semelhando a isso abaixo.
















Sua máquina irá mostrar algo diferente, como não definimos nada o "opengl" mostra dados randômicos da sua memoria RAM. O importante neste ponto é a simplicidade do código, com pouco código já se pode ver algo produzido pelo Jogl.

O meu código final para o JFrame ficou assim:
import javax.media.opengl.GLCanvas;
import javax.swing.JFrame;

public class FrameJogl extends JFrame {

public static void main(String[] args) {
new FrameJogl().setVisible(true);
}

public FrameJogl() {
super("OpenGl 2D - Java 2D com opengl Jogl");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(514, 258);
GLCanvas canvas = new GLCanvas();
add(canvas);
}
}
Note que também adicionei um comportamente padrão para quando o usuário clicar no botão X da Janela.

Links:
  1. http://archsofty.blogspot.com/2009/05/jogl-java-bindings-for-opengl-api-with.html
  2. http://archsofty.blogspot.com/2009/05/tutorial-jogl-configuracao-do-ambiente.html
  3. http://archsofty.blogspot.com/2009/05/tutorial-jogl-desenhando-em-java-com.html

Jogl - Java bindings for OpenGL API with OpenGL 1.5 specification

Pretendo nos próximos posts explicar sobre como utilizar a API OpenGL no Java. Especificamente o "framework" Jogl.
Essas primeiras partes abordaram o básico ( não pretendo aprofundar muito nos conceitos, mostrar só a prática mesmo ) e o produto final desse tutorial - se assim posso chamar - será um programa que irá desenhar, em uma tela, pixels com cores randômicas... similar ao efeito de uma tv desintonizada.

Links:
  1. http://archsofty.blogspot.com/2009/05/jogl-java-bindings-for-opengl-api-with.html
  2. http://archsofty.blogspot.com/2009/05/tutorial-jogl-configuracao-do-ambiente.html
  3. http://archsofty.blogspot.com/2009/05/tutorial-jogl-desenhando-em-java-com.html

quarta-feira, 22 de abril de 2009

DSL Interna ou DSL Externa dão brigas feias


O assunto interessantissímo DSL (domain-specific language) é contraverso (assim como a maioria das tecnicas/metodologias/tecnologias novas) e chega a dar briga!

Acompanho direto foruns e artigos sobre o assunto, para alguns ela é dividida em dois ramos dsl interna e externa, pra outros essa divisão é sem sentido. A discussão já começa na definição do conceito ou conjunto de conceitos por trás do assunto.

Leia a opinião de Martin Fowler sobre DSL's (interna e/ou externa): DSL (domain-specific language)
Leia também a opinião de Phillip Calçado: Domain-Specific Language Interna

E por último não deixe de conferir este artigo no infoq: http://www.infoq.com/articles/External-DSL-Vaughn-Vernon

sexta-feira, 17 de abril de 2009

Lula on South Park

Este post vai fugir bastante (no fundo acho que não) do usual aqui. Ontem assisti o novo episódio (transmitido na quarta) de south park, nele os grandes líderes do mundo aparecem and Guess Who.... Mister Lula também aparece. Não sou daqueles a favor do Lula muito ao contrário sou sempre um vigia do atual governo. Mas achei muito bom a aparição dele "entre os líderes mundiais" bem como o episódio. Esta temporada de south park está de mais, o melhor episódio IMHO foi Gay Fish. (hilário)



quarta-feira, 18 de março de 2009

Spring, spring meu existe alguém que te usa mais do que eu

Sem dúvida um dos frameworks mais agitados e falados (e usados também) ultimamente é o senhor Spring Framework. Eu há muito tempo (muito mesmo) já gostei da idéia, mas porém contudo todavia tenho hoje uma visão crítica de que não é TODO projeto que se deve usar (ou ao menos em todos os componentes) o mesmo. Essa opinião foi formada devido a um projeto que estive trabalhando nesses últimos meses. Resumidamente o projeto tinha mais ou menos a arquitetura abaixo. (apenas estava servindo como reparador não foi eu que criei)

As dependencias das actions são todas gerenciadas pelo "container" (Spring), logo nas actions só se tem declaração de interfaces (no exemplo qualquer classe sem Imp era uma interface) e o Spring faz a injenção com as classes que as implementa (ClasseImp.java) e isso sucessivamente, ou seja, as dependencias das classes de "negocios" também...

Em si isso é comum, o fato não é o jeito que as coisas foram feitas e sim o motivo, nesse projeto pode se reduzir BASTANTE o uso do Spring mas ao contrário as pessoas apenas querem usar desefreadamente os frameworks em voga.

Eu acredito que o uso de qualquer framework exige um senso apurado assim como uma visão crítica, há projetos em que o uso de JPA pode degradar a performance final e assim como vários outros exemplos de que nem sempre é necessário estar na "moda".

Usar por usar (sem saber o pôrque) não vale a pena! Veja e tente entender os beneficios de se usar esse ou aquele framework ou mesmo alguma metodologia!

terça-feira, 17 de março de 2009

Bons e Novos Jogos!

Influenciado fortemente pelo post no meu outro blog em inglês trago hoje (para uns) novidade na cena da criação de jogos!

Ultimamente estou observando de muito perto a criação de alguns jogos independentes. Especificamente três jogos me tomaram totalmente a atenção; são eles: Braid, Aquaria e Crayon Physics. Se você é daqueles que ainda se lembra da caixa do super nintendo ou do mega drive, dê uma chance a esses jogos.
http://www.geocities.com/compcloset/NintendoSNESBox.jpg


Braid (a versão pra PC sairá dia 31 de Março de 2009)
Um jogo no estilo Super Mario (alias até é meio que uma homenagem) e com uma história depressiva e imperdivel.
Official site: braid-game.com/


Aquaria (já disponivel)
http://www.g4g.it/g4g/wp-content/uploads/2007/12/aquaria_demo_01.jpg
Um épico dos RPGs 2D... se você gosta do estilo, irá amar joga-lo, vai sentir nostalgia e com certeza se lembrará de jogos como... Castlevania!
Official Site: http://www.bit-blot.com/aquaria/

Crayon physics (já disponivel)Esse jogo não encontrei meios ou palavras pra descreve-lo, é incrivel a única coisa que posso dizer é: Entre no site e assista o vídeo de demonstração.... veja vale MUITO a pena!
Official Site: www.crayonphysics.com/