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.

quarta-feira, 28 de abril de 2010

Integrando google app engine (GAE) + Spring 3.0.2 + Hibernate (JPA)

Google App Engine - GAESpring FrameworkHibernate - JPA

Introdução

Usar a infraestrutura do google para hospedar suas aplicações pode parecer algo fantástico. Imagine ter todo o poder e segurança fornecido pelo Google diretamente nas suas aplicações. É com essa promessa que o Google App Engine (GAE) foi lançado. Pode-se criar aplicações Web usando Python ou Java.
+Vantagens: boa documentação em pt_BR, aproveitar da escalabilidade do google, desenvolver em Java (no ponto de vista de número de pessoas aptas) e etc.
-Desvantagens: JRE com menos classes, frameworks não funcionando ou funcionando parcialmente, restrições ao uso do JPA e etc.

Configurando plugin no Eclipse

Para facilitar, muito, a criação, deploy e debug de seus aplicativos aconselho a utilizar o Eclipse juntamente com o plugin fornecido pelo google.

Integrações

Spring 3.0.2

Gosto de usar o controle transacional do Spring (@Transactional) , injeção de dependência e a implementação do open session in view (OpenEntityManagerInView) e para usar tais recursos tive que configurar o web.xml dessa forma.

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<filter>
<filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Já o arquivo applicationContext.xml ficou assim.

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" lazy-init="true">
<property name="persistenceUnitName" value="t3st3" />
</bean>
<bean name="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

JavaServer Faces 2 (JSF 2.0)

Costumo repassar o trabalho de cuidar do ciclo de vida dos managedbean para o Spring. A utilização do jsf 2 (implementação myfaces) traz as novidades do jsf 2.0 (que é um grande passo) e saber que é compatível com gae é muito bom. Bem meu web.xml ficou assim.

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>


<!--
We need to set annotation lifecycyle provider manually as org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider.
Other providers use some classes that are restricted on Google App Engine.
-->
<context-param>
<param-name>org.apache.myfaces.config.annotation.LifecycleProvider</param-name>
<param-value>org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider</param-value>
</context-param>

<!--
Need to set a secret to avoid javax.crypto.BadPaddingException.
"param-value" must be Base64 encoded.
More details: http://wiki.apache.org/myfaces/Secure_Your_Application
-->
<context-param>
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>NzY1NDMyMTA=</param-value>
</context-param>

e o faces-config.xml assim:

<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>

Hibernate

Só usar! Ahh é mesmo tem que se criar um arquivo persistence.xml (META-INF) mínimo.

Observações gerais:
Tente usar sempre o objeto Key como id, pois objetos filhos devem usar Key ou String codificada, não sendo possível usar long ou int.
Você pode acompanhar o status do ambiente, quais serviços estão online qual a latência de uso e etc.

sexta-feira, 9 de abril de 2010

Artigo publicado na InfoQ Gringa

Nota rápida: o pessoal da InfoQ publicou meu artigo sobre Implementing Google's "Did you mean" Feature In Java. Todo feedback será bem-vindo.

URL amigáveis com JavaServer Faces (jsf) 1.X

Uma das críticas dos usuários de JSF é : "você não consegue criar urls que podem ser bookmarked (favoritadas)".

Eu pensei que iria ter uma trabalheira do cão... pensei que não iria dar muito certo com Richfaces, Spring ... enfim todas as integrações... pensei... pensei errado! :)

Há um framework chamado PrettyFaces (para jsf 1.1 , 1.x e 2.0) o qual o uso é extremamente fácil.

Com apenas dois passos você adiciona url amigáveis ao JSF:

1º Passo: Registrar o filtro no web.xml

<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

2º Passo: criar o arquivo pretty-config.xml dentro de WEB-INF:

<pretty-config
xmlns="http://ocpsoft.com/prettyfaces-xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ocpsoft.com/prettyfaces-xsd
http://ocpsoft.com/xml/ns/prettyfaces/pretty-1.0.xsd">
<url-mapping id="verNoticia">
<pattern>/noticia/#{myBean.currentStoryId}/</pattern>
<view-id>/noticia.xhtml</view-id>
<action>#{myBean.loadComment}</action>
</url-mapping>
</pretty-config>


Com as configurações acima se você digitasse http://seuhost/seuprojeto/noticia/12345/ você mostraria o bean (de ViewID=/noticia.xhtml) com a notícia de id=12345 :)

ps: um passo omitido seria o download do jar e o registro do mesmo no classpath da sua aplicação.

segunda-feira, 29 de março de 2010

Freelancer Java - Tive bons resultados.

Freelancer Java

De acordo com a Wikipedia: "Freelancer é o termo inglês para denominar o profissional autônomo, que se auto-emprega em diferentes empresas ou, ainda, guia seus trabalhos por projetos, captando e atendendo seus clientes de forma independente. É uma tendência muito em voga no mercado de jornalismo, design, propaganda, web, tecnologia da informação, música e muitos outros."
Há - muito - tempo atrás li um post interessantíssimo denominado o guia de guerra para freelancers. E eu também tentei me aventurar pelo mundo dos serviços de freelancer java. Até que me posicione bem no google, se você pesquisar "trabalho freelancer java" no google, meu blog aparecerá no fim da primeira página ou no inicio da segunda, claro (quase) todos os créditos aos trabalhos que obtive foram vindos do google. Para minha surpresa tive alguns contatos bem rápidos e um ponto interessante foi que a maioria deles não moravam próximo a mim. Todo trabalho desenvolvido (para os clientes) foi baseado na confiança e a comunicação basicamente foi por emails. Dá pra ganhar uma graninha extra com disciplina e responsabilidade. =D

terça-feira, 9 de março de 2010

boasPraticas.add deploy, tdd, ddd

Recebi a visita de um super amigo das antigas (leia-se VB.NET), eu tinha que entegrar um simples gerenciador de conteúdo e meu amigo me acompanhou e ficou questionando sobre por que eu fazia assim, usava aquilo, não fazia isso... no fim ele disse que precisava de desenvolver com mais qualidade, controle e facilidade. Ele ainda me pediu uma lista de livros pra ler e quais praticas eu usava, naquele momento começei a falar tanta coisa, ferramenta, framework, metodo... que ele mesmo disse "escreva uma lista dessas boas práticas"! E aqui estou eu, vou tentar apenas listar os tópicos e os links que acho interessante.

Não reivente a roda - quase sempre há uma common pronta, então quando surgir uma necessidade pesquise antes sobre o assunto. Tive uma péssima experiência com um agendador de tarefas (que eu criei) em Java, tudo isso porque não conhecia o Quartz.
Melhore seu design OO - por mais que pareça esgotado esse assunto, ainda há pessoas que não compreendaram assuntos básicos, esse tópico (sobre OO) não dá pra ser resolvido com uns poucos links mas se eu pudesse indicar um site seria o do Philip Calçado. PS: outras boas práticas abaixo listadas podem lhe ajudar também num design mais charmoso.
TDD - uma ótima prática que pode lhe livrar de dores de cabeças infernais. No inicio pode parecer perda de tempo mas com tempo você vai ver o valor de usar Test Driven Development.
Logging - não há nada mais chato do que ler grandes arquivos de logging não é mesmo?! Há sim, debugar! :P então: prefira Logar do que Degubar! Pode começar lendo um tutorial de log4j.
Deploy - Automatizar suas construções e criar um processo de deploy continuo :)
Boas práticas com JPA - às vezes passamos raiva só por desconhecimento (profundo) de um certo recurso do framework. Logo digo leia esse ótimo post sobre os bons habitos de usar JPA.
Integração continua - Leia o post de Integração continua ahhh outra dica automatize tudo o possível.
Aprenda outra linguagem - Sua cabeça pode se tornar viciada numa linguagem só e isso pode lhe privar de conhecer ou melhor entender como outros organismos funcionam. Além do mais é divertido aprender Ruby e ver como as pessoas resolvem problemas de maneiras tão distintas.
Comunidade - Nem só de código fonte a comunidade open-source se alimenta, usar forums para aprender e ensinar é algo muito valioso.
Outros bons livros :)

Tudo isso pode parecer plágio de um grande blog de ótimo desenvolvedores, mas não é :) Juro!

terça-feira, 23 de fevereiro de 2010

Como usar JavaScript na plataforma Java

Em minha mente o assunto scripting na plataforma Java já estava bem explorado e difundido. Mas hoje fui supreendido por um amigo com um mini-framework que servia de analisador e parser para simples fórmulas matemáticas como p.ex:
2+2-1*3/3
(2+2)*10

Usando Java 6 basta esse simples código.

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
try {
String script = " 10 + 2 * 2 "; //ou sua expressão
Object result = engine.eval(script);
System.out.println(result);
} catch (ScriptException ex) {
System.out.println("deu erro :P "+ex);
}

sábado, 13 de fevereiro de 2010

JTableAnnotations - Um jeito mais simples de criar JTable

JTableAnnotations
Há algum tempo atrás escrevi um mini-framework para criação de JTable por anotação. Talvez esse pedaço de código possa lhe servir, criar JTable sempre é uma tarefa chata e tediosa (e para alguns dificil). O JTableAnnotations propõe uma simplificação no processo de configuração e preenchimento das tabelas.

Basicamente você precisará anotar suas entidades

@JTableConfiguration(rowHeight=48)
public class Product {
@JTableColumnConfiguration(order=1,width=55)
private Long id;
@JTableColumnConfiguration(order=2,width=300,editable=true,align=Align.CENTER)
private String name;
@JTableColumnConfiguration(order=3,name="Price",decimalFormat="U$ 0.00")
private BigDecimal value;
@JTableColumnConfiguration(order=4,name="Costumer Name",width=300)
private Customer customer;
@JTableColumnConfiguration(order=0,name="Photo",cellRender=IconCellRender.class)
private String picturePath;

E então o trabalho de configurar e popular fica a cargo da classe Configurator:

Customer master = new Customer();
master.setName("Master");
master.setUserName("Admin");
list = new ArrayList();
list.add(
createProduct(
master, 0L,
"Nintendo Wii",
"pictures/wii.jpg",
new BigDecimal(999.50)));
list.add(
createProduct(
master, 1L,
"XBox360",
"pictures/xbox360.jpg",
new BigDecimal(1020.85)));
list.add(
createProduct(
master, 2L,
"PS3",
"pictures/ps3.jpg",
new BigDecimal(1000.0)));
list.add(
createProduct(
master, 3L,
"PSP",
"pictures/psp.jpg",
new BigDecimal(490.0)));
list.add(
createProduct(
master, 4L,
"Nintendo DS",
"pictures/nds.jpg",
new BigDecimal(359.59015)));
new Configurator().configureAndPopulateJTable(jTable, list);
E voilá!
(odeio essa resolução do blogspot)
[Clique aqui para ver a figura abaixo]

Mais informações na página do projeto http://code.google.com/p/jtableannotations/

quarta-feira, 27 de janeiro de 2010

Vagas Agile Funny - OFF

Com o título Vagas na Fibonacci Soluções Agéis - foi um anuncio feito pelo GOJava (legal) veja:

Requisitos:

Imprescindíveis:

- Gostar muito de programação
- Não achar que a carreira ideal é aquela em que você começa como programador, é "promovido" para analista e um dia se torna gerente de "sua própria equipe"
- Preferir trabalhar em uma equipe auto-gerenciável
- Não acreditar que uma única tecnologia é a solução para todos os problemas, mas sim que existe a ferramenta correta para cada trabalho
- Ser bom em google-fu

Desejáveis

- Experiência/conhecimento em Desenvolvimento Orientado a Testes, Desenvolvimento para Web, Arquitetura de Software, Desenvolvimento Orientado a Objetos, Metodologias Ágeis
- Saber jogar truco
- Ser ala-direita ou centro-avante no futebol (precisamos completar o time)
- Gostar de video-game

Benefícios:

- Os tradicionais vale-transporte e plano de saúde
- Uma cozinha com lanche disponível o tempo todo e dois horários de lanche por dia (de manhã e de tarde)
- Não ter chefe, porque aqui não é nenhuma tribo.
- Você nunca vai ter que explicar seu trabalho nem vai ser avaliado com base em um Diagrama de Gantt


Quem derá as empresas tivessem um pouco mais desse espírito.
PS: não trabalho, não conheço nada nem ninguém da empresa.