Pesquisar

quinta-feira, 4 de novembro de 2010

A prática do SEO e os resultados

Apesar de ter um trabalho fixo; hora ou outra também executo trabalhos freelancer java. E ultimamente as propostas de trabalho tem aumentado consideravelmente. E esse aumento se deve (na maioria absoluta) ao uso de um conjunto de técnicas (e ou estratégias) SEO.

É impressionante o quanto o google pode lhe dar retorno com um bom posicionamento, e digo isso baseado apenas no lucro que obtive em pequenos trabalhos ou ajuda (consultória) em Java, Richfaces, JSF, JPA enfim...

Por isso e outros fatores noto que a propaganda paga ao google é um investimento que tem retorno garantido. Só pra esclarecer não tenho nenhum vinculo com google (empregatício porque de uso muito de seus serviços).

Para se ter uma ideia, se você procurar por freelancer java no google, o blog vem em 5º lugar (claro esse posicionamento vai se atualizar) e com esse "5º lugar" noto que a diferença de divulgação por email, forum e etc é extremamente irrisória se comparada ao jeito google de ser.

Portanto fica aqui a dica se não conhece vale a pena dar uma estudadinha em SEO e suas consequências.

terça-feira, 10 de agosto de 2010

Decisões de design - Herança X Composição

Mesmo que esse assunto pareça já explorado de todas as formas ainda há certas situações que relutamos (pelos menos eu) em usar a herança ao invés da composição.
Invejando descaradamente o conto de cada dia do Phillip http://images.americanas.com.br/produtos/item/2508/8/2508843gg.jpg. Vou contar de uma experiência que tive. O exemplo clássico é o controlador CRUD (seja seu servelet, managed bean, action form... ) que contém os métodos para uso geral e genérico e alguns ganchos. Vou dar um exemplo bem simples de um Managed Bean CRUD.

public class ManagedBeanCRUD [E,ID]{
private E instancia;
public E getInstancia(){return instancia;}
public Void setInstancia(E entidade){this.instancia = entidade;}

public String salvar(){
preSalvar();
servicoCrud.salvar(getInstancia);
return "navegacaoListar";
}
public void preSalvar(){}
}

E apartir desse MB crio os meus outros CRUDS simples, exemplo telefone:

public class TelefoneMB extends ManagedBeanCRUD [Telefone, Integer] {
@Override
public void preSalvar(){
System.out.println("Oi esse é gancho ...");
}
}

Ótimo, houve reuso por meio da herança mas logo veio as seguintes perguntas: porque não transformou os métodos preXXX em métodos abstratos? Porque daí eu teria que obrigar o usuário a implementar sempre mesmo quando não fosse necessário. porque não usou composição ao invés da herança? Porque minha visão (xhtml) já está toda padronizada.

[c:campoentrada binding="#{mb.instancia.numero}"/]
[c:botao binding="#{mb.salvar}"/]

Note que o método salvar não existe (ao menos no fonte) na classe TelefoneMB ele é acessado por herança. A primeira tentativa foi substituir a herança por composição por meio de delegação, minha classe TelefoneMB ficaria mais ou menos assim:

public class TelefoneMB{
private ManagedBeanCRUD[Telefone, Integer] delegate;
public String salvar(){
return delegate.salvar();
}
// + do mesmo
}
Mas será que não pode ser melhorado?!

Claro que sim até agora consegui chegar num patamar assim: os métodos ganchos se transformam no padrão decorator e a herança se torna composição por delegação mas de um modo diferente, fiz o MangedBeanCRUD ser um atributo de leitura :

public class TelefoneMB{
private ManagedBeanCRUD[Telefone, Integer] crud;

public TelefoneMB(){
crud.addEventoPreSalvar(new Evento(){
public void executar(){
System.out.println("antes de salvar...");
}
});
}

public ManagedBeanCRUD getCrud(){
return crud;
}
}
E na view (jsf, xhtml ...) não terei muita mudança será uma navegação a mais na #EL #{telefonemb.crud.salvar} terei que adicionar o crud antes do padrão CRUD de ser.

Com isso tenho um managed bean livre de más práticas, melhorei o sistema de eventos e mais um plus não terei problemas futuros com proxies do JDK ou GLIB2! Mais camadas e indireções sempre foi o caminho conforme post sobre abstrações pra todo lado.

Todo comentário sempre é e será bem-vindo!

ps: só pra deixar claro não sou contra o uso da herança, há casos que você pode usar herança para compor suas entidades e outros n usos. O único cuidado que deve ter é pensar, pensar, pensar e pensar para decidir se é herança ou não.

terça-feira, 13 de julho de 2010

Wii Hacking ;D

Primeiramente, pra esclarecer...
O que esse post não é?

Um tutorial de como fazer hacking, desbloquear, instalar o homebrew channel...

O que é?

Uma visão geral (BEM resumida) sobre a arquitetura do wii, os processos de hacking atuais; enfim, se trata mais de um post de curiosidade do que um manual. :P (quem quiser isso pode ir no wii players forum ou gbatemp, nesses sites você encontra o melhor e mais atualizado conteúdo sobre wii hacking).


Wii Hacking

É o ato de tentar hackear a máquina nintendo Wii :)

Mas pra que hackear o Wii?

Pra essa pergunta há N-respostas que vão desde um simples desejo de rodar programas feitos por você ou outras pessoas (homebrew - código não assinados) até rodar jogos (seus backups) pelo hd usb externo.

Então como é feito o processo de hacking do Wii?

Como quase todo hacking, baseado nas falhas existentes. Pra melhor entender e explorar o assunto é necessário ter a visão básica de como funciona (bem básico) a pilha de software do Wii.

[Quase sempre vísivel ao usu] - System Menus (4.2U , 3.5K).
[Quase sempre invísivel ao usu] - IOS sistemas internos (IOS 222,36).
[Quase nunca vísivel ao usu] - BOOT0, BOOT1 e BOOT2.

Os Exploits!

O mais famoso (e também antigo, obsoleto, só funciona com system menus até o 3.4...) deles é o que é executado por meio do jogo The Legend of Zelda: Twilight Princess, mas tem o "inconveniente" de que você necessita de ter o jogo (você deveria tê-lo mesmo :P). Se você quiser saber mais sobre esse exploit (criado pelo Team Twiizers) leia Twilight Hack.

Hoje em dia as pessoas utilizam com maior frequência o Bannerbomb que é um processo bem mais seguro, testado e fácil. Você carrega um SDcard com arquivo compatível com seu system menu e o executa pelo ícone do SDcard.









A famosa expressão Brick!


Há, sempre que se fala desse assunto, um risco ao fazer tais operações. A partir do exploit executado você começa o processo de hacking... isso envolve você 'retirar' algumas IOS que podem lhe 'barrar' de algumas operações, substituir algumas IOS por outras cIOS feitas pela comunidade. Sempre que você alterar essas características você corre o risco. Mas hoje o risco mais é de você atualizar o Wii (pela wifi) para uma versão mais nova do system menu (claro que a nintendo sempre corrige esses bugs, ou tenta) e daí você pode sim ter o Wii invalidado pra sempre. (isso não é brincadeira)

E o hacking ... como é feito?

Você executa um dos exploits (por sua conta é total risco, sobre a pena do Bricked Wii) que normalmente lhe dá condições para que o HomeBrew Channel seja instalado. Esse será sua porta pra rodar aplicativos feitos por você ou outras pessoas na Internet. Além do homebrew channel é importante também remover alguns IOS e substituir outros por cIOS. Isso é feito pra que você volte a ter 'bugs' conhecidos e também acesso a dispositivos externos como HD USB. Um fato importante e muito bom de se 'hacker' o wii, é que você pode fazer várias operações que garantem uma vida útil maior e também ferramentas pra recuperação de erros. Backup da NAND pode lhe garantir num futuro uma possível 'restauração' do sistema.

Ferramentas que normalmente são instaladas

HomeBrew Channel - também conhecido como HBC, é o canal (aparece no menu inicial do Wii) que lhe permite executar aplicativos não assinalados.
BootMii - Um conjunto de sistemas que você pode instalar no wii pra lhe oferecer mais 'utilidades' ao aparelho.
Priiloader - Sistema que fica exatamente entre a sequência de boot e o system menu. Hoje em dia ele é instalado como se fosse um IOS. Ele lhe dá acesso à vários hacks interessantes e úteis, por exemplo: remover a atualização automática, apertar A naquela tela chata de inicio... e claro pode ser sua salvação, caso o venha a Brickar, ele fornece meios pra você recuperar sua NAND (baseado no seu bkp). Mas ele como IOS não garante 100% de unbrickablility. (Perfeito é quando você consegue, em versões mais antigas do Wii, instala-lo as boot2 aí sim você tem um Wii quase unbrickable, já que você detém o poder do boot :) )
Multiple WAD Manager - O famoso MMM é um gerenciador de pacotes de instalação para o Wii ele é essencial. É díficil de usar, a principio, pois sua interface (textual, não gráfica) não ajuda muito. Nele que você instala cIOS (custom IOS), remove IOS, instalar canais...

ps: mais uma vez, não mude seu wii sem conhecer o que é feito com ele e sem ter a noção dos riscos ao substiuir IOS's por cIOS's. E claro, sempre assuma os riscos por sua conta. (ps2: eu, depois de me informar, acho seguro e com possibilidades pequenas [mas ainda existem] de você perder seus wii.)

E lembre-se há homebrews que valem muito a pena.

terça-feira, 29 de junho de 2010

Habilitando Cache level 2 no JPA 1.0 (Hibernate)

Uma das características prometidas para o JPA 2.0 e já implementada no hibernate é Second Level cache! Pra habilita-lo é bem simples:

Basta informar ao Hibernate (seja pelo persistence.xml ou pelo applicationContext.xml) as seguintes propriedades.
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider {classe padrão pra prover serviços de cache}
hibernate.cache.use_query_cache=true {se deve ou não fazer caches de queries}


Lembrando que por padrão você deve configurar entidade a entidade as quais devem ou não serem cacheadas (com a anotação @Cache junto a @Entity, você também pode cachear coleções!) e qual a política (de concorrência) que deve ser usada no esquema de cache (NONSTRICT_READ_WRITE, NONE, READ_ONLY, WRITE_ONLY, TRANSACTIONAL). Depois é só observar pelo log de sql :D! Have fun!

sábado, 29 de maio de 2010

NoSuchFieldException no Hibernate (JPA)

No padrão JPA você pode anotar suas entidades pelos métodos (getters) ou pelos atributos, é um ou exclusivo ou vocÊ anota tudo pelos atributos ou pelos getters. O relato que segue é sobre um código que funcionou muito bem por muito tempo mas que na última sexta feira (28/05/2010) me deu muita dor de cabeça.

Devido a limitação do JSF (1.X) quanto a população de combos (o usuário do framework é obrigado a passar uma lista/matriz de SelectItem), eu criei um código para que dado uma lista de objetos, o nome do atributo à ser mostrado (descricao) e o nome do atributo com valor (id) retorna uma matriz de SelectItem.

API SelectItem[] converterListaParaCombo(final List objetos,String attMostrar,String attValor)

O código é simples; faz um loop nos objetos e vai recuperando os valores dos campos por reflexão e criando objetos do tipo SelectItem e os adicionando na lista/matriz.

Bem, voltando ao relato. Quase sempre eu usei anotar (JPA Annotations) as entidades nos campos, por boa prática comecei anotar pelos getters.

Quando fui testar percebi que o método converterListaParaCombo estava lançando a exceção NoSuchFieldException. Dessa vez o log não ajudou quase nada, tive que debugar... para minha surpressa a lista ia sendo populada normalmente até chegar num objeto (da lista) que não tinha o campo descrição :S. A primeira pergunta: Como isso é possível se eu mesmo declarei o campo na entidade?

Para responder essa pergunta criei mais um teste sobre a lista de objetos que eu passava para o método. Mandei (imperativamente) um sysout sobre getId e getDescrição... aqui outra surpresa não houve nenhum erro :S. Numa pesquisa mais profunda sobre o assunto descobri que o hibernate tem "seu modo de fazer cache" que pode causar alguma surpresa para os mais desavisados e na verdade ele nem sempre retorna a sua entidade e sim um proxy {eu pensava
que esse proxy era somente para List}. E um desses proxies "não tinha" o campo descricao...

Para resolver o problema, eu apenas mudei no método a forma de recuperar os valores. Ao invés
de pegá-los pelo atributos agora pelo pelos métodos getters. :D

sexta-feira, 7 de maio de 2010

Adicionando escopo de conversação ao JavaServer Faces 1.X (JSF 1.2)

Que o JSF não é perfeito todos sabemos mas se há algo que me incomoda muito são duas coisas chatas: URL amigáveis (que consegui resolver facilmente com PrettyFaces.) e tratar tudo como escopo de sessão (por falta de um escopo entre o requisição e o sessão).

Para o último problema começei a pesquisar algumas soluções possíveis e cheguei ao framework MyFaces Orchestra.

O MyFaces Orchestra é um framework que pode ser usado em aplicações web para prover as caracteristicas de escopo conversacional. Apesar de ter sido criado para ser um framework de escopo para web presentations ele tem, hoje, só implementações para JSF 1.1, 1.2 e 2.0.

Para utilizar o framework você precisa, obrigatoriamente, usar o Spring 2.0 (ou maior) como gerenciador de seus managed beans. E claro ter os modulos do Orchestra (core12 e o core15 são os usados no exemplo) no seu classpath.

Exemplo

Fiz um exemplo utilizando Eclipse juntamente com quarteto fantástico : richfaces 3.3.3 + Facelets + spring 3.0.1 + hibernate 3.0.2 (JPA)! e tive que mudar/configurar os seguintes arquivos:

web.xml

<listener>
<listener-class>org.apache.myfaces.orchestra.conversation.servlet.ConversationManagerSessionListener</listener-class>
</listener>

applicationContext.xml

<import resource="classpath*:/META-INF/spring-orchestra-init.xml" />

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="conversation.manual">
<bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="timeout" value="30" />
<property name="lifetime" value="manual"/>
</bean>
</entry>

<entry key="conversation.access">
<bean class="org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope">
<property name="timeout" value="30" />
<property name="lifetime" value="access"/>
</bean>
</entry>
</map>
</property>
</bean>


Simplesmente após ter feito tais mudanças e ter atendido aos requisitos básicos: declarei meu bean no applicationContext com scope="conversation.access". No exemplo naveguei de uma página listar.xhtml para outra editar.xhtml mantendo o estado! Fiz testes posteriores também com uso de Ajax (a4j) com multiplos requests para mesma página ou outra tudo passou perfeito!

Se quiser ver o projeto baixe aqui o projeto (.war com sources)!

Further Reading!

O framework também fornece uma solução (essa eu não testei) para os lazy initializations lançados (esse com integração forte ao hibernate). Há também um esquema de binding muito legal.

ps: todo o post está levando em consideração as características do Jsf 1.x o Jsf 2.0 resolve alguns desses empecilhos.
ps2: ainda há algo que me incomoda é a quantidade de linhas no faces-config para lhe dar com navegação entre as páginas.
ps3: fiz testes básicos nesse projeto aconselho fazer mais testes reais na sua aplicação antes de substituir session por conversation.