
O Grupo de Usuários Java do Rio Grande do Sul (RSJUG), promove no dia 13 de dezembro o evento JUG Day, um dia inteiro dedicado à tecnologia Java.
O JUG Day é um evento semestral do RSJUG e conta com o apoio da SUCESU/RS. Esta edição ocorrerá nas instalações do Campus Tecnológico DC Shopping, do IPA Metodista, contando com uma grade de programação que envolve temas atuais no cenário Java, além de tutoriais de nível iniciante e intermediário, com o objetivo de promover a integração entre os participantes e difusão do conhecimento.
As inscrições estão abertas no site oficial (http://jugday.rsjug.org) com valor promocional de R$ 20,00 entre os dias 12 e 27 de novembro. Estudantes e associados SUCESU-RS têm desconto de R$5,00.
Tags: evento, propaganda, rsjug
Yeap, exatamente isto, a dica ta meio atrasada, mas só me registrei para fazer a prova hoje.
Para quem já tem a certificação SCJP (Sun Certified Java Programmer), pode fazer até o próximo dia 10/12/2008 “di gratis” a prova beta da nova certificação da SUN.
Não acredito que certificação prove alguma coisa, mas sempre ajuda colocar mais uma sigla no currículo, já que as empresas gostam delas por algum motivo
Quem quiser se inscrever, basta ligar para qualquer centro prometric ou acessar a página da prometric diretamente, não é necessário um voucher paraesta prova.
O conteúdo que estão pedindo não é nada demais para quem já trabalha com web services, segue o outline:
Mais informações na página da certificação.
Depois da prova (vou fazer dia 10) eu posto o que achei das questões por aqui.
Tags: certificação, Java, Java EE
Acabei de atualizar o WP e aproveitei para mudar o tema do blog também.
Acho que este é mais clean que o anterior.
O que vocês acham?
Sei que a maior parte lê só pelo feed mesmo, mas agradeço comentários.
Vou pensar em tirar uma das barras laterais, mas por enquanto ficam duas mesmo
Continuando com a seqüência de posts com títulos polêmicos que comecei dizendo que “Comentário no código é para os fracos“, segue um curso básico de refactoring para quem é pobre (por que vou utilizar o eclipse que é uma excelente IDE e alem de tudo é “di grátis”), e preguiçoso, por que o eclipse vai fazer quase todo o trabalho para nós.
O ponto de partida vai ser o “exercício” que deixei no final do post sobre comentários no código.
Par quem não quiser ler todo o outro post, o código inicial vai ser este abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package blog; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class VeryBadlyNamedFile { private static final char[] asdfg = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'}; private String an; private BufferedReader rfsdw; private FileReader temp; public VeryBadlyNamedFile(String an, BufferedReader rfsdw, FileReader temp) { super(); this.an = an; this.rfsdw = rfsdw; this.temp = temp; } public void doIt() throws IOException { ctfiidne(); startDoing(); try { canIDoAnyThing(); } catch (RuntimeException yicdet) { nowReallyDoIt(); } } private void nowReallyDoIt() { firstDoTheOtherThing(); reallyDoItInternal(); } private void firstDoTheOtherThing() { rfsdw = new BufferedReader(temp); } private void reallyDoItInternal() { while (true) { try { imDoingIt(); } catch (Exception e) { break; } } } private void imDoingIt() throws Exception { String s = rfsdw.readLine(); if (s == null) throw new Exception("hahaha, I bet you did not understood the code"); System.out.println(s); } private void ctfiidne() throws IOException { File a = new File(an); if (!a.exists()) { FileWriter wrfedsd = new FileWriter(a); wrfedsd.write(asdfg); wrfedsd.close(); } } private void canIDoAnyThing() { if (new File(an).exists() && new File(an).canRead() && new File(an).canWrite()) throw new RuntimeException(); } private void startDoing() throws FileNotFoundException { File f = new File(an); temp = new FileReader(f); } } |
Antes de começar o refactoring, vamos definir o que é refactoring de uma forma bem simples:
Refactoring = Alterar partes do código de uma aplicação sem quebrar outras partes da aplicação que dependam daquele código.
Refactoring é uma forma de melhorar o design de um código existente enquanto ele continua funcionando.
Gosto muito de uma frase espetacular do Fowler, um dos papas do desenvolvimento ágil, que coloco abaixo:
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999
Nos vamos utilizar os recursos de refactoring do Eclipse para transformar este lixo acima em alguma coisa legível, mantendo exatamente o mesmo comportamento, ou seja, sem quebrar o código que já funciona.
Para facilitar o trabalho, este tutorial (se é que pode ser chamado de tutorial), vai ser um simples “passo a passo” que eu utilizei para alterar este código no Eclipse, que é a minha segunda IDE preferida (a melhor de todas na minha opinião é o IntelliJ IDEA, mas se eu utilizasse este, não seria um tutorial para quem é pobre
)
Siga os passos abaixo:
1 | fileLineReader.useDelimiter("\n"); |
1 2 3 4 5 6 7 8 9 | Iterable<String> lineIterator = new Iterable<String>(){ @Override public Iterator<String> iterator() { return fileLineReader; } }; for(String line : lineIterator){ System.out.println(line); } |
1 2 3 4 5 6 7 | File file = new File(fileName); boolean fileExists = file.exists(); if (!fileExists) { FileWriter fileWriter = new FileWriter(file); fileWriter.write(conteudoPadraoParaNovoArquivo); fileWriter.close(); } |
Pronto, o Eclipse acabou de nos ajudar a ter um código menos porco na classe do post sobre comentários de código.
Claro que o código ainda não esta nenhum primor, mas a idéia deste post era mostrar que é possível utilizar recursos da IDE para facilitar o refactoring de código porco quando este for encontrado.
E não se iluda, se você estuda para melhorar o seu conhecimento sobre desenvolvimento e ser um profissional cada vez melhor, provavelmente o código que você escreveu a dois meses atrás você ache muito ruim hoje.
Só para finalizar o post, o seu código deve ter ficado parecido com este:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | package blog; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import java.util.Scanner; public class TextFileToScreenPrinter { private static final char[] standardContentForNewFiles = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'}; private String fileName; private Scanner fileLineReader; public TextFileToScreenPrinter(String fileName) { super(); this.fileName = fileName; } public void doIt() throws IOException { ensureFileAlreadyExists(); abortIfCanNotReadOrWriteFile(); printEachLineFromFileToConsole(); } private void printEachLineFromFileToConsole() throws FileNotFoundException { createLineReader(); forEachLineInTheFilePrintItOnTheScreen(); } private void createLineReader() throws FileNotFoundException { fileLineReader = new Scanner(new File(fileName)); fileLineReader.useDelimiter("\n"); } private void forEachLineInTheFilePrintItOnTheScreen() { Iterable<String> linesInTheFile = initializeLineIteratorFromLineReader(); for(String line : linesInTheFile){ System.out.println(line); } } private Iterable<String> initializeLineIteratorFromLineReader() { Iterable<String> lineIterator = new Iterable<String>(){ @Override public Iterator<String> iterator() { return fileLineReader; } }; return lineIterator; } private void ensureFileAlreadyExists() throws IOException { File file = new File(fileName); boolean fileExists = file.exists(); if (!fileExists) { FileWriter fileWriter = new FileWriter(file); fileWriter.write(standardContentForNewFiles); fileWriter.close(); } } private void abortIfCanNotReadOrWriteFile() { boolean fileExists = new File(fileName).exists(); boolean canReadTheFile = new File(fileName).canRead(); boolean canWriteToTheFile = new File(fileName).canWrite(); if (!fileExists && !canReadTheFile && !canWriteToTheFile) throw new RuntimeException(); } } |
E o atalho de teclado mais mágico de todos é:
COMMAND+SHIFT+L (CTRL+SHIFT+L em PCs) -> Lista os atalhos de teclado.
Acho que isto já esta bom para começar, se você for realmente um preguiçoso inteligente (o tipo que passa um pouco mais de tempo pensando para ter uma solução melhor agora e trabalhar menos no futuro), provavelmente você vai prestar atenção nos menus do eclipse e vai ir decorando as teclas de atalho com o tempo
PS.: Será que alguém vai ficar ofendido com o titulo deste post e vai ficar reclamando que não é pobre ou não é preguiçoso?
Tags: Eclipse, Java, livro2, refactoring
É isto mesmo, Star Trek “The Movie” dia 8 de maio de 2009 nos cinemas!
Deem uma olhada no site http://www.startrekmovie.com/.
Vai ser espetacular o filme, é o primeiro filme que conta um pouco de antes de construirem a USS Enterprise (fora as viagens para o passado durante os seriados).
Um trailer
Outro trailer
E ainda hoje deve sair mais um trailer no site oficial do filme http://www.startrekmovie.com/.
Este eu quero ver
Tags: filme
Provavelmente serei crucificado por causa deste post, mas se você se der ao trabalho de ler até o final, provavelmente vai concordar comigo que comentários no código são para os fracos, programador hardcore de verdade escreve código legível!
É exatamente isto que eu estou dizendo, por exemplo, o que faz o código abaixo?
1 2 3 4 5 6 7 8 9 10 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
Difícil? E este ainda é um código simples, mas vamos dar uma melhorada nele …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public String read(StringBuilder fle, StringBuffer con) { //Opens the file with the name container in the fle parameter File f = new File(fle.toString()); //Create a file reader, then a buffered reader to make our work easier FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; //Read each line of the file until it is null while((lin=br.readLine())!=null){ //Put the content read into the buffer pointed by the parameter "con" con.append(lin).append("\n"); } //The caller already have the content, because he created the buffer, but I'll return the string anyway return con.toString(); } |
Mais fácil certo? Bastou ler os comentários, mas o código continua um lixo.
Ou seja, esta é uma gambiarra utilizada por péssimos programadores para contornar a própria limitação de não conseguir escrever um código decente.
Então qual a solução que eu recomendo?
Vamos tentar reescrever este método então:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public String readFileContents(File fileToRead) { boolean canReadFile = fileToRead.exists(); if(!canReadFile) return ""; StringBuilder buffer = new StringBuilder(); BufferedReader readerForFile = openBufferedReaderForFile(fileToRead); readFileContetIntoBuffer(buffer,readerForFile); closeFileReader(readerForFile); return buffer.toString(); } private BufferedReader openBufferedReaderForFile(File fileToRead){ return new BufferedReader(new FileReader(fileToRead)); } private void readFileContetIntoBuffer(buffer,readerForFile){ String line; while((line=readerForFile.readLine())!=null){ buffer.append(line).append("\n"); } } private void closeFileReader(readerForFile){ readerForFile.close(); } |
Agora se você prestar atenção no nome do método “readFileContents” já vai saber o que o método faz, Além disto, o código do método é quase legível em inglês. A leitura dele ficaria mais ou menos assim:
if not can read file, return null
open Buffered Reader For File: fileToRead
read File Contet Into Buffer: buffer, readerForFile
close File Reader: readerForFile
return buffer.toString();
Ou seja, qualquer um que entenda inglês, como qualquer desenvolvedor tem a obrigação de entender, vai ler o método como se fosse um comentário.
E eu já vi gente fazendo pior do que isto, o código tinha comentários, mas parecia com esta coisa ai em baixo:
1 2 3 4 5 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
Com certeza tinha muito menos linhas de código do que a minha versão ![]()
Mas não é uma tarefa fácil entender o código que uma criatura destas escreve
Claro que o exemplo que eu apresentei foi um exemplo bem simples, e que escrever código legível requer uma certa prática …
Então, vou fazer uma proposta:
Vou deixar um exemplo de código abaixo, e vocês tentam torna-lo mais legível. Em um ou dois dias eu posto a minha resposta aqui.
Quem quiser pode postar nos comentários o código que escreveu.
Para que o código fique colorido no blog, basta colocar dentro de uma tag <pre lang=”java” line=”1″> … </pre>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package blog; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class VeryBadlyNamedFile { private static final char[] asdfg = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'}; private String an; private BufferedReader rfsdw; private FileReader temp; public VeryBadlyNamedFile(String an, BufferedReader rfsdw, FileReader temp) { super(); this.an = an; this.rfsdw = rfsdw; this.temp = temp; } public void doIt() throws IOException { ctfiidne(); startDoing(); try { canIDoAnyThing(); } catch (RuntimeException yicdet) { nowReallyDoIt(); } } private void nowReallyDoIt() { firstDoTheOtherThing(); reallyDoItInternal(); } private void firstDoTheOtherThing() { rfsdw = new BufferedReader(temp); } private void reallyDoItInternal() { while (true) { try { imDoingIt(); } catch (Exception e) { break; } } } private void imDoingIt() throws Exception { String s = rfsdw.readLine(); if (s == null) throw new Exception("hahaha, I bet you did not understood the code"); System.out.println(s); } private void ctfiidne() throws IOException { File a = new File(an); if (!a.exists()) { FileWriter wrfedsd = new FileWriter(a); wrfedsd.write(asdfg); wrfedsd.close(); } } private void canIDoAnyThing() { if (new File(an).exists() && new File(an).canRead() && new File(an).canWrite()) throw new RuntimeException(); } private void startDoing() throws FileNotFoundException { File f = new File(an); temp = new FileReader(f); } } |
E agora um “main” só para executar o lixão acima.
1 2 3 4 5 6 7 8 9 | package blog; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { new VeryBadlyNamedFile("c:\\anyFile.any",null,null).doIt(); } } |
Os exemplos estão em java, mas em qualquer linguagem os comentários para explicar o código servem para mascarar a incapacidade dos programadores escreverem código decente.
PS.: Só para constar, eu não acho de verdade que vocês não devem comentar o código, mas se vocês não escrevem código legível, ou escrevem código que realmente precisa de um comentário para outro programador entender, então vocês não aprenderam a programar ainda!
PS2.: só para constar, o código deste post foi inventado na hora, inspirado em coisas que ja vi em diversos lugares por ai, masescrevi ele direto no blog, então existe uma grande possibilidade de não compilar.
PS3.: acho que preciso de exemplos melhores, mas vocês devem ter entendido a idéia deste post
Tags: dicas, livro2, produtividade, refactoring
O Java EE esta cada vez mais simples de se utilizar, então por definição esta cada vez melhor.
O motivo deste post são algumas melhorias vindas da especificação do EJB 3.1 que eu achei espetaculares:
Interface local opcional
Exatamente isto, agora a interface local dos EJBs é Opcional. Isto permite que o seguinte código seja válido:
1 2 3 4 | @Stateless public class HelloBean { public String hello() { return "hello"; } } |
E o cliente utiliza isto mais ou menos assim:
1 2 3 | @EJB Hello helloRef; ... helloRef.hello(); |
Mesmo a classe sendo acessada diretamente, o cliente nunca instância o objeto com um “new”, ele recebe um proxy, exatamente como se estivesse trabalhando com uma interface, mas mesmo assim o modelo fica mais simples e é menos trabalho para o programador
Nomes globais JNDI portáveis
Não sei se fui apenas eu, mas é um inferno desenvolver aplicações Java EE que precisem acessar EJBs em mais de um container, exceto se elas puderem fazer isto via anotações o que não cobre 100% dos casos, cada container utiliza um nome global diferente para o EJB, agora no Java EE 6 o nome global dos EJBs faz parte da especificação, então vai ser igual para todos os containers ![]()
Só quero ver como eles vão fazer para manter a compatibilidade com versões anteriores dos mesmos containers, acho que os EJBs vão ter nome e apelido ![]()
A sintaxe para os nomes globais dos EJBs vai ser a seguinte:
java:global[/<app-name>]/<module-name>/<bean-name>
E caso o session bean exponha mais de uma interface, o nome vai ser:
java:global[/<app-name>]/<module-name>/<bean-name>/<intf-name>
Isto quer dizer que para o EJB abaixo:
1 2 | @Stateless public class FooBean implements FooRemote { ... } |
Publicado em um arquivo de nome foobar.jar, podemos acessa-lo com o seguinte código:
1 | FooRemote foo = (FooRemote) = new InitialContext().lookup("java:global/foobar/FooBean") |
E acabou o nome especifico para cada container, ou pior, nome para cada deployment como alguns containers faziam.
Empacotamento de EJBs Simplificado
No Java EE 6 não será mais necessário em uma aplicação criar um .war para a aplicação web, um .jar para os EJBs e empacotar tudo isto em um .ear só para acessar alguns EJBs pela aplicação WEB, vai bastar colocar os EJBs dentro do WEB-INF/classes ou até mesmo em um jar dentro do WEB-INF/lib da aplicação WEB e tudo vai funcionar como mágica
Singleton EJBs
Esta última novidade eu não sei se é boa ou ruim …
Singletons são a forma mais podre de programação não orientada a objetos em uma linguagem OO.
Claro que em raros casos um singleton é realmente utilizado como um singleton e neste caso ele é realmente útil, mas eu vi apenas uns dois ou três casos destes até hoje, todas as outras aplicações que tem diversos singletons utilizam os mesmos como um repositório de métodos que não pertencem a objeto nenhum. Ou seja, uma entidade não OO na aplicação …
Mas fora a discussão filosófica, o pior é achar que você tem um singleton e a aplicação possuir duas instâncias do mesmo, por que na implementação clássica de singletons no java, eles são singletons apenas por classloader, o que causa diversos problemas …
Para solucionar este problema, o Java EE 6 possui EJBs Singletons ![]()
Exatamente isto.
Eles são utilizados como qualquer outro EJB, mas existira apenas uma instância dele no container ou no cluster, ou seja, apenas uma instância na aplicação …
Para criar um EJB Singleton, o código vai ser mais ou menos este:
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.sun.ejb31.test; import javax.ejb.Singleton; @Singleton public class CounterBean { private int hitCount; //Perceba a utilização de synchronized aqui public synchronized int incrementAndGetHitCount() { return hitCount++; } } |
E era isto, utilize como no primeiro exemplo!
Bom, por enquanto era isto, estou achando que o Java EE 6 vai matar a pau, ainda mais juntando com a especificação de WebBeans que deve sair junto!
Em todos os meus trabalhos com Ruby On Rails até agora eu não achei necessária uma IDE, pois eu sempre fui mais produtivo com simples editores de texto (tudo bem, não eram editores tão simples assim), As IDEs eram sempre lentas, muito mais lentas que os editores de texto. Mas o pessoal da JetBrains se superou, na verdade não se superou, pois o IntelliJ IDEA ja é expetacular.
Mas o RubyMine é a IDE para Rails mais rápida até agora, com performance similar ao GEdit e GVim que são os meus editores favoritos (mesmo preferindo o KDE não consigo me acostumar com o Kate).
Eu não sei direito como eles fizeram, mas o code completion para Ruby e Rails esta muito rápido.
A IDE ficou Leve, o que é uma novidade interessante, pois o IntelliJ IDEA é quase tão pesado quanto o Eclipse.
E o melhor de tudo! O RubyMine tem Refactorings para código Ruby, coisa que não encontrei em nenhuma outra IDE (o NetBeans tem algumas tentativas, mas no meu último teste não funcionaram muito bem).
Bom, segue então uma lista do que faz o RubyMine ser uma ótima IDE para desenvolvimento Rails na minha opinião, com alguns screenshots ![]()




Isto fora os recursos ja conhecidos do IntelliJ IDEA para edição de HTML e Javascript, com refactorings para ambos. E o fato de o RubyMine ser a IDE mais rápida para Ruby que eu encontrei até agora. Fazem ela ser a minha preferida desde ontem também
Claro que trabalhei com ela muito pouco tempo, mas mesmo assim, ja gostei bastante do que vi.
Só falta ver como vão ficar os preços, ja que é uma IDE comercial.
Se o preço for bom, por exemplo, próximo ao preço do TextMate, vai valer a pena com certeza!
Tags: ide, intellij, jetbrains, rails, Review, Ruby, rubymine

E só pra constar, ele esta mais rápido do que as versões do KDE3 que eu estava utilizando antes.
Então se estiver com o mesmo problema, é só fazer o mesmo.
PS.: parece que isto faz o KDE não reconhecer monitores conectados ao computador depois dele ligado, mas ai é só ativar e desativar o serviço quando necessário, eu vou testar ligando o note na televisão em casa no findi e atualizo o post dizendo o que aconteceu.