Semântica em software. Não subestime sua produtividade

March 2, 2010

Semântica aplicada quando bem aplicada ao desenvolvimento de desenvolvimento de software traz consigo bastante produtividade, diminuição de erros por confusão de idéias e maior confiança no produto final. Frameworks como Spring (que já não é propriamente somente um framework faz tempo) e o Hibernate surpreendem em uma série de características e uma delas é o esforço dos arquitetos visando a corretude semântica dos frameworks. Um breve exemplo baseado no Hibernate segue:


@Entity @Table(name = "user")

public class User {
@Column(name = "firstname")
private String firstName;

@Column(name = "middlename")
private String middleName;
@Column(name = "last_name")
private String lastName;
@Embedded
private Contact contact;
...
Getters e Setters
...
}

A classe Contact é mapeada para User como um componente.

@Embeddable
public class Contact {

     @Column(name = "contactfone")
     private String fone;

     @Column(name = "contactmail")
     private String mail;

     ...
     Getters e Setters
     ...
}

Num projeto real o código acima não deve figurar. Mas algo parecido pode acontecer e por hora serve de exemplo para o que quero falar. Com o mapeamento acima, as informações de Contact serão armazenadas na tabela de User (crianças, não façam isso em casa… nem no trabalho!). Então armazena-se uma instância de User na base de dados sem informar nenhum dado para Contact (talvez porque não seja obrigatório). O que aconteceria agora se fosse recuperado tal instância de User e executado um user.getContact()? Retornado uma instância de Contact com os atributos null? SIM!!?? Peraí, você acha semânticamente correto? Eu não acho e pelo visto o pessoal do Hibernate também não. user.getContact() retorna null uma vez que nenhum atributo é diferente de null (nenhum detalhe de Contact foi passado para a aplicação) e realmente creio que seja a coisa certa a ser feita.

Acredito que alguns dirão que não concordam. Cada um tem sua semântica, obviamente. Mas acredito que na maioria das situações features (ou issues para alguns) como essa trará bons frutos de produtividade.

How to Hibernate in windows 7

September 28, 2009

Sempre fui muito fã do tal da ferramenta hibernate (não estou falando do framework de persistência de dados) que permite desligar a energia da máquina e assim que religar, encontrar todo o contexto do seu trabalho levantado! Todos os processos que estavam em andamento, janelas.. tudo rodando relativamente bem. Para mim, isso é fantastico! Quando estou numa máquina desktop, por exemplo, e ocorre falta de energia me irrito ao ter que reabrir todas as aplicações e lembrar arquivo por arquivo que estava editando ou rotinas que executavam antes da queda de energia.

Como no trabalho utilizo o windows 7 e não tendo encontrado neste SO a task no menu iniciar que fazia com que a máquina hibernasse – como havia no saudoso XP – fui procurar uma solução. É muito simples.

hibernateoptioninwindows7

1. Abra um prompt de comando com permissoes de Administrador da máquina (menu iniciar -> executar -> “cmd” + enter)

2. Execute o comando “powercfg /hibernate on” + enter

hibernatecommand

3. Feche o prompt digitando “exit” + enter

4. Se você ainda não conseguir visualizar a opção “Hibernar” no menu iniciar faça o seguinte:

4.1. Abra o menu iniciar e digite “Opções de Energia” + enter

4.2. Acesse a opção do menu esquerdo “Alterar suspensão da atividade do computador” e depois a opção “Alterar configurações de energia avançadas

hibrido

4.3. Abaixo de “Suspender” desligue o modo de suspensão híbrido.

Agora você já pode acessar o menu iniciar e utilizar a task de Hibernar.

Adicionando e ordenando loading nos outros classloaders do Tomcat5

September 11, 2009

Há algumas semanas publiquei um post que ensinava como ordenar os JARs das aplicações web (toda e qualquer aplicação dentro do diretório webapps do tomcat) através da manipulação do WebappClassloader, porém fiquei devendo falar sobre os outros classloaders presentes no tomcat, particularmente os que mais interessam são o common classloader e o shared classloader – não sabe o que são classloaders, ou não sabe o papel de cada um desses no tomcat? -> Understanding classloaders.

Achei que modificá-los seria uma tarefa mais fácil que enfrentei para manipular o loading das webapps. Definitivamente não! A começar que DocJar, muita reflexão e  java.lang.reflect.* foram precisos para hit-the-goal.

JAVA Reflection!!?? Pra quê??? Vou explicar…  A partir de gora leia (e talvez releia) com calma porque a priori pode parecer um pouco complicado por conta do vai-pra-lá-vem-pra-cá das classes das quais estarei falando a seguir.

Existe um tal de StandardClassLoader (org.apache.catalina.loader) que é a classe que irá implementar os três classloaders, do tomcat, pouco conhecidos mas essenciais para o seu funcionamento, a saber: common, shared e o server (também conhecido como o catalina classloader). E mais uma vez repito, se não tiver idéia do papel desses classloaders -> Understanding classloaders (é condição sine qua non para você entender este post). Enfim, voltando, essa classe extende o, largamente utilizado, URLClassLoader (java.net) o qual realiza suas tarefas lançando mão de um atributo do tipo URLClassPath (sun.misc) que realiza o trabalho pesado. Porém, se vocês tiverem a curiosidade, vejam que o atributo URLClassPath (o ucp) tem visibilidade default de forma que o mesmo não é acessível em uma subclasse de outro pacote. E infelizmente, como eu disse antes, o ucp realiza uma boa parte do trabalho atribuido ao URLClassLoader então como manipulá-lo? FOI TRISTE para nós!? Não!

Agora entra em cena as armas fornecidas pelo pacote java.lang.reflect. UM MOMENTO! Para o entendimento desse post é necessário que você saiba trabalhar bem com reflection, se não está seguro disso, consta aqui no publicclass{} um breve post que mostra como acessar métodos, atributos e inner classes inacessíveis (leia-se privados ou protected). Isso será suficiente para compreender os próximos parágrafos…

Read the rest of this entry »

Acessando métodos / atributos / classes privadas? Reflection!!

September 3, 2009

Eu sempre fui um verdadeiro admirador do pacote java.lang.reflect, não nego… Através dele (suas classes) pode-se realizar maravilhas!! ;pp

E agora, vejam que legal!! Para os que precisarem de acessar métodos, atributos, construtores, anotações (annotations) e classes internas inacessíveis (a priori), por conta de sua restrição de acesso (vide os modificadores private, protected e default) pode utilizar as features(hahahah!! @since JDK1.1) fornecidas pela classe Class e as filhas de java.lang.reflect.

Temos X:

public class X {

private double xValue;

public X(){

xValue = Double.MAX_VALUE;

}

private void shout(){

System.out.println(“ARrrRRrrR!!”);

}

public Y getY(){

return new Y();

}

private class Y {

public String getSomeString(){

return “Java Reflection”;

}

}

}

Farei agora uma pergunta com relação a um atributo inacessível, mas que poderia ser feita também se referindo a um método ou classe interna privados (ou qualquer outro modificador que os tornassem inacessíveis). Como faríamos para acessar o atributo xValue de X?? Se você respondeu para si mesmo “Abro o código, crio um método public void setXValue e acabou-se!!” esse post é abrirá uma janela na sua vida! How poetic!!

Agora vejam abaixo a solução:

public static void main(String[] args) {

try {

X x1 = new X();

Method m1 = X.class.getDeclaredMethod(“shout”);

m1.setAccessible(true);

m1.invoke(x1);

Field field1 = X.class.getDeclaredField(“xValue”);

field1.setAccessible(true);

System.out.println(field1.get(x1));

Object yObject = X.class.getMethod(“getY”).invoke(x1);

Method m2 = yObject.getClass().getMethod(“getSomeString”);

System.out.println(m2.invoke(yObject));

} catch (Exception e) {

e.printStackTrace();

}

}

O “pulo do gato” aqui é o seguinte… há métodos na Class que retornam somente os métodos acessíveis que é o getMethod e há também seu “irmão” que retorna todos os métodos, quer eles sejam privados, protected, default ou public, que é o getDeclaredMethod. Há também os relativos a atributos (getField e getDeclaredField), classes internas (getClasses e getDeclaredClasses), construtores (getConstructore getDeclaredConstructor) e por fim anotações (getAnnotations e getDeclaredAnnotations).

Uma vez retornados, realiza-se uma chamada ao método setAccessible passando como parâmetro true bastando isso para torná-lo acessível. Então lembre-se, a partir de hoje, pense duas vezes em abrir código, modificá-lo e recompilá-lo!! Há situações em que uma simples reflexão resolve.

Adicionando/Subtraindo periodos de tempo às datas com JAVA

September 2, 2009

Há pouco tempo atrás um colega me perguntou se havia alguma maneira de adicionar/subtrair dias, meses, anos, etc. às datas (quando se está trabalhando com JAVA) sem ter que lançar mão de trechos de código como o logo abaixo

calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);

cara.. isso é no mínimo horrível, sem falar que não tratado corretamente torna-se um ERRO CRASSO que pode constar numa aplicação e passar desapercebida por algum tempo (por algum tempo e só por algum tempo…), vide adicionar 1 dia à data 28 de fevereiro (calendário gregoriano) via esse trecho de código mal feito acima. Vocês podem imaginar o que pode acontecer.. tratamento para bisexto, tratamento para virada de mês, de ano, que chatisse!

Enquanto não sai JAVA 1.7 que terá a implementação da JSR-310 que trará inúmeras inovações no tratamento de entidades relacionadas ao tempo, usem o velho e bom Calendar ao invés!

 Date now = new Date();
 System.out.println("Data de hoje:\t" + now); 
 // prints Data de hoje:    Wed Sep 02 03:24:12 GMT-00:03 2009

 Calendar calendar = new GregorianCalendar();

 // subtraindo dias
 calendar.add(Calendar.DAY_OF_MONTH, -1);
 System.out.println("Date de ontem:\t" + calendar.getTime());
 // prints Date de ontem:    Tue Sep 01 03:24:12 GMT-00:03 2009

 // adicionando dias
 calendar.setTime(now);
 calendar.add(Calendar.DAY_OF_MONTH, 1);
 System.out.println("Date de amanha:\t" + calendar.getTime());
 // prints Date de amanha:    Thu Sep 03 03:24:12 GMT-00:03 2009 

Ordenando JAR loading através do WebappClassloader do Tomcat 5

August 11, 2009

No post anterior tratei de como funcionam os classloaders, algo que tira o sono de muitos programadores JAVA. Se você, leitor, não entende bem o que são os classloaders ou como é o modelo de delegação num servidor de aplicação (que implementa a partir da especificação Servlet Specification versão 2.3, vide seção 9.7.2) recomendo que leia o post anterior (Understanding Classloaders) para que possa compreender os conceitos que serão expostos a seguir.

Para você não perder seu precioso tempo lendo o que possa não o interessar, vou fazer uma pergunta e se sua resposta for “sim” este post é sim do seu interesse: você já precisou forçar a ordem de loading de um JAR na sua aplicação web (leia-se dentro do diretório webapps) para que uma classe X específica (ou mais de uma) definida em um ou mais JARs fosse carregada? Se não entendeu, vou ser mais claro. Vamos supor que há a classe foo.X presente no arquivo app1.jar e presente também no app2.jar e ambos JARs estão no /WEB-INF/lib da sua aplicação mas você redefiniu sua classe foo.X no app2.jar e precisa que ela seja carregado (para que esta versão do tipo seja a carregada pela JVM) antes do app1.jar pois a foo.X deste último está depreciada. No comportamento default do tomcat o app1.jar será carregado antes do app2.jar o que tornaria sua empreitada um fracasso. Diante do cenário exposto posso agora perguntar novamente: você já se deparou com essa situação?

– SIM!!!

Então vamos lá…

Durante todo este post sempre que tratar de tomcat será o tomcat 5.5, no entanto o que for dito aqui funciona para o tomcat 6 e muito provavelmente para as futuras versões, mantendo-se as devidas restrições de implementação, claro.

Foi necessário fuçar o código que implementa o tomcat – algumas partes em específico, como o bootstrap.jar e principalmente o catalina.jar – para que pudesse entender como este realizava a rotina de loading dos arquivos JAR e class contidos nos vários repositório existentes.

Após muitas xícaras de café, googling, deep inside tomcat source consegui resolver um problema que tenho certeza que afeta programadores J2EE de aplicações de nível alto. Modificando o código do tomcat foi possível ordenar da maneira como quis o loading dos JARs – o que também vale para os class e os resources. Existe um método na class org.apache.WEBCLASSLOADER setRepositories() que é o ponto x da questão tratada neste post. É ele – depois de alterado – que será mostrado a seguir.

Read the rest of this entry »

Understanding classloaders

August 1, 2009

Havia algum tempo que eu vinha estudando sobre o problema que é conhecido como classloader hell e, como todo problema complexo, levei tempo razoável para dar ao menos uma solução viável.

Pesquisei bastante em sites (Understanding J2EE … Loading Architectures, Classloaders) e blogs como o de Daniel que tem o ótimo post Classloading … que me auxiliaram no desafio imposto a mim mesmo. E após várias noites mal dormidas e deadlines da minha monografia estourados, resolvi que ia deixar essa pesquisa para depois.

Algum tempo depois, após ouvir uma conversa de dois colegas de trabalho – eles se perguntavam qual a lógica de carregamento dos .jar no Tomcat–, resolvi continuar minha pesquisa.

Enfim vamos ao que interessa:

Muitos programadores certamente nunca se depararam com o problema tratado nesse post. Se você nunca se perguntou como uma classe é carregada ou nunca enfrentou problemas de ClassCastException onde se tem certeza de que o casting está correto, provavelmente esse post não é interessante para você no momento, mas recomendo que leia pois um dia precisará desses conhecimentos.

De início, você deverá entender que tipo e classe são coisas diferentes (por mais que nós, desenvolvedores, utilizemos tais termos como sendo uma coisa só). Um tipo (java.lang.reflect.Type) é o nome completo de uma entidade formal JAVA (o que comumente chamamos de classe) que não é a mesma coisa de uma classe (java.lang.Class). Para o dia-a-dia do desenvolvedor pode-se utilizar esses dois termos se referindo à mesma coisa sem medo de errar, pois Class implementa Type, então uma Class é um Type. Mas para nossa abordagem, vamos diferenciar um do outro, uma Class para nós será um Type carregado por um Classloader, ou seja, uma classe é um tipo dentro de um contexto específico. Exemplo: com.example.Person é um tipo e não uma classe, este só será uma instância de um java.lang.Class depois de carregado por um ClassLoader. Read the rest of this entry »

PHP e as referências

August 1, 2009

Nos primórdios da sua fase de criação, PHP não tinha como objetivo ser uma ferramenta poderosa que resolvesse todos os problemas da vida de um programador WEB, muito menos pretendia compreender os conceitos de OO – os quais estavam ganhando fama na época de sua concepção. Foi criada por Rasmus Lerdorf em 1995, e na verdade se chamava PHP/FI e só tinha como ambição exibir estatísticas de acesso para o currículo on-line do criador.

O que aconteceu foi: mais funcionalidades foram requeridas e Rasmus continuou implementando, até que em 1997, PHP foi rescrito por Andi Gutmans e Zeev Suraski e assim descontinuando o PHP/FI 2.0.

E assim o PHP foi crescendo. Mas sempre visando ser simples, não burocrática, flexível, por isso não foram adicionados conceitos como: tipagem forte (até PHP 4 a tipagem é fraquíssima) e encapsulamento.

Concordo que em certos momentos, uma linguagem como PHP é perfeita, pois em poucas linhas de códigos se resolve um problema relativamente grande. Porém, há ocasiões em que o programador arrepende-se de ter usado PHP. Um exemplo a seguir: o PHP em seus scripts armazena valor de uma variável, mesmo que a variável guarde um “objeto”, ao invés de sua referência na memória. Muitos devem estar pensando: “ah! Mas tem como trabalhar com referências e não valores”, concordo, mas torna a codificação cansativa e perigosa. Read the rest of this entry »


Follow

Get every new post delivered to your Inbox.