Editores Osvaldo Doederlein Eduardo Spínola

Tamanho: px
Começar a partir da página:

Download "Editores Osvaldo Doederlein (osvaldo@javamagazine.com.br) Eduardo Spínola (eduspinola@gmail.com)"

Transcrição

1

2 Editores Osvaldo Doederlein Eduardo Spínola Arte Diagramação - Romulo Araujo Capa - Antonio Xavier Produção Gerência de Marketing - Kaline Dolabella Atendimento ao leitor A DevMedia possui uma Central de Atendimento on-line, onde você pode tirar suas dúvidas sobre serviços, enviar críticas e sugestões e falar com um de nossos atendentes. Através da nossa central também é possível alterar dados cadastrais, consultar o status de assinaturas e conferir a data de envio de suas revistas. Acesse ou se preferir entre em contato conosco através do telefone Edições anteriores Adquira as edições anteriores da revista Java Magazine ou de qualquer outra publicação do Grupo DevMedia de forma prática e segura, em Publicidade Anúncios - Anunciando nas publicações e nos sites do Grupo DevMedia, você divulga sua marca ou produto para mais de 100 mil desenvolvedores de todo o Brasil, em mais de 200 cidades. Solicite nossos Media Kits, com detalhes sobre preços e formatos de anúncios. Java, o logotipo da xícara de café Java e todas as marcas e logotipos baseados em ou referentes a Java são marcas comerciais ou marcas registradas da Sun Microsystems, Inc. nos Estados Unidos e em outros países.

3 ÍNDICE [Easy Java, Core] Um pouco de Groovy Uma linguagem de scripts simples e 100% compatível com Java Marcelo Castellani [Core, Web] JBoss Application Server 5 As principais novidades do JBoss AS 5 Bruno Rossetto Machado e João Paulo Viragine [Web, Tutorial] Spring Security Segurança simples, poderosa e portável - à moda do SpringFramework Michel Zanini [Core, Web, Mobile] JavaFX Script Uma referência didática da linguagem JavaFX Script, uma das principais peças da plataforma JavaFX Osvaldo Pinali Doederlein [Vanguarda, Core] Novos tempos: javax.time A nova API de Data e Hora, que facilita a programação e corrige falhas históricas das suas antecessoras Daniel Cicero Amadei e Michael Nascimento Santos [Mobile] Java ME Platform SDK 3 As novidades do novo SDK para Java ME, que substitui o antigo Wireless Toolkit Ernandes Mourão Júnior [Boas Práticas] Estratégias de Integração de Aplicações Java EE Melhores práticas de interoperabilidade Java para o desenvolvimento de aplicações robustas Marco Aurélio de Souza Mendes [Core, Expert] Estratégias de Integração de Aplicações Java EE Desenvolvendo aplicações concorrentes estáveis e escaláveis com a java.util.concurrent Ronaldo Blanch Rocha

4 Um pouco de Groovy Marcelo Castellani Marcelo Castellani é analista de sistemas sênior na Itautec S/A e atua na área de desenvolvimento desde 1996, passando por linguagens como Visual Basic, C, C++ e Java. Mantém o blog hype quino (www.hypequino.com) aonde fala de novas tecnologias em matérias curtas. De que se trata o artigo: Apresenta uma introdução a linguagem dinâmica Groovy, que possibilita ter uma produtividade de linguagens dinâmicas como Python e Ruby dentro da máquina virtual Java, sem emendas. Para que serve: Tornar o desenvolvimento em Java mais rápido e produtivo, além de apresentar novos conceitos, como closures, não disponíveis na linguagem Java, que podem facilitar a vida do desenvolvedor em tarefas corriqueiras. Em que situação o tema é útil: Para agilizar o desenvolvimento de aplicações Java, otimizando situações onde a mesma é muito verbosa, como manipulação de XML por exemplo. Groovy possibilita, através de mecanismos como closures, uma sintaxe mais limpa e produtividade em alto nível. Um pouco de Groovy: É possível programar para a plataforma Java sem usar a linguagem Java, e ainda por cima ser extremamente produtivo. Groovy é uma linguagem dinâmica, flexível e que se integra com Java sem emendas, além de fornecer recursos como closures e atribute accessors, não disponíveis na linguagem padrão da JVM. Groovy, ao contrario de outras linguagens dinâmicas, possibilita gerar bytecodes Java e possibilita o uso de toda a infra-estrutura já desenvolvida para suas aplicações. Introdução Linguagens dinâmicas estão na moda já há algum tempo. Desde o advento de frameworks de alta produtividade como o Ruby on Rails e o Django, linguagens como Ruby e Python saíram de seus nichos e passaram a fazer parte das rodinhas de conversa de desenvolvedores Java, outrora um tanto quanto seletivos. Esses, então, descobriram um admirável novo mundo, com closures, tipos de dados complexos e facilidades que não existem na sua linguagem preferida. Foi mais ou menos nesse meio que surgiu o embrião do que viria a ser o Groovy. Como tudo começou No dia 29 de agosto de 2003 James Strachan publicou em seu blog o primeiro artigo sobre aquilo que viria a ser o Groovy (veja em Links o endereço do post). Ele deixava bem claro as suas intenções na época: minha idéia inicial é fazer uma pequena linguagem dinâmica, que seja compilada diretamente em classes Java e que tenha toda a produtividade elegante encontrada em Ruby e Python, mas que permita reusar, estender, implementar e testar código Java já existente. James procurava uma linguagem dinâmica para desenvolver em plataforma Java, e em seu post ele deixava claro que as opções da época não eram interessantes. Ele não queria apenas uma linguagem dinâmica, mas sim algo que pudesse ser integrado ao que ele já tinha pronto em Java, algo que acelerasse seu desenvolvimento e que não o obrigasse a jogar tudo o que tinha de código Java já pronto e testado (e em produção) no lixo. Enfim, ele queria algo que não existia na época. Mas como querer é poder, James uniu-se a Bob McWhirter e juntos fundaram o projeto Groovy em Logo, com um grupo de pessoas que compartilhavam da mesma idéia, iniciaram o desenvolvimento da linguagem. Foi em 2004, com a fundação do GroovyOne e a entrada de outros desenvolvedores (entre eles Guillaume Laforge hoje o mantenedor do projeto) que a coisa decolou. Foi criada a Groovy Language Specification (GLS) e o kit para testes de compatibilidade (o TCK), além do parser básico da linguagem. O embrião do projeto estava pronto e a partir daí não teria mais como voltar atrás.groovy

5 evoluiu desconhecido por algum tempo, e até dezembro de 2007 várias versões foram lançadas sob o número 1.1.x. Em 7 de dezembro de 2007 a versão final da família 1.1 foi lançada, e então nomeada Groovy 1.5 devido às diversas modificações realizadas na mesma. Hoje a linguagem é uma especificação do JCP (JSR 241) e é considerada a segunda linguagem oficial da plataforma.ao contrario do que alguns pensam, Groovy não é um concorrente do Java, mas uma ferramenta de apoio, como veremos neste artigo. O que é Groovy? O web site oficial da linguagem possui uma das melhores definições sobre a linguagem, a qual reproduzo a seguir: Groovy é uma linguagem ágil e dinâmica para a Plataforma Java com recursos que são inspirados em linguagens como Python, Ruby e Smalltalk, tornando-os disponíveis aos programadores Java, usando uma sintaxe mais próxima do Java. Ou seja, Groovy possui uma sintaxe semelhante ao Java, mas com o poder de linguagens dinamicamente tipadas. Mas Groovy não é apenas uma linguagem de script. Groovy pode ser compilada, gerando bytecodes Java, ou seja, um arquivo de código fonte Groovy pode virar um arquivo.class (e esse recurso você não encontra por exemplo no JRuby). Isso garante que a única coisa que você precisa para rodar seus códigos Groovy no ambiente de produção é a máquina virtual Java (ou seja, nada mais do que usualmente já precisaria) e o jar com o runtime e API`s do Groovy. É comum dizer que Groovy roda integrado com o Java sem emendas, o que não acontece com seus concorrentes, por assim dizer. Mais do que isso, o Groovy é totalmente integrado ao Java no mais baixo nível. Por exemplo, se você instanciar um objeto do tipo Date em Groovy esse nada mais é do que uma instância de java.util.date. E tudo funciona de maneira transparente por que, por debaixo dos panos, tudo é bytecode Java. Aí você me pergunta ok, então pra que eu preciso disso?, e a resposta é simples: para facilitar sua vida. Groovy possui uma sintaxe mais simples e enxuta do que o Java, apesar de ainda parecer Java, e possui recursos poderosos que não são encontrados na linguagem Java, como closures.e Groovy possui um grande aliado, o Grails, um framework de produtividade baseado em Spring e Hibernate que permite o desenvolvimento de aplicações Java EE com a mesma agilidade do pessoal do Ruby on Rails (e sem configurar centenas de arquivos XML!). Outro ponto importante é que ambos, Groovy e Grails, são hoje propriedades da SpringSource, empresa que mantém o framework Spring. A empresa adquiriu a G2One, que cuidava de ambos, em 11 de novembro de 2008 e em seu site (novamente na seção Links) é possível ver uma nota interessante sobre o assunto. O que preciso para desenvolver em Groovy? Como qualquer outra linguagem, para desenvolver em Groovy você precisa de um editor de textos, de um interpretador/compilador e outras ferramentas. Felizmente o NetBeans nos fornece tudo o que precisamos (e até mais) num único pacote.o NetBeans é uma excelente IDE mantida pela Sun e desenvolvida por uma grande comunidade ao redor do mundo. Ela possui suporte nativo a Java, C/C++, PHP, JavaScript, Ruby e Groovy. Para este artigo vou usar a versão 6.5 da IDE rodando no Mac OS X versão Você pode baixar gratuitamente o NetBeans de seu site (veja o endereço no quadro Links). Caso deseje usar o Eclipse (que também suporta Groovy via plugins) ou outra IDE para testar os códigos deste artigo, ou mesmo um editor de textos simples como o GEdit do Gnome ou o Notepad do Windows, você deverá configurar o ambiente. Para isso recomendo que acesse a página do projeto na internet. Porém, caso ainda não use o NetBeans, dê uma chance a ele. Essa é a oportunidade de conhecer duas ferramentas novas e de alta qualidade ao mesmo tempo. Alô Mundo Vamos começar nossa viagem pelo admirável mundo novo do Groovy com um exemplo extremamente simples. Sou fã do tradicional Alô mundo, apesar de ser um exemplo simples para iniciar numa linguagem. No nosso caso ele será suficiente para apresentar muitos recursos, como attribute accessors, como usar Groovy dentro do Java e muito mais. Abra o NetBeans (ou o ambiente de sua escolha) e crie uma nova aplicação Java. Você verá uma categoria Groovy na janela de Novo Projeto, mas ela tem apenas um template para a criação de um projeto Grails. Como este não é o escopo deste artigo vamos ignorar essa categoria de projetos. Para isso use a categoria Java, como na Figura 1. Clique no botão Próximo e então informe um nome para seu aplicativo (eu usei o singelo nome AloMundoGroovy ) e selecione onde o deseja salvar. Clique em Finalizar e seu aplicativo será criado. Até agora não colocamos nem um pouco de Groovy no projeto, ele é um tradicional e simples projeto de aplicação Java que você já conhece.

6 Vamos adicionar então o Groovy ao projeto. Para isso clique com o botão de atalho do mouse sobre o projeto e selecione o menu Propriedades. Na janela que será aberta selecione o item Groovy na lista de categorias e marque a opção Ativar Groovy, como na Figura 2. Figura 1: Criação de um novo projeto Java. Figura 2: Adicionando Groovy ao projeto Agora nosso projeto já possui Groovy em sua estrutura. Perceba, na Figura 3, que, no grupo Categorias, no navegador do projeto, foi adicionado o groovy-all.jar, que é quem faz a mágica para nós.

7 Figura 3: Nosso projeto agora tem Groovy. Por padrão o NetBeans criará um arquivo.java no nosso projeto. Remova-o pois não o usaremos, e então crie um pacote chamado org.groovy.maonamassa para adicionarmos os códigos-fonte de nosso projeto. Dentro desse pacote adicione um novo JFrame e, na janela de design do NetBeans, adicione uma caixa de texto ao JFrame, como na Figura 4. Figura 4: Um JFrame com uma caixa de texto dentro. Agora vamos adicionar um arquivo.groovy em nosso projeto. Para isso clique sobre o pacote criado e clique com o botão de atalho do mouse. Selecione então a opção Novo>Outro, e na janela que será aberta, na categoria Groovy, selecione Classe do Groovy. Nomeie-a como considerar mais interessante, sem a necessidade de ser o nome da classe principal, pois Groovy não faz essa diferenciação como o Java. Vamos adicionar o código à nossa classe Groovy. Para isso, digite o código da Listagem 1. Listagem 1. Nossa classe Groovy package org.groovy.maonamassa class AloMundoGroovy { def saudacao = "Alô mundo, em Groovy!!!!"

8 Perceba que não usamos ponto-e-vírgula no final de nossa declaração, e que usamos a palavra reservada def na criação de nosso objeto (sim, objeto, da classe Object). O restante deve ser conhecido para programadores Java. Nossa classe Groovy está pronta para uso. Basta editarmos o código de nosso JFrame para colocar tudo em funcionamento. O código do JFrame deverá ficar como apresentado na Listagem 2. Listagem 2. O código de nosso JFrame package org.groovy.maonamassa; public class MostrarJFrame extends javax.swing.jframe { AloMundoGroovy meualomundo = new AloMundoGroovy(); /** Creates new form MostrarJFrame */ public MostrarJFrame() { initcomponents(); String alomundo = meualomundo. getsaudacao().tostring(); jtextfield1.settext(alomundo); /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. // private void initcomponents() { jtextfield1 = new javax.swing.jtextfield(); setdefaultcloseoperation(javax.swing. WindowConstants.EXIT_ON_CLOSE); getcontentpane().add(jtextfield1, java.awt.borderlayout.center); pack(); // /** args the command line arguments */ public static void main(string args[]) { java.awt.eventqueue.invokelater (new Runnable() { public void run() { new MostrarJFrame().setVisible(true); ); // Variables declaration -do not modify private javax.swing.jtextfield jtextfield1; // End of variables declaration Repare na linha em negrito, é nela que chamamos o método getsaudacao() de nossa classe Groovy. Se

9 você olhou o código da Listagem 1 e não achou esse método não se preocupe, ele é criado através de um recurso comum no Groovy e no Ruby, que é chamado attribute accessor. Esse recurso cria os getters e setters para propriedades de uma maneira simples e eficaz, sem excesso de código. Isso acontecerá sempre que você definir um membro de sua classe sem especificar a visibilidade (protected, public ou private): o Groovy o considera como uma propriedade e define automaticamente os getters e setters. A mesma classe da Listagem 1, escrita em Java, teria o dobro do tamanho. Veja na Listagem 3. Listagem 3. Nossa classe AloMundoGroovy em Java - um tanto quanto prolixo, não acha? package org.groovy.maonamassa; public class AloMundoJava { String saudacao = new String(); public String getsaudacao() { return saudacao; public void setsaudacao(string saudacao) { this.saudacao = saudacao; Note que parte de nosso projeto foi feito em Java (para tirar proveito do editor visual do IDE), mas uma parte foi feita em Groovy (e isso deixou as coisas mais simples - uma linha ao invés de sete), e ambos funcionam bem juntos, como é possível ver na Figura 5. Figura 5: Nosso projeto em execução. O leitor mais atento deve ter reparado no.tostring() junto ao nosso método getsaudacao(), mostrado na Listagem 2, o que mostra que tanto o getter como o setter de saudacao trabalham com um Object. Isso se deve ao fato de que não definimos o tipo de nosso objeto no momento da sua criação com o def. Listagem 4 e remova o.tostring() da Listagem 2. Verifique que agora ambos os métodos getter e setter trabalham com String e não com Object. É possível ser menos verboso ainda e deixar de utilizar o def, pois ele pode ser omitido quando especificamos o tipo do objeto. Listagem 4. Nossa classe Groovy modificada package org.groovy.maonamassa class AloMundoGroovy { // aqui você pode omitir o def def String saudacao = "Alô mundo, em Groovy!!!!"

10 GDK Assim como o Java possui a JDK, o Groovy possui a GDK. É fácil confundir-se quando pensamos nisso pois todo objeto Java pode ser usado dentro do Groovy, mas o contrario não é verdade. A GDK estende a JDK adicionando métodos que não existem originalmente nos objetos Java. Um exemplo seria como obter o tamanho de uma determinada instancia de uma classe. Em Java isso é bem confuso pois existem objetos que usam o método length() (como os que são instancias de arrays e Strings), outros usam o método size() (como os que são instancias de Collections e Maps). Temos até um getlength()(para java.lang.reflect.array) e o método groupcount(), para instancias da classe Matcher. Groovy, através de um dispositivo chamado MetaClass, possibilita que todos esses objetos utilizem um mesmo método para obter o tamanho de um objeto: o size(). Isso possibilita termos o código da Listagem 5, onde temos tanto um ArrayList quanto uma String usando o mesmo método, o size(). Listagem 5. O poder de fogo do GDK class TestaSize { public def imprime() { String teste = "isso é um teste" ArrayList meuarray = new ArrayList() meuarray.add(teste) println teste.size() println meuarray.size() Outra vantagem do GDK sobre a biblioteca padrão do Java é que Groovy não diferencia entre tipos primitivos e objetos. Em Groovy a expressão valor01 + valor02, considerando valor01 e valor02 do tipo java.lang.integer, retorna a soma dos dois inteiros. Mas o Groovy vai além, definindo uma equivalência entre operadores e métodos: no caso, a expressão acima será interpretada como valor01.plus(valor02). Se você quiser criar novas classes com suporte a operadores, basta definir nela o método que será chamado para cada operação (para + o método é o plus(), para - o método é o minus(), para ++ é next() e por aí vai - consulte a documentação do Groovy para a lista de métodos e operações correspondentes). Pense na utilidade prática disso. Quantas vezes você já não teve uma classe em que seria conveniente usar o operador + para somar uma instância com outra e teve que apelar para métodos mirabolantes como somaclasse() ou append()? Em Groovy basta definir o método correto e, ao avaliar a operação, o Groovy procura o método correspondente. Isso só é possível por que o Groovy usa o conceito de MetaClass apresentado acima. Quando o compilador encontra uma expressão como valor01 + valor02 num código Groovy, ele gera um bytecode diferente do que gera quando encontra essa mesma expressão num arquivo de código Java, pois chamadas de métodos são redirecionadas pelo MetaClass do objeto, o que possibilita ao Groovy interceptar, adicionar, redirecionar e remover código em tempo de execução. É esse truque que possibilita valor01 + valor02 tornar-se valor01.plus(valor02) em tempo de execução. Claro que todo esse poder tem um preço: um código Groovy é ligeiramente mais lento do que um código Java durante a execução, mas nada que torne proibitivo seu uso. Fazendo uma analogia, num comparativo com o desenvolvimento para sistemas operacionais, a JVM seria nosso sistema operacional, e ao desenvolver optaríamos por Java quando precisamos de velocidade, e por Groovy quando precisamos de facilidades e performance não é um dos requisitos principais. Pode parecer, com todo esse

11 parágrafo, que Groovy é um elefante pesado e lento, mas Groovy é apenas um pouco mais lento que Java. Na Listagem 6 é possível encontrar um exemplo de como sobrescrever o operador + através do uso do método plus(). Criei uma classe chamada SomaODobro que, quando tem duas instâncias somadas, realiza a adição e depois a multiplicação para retornar o resultado. Veja o código. Listagem 6. Usando o plus para aumentar o poder do + package org.groovy.maonamassa class SomaODobro { def Integer valorinicial public def plus(somaodobro outro) { return (valorinicial + outro.valorinicial) * 2 class AloMundoGroovy { public def testa() { SomaODobro valor01 = new SomaODobro() SomaODobro valor02 = new SomaODobro() valor01.valorinicial = 10 valor02.valorinicial = 20 println valor01 + valor02 É importante ressaltar que sim, é possível, em Groovy, ter mais de uma classe dentro de um arquivo de código fonte como visto acima. As classes podem, inclusive, ser públicas, ao contrário do Java, onde podemos ter apenas uma classe pública por arquivo. Veja nas Listagens 7 e 8 um exemplo simples. Listagem 7. Um arquivo Groovy com duas classes públicas package groovytest public class Carro { public def imprime() { println "Sou um carro" public class Moto { public def imprime() { println "Sou uma moto"

12 Listagem 8. Instanciando as classes Groovy package groovytest; public class Main { public static void main(string[] args) { Carro meucarro = new Carro(); Moto minhamoto = new Moto(); meucarro.imprime(); minhamoto.imprime(); Closures Um dos recursos mais úteis e apaixonantes de linguagens dinâmicas são os closures, ou fechamentos, ou blocos, que dão um poder de fogo enorme no desenvolvimento. Closures nada mais são do que pedaços de código tratados como objetos, e como tal podem receber parâmetros e retornar valores. E como a JVM não sabe se o código que está rodando é Groovy ou Java, é perfeitamente possível dizer que um closure é apenas mais objeto para a JVM, tal qual uma String ou um Integer. Uma aplicação robusta e poderosa de closure é na classe File da GDK. O Groovy estende o objeto File padrão do Java e adiciona um método eachline(), que recebe como parâmetro um closure: new File( arquivo.txt ).eachline { println it O closure nada mais é do que o bloco { println linha, que será executado para cada iteração de eachline(), ou seja, essa única linha abrirá um arquivo de texto chamado arquivo.txt, lerá linha por linha até o final e passará cada linha ao closure, que imprimirá o que recebeu na saída padrão usando o println() (o it representa a linha recebida). Tudo isso em apenas uma linha de código. Outro exemplo bem interessante é apresentado a seguir, onde temos um tipo de dado do Groovy (o Range, que é um intervalo representado com dois números separados por dois pontos simples, como em , que inclui os números de 1 a 100); e o método each(), que varre cada membro do Range, e depois executa a closure que o imprime. (1..10).each { println it Ok, mas o que é esse tal de it no meu código? Ele é uma variável conhecida como Magic variable, ou variável mágica, algo que não precisa ser declarado pra existir. it pode ser visto como um membro da classe que define os closures do Groovy, é ele quem recebe o parâmetro padrão quando esse não é declarado. Veja como fica a opção de uso de uma variável explícita no lugar da variável mágica. (1..10).each { valoratual -> println valoratual É o sinal de -> que separa a declaração de variáveis do corpo do closure. Mas closures não são úteis apenas para imprimir um valor na saída padrão, eles podem ser usados para operações complexas, sua imaginação é o limite. O poder dos closures Vamos criar um exemplo pra demonstrar um pouco do poder e da elegância do uso de closures. Crie um novo projeto Java e adicione Groovy a ele como visto anteriormente. Adicione uma nova classe Groovy chamada Aluno e então insira o código da Listagem 9. Listagem 9. A classe Aluno.groovy

13 package groovy2 class Aluno { // definimos as propriedades String nomealuno Integer matriculaaluno // variavel para a matriculo static int matricula = 0 // Construtor Aluno(String nome) { matricula = matricula + 1 this.setnomealuno(nome) this.setmatriculaaluno(matricula) public String tostring() { return "Matricula: " + this.getmatriculaaluno().tostring() + " Nome: " + this.getnomealuno() Nessa classe temos duas propriedades, o nome do aluno e o número de sua matrícula. O nome deverá ser informado no momento da criação do objeto, através de nosso construtor e o número da matrícula é sugerido através do uso de um membro estático que é incrementado a cada nova instancia criada (perceba que esse recurso não deve ser usado em situações reais, mas encaixa como uma luva nesse exemplo). Redefinimos também o método tostring(), para possibilitar uma impressão simplificada de nossos valores, quando necessário. Perceba que faço uso dos getters e setters sem os declarar pois, como foi visto antes, eles são criados automaticamente quando definimos membros de classe sem especificar sua visibilidade. Na Listagem 10 instanciamos, em um arquivo main.java três objetos de nossa classe e imprimimos seus dados, usando o tostring(). Listagem 10. A classe Main.java, instanciando três objetos aluno package groovy2; public class Main { public static void main(string[] args) {

14 Aluno aluno01 = new Aluno("Marcelo"); Aluno aluno02 = new Aluno("Giuliana"); Aluno aluno03 = new Aluno("Ana Beatriz"); System.out.println(aluno01.toString()); System.out.println(aluno02.toString()); System.out.println(aluno03.toString()); O resultado será algo como: Matricula: 1 Nome: Marcelo Matricula: 2 Nome: Giuliana Matricula: 3 Nome: Ana Beatriz Vamos agora criar, na Listagem 11, uma nova classe Groovy chamada Aula. Vamos utilizá-la para agrupar nossos alunos em aulas. Listagem 11. A classe Aula.groovy package groovy2 class Aula { ArrayList alunos = new ArrayList() def adicionaaluno(aluno nomealuno) { alunos.add(nomealuno) def removealuno(aluno nomealuno) { alunos.remove(nomealuno) def imprimelistaalunos() { alunos.each() { alunoatual -> println alunoatual.tostring() Modifique o arquivo Main.java para que fique como na Listagem 12. Listagem 12. A classe Main.java, modificada package groovy2; public class Main { public static void main(string[] args) {

15 Aluno aluno01 = new Aluno("Marcelo"); Aluno aluno02 = new Aluno("Giuliana"); Aluno aluno03 = new Aluno("Ana Beatriz"); Aula historia = new Aula(); historia.adicionaaluno(aluno01); historia.adicionaaluno(aluno02); historia.adicionaaluno(aluno03); historia.imprimelistaalunos(); Ao chamarmos o método imprimelistaalunos() faremos uso de um closure para percorrer todos os membros do ArrayList da classe Aula (através do each()). Agora faça um teste e escreva as classes Aluno e Aula em Java e veja quantas linha a mais de código seriam necessárias para o mesmo resultado. A maior parte das linguagens e recursos que se propõe a enxugar o código o faz às custas de clareza. Isso não acontece em Groovy: o código continua perfeitamente legível, mesmo com linhas a menos. Em alguns casos, como no exemplo acima, é até mais fácil ler um código Groovy do que um código Java. Para onde ir agora? Groovy é extremamente poderosa e pode lhe ajudar muito em seus projetos Java. Ela é particularmente útil para processamento de texto graças a um poderoso suporte a expressões regulares, para processamento de listas e de arquivos graças ao uso de closures e principalmente para o processamento de XML, onde o Java é deveras confuso e prolixo. Além disso Groovy é a base do Grails, framework de produtividade para o desenvolvimento de aplicações web que une a poderosa infra-estrutura do Spring e Hibernate à simplicidade das idéias do Ruby on Rails. Grails possibilita o desenvolvimento de aplicações complexas de maneira rápida e indolor, gerando uma aplicação web totalmente compatível com Java EE em um arquivo.war. Para aprender mais sobre Groovy dê uma olhada na página do projeto na web. Existem dúzias de exemplos e informação relevante para que você torne-se produtivo rapidamente. Além disso, é interessante dar uma olhada no livro Groovy em ação, escrito por Dierk König junto a Andrew Glover, Paul King, Guillaume Laforge (o mantenedor do projeto) e Jon Skeet, publicado pela editora AltaBooks. (O original, Groovy in action, é publicado pela Manning, caso inglês não seja um problema). Groovy é simples e poderoso e merece sua atenção. O tempo que irá ganhar quando começar a usá-lo compensará e muito seu aprendizado. Links Post de James Strachan, onde surgiu a idéia sobre o Groovy Página da SpringSource comentando a compra da G2One Site do NetBeans, a única IDE que você precisa Site do Grails, framework para aplicações web que usa o Groovy como base

16 Site do Groovy Saiba Mais Auditório Virtual DevMedia - Groovy na web com Struts 2 Curso Online - Introdução ao Groovy Java Magazine 32 - Groovy: Java Através de Scripts

17 JBoss Application Server 5 João Paulo Viragine é bacharel em Ciência da Computação pela Unesp. Trabalha como Arquiteto de Soluções na JBoss, a division of Red Hat, onde uma de suas atribuições é ser o evangelista oficial de Seam no Brasil. Acumula cerca de 7 anos de experiência na tecnologia Java, tendo atuado em projetos da área de Governo e Finanças. Possui as certificações: SCJP e SCWCD. Bruno Rosseto É bacharel em Sistemas de Informacão pela Universidade Mackenzie e atua com desenvolvimento de software com a plataforma Java há quatro anos. Possui experiênciaem projetos Java EE nas áreas automotivas, e-commerce,e outros projetos de missão crítica. Participou do projeto ganhador do Duke s Choice Awards de SIGA Saúde. Atualmente é consultor da Summa Technologies do Brasil. De que se trata o artigo: Após três anos de desenvolvimento, o JBoss Application Server 5 está pronto e traz uma arquitetura totalmente redesenhada. Este artigo introduzirá a nova arquitetura baseada no JBoss Microcontainer, suas vantagens e principais diferenças em relação à sua antecessora baseada no JBoss Microkernel. Além disso, detalhará as principais novidades em mensageria, clustering, balanceamento de carga, cache, transações e monitoração. Para que serve: O JBoss Application Server 5 serve para disponibilizar os recursos necessários à execução de aplicações Java EE 5. Sua arquitetura flexível permite total controle, customização e tuning, conforme as necessidades do desenvolvedor. Além disso, sua instalação é simples e rápida. Em que situação o tema é útil: O artigo atualiza o leitor em relação às mudanças mais expressivas da nova versão do JBoss Application Server, o servidor de aplicações mais utilizado do mundo.

18 JBoss Application Server 5: O JBoss Application Server 5 é resultado de três anos de pesquisas e desenvolvimento, que culminou em um total redesenho da arquitetura interna do servidor de aplicações. Além da compatibilidade total à especificação Java EE 5 e do suporte ao JDK 6, a principal característica dessa nova versão é a substituição do JBoss Microkernel pelo JBoss Microcontainer. Com o JBoss Microcontainer, é possível desenvolver serviços baseados em POJOs, não sendo mais necessário implementar MBeans. Com isso, a integração de novos módulos torna-se ainda mais dinâmica e rápida, o que facilita customizar, excluir ou acoplar novos serviços. É possível também integrar componentes baseados nos antigos MBeans, módulos OSGi, entre outros. Houve também mudanças significativas no mecanismo de classloader para a utilização do Virtual Deployment Framework (VDF), o qual garante que toda dependência do deploy seja satisfeita antes da disponibilização do serviço. Os principais módulos também sofreram evoluções, como: clustering, mensageria, cache, binding de portas, etc. A interface gráfica do novo JBossAS também foi atualizada, e foi criado o projeto Jopr - uma interface web para monitoração e controle de toda a infraestrutura JBoss, o que possibilita, entre outras coisas: a criação de novos datasources, deploy de pacotes, monitoração de pools de conexão, mantendo um histórico de ações e gráficos para futuras consultas. Dessa forma, ficou muito mais fácil cuidar dos seus JBosses. O lançamento do JBoss AS 5 é apenas o começo de uma nova era para os projetos JBoss, uma vez que outras soluções, como a Plataforma SOA, Portais, etc., poderão usufruir desse robusto e performático servidor de aplicações. A versão 5 do JBoss Application Server, que a partir desse momento chamaremos simplesmente AS5, foi resultado de uma maratona de três anos de pesquisas e desenvolvimento que culminou em um total redesenho da arquitetura interna do servidor de aplicações. Essa versão marca o início de uma nova era para o servidor de aplicações mais popular, querido e utilizado do mundo. Não se trata apenas de uma nova versão do servidor de aplicações, mas de todo um ambiente em estado da arte para execução da próxima geração de projetos desenvolvidos pela JBoss. Sobre a JBoss JBoss, apesar de ser sinônimo de servidor de aplicações, não está restrito apenas a isso. A comunidade JBoss (www.jboss.org) possui hoje mais de 35 projetos. Entre eles, podemos destacar: Hibernate - o framework de persistência ORM (Object Relational Mapping) mais utilizado do mundo e que muito influenciou a especificação de EJB 3.0. JBoss Seam - o framework que combina o que há de melhor em desenvolvimento Web 2.0 com o novo modelo de componentes de negócio EJB 3.0, aumentando a produtividade e disponibilizando inúmeros componentes para facilitar e acelerar o desenvolvimento de aplicações corporativas em Java. O reconhecimento do poder do JBoss Seam por parte da comunidade deu origem à JSR Web Beans. Ver Edição 58. Além de influenciar o futuro da plataforma Java EE, seja com participações nas JSRs, seja com a implementação de referência de JSRs, a JBoss conta hoje com a participação de brasileiros, funcionários da Red Hat Brasil, como principais desenvolvedores em diversos projetos da comunidade JBoss, dedicando-se em tempo integral a atividades de desenvolvimento e suporte a clientes. Dentre esses projetos, podemos destacar: o próprio JBoss AS, o JBoss Rules - motor de regras e BRMS (business rule management system), JBoss AOP - framework para AOP (programação orientada a aspectos), JBoss SX (framework de segurança da JBoss), JBoss Profiler (ferramenta de profiling baseada em log), JBoss Messaging (JMS provider), JBoss ESB (para integração SOA, ver Edição 59) e JBoss Portal (solução para portais corporativos). Mais detalhes sobre esses e outros projetos JBoss (como o JBoss jbpm, JBoss Tools, Teiid) podem ser encontrados no site: Apesar de os projetos JBoss serem conduzidos, em sua maior parte, por funcionários da Red Hat/JBoss, é inegável a contribuição da comunidade durante todos esses anos de existência da jboss.org. Essa

19 contribuição é de extrema importância para a sobrevivência e qualidade dos projetos. A contribuição não é feita apenas com desenvolvimento de código fonte, mas também com participação em fóruns de discussão, relato de bugs, pedido de novas funcionalidades, elaboração/tradução de documentação, blogs pessoais, eventos organizados pela comunidade, etc. Veja os links de referência no final do artigo para saber mais informações sobre como contribuir com a comunidade JBoss Novidades Uma das novidades da versão 5 do JBoss AS é a compatibilidade total à especificação Java EE 5. Apesar de a versão 4.x já suportar grande parte da especificação Java EE 5 (EJB 3.0, JPA, JAX-WS, etc.) e ser um dos primeiros servidores de aplicações a suportar a especificação de EJB 3.0, o suporte à Java EE 5 não era completo nem certificado. A certificação era uma característica bastante requisitada por clientes corporativos da Red Hat, principalmente em relação à garantia de compatibilidade das aplicações desenvolvidas. O suporte ao JDK 6 é também uma novidade dessa versão. Apesar de suportar o Java 6 desde a versão 4.2, é na versão 5 que esse suporte foi aprimorado e tornou-se padrão para execução do servidor de aplicações. Além da certificação Java EE 5 e do suporte ao Java 6, o destaque dessa versão, sem dúvida nenhuma, fica a cargo do JBoss Microcontainer. O AS5 faz parte de uma nova geração do servidor de aplicações, construído com base no novo JBoss Microcontainer. O JBoss Microcontainer é resultado de uma completa reescrita do JBoss JMX Microkernel (utilizado nas versões das séries 3.x e 4.x do JBoss AS) e o substitui completamente para suportar a utilização direta de POJOs e o uso como um projeto independente do servidor de aplicações JBoss, seguindo a tendência e evolução do desenvolvimento Java EE com a utilização de novos paradigmas como AOP, injeção de dependência e inversão de controle, e o foco na utilização de POJOs (como EJB 3.0, JPA, Spring, Guice, entre outros). O AS5 utiliza o JBoss Microcontainer para fazer a integração dos serviços disponibilizados pelo servidor de aplicações, entre eles: container Servlet/JSP; container EJB; gerenciador de deploy, entre outros, disponibilizando, assim, um ambiente Java EE padrão. O JBoss AS não é um servidor de aplicações monolítico - com um único kernel fornecendo os serviços requeridos pela especificação Java EE - mas sim, uma coleção de componentes independentes e interconectados, cada um deles com foco em uma funcionalidade específica requerida pela especificação Java EE. Essa arquitetura flexível possibilita que novos serviços possam ser facilmente adicionados e os serviços desnecessários possam ser removidos. Se houver necessidade de um serviço adicional, simplesmente fazemos o deploy do serviço desejado. De maneira análoga, se não precisamos de um serviço, podemos simplesmente removê-lo. A Figura 1 mostra uma visão geral de como os serviços são associados e disponibilizados pelo Microcontainer. Como resultado, temos um servidor de aplicações totalmente customizado às nossas necessidades, com o uso eficaz de recursos do servidor físico (CPU, memória, disco). A flexibilidade é tamanha, que os serviços construídos com base no JBoss Microcontainer podem ser utilizados de maneira independente em outros ambientes/servidores de aplicações não JBoss, como o GlassFish, ou até mesmo o Tomcat. Como exemplo, podemos citar o suporte total ao EJB 3.0 no Tomcat (bastando para isso, fazermos o deploy do JBoss EJB 3.0 container no Tomcat). Como o JBoss Microcontainer é extremamente leve, pode ser utilizado para disponibilizar serviços até mesmo em um ambiente Java ME. Desse modo, abre-se um novo horizonte de possibilidades para aplicações móveis que passam a usufruir dos serviços enterprise, sem a necessidade de utilização de um ambiente/servidor Java EE completo. O JBoss Microcontainer utiliza o conceito de injeção de dependências (IoD) para interconectar e disponibilizar os serviços do servidor de aplicações. Além disso, pode ser utilizado como container de injeção de dependências de propósito geral ao estilo Pico Container

20 e Spring. Como amplamente consolidada no Java 5, toda configuração do JBoss Microcontainer pode ser realizada através de anotações ou XML, dependendo do local onde a informação de configuração está localizada (classes Java ou arquivos de configuração). Além de tudo isso, o JBoss Microcontainer possui classes de testes utilitárias que estendem o JUnit e tornam a configuração e a execução de testes unitários uma tarefa extremamente simples, permitindo que o desenvolvedor acesse POJOs e serviços nas classes de testes com apenas algumas linhas de código. Todo o mecanismo de classloader do JBoss AS também foi modificado para utilizar o avançado conceito do Virtual Deployment Framework (VDF). O VDF foi desenvolvido para abstrair, simplificar e unificar a manipulação de arquivos pelo servidor de aplicações. Denominado Virtual File System (VFS) Class Loader, esse novo mecanismo de classloader, além do uso do VDF para localizar bibliotecas e classes, faz uso extensivo de AOP para aspectizar o deploy de aplicações/serviços no servidor de aplicações. O VFS faz a análise dos deploys produzindo meta-informações que serão utilizadas pelo JBoss Microcontainer para instanciar, interconectar e controlar o ciclo de vida e dependência dos deploys. O JBoss Microcontainer utiliza uma máquina de estados para garantir que toda e qualquer dependência do deploy seja satisfeita antes de disponibilizar o serviço. Modularização dos serviços - Maior possibilidade de escolha e flexibilidade Um grande avanço do AS5 foi a modularização dos serviços internos do servidor de aplicações em projetos independentes. Essa modularização não traz impactos diretos para o usuário final, mas faz parte de uma importante estratégia da JBoss em disponibilizar os vários serviços Java EE como projetos independentes. Assim, esses serviços podem ser consumidos a la carte em diferentes ambientes, e não apenas no próprio servidor de aplicações, o que permite grande flexibilidade e liberdade de escolha. Remover serviços é tão simples quanto adicionar novos. Muitas das principais funcionalidades do AS5 são providas da integração de vários outros projetos JBoss, entre eles: JBoss EJB Implementação da última versão da especificação EJB A especificação de EJB 3.0 faz parte de uma total reestruturação da especificação EJB. E tem por objetivo a simplificação do desenvolvimento; JBoss Messaging - Reescrita completa do antigo JBossMQ (que é o provedor JMS padrão no JBoss AS das séries 4.x). É uma implementação de JMS de alta performance compatível com a JSR-914, com suporte out-of-thebox a cluster de filas e tópicos, com tolerância a falhas transparente e um sistema de redistribuição de mensagens inteligente. É hoje o provedor de mensageria padrão do AS5, além de ser parte integrante da infraestrutura do JBoss ESB; JBoss Cache - É a implementação de cache utilizada no AS5. É utilizado principalmente em conjunto com o JGroups para fornecer uma solução completa de cluster. Entre as diversas características está o buddy replication: permite que o cache seja replicado apenas para um buddy (companheiro) no cluster, evita a sobrecarga de outros nós no cluster sem necessidade, realiza uma espécie de backup do estado do nó; JBoss WS - Implementação da pilha de web services compatível com a especificação JAX-WS 2.0/JAXRPC. Além de implementar toda a especificação de Web Services, foi criada uma camada de abstração que possibilita que se pluguem outras implementações. Por exemplo: podemos utilizar a implementação nativa do JBoss WS, o Metro (implementação de web services da Sun), ou ainda o CXF (implementação da Apache), sem qualquer tipo de impacto sobre o JBoss AS. Assim, o usuário tem total liberdade para escolher a implementação que melhor se adapta às suas necessidades. No final do mês de março, foi anunciado que os esforços serão focados em uma única implementação: JBossWS-CXF, ou seja, as próximas versões do JBoss AS virão com o CXF nativo. Aqueles que usam o JBoss WS nativo não precisam se preocupar, pois a transição será realizada gradativamente e trará grandes benefícios, principalmente no que diz respeito a soluções SOA; JBoss Transactions - é o gerenciador de transações padrão no AS5. O JBoss Transactions foi adquirido em

21 2005 da Arjuna/Hewlett-Packard - um gerenciador de transações extremamente rápido e robusto. Resultado de mais de 18 anos de experiência dos seus criadores em gerenciamento de transações, foi a primeira implementação de JTA e JTS do mercado; JBoss Web - É o container Web/Servlet do AS5, comumente conhecido como "Tomcat on stereoids". Tem sua implementação baseada no Apache Tomcat 6.0 e inclui suporte a conectores baseados no Apache Portable Runtime (APR) para alcançar maior performance e escalabilidade, podendo, em alguns casos, equiparar-se ao Apache HTTP Server ou até superá-lo; JBoss Security - Além do suporte a JAAS, foi atualizado para suportar mecanismos de autorização plugáveis: SAML, XACML e SSO. A Tabela 1 compara os principais serviços utilizados no AS5 e no seu sucessor (JBossAS 4.2.3), para facilitar a visualização da evolução de versões entre os dois. Tabela 1: Matriz de comparação de versão entre o JBossAS e o JBossAS 5 O AS5 suporta nativamente POJOs, MBeans e OSGi bundles (com ajuda do Apache Felix). Suportar um novo modelo de componentes é tão simples quanto implementar uma nova fachada para o JBoss Microcontainer. Isso permite que o JBoss AS suporte qualquer outro modelo de componentes existente ou que ainda está por vir; já está preparado, portanto, para o sistema de módulos que será implementado no Java 7. Novidades em Cluster Uma das melhorias no AS5 foi a criação de um novo mecanismo de integração entre o JBoss Cache e o Hibernate/JPA para a utilização de Second Cache Level (ou cache L2, introduzido no Hibernate 3.3). Existem basicamente quatro tipos de objetos que podem participar de um Second Cache Level: entidades, collections, resultados de query e timestamps. Nas versões 4.x, apenas um único cache podia ser utilizado para armazenar todos os tipos de objetos, causando dificuldades na consulta. Com o AS5 existe um cache diferenciado para cada tipo de objeto, evitando assim sobrecarga e lentidão na busca de objetos na árvore de cache. Essa versão também permite buddy replication de Stateful Session Beans. Com buddy replication, é possível diminuir a carga de memória e o tráfego na rede. A Figura 2 mostra uma arquitetura com seis nós, onde cada nó possui os seus dados e um cache do nó anterior. Quando ocorre queda de um dos nós, automaticamente o nó que possuía o cache do nó em queda assume o comando, guardando também o cache do nó anterior, fechando o círculo. A Figura 3 mostra a queda do servidor nó 1 e o servidor nó 2 assumindo o cache do nó 1 (em queda) e 6. Nas versões 4.2.x, buddy replication era configurada no arquivo $JBOSS_HOME/server/all/deploy/jbossweb-cluster.sar/META-INF/jboss-service.xml (apenas camada web). Já o AS5 centraliza toda a configuração de cache no serviço chamado Cache Manager, que está localizado em $JBOSS_HOME/server/all/deploy/cluster/jboss-cache-manager.sar. Com a utilização do JBoss Messaging em vez do JBossMQ, a clusterização do provider de mensageria também mudou. O antigo JBossMQ era executado em modo HA-Singleton, ou seja, apenas uma instância de JBoss executava o provider de mensageria por vez. Com o JBoss Messaging, é possível ter todos os nós ativos para o serviço de mensageria, proporcionando um balanceamento de carga entre os diversos nós, caso ocorra uma sobrecarga no servidor. Para que as filas sejam consideradas clusterizadas, é

22 necessário adicionar o atributo Clustered com valor True na declaração da Queue ou Topic, conforme mostra a Listagem 1. Listagem 1. $JBOSS_HOME/server/all/deploy/cluster/jboss-cache-manager.sar <mbean code="org.jboss.jms.server.destination. QueueService" name="jboss.messaging.destination:service=queue, name=testdistributedqueue" xmbean-dd="xmdesc/queue-xmbean.xml"> <depends optional-attribute-name= "ServerPeer">jboss.messaging:service= ServerPeer</depends> <depends>jboss.messaging:service=postoffice </depends> <attribute name="clustered">true</attribute> </mbean> A configuração do serviço de portas também mudou. Com a utilização de POJOs e AOP no Microcontainer, as portas agora são injetadas conforme a necessidade da configuração. O serviço ServiceBindingManager é o responsável por fazer a associação entre as portas e cada um dos serviços, por exemplo, HTTP na porta 8080, AJP na porta 8009, etc. Na versão 5.0, ocorre uma chamada ao arquivo bootstrap.xml (Listagem 2), que é o responsável por carregar algumas configurações em tempo de inicialização. O bootstrap.xml está configurado para utilizar o arquivo de configuração de portas bindings.xml, o qual já possui algumas configurações pré-definidas que podem ser utilizadas e customizadas conforme a necessidade do usuário. Listagem 2. $JBOSS_HOME/server/$PROFILE/conf/bootstrap.xml <bootstrap xmlns="urn:jboss:bootstrap:1.0"> <url>bootstrap/vfs.xml</url> <url>bootstrap/classloader.xml</url> <url>bootstrap/aop.xml</url> <url>bootstrap/jmx.xml</url> <url>bootstrap/deployers.xml</url> <url>bootstrap/bindings.xml</url> <url>bootstrap/profile-repository.xml</url> </bootstrap> A Listagem 3 mostra a injeção das configurações de portas disponíveis. No caso, estão sendo injetadas as configurações de PortsDefaultBindings, Ports01Bindings, Ports02Bindings e Ports03Bindings. Listagem 3. Trecho do arquivo bindings.xml - definição de alias <bean name="servicebindingstore" class="org.jboss.services.binding.impl. PojoServiceBindingStore"> <!-- Base bindings that are used to create bindings for each set --> <property name="standardbindings"> <inject bean="standardbindings"/> </property> <!-- The sets of bindings --> <property name="servicebindingsets"> <set> <inject bean="portsdefaultbindings"/> <inject bean="ports01bindings"/> <inject bean="ports02bindings"/> <inject bean="ports03bindings"/> </set>

23 </property> </bean> A definição das configurações PortsDefaultBindings e beans do tipo ServiceBindingSet (Listagens 4 e 5). Ports01Bindings é realizada com a injeção de Listagem 4. Trecho do arquivo bindings.xml - definição de PortsDefaultBindings <bean name="portsdefaultbindings" class="org.jboss.services.binding. impl.servicebindingset"> <constructor> <!-- The name of the set --> <parameter>ports-default</parameter> <!-- Default host name --> <parameter>${jboss.bind.address</parameter> <!-- The port offset --> <parameter>0</parameter> <!-- Set of bindings to which the "offset by X" approach cant be applied --> <parameter><null/></parameter> </constructor> </bean> Listagem 5. Trecho do arquivo bindings.xml - definição de Ports01Bindings <bean name="ports01bindings" class="org.jboss.services.binding.impl. ServiceBindingSet"> <constructor> <!-- The name of the set --> <parameter>ports-01</parameter> <!-- Default host name --> <parameter>${jboss.bind.address</parameter> <!-- The port offset --> <parameter>100</parameter> <!-- Set of bindings to which the "offset by X" approach cant be applied --> <parameter><null/></parameter> </constructor> </bean> O trecho referente a port offset atua diretamente na configuração de StandardBindings (Listagem 6), realizando uma somatória no valor de cada porta. No caso, o PortsDefaultBindings irá manter as configurações conforme estão no arquivo, pois seu port offset está definido com valor 0, porém a configuração Ports01Bindings irá somar 100 em cada uma das portas. Portanto, para o Ports01Bindings, a porta 1099 será 1199, a porta 1098 será1198, a porta 8080 será 8180, e assim por diante. Listagem 6. Trecho do arquivo bindings.xml - definição de StandardBindings - portas padrão <bean name="standardbindings" class="java.util.hashset" elementclass="org.jboss. services.binding.servicebindingmetadata"> <constructor> <parameter> <set> <!-- ********************* conf/jboss-service.xml ****************** --> <!-- Naming Service --> <bean class="org.jboss.services. binding.servicebindingmetadata"> <property name="servicename"> jboss:service=naming</property> <property name="bindingname">

24 Port</property> <property name="port">1099</property> </bean> <bean class="org.jboss.services. binding.servicebindingmetadata"> <property name="servicename"> jboss:service=naming</property> <property name="bindingname"> RmiPort</property> <property name="port">1098</property> </bean>... </set> </parameter> </constructor> </bean> $JBOSS_HOME é o diretório de instalação do JBoss AS5. $PROFILE é o diretório referente ao profile/configuração, por exemplo: default, all, web, etc. As portas padrão do JBoss Application Server são definidas no bean StandardBindings, o qual realiza a associação de cada porta a cada serviço específico. A Listagem 6 mostra um trecho da declaração do StandardBindings, em que o serviço Naming (JNDI) está sendo associado à porta 1099 e à porta RMI Com a utilização do ServiceBindingManager, torna-se mais fácil a utilização de várias instâncias de JBoss AS no mesmo servidor físico. Desse modo, a configuração de portas é mantida em um único lugar, o que facilita a manutenção. Injeção de POJOs utilizando o Microcontainer Os arquivos que terminam com jboss-beans.xml são utilizados pelo Microcontainer para realizar a injeção de POJOs. São semelhantes aos -service.xml que eram utilizados nas versões 4.x. A maioria dos serviços do AS5 já foi convertida para POJOs. Porém, ainda restam alguns MBeans das versões antigas que utilizam os -service.xml, os quais serão substituídos em versões futuras. Para facilitar o entendimento da injeção de POJOs realizada pelo Microcontainer, criamos a classe PojoServiceExample (Listagem 7). Listagem 7. Classe PojoServiceExample package jm.exemplos.pojo; public class PojoServiceExample { public PojoServiceExample() { System.out.println("Construtor de PojoServiceExample()"); É uma classe muito simples, com apenas um método construtor que imprime uma mensagem na tela. A Listagem 8 mostra o arquivo jboss-beans.xml, o qual possui a declaração do POJO com o nome PojoServiceExample. Listagem 8. Arquivo jboss-beans.xml

25 <?xml version="1.0" encoding="utf-8"?> <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="pojoserviceexample" class="jm.exemplos.pojo.pojoserviceexample"/> </deployment> Ao realizar o deploy, deverá ser exibida a mensagem conforme mostra a Listagem 9. Listagem 9. $JBOSS_HOME/server/$PROFILE/log/server.log :10:16,060 DEBUG [org.jboss.deployers.structure. spi.helpers.abstractdeploymentcontext] (main) Added component PojoServiceExample to vfszip:/opt/downloads/jboss ga/server /default/deploy/jboss5-servico-exemplo.beans :10:16,063 INFO [STDOUT] (main) Construtor de PojoServiceExample() Esse exemplo mostra a forma mais simples de disponibilizar um POJO utilizando o Microcontainer. Basicamente todos os serviços, módulos e suas dependências são injetados como POJOs e manipulados dessa forma, sem a necessidade de ter de implementar uma interface ou estender uma classe abstrata. Instalação Para a instalação, utilizaremos a versão binária da distribuição do JBoss AS. Para fazer o download do AS5, basta acessar a página de download (ver Links) e selecionar o arquivo jboss ga.zip. O site JBoss.org disponibiliza também versões anteriores e um Release Notes de cada uma das versões. Recomendamos a utilização da versão GA (General Availability), que é a versão estável da distribuição. O único pré-requisito para execução do JBoss AS é uma máquina virtual Java (JRE) 1.5 ou superior instalada. Na versão 5, não há mais a necessidade de instalação do JDK, pois o AS5 já vem com o ECJ (compilador do Eclipse JDT), necessário para compilar JSPs. O AS5 pode ser instalado e executado utilizando uma máquina virtual Java 5 ou 6 em qualquer Sistema Operacional. Os binários compilados com as duas JDKs estão disponíveis no site Apesar de o número de downloads do binário compilado com Java 6 ser superior e ser considerado uma versão experimental, a versão com Java 5 é a chamada versão primária e é recomendada para utilização em produção. Caso queira rodar o AS5 compilado com JDK 5 utilizando JRE 6, quatro bibliotecas devem ser copiadas do diretório /client para o diretório /lib/endorsed. São elas: jbossws-native-saaj.jar; jbossws-native-jaxrpc.jar; jbossws-native-jaxws.jar; jbossws-native-jaxws-ext.jar. Porém, utilizando o binário compilado com JDK 6 em uma JRE 6, nenhuma alteração é necessária.o que muda em geral é o script de inicialização de cada ambiente. Por exemplo: no Windows utilizamos run.bat, no Unix/Linux, run.sh (para simplificar, omitiremos a extensão a partir deste ponto). O processo de instalação básica do JBoss AS é extremamente simples: basta descompactá-lo em algum diretório de sua escolha. Todo o JBoss AS e sua configuração estão contidos em uma única estrutura de diretório. Então para desinstalar o JBoss AS basta removermos todo o diretório.

26 Inicializando o servidor Após a descompactação do arquivo, iremos iniciar o Application Server. Os scripts de inicialização estão localizados no diretório /bin; execute o script run. Caso esteja utilizando o Windows, execute o arquivo run.bat. O prompt de comando deverá exibir algo semelhante à Figura 4. Figura 4: Prompt de inicialização do AS5 Com isso, seu AS5 está pronto para ser utilizado. Os arquivos de inicialização utilizarão por padrão o profile default. Veja o quadro Explorando a nova estrutura de diretórios para entender melhor os profiles existentes no AS5. Com o parâmetro -c, é possível inicializar diferentes profiles: #./run -c allp Por questões de segurança, o JBoss AS, quando executado, atende às requisições apenas na interface local ( ). Esse comportamento faz com que o servidor não seja acessível remotamente. Para habilitar o acesso remoto ao servidor de aplicações, basta utilizarmos a opção -b no script de inicialização do servidor. O comando abaixo fará o JBoss AS executar os serviços em todas as interfaces de rede do servidor onde está sendo executado. # run.sh -b De qualquer maneira, esteja ciente da necessidade da correta configuração de segurança do servidor conforme a política de segurança local.

27 Explorando a nova estrutura de diretórios A estrutura de diretórios do AS5 é muito semelhante à dos seus antecessores (Figura 5). Iremos detalhar as principais diferenças entre a estrutura de diretórios de uma versão da série 4.x para a versão 5. Ao instalar o AS5, percebe-se o novo diretório common na raiz da instalação. Nas versões anteriores, o diretório lib de cada profile (configuração) possuía praticamente as mesmas bibliotecas. Em um ambiente com diversos profiles sendo executados em paralelo, o tamanho em disco do JBoss AS aumenta consideravelmente. No AS5 as bibliotecas que são obrigatórias para o funcionamento de todos os profiles foram movidas para o diretório $JBOSS_HOME/common/lib. Esse diretório funciona como uma extensão do diretório $JBOSS_HOME/server/$PROFILE/lib, deixando-o mais limpo e de fácil manutenção, especialmente para gerenciar seus drivers jdbc ou bibliotecas específicas das aplicações. Os outros diretórios da raiz da instalação permanecem com as mesmas funções: bin - possui todos os scripts e arquivos binários necessários para iniciar e parar o AS; client - contém bibliotecas necessárias à comunicação de uma aplicação cliente com o JBoss AS. Essas bibliotecas não são carregadas pelo JBoss AS diretamente, mas por aplicações clientes rodando em JVMs diferentes; docs - diretório com exemplos de configuração de Datasources, DTDs e XML schemas, licenças de bibliotecas e resultados de testes unitários. Para documentação completa do JBoss AS, acesse o site da comunidade JBoss lib - possui as bibliotecas necessárias para executar o core do AS; server - é um dos diretórios mais importantes e contém os profiles e as configurações para a execução de aplicações Java EE. Além dos profiles clássicos das versões anteriores (minimum, default, all), dois novos profiles foram adicionados ao diretório server: web e standard. O profile web foi criado com o objetivo de executar apenas aplicações web, ou Figura 5: Estrutura de diretórios da raiz do AS5 seja, JSPs e Servlets (sem a utilização de EJBs). Além disso, também estão disponíveis JTA, JCA e JPA; porém a maioria dos outros serviços não está disponível, como os serviços de , mensageria, Quartz, gerador de chaves, etc. Esses serviços só estão disponíveis a partir do profiler default. O profile standard foi criado para a execução dos testes de compatibilidade com Java EE 5. O profile default é um superset do standard e possui algumas poucas configurações e aplicações adicionais. Muitos usuários se perguntam qual profile devem utilizar para executar suas aplicações. A Tabela 2 mostra as principais diferenças entre os cinco profiles.

28 Tabela 2: Serviços disponíveis em cada profile. Os profiles mais utilizados nas versões anteriores eram o default e o all. No AS5, além destes, o profile web deverá ser utilizado em grande escala, substituindo a utilização do Tomcat e jboss-web stand-alone. Se a aplicação necessita de alta-disponibilidade (HA), utiliza-se o profile all. A maioria dos outros casos será atendida com o profile default. Cada profile possui um diretório conf. Assim como nas versões anteriores do JBoss AS, possui as configurações gerais do servidor de aplicação, como controle transacional, log4j, diretórios de deploy, etc. O diretório deploy é o local utilizado para publicar aplicações e disponibilizar serviços no JBoss AS. No AS5, houve a separação dos serviços deployáveis com a criação do diretório deployers (Figura 6).

29 Figura 6: Serviços disponíveis em cada profile. Assim, não ficam mais misturados no diretório deploy, sendo armazenados no diretório deployers(a exemplo do jbossweb.deployer). O diretório lib contém bibliotecas que serão compartilhadas por todos os serviços e aplicações disponíveis para o profile. Caso queira compartilhar um driver JDBC entre várias aplicações no mesmo profile, adicione a biblioteca do drive no diretório lib. Para o profile all, foi criado o diretório cluster, o qual armazena uma total reestruturação dos arquivos de configuração de cluster. O arquivo cluster-service.xml não existe mais, e seu equivalente é o $PROFILE/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml.

30 JBoss AS de cara nova O design do JMX Console e Web Console também foi atualizado para facilitar a busca de serviços. Agora, há um menu lateral esquerdo com filtro para facilitar a identificação dos serviços. Ao clicar no link, apenas os serviços relacionados serão exibidos (Figura 7). Figura 7: Novo design do JMX Console O Web Console também foi modificado, incorporando o design do JMX Console (Figura 8). Figura 8: Novo design do Web Console

31 Mitos Acabando com o mito: O JBoss AS não tem um console unificado de administração, monitoração e controle, tudo tem de ser feito à mão. Não basta ser um servidor moderno, robusto e performático se a administração não for algo simples e intuitivo. Pensando nisso, foi criado o projeto Jopr (Figura 9). O nome Jopr (pronuncia-se jopper) foi escolhido baseado no filme Jogos de Guerra (WarGames), em que havia um super computador chamado WOPR (Whopper) - War Operation Plan Response - o qual era responsável por responder a todo e qualquer ataque nuclear inimigo. Figura 9: Jopr O propósito desse projeto é disponibilizar ao administrador uma interface Web integrada e intuitiva para a administração, monitoração, configuração e controle da Plataforma JBoss. Através do Jopr é possível, entre várias outras coisas: Saber o consumo de CPU, memória, disco e rede do servidor; Saber o consumo de memória da JVM utilizada pelo servidor de aplicações; Visualizar e monitorar métricas do servidor de aplicações e das aplicações. (Ex: saber quantas sessões estão abertas em uma determinada aplicação); Realizar start/stop/restart do servidor de aplicações; Monitorar métricas e criar/deletar/configurar datasources, connection factories, JMS topics; Gerar alertas através de e/ou traps SNMP quando da ocorrência de uma condição préconfigurada (Ex: utilização de CPU ultrapassar 80%; memória da JVM ultrapassar 90%).

32 Além do Jopr Server - com foco em várias instâncias de JBoss AS, existe também uma versão com foco em apenas uma instância de JBoss AS chamado Embedded Jopr, o qual é disponibilizado no próprio servidor. Com o Embedded Jopr (Figura 10), é possível realizar deploys de EARs e WARs, criar novos Datasources, criar novas filas JMS, monitorar o pool de conexões, executar scripts, etc. Tudo isso utilizando uma interface Web intuitiva. Figura 10: Embedded Jopr. Para completar seu estudo sobre o JBoss AS 5, veja a Apresentação Mergulhando fundo no JBoss AS 5 e Jopr. Conclusão Após três anos de pesquisas e desenvolvimento, o JBoss Application Server 5 está pronto para sua grande estréia. Com um novo kernel construído a partir do zero, substitui a utilização de MBeans por POJOs, utiliza extensamente AOP, unifica a manipulação de metadados, altera o mecanismo de classloading, aspectiza os deployers, tudo isso mantendo a compatibilidade com a maioria dos serviços existentes. Essas são algumas das novidades dessa nova versão. O lançamento do AS5 é apenas o começo de uma nova era para os projetos JBoss. A flexibilidade proporcionada pelo Microcontainer permitirá à Red Hat/JBoss, além de inovar, estar up-todate com as especificações do JCP. O objetivo da Red Hat/ JBoss é ter o mais inovador, robusto e performático servidor de aplicações do mercado. As possibilidades são infinitas e a Red Hat/JBoss precisa da participação da comunidade para ajudar na definição do futuro e no desenvolvimento do JBoss AS e de todos os outros projetos. Essa contribuição é essencial para manter os projetos JBoss como os mais populares, queridos e utilizados do planeta. A comunidade é o poder do open source. Não seja apenas usuário: participe, teste, reclame, sugira, contribua.

33 Links Página principal da JBoss Como contribuir com a comunidade JBoss Listagem de Servidores de Aplicação compatíveis com Java EE 5.0 Página da especificação Java EE 5.0 Página de padrões suportados pelo JBoss AS Página de download do JBoss AS Página principal do Jopr Página principal do Apache Felix Entrevista com Chris Morgan sobre Jopr Livros JBoss in Action, Javid Jamae e Peter Johnson, Manning Publications, 2009 Nova versão do livro JBoss in Action a qual foca nas principais configurações do JBoss Application Server 5 Saiba Mais Java Magazine 46 - JBoss: Instalação, Arquitetura, Configuração, Tuning e Administração Java Magazine 51 - Portlets com JBoss Portal Java Bagazine 53 - Drools: Regras na Prática Java Magazine 58 - JBoss Seam Java Magazine 59 - JBoss ESB

34 Spring Security Michel Zanini Formado em Ciências da Computação pela Universidade Federal de Santa Catarina (UFSC) e possui as certificações SCJP, SCWCD, SCBCD e SCDJWS. De que se trata o artigo: O artigo apresenta o projeto Spring Security como uma alternativa na área de segurança à tradicional especificação Java EE, através de um exemplo prático e realista. Para que serve: Com o Spring Security é possível criar um mecanismo de autenticação e autorização para sua aplicação web em questão de minutos. O framework foca em facilitar a implementação dos casos de uso mais freqüentes, porém oferece valiosos pontos de extensão para requisitos mais complexos. Por fim, disponibiliza suporte a inúmeros diferentes tipos de autenticação e integração com as mais usadas tecnologias na área de segurança. Em que situação o tema é útil: Para qualquer aplicação web que necessite restringir seus recursos para diferentes tipos de usuário, bem como assegurar que se autentiquem de forma prática e segura. Spring Security: O Spring Security surgiu da necessidade de melhorar o suporte à segurança oferecido pela especificação Java EE. O framework centraliza a configuração em um único XML, dispensando configurações do container e tornando a aplicação web um arquivo WAR auto contido. Para começar a utilizá-lo basta adicionar seus JARs ao classpath, configurar um filtro e um listener no web.xml e criar um application context (XML de configuração). O XML centraliza todas as configurações de autenticação e autorização. As tags definem quais roles podem acessar cada grupo de URLs. A tag define a fonte de dados para as informações de usuários (banco de dados, arquivo de propriedades, LDAP, etc.). Quando necessário, é possível utilizar os eventos publicados pelo framework a cada sucesso ou falha na autenticação ou autorização. Ouvir os eventos permite criar complexos casos de gerenciamento de usuários. O Spring Security ainda oferece integrações com a API de Servlets, taglibs para facilitar a codificação de JSPs, suporte à HTTPS, segurança em métodos com uso de anotações e suporte a autenticação com LDAP ou certificados X509. Segurança é um requisito importante presente na grande maioria dos sistemas desenvolvidos. Na plataforma Java EE temos uma solução oferecida pela especificação que determina como uma aplicação pode definir regras de controle de acesso e autenticação. Entretanto, ainda é comum nos depararmos com soluções caseiras para cumprir tal requisito. Em parte, tais soluções são criadas pela falta de experiência dos desenvolvedores, ou por outro lado, porque a especificação não é flexível o suficiente para comportar os requisitos. Com o objetivo de preencher a lacuna deixada pela especificação, em 2003 surgiu o Acegi Security System for Spring. O Acegi Security é conhecido por ser extremamente configurável e poderoso, porém difícil de utilizar devido à enorme quantidade de configuração XML necessária. Em 2007 o projeto Acegi foi incorporado dentro do guarda-chuva de projetos do Spring Framework Portifolio, e então, renomeado como Spring Security.

35 Em abril de 2008 a versão do Spring Security foi lançada tomando como proveito a configuração baseada em namespaces do Spring 2.0. Hoje, o Spring Security é extremamente fácil de configurar, sem perder a flexibilidade e o poder do antigo Acegi. O Spring Security depende de alguns JARs do Spring Framework core. Entretanto, não é necessário que sua aplicação seja construída com o modelo de programação do Spring Framework. Ou seja, uma aplicação pré-existente que não usa Spring pode passar a utilizar o Spring Security sem grandes modificações. Para aprender mais sobre o Spring Framework consulte o artigo de capa da Edição 65. Assim como o Java EE o Spring Security possui uma abordagem declarativa para segurança, baseada em roles (papéis). A abordagem é declarativa, pois a aplicação não precisa chamar nenhum método para realizar autenticação ou autorização, tudo é feito através de configuração XML. Para configurar o Spring Security de forma declarativa, assim como no Java EE, é necessário declarar quais serão os roles envolvidos, quais os recursos que serão protegidos, e quais roles podem acessar cada recurso. Além disso, declara-se como a autenticação será feita (basic, digest, form login, LDAP, etc.). Este artigo apresenta as características do Spring Security, mostrando alguns recursos importantes não presentes na especificação Java EE. Exemplos práticos serão construídos, abordando cenários frequentes que são requisitos de grande parte das aplicações web. Os conceitos básicos sobre segurança não são abordados no artigo. Entretanto, o artigo de capa da Edição 22 descreve tais conceitos e demonstra exemplos práticos utilizando a especificação Java EE. Primeiro exemplo Como primeiro exemplo vamos criar uma aplicação web simples com duas áreas de acesso restrito: uma permitida para qualquer usuário autenticado (/usuarios/index.jsp) e outra apenas para usuários administradores (/admin/index.jsp). As páginas restritas apenas exibem uma mensagem e possuem um link de retorno à página principal. Espera-se que um login seja solicitado ao acessar qualquer uma destas áreas. A página inicial da aplicação (/index.jsp), ilustrada na Figura 1, tem acesso livre e possui links para as duas áreas restritas. Figura 1: Página inicial da aplicação. O código fonte dos três JSPs são HTML simples e portanto não serão exibidos nas listagens (estão disponíveis para download no site da Java Magazine). Configurando o web.xml O Spring Security utiliza-se de um filtro HTTP, declarado no web.xml (Listagem 1), para interceptar todas as URLs acessadas e conferir suas permissões de acesso. Por isso, o filtro é aplicado com o url-pattern barra asterisco. No Java EE tal filtro não é necessário, pois o controle de acesso é realizado pelo próprio container. É importante notar que o nome do filtro é springsecurityfilterchain e não deve ser alterado, pois o Spring Security já espera que o filtro esteja com este nome, por convenção. No Java EE as configurações de autenticação e autorização são feitas no web.xml. No Spring Security são

36 feitas em um application context padrão do Spring Framework. Dessa forma, precisamos do listener ContextLoaderListener declarado no web.xml para carregar o application context na inicialização da aplicação web. O atributo contextconfiglocation do listener indica a localização do application context, neste caso, na raiz do classpath com o nome spring-security-config.xml. O web.xml da Listagem 1 aplica essas configurações. Listagem 1. web.xml - Configuração do Spring Security no web.xml <web-app> <filter> <filter-name>springsecurityfilterchain </filter-name> <filter-class>org.springframework.web.filter. DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springsecurityfilterchain </filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web. context.contextloaderlistener </listener-class> </listener> <context-param> <param-name>contextconfiglocation</param-name> <param-value>classpath: spring-security-config.xml </param-value> </context-param> </web-app> Application context é o nome dado aos XMLs de configuração do Spring Framework. Esses arquivos são genéricos o suficiente para configurar qualquer tipo de aplicação. Em casos específicos, como do Spring Security, namespaces são utilizados para reduzir a quantidade de XML necessária. Controle de acesso e autenticação no spring-security-config.xml Agora é necessário criarmos o arquivo spring-security-config.xml, conforme a Listagem 2. Este arquivo, carregado pelo listener do web.xml, utiliza o namespace do Spring Security (http://www.springframework.org/schema/security) para declarar regras de autenticação e autorização. Declaramos este namespace como default para o XML (sem prefixo) e o prefixo beans para o namespace normal do Spring Framework. Listagem 2. spring-security-config.xml - Arquivo de configuração do Spring Security <beans:beans xmlns="http://www.springframework.org/ schema/security" xmlns:beans="http://www.springframework.org /schema/beans" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemalocation=" beans/spring-beans-2.5.xsd schema/security

37 schema/security/ spring-security xsd"> <http auto-config="true"> <intercept-url pattern="/usuarios/**" access="role_usuario,role_admin" /> <intercept-url pattern="/admin/**" access="role_admin" /> </http> <authentication-provider> <user-service> <user name="joao" password="123" authorities="role_usuario" /> <user name="admin" password="123" authorities="role_admin" /> </user-service> </authentication-provider> </beans:beans> Se o leitor utiliza a IDE Eclipse, aconselhamos a instalação do plugin Spring IDE (veja seção de links) para facilidades na edição de application contexts. Outras IDEs como NetBeans e IntelliJ IDEA também possuem excelentes plugins de integração com o Spring, vale à pena conferir. O controle de acesso é definido pela tag interna à tag. No atributo pattern definimos uma expressão que atenderá as URLs acessadas e no atributo access definimos os roles de usuários que poderão acessar as URLs, separados por vírgulas. Definimos que todas as URLs com prefixo /usuarios serão acessadas por usuários normais e administradores e URLs com prefixo /admin apenas por administradores. Por default a sintaxe das expressões utilizadas no atributo pattern é a mesma utilizada no Ant. Porém, se desejado, pode-se alterá-la para seguir a sintaxe de expressões regulares. Para tal, basta adicionar o atributo path-type="regex" na tag. Dessa forma é possível criar expressões tão complexas quanto necessário para atender às URLs, de acordo com os requisitos do desenvolvedor. As tags serão interpretadas em ordem de definição e a primeira a atender será usada. Dessa forma, os patterns mais específicos devem vir primeiro. Por exemplo, a expressão /usuarios/vip/** deve ser declarada acima da expressão /usuarios/**, caso contrário a expressão vip nunca será avaliada, pois a expressão /usuarios/** também atende a URLs do tipo /usuarios/vip/**. O atributo auto-config= true da tag configura automaticamente a aplicação para utilizar login baseado em formulário. O JSP do formulário nem mesmo precisa ser codificado, o Spring Security irá gerá-lo dinamicamente conforme a Figura 2. Para mais informações sobre o auto-config= true veja o quadro Entendendo o auto-config. Figura 2: Login gerado automaticamente pelo Spring Security. Entendendo o auto-config O atributo auto-config da tag na configuração do Spring Security ativa as opções mais usadas do framework, ajudando a diminuir a quantidade de XML necessário. Quando setamos seu valor para true o Spring Security considera o XML como a seguir:

38 <http> <form-login /> <anonymous /> <http-basic /> <logout /> <remember-me /> </http> Isso configura o framework para utilizar autenticação por formulário e http-basic, bem como tratamento de usuários anônimos e previamente autenticados (remember-me). Cada uma das tags possui atributos. Para modificá-los é necessário apenas escrever a tag específica, e o auto-config=true substituirá esta parte da configuração. As tags omitidas continuam sendo consideradas. Por exemplo, o código abaixo muda o JSP do formulário de login e o restante das configurações automáticas continuam aplicadas. Isso configura o framework para utilizar autenticação por formulário e http-basic, bem como tratamento de usuários anônimos e previamente autenticados (remember-me). Cada uma das tags possui atributos. Para modificá-los é necessário apenas escrever a tag específica, e o auto-config=true substituirá esta parte da configuração. As tags omitidas continuam sendo consideradas. Por exemplo, o código abaixo muda o JSP do formulário de login e o restante das configurações automáticas continuam aplicadas. <http auto-config=true> <form-login login-page=/login.jsp/> </http> Desta forma, a última coisa que nos resta é definir os usuários possíveis e seus papéis. No primeiro exemplo, para facilitar, iremos utilizar a tag que permite definir usuários, senhas e roles no próprio arquivo XML (também é possível referenciar um arquivo de propriedades). Normalmente, em uma aplicação real, não é viável definir os usuários em arquivo. Nos próximos exemplos iremos apresentar alternativas. Últimos passos O esqueleto do projeto, juntamente com os JARs necessários para rodar os exemplos, podem ser vistos da Figura 3. Para ajudar na depuração da aplicação, através de log, criamos o arquivo log4j.properties e adicionamos o log4j.jar ao classpath. O JAR do banco de dados HSQL-DB está presente pois será utilizado em breve, nos próximos exemplos. O resto das bibliotecas são dependências do Spring Security. Os JARs estão disponíveis no download dessa edição no site da Java Magazine. Com os três JSPs, o web.xml, o spring-security-config.xml e os JARs necessários, podemos executar a aplicação. O deploy pode ser realizado em qualquer servidor da preferência do leitor, pois o Spring Security não requer configurações adicionais dependentes de container. Executando o exemplo Ao acessar o index da aplicação (Figura 1) dois links serão apresentados. Ao clicar em algum deles, por exemplo /usuarios/index.jsp, o filtro do Spring Security irá detectar como uma página protegida e irá gerar automaticamente o HTML para o login (Figura 2). Um usuário normal, ao logar-se, terá acesso à página de usuários, mas não à de administradores. Já o administrador tem acesso a ambas as páginas. Note que o serviço de remeber-me para o login já está funcionando. O exemplo é bastante simples, mas já cobre alguns dos principais conceitos e casos de uso. Utilizando algoritmos de hash para senhas Figura 3: Arquivos do primeiro exemplo.

39 No primeiro exemplo as senhas dos usuários estão visíveis aos administradores da aplicação. Isto apresenta um risco de segurança. Um algoritmo de hash é normalmente usado em uma aplicação real, impossibilitando o acesso à senha original. Para tal, o Spring Security oferece a tag. São oferecidos os principais algoritmos de hash e também é possível criar uma implementação customizada. A Listagem 3 aplica o algoritmo md5 como password-encoder. Listagem 3. spring-security-config.xml - Utilizando um password-encoder <beans:beans (...) > (...) <authentication-provider> <password-encoder hash="md5" /> <user-service> <user name="joao" password="202cb962ac59075b964b07152d234b70" authorities="role_usuario" /> <user name="admin" password="202cb962ac59075b964b07152d234b70" authorities="role_admin" /> </user-service> </authentication-provider> (...) </beans:beans> <beans:beans (...) > (...) <authentication-provider> <password-encoder hash="md5" /> <user-service> <user name="joao" password="202cb962ac59075b964b07152d234b70" authorities="role_usuario" /> <user name="admin" password="202cb962ac59075b964b07152d234b70" authorities="role_admin" /> </user-service> </authentication-provider> (...) </beans:beans> Para gerar rapidamente um hash md5 para utilizar nos exemplos o leitor pode implementar uma classe Java simples de utilidade ou acessar um gerador online (veja Links). Formulário personalizado A geração automática de formulário é útil apenas para testes. Uma aplicação real necessita de uma página de formulário customizada. Iremos criar um JSP (/login.jsp) com um formulário para o nosso exemplo. Para isso acrescentamos este trecho dentro da tag no spring-security-config.xml: <form-login login-page="/login.jsp" authentication-failure-url= "/login.jsp?login_error=true" /> O atributo authentication-failure-url configura o JSP que será apresentado caso o login falhe. Neste caso configuramos o mesmo JSP do formulário de login com um parâmetro login_error=true. Esse parâmetro é utilizado pelo JSP de login da Listagem 4. Listagem 4. login.jsp - Página de login <html> <head> <title>spring Security</title> </head> <body> <h1>spring Security</h1><hr/> <p> <% if (request.getparameter ("login_error")!= null) { %> <font color="red">

40 Não foi possível se autenticar.<br/> Motivo: ${SPRING_SECURITY_LAST_ EXCEPTION.message. </font> <% %> </p> <form action= "j_spring_security_check" method="post"> Login: <input type=text name=j_username value="${not empty login_error? SPRING_SECURITY_LAST_USERNAME : " /> Senha: <input type=password name=j_password> <input type="checkbox" name="_spring_security_remember_me" /> Salvar as minhas informações neste computador? <input name="submit" type="submit" value= Login /> <input name="reset" type="reset" value= Limpar /> </form> <a href="index.jsp">voltar...</a><br> </body> </html> Os exemplos demonstrados utilizam Scriplets (código Java no JSP) apenas por questões didáticas. Uma aplicação real estaria utilizando a taglib JSTL. No topo do JSP, abaixo do título, testamos se o parâmetro login_error é igual a true. Caso verdade (o login falhou) então mostramos uma mensagem de erro. A expressão $ {SPRING_SECURITY_LAST_EXCEPTION.message recupera a última mensagem de erro gerada pelo framework. Essa mensagem por default está em inglês, mas pode ser internacionalizada. Em seguida codificamos o formulário. Por default a action do formulário de login deve ser j_spring_security_check e o name dos inputs de usuário e senha j_username e j_password, respectivamente. No nosso exemplo, para habilitar o remember-me, adicionamos um checkbox com o name _spring_security_remember_me. Esse JSP gera a imagem da Figura 4. Figura 4: Página de login customizada Logout O atributo auto-config=true da tag <http> já configura uma URL default para realizar o logout, /j_spring_security_logout. Ao clicar em um link apontando para esta URL o logout é realizado. Caso necessário, é possível modificar a URL acrescentado a tag <logout> dentro da tag <http>: Quando um usuário normal acessa a página protegida dos administradores o container apresenta uma

41 mensagem padrão para o erro 403 (access denied). Essa página pode ser personalizada pelo Spring Security acrescentando o atributo access-denied-page à tag : <http access-denied-page="/accessdenied.jsp" (...) > E então, criamos o accessdenied.jsp conforme a Listagem 5. Listagem 5. accessdenied.jsp - Página de erro <html> <body> <h1>spring Security</h1><hr/> <p><font color="red">acesso negado. O usuário não tem permissão para acessar essa página.</font><p> <p>remote user...: <%= request.getremoteuser() %></p> <p>user principal...: <%= request.getuserprincipal() %></p> <a href="../">voltar...</a><br> <a href="../j_spring_security_logout"> Logout</a><br> </body> </html> Formulário de login embutido em outras páginas Quem tem experiência com a segurança tradicional Java EE sabe que não é possível acessar o JSP de login diretamente pela aplicação. O container deve apresentar este JSP quando uma página protegida é acessada. Essa limitação cria outros problemas, por exemplo, quando um portal deseja que o formulário de login esteja contido em todas as áreas do site. Nesse caso, os desenvolvedores se obrigam a criar algum mecanismo utilizando JavaScript para contornar a situação. No Spring Security tais limitações simplesmente não existem. Quando o usuário acessa diretamente o JSP de login, ou quando um formulário de login embutido é utilizado, o Spring Security utiliza uma URL default para redirecionar o usuário. A tag <form-login> possui um atributo default-target-url que indica esta URL (se não informada o default é a raiz da aplicação). Por exemplo, se o formulário for configurado desta forma: <form-login default-target-url="/index.jsp" (...) /> Sempre que o formulário de login for acessado diretamente, após logar-se, o /index.jsp será carregado. Caso o usuário acessar uma página protegida, após logar-se, esta será a página exibida e não o /index.jsp. Se o atributo always-use-default-target for true o usuário sempre será redirecionado para o /index.jsp. Autenticação utilizando banco de dados A última modificação necessária para tornar o exemplo realístico é adicionar um banco de dados, substituindo a configuração dos usuários e roles do XML. Um modelo de dados típico para uma aplicação web, de maneira simplificada, é algo parecido com as tabelas da Figura 5. Figura 5: Modelo de dados para armazenar os usuários, senhas e perfis.

42 Apesar de não ser necessário no nosso exemplo, criamos uma tabela de junção entre as tabelas de usuário e perfil para termos uma relação NxN. Este cenário é muito comum em aplicações enterprise. O campo chamado ativo na tabela de usuários serve para impedir que usuários bloqueados autentiquemse. Caso este campo for false o usuário está com o acesso bloqueado. O campo tentativas_login armazena o número de vezes que o usuário errou a senha consecutivamente. Esse campo será utilizado apenas em exemplos posteriores. O download do artigo traz dois scripts para serem executados no banco de dados HSQL. Um script cria as tabelas e outro cria alguns usuários para teste. Para rodar o HSQL basta executar este comando no prompt do sistema operacional (considerando que o jar do HSQL está no diretório corrente): java -cp hsqldb jar org.hsqldb.server Logo após, abra outro prompt e execute o comando para abrir o console SQL com interface gráfica: java -cp hsqldb jar org.hsqldb.util.databasemanagerswing Selecione a opção HSQL Database Engine Server e pressione OK. Ao abrir o console execute os dois scripts para criar e popular as tabelas. Feche o console, mas mantenha sempre o prompt do servidor HSQL rodando. Alterar a configuração do Spring Security para considerar as tabelas é algo muito simples, pressupondo que o banco de dados está corretamente configurado. Duas modificações são necessárias: substituir a tag por uma tag e acrescentar um spring bean para a configuração do banco de dados (data-source). A Listagem 6 demonstra o novo spring-security-config.xml. Listagem 6. spring-security-config.xml - Adicionando autenticação com banco de dados <beans:beans (...)> <http auto-config="true" access-denied-page= "/accessdenied.jsp"> <intercept-url pattern="/usuarios/**" access="role_usuario,role_admin" /> <intercept-url pattern="/admin/**" access="role_admin" /> <form-login login-page="/login.jsp" authentication-failure-url= "/login.jsp?login_error=true" default-target-url="/index.jsp" /> </http> <authentication-provider> <password-encoder hash="md5" /> <jdbc-user-service data-source-ref="datasource" users-by-username-query="select login as username, senha as password, ativo as enabled from usuario where login =?" authorities-by-username-query="select u.login as username, p.descricao as authority from usuario u join usuario_perfil up on u.login = up.login join perfil p on up.id_perfil = p.id_perfil where u.login =?" /> </authentication-provider> <beans:bean id="datasource" class="org.springframework.jdbc. datasource.drivermanagerdatasource"> <beans:property name="url" value="jdbc:hsqldb:hsql://localhost" /> <beans:property name="driverclassname" value="org.hsqldb.jdbcdriver" /> <beans:property name="username" value="sa" /> <beans:property name="password" value="" /> </beans:bean> </beans:beans>

43 Precisamos de três atributos para configurar a tag. O primeiro atributo é uma referência para a configuração do banco de dados que será utilizado (data-source-ref). O segundo é a query que será utilizada para buscar os usuários dado um username (users-by-username-query). Essa query necessita retornar três colunas esperadas pelo Spring Security: username, password e enabled. Mapeamos as colunas do nosso modelo para as esperadas pela query. Por último, uma query para buscar os roles (authorities) do usuário, dado um username (authorities-by-username-query). Essa query retorna um username e a authority (role). Isso permite ao framework realizar as queries no banco e utilizar as informações retornadas para autenticação. No final do arquivo de configuração adicionamos um bean datasource e o configuramos para acesso ao banco de dados HSQL. Repare que utilizamos a classe DriverManagerDataSource que serve apenas para propósitos de teste. Em uma aplicação real configuraríamos um pool de conexões como data-source, normalmente oferecido pelo container através de um nome JNDI. Eventos de autenticação e autorização O Spring Security utiliza a infra-estrutura do application context do Spring para publicar eventos referentes a momentos importantes em seu fluxo de execução. Existem duas categorias de eventos: eventos de autenticação e eventos de autorização. Para cada situação existe um evento correspondente. Por exemplo, quando uma autenticação ocorre com sucesso, um evento AuthenticationSuccessEvent é publicado; quando a autenticação falha porque a senha está errada, um evento AuthenticationFailureBadCredentialsEvent publicado; se a autenticação falha porque o usuário está inativo, um evento AuthenticationFailureDisabledEvent ocorre; e assim por diante. O Spring Security utiliza a infra-estrutura do application context do Spring para publicar eventos referentes a momentos importantes em seu fluxo de execução. Existem duas categorias de eventos: eventos de autenticação e eventos de autorização. Para cada situação existe um evento correspondente. Por exemplo, quando uma autenticação ocorre com sucesso, um evento AuthenticationSuccessEvent é publicado; quando a autenticação falha porque a senha está errada, um evento AuthenticationFailureBadCredentialsEvent é publicado; se a autenticação falha porque o usuário está inativo, um evento AuthenticationFailureDisabledEvent ocorre; e assim por diante. Quando uma URL é acessada e o filtro do Spring Security verifica se o usuário tem autorização para acessar a URL, eventos de sucesso ou falha também são publicados. Veja na Figura 6 uma hierarquia de eventos de autenticação e autorização. Consulte o Javadoc de cada classe para entender o momento em que cada evento é publicado. Figura 6: Eventos de autenticação e autorização publicados pelo Spring Security. Para ouvirmos aos eventos acima é necessário implementar a interface ApplicationListener e registrar a classe no application context. A Listagem 7 demonstra um exemplo simples de como ouvir a eventos de sucesso ou falha na autenticação. Listagem 7. TestEventListener.java - Ouve eventos de autenticação publicados pelo Spring Security public class TestEventListener implements

44 ApplicationListener { public void onapplicationevent (ApplicationEvent event) { if (event instanceof AuthenticationSuccessEvent) { System.out.println ("Usuário autenticado com sucesso"); if (event instanceof AbstractAuthenticationFailureEvent) { System.out.println ("Usuário não autenticado"); Lembre-se de adicionar o novo bean no application context: <beans:bean class="br.com.jm.security. TestEventListener" /> Essa funcionalidade permite implementar complexos casos de uso, com baixo acoplamento entre a aplicação e o Spring Security, como veremos em um exemplo adiante. Para facilitar o aprendizado de quando os eventos ocorrem, registre dois listeners que vêm juntos com a distribuição do Spring Security, como a seguir: <beans:bean class="org.springframework.security.event. authorization.loggerlistener" /> <beans:bean class="org.springframework.security.event. authentication.loggerlistener" /> Estes listeners efetuam log de todos os eventos que ocorrem, de autenticação e autorização. Uma ótima forma de aprender o funcionamento do framework é a análise do log gerado por estes listeners. Explorando os pontos de extensão Escolhemos um caso de uso para demonstrar como os eventos de autenticação são úteis e como é fácil customizar o framework. Cada vez que um usuário errar a senha por três vezes consecutivas, a sua conta será bloqueada. Essa funcionalidade é muito comum em sites que exigem altos padrões de segurança, como bancos por exemplo. A cada erro de autenticação por informar a senha incorreta (evento AuthenticationFailureBadCredentialsEvent) a coluna tentativas_login será incrementada. A cada autenticação com sucesso (evento AuthenticationSuccessEvent) a coluna tentativas_login será zerada. A cada tentativa de login, caso a coluna tentativas_login for igual ou maior que três, a autenticação será bloqueada. Veja na Listagem 8 o listener que atualiza a coluna tentativas_login. Escolhemos um caso de uso para demonstrar como os eventos de autenticação são úteis e como é fácil customizar o framework. Cada vez que um usuário errar a senha por três vezes consecutivas, a sua conta será bloqueada. Essa funcionalidade é muito comum em sites que exigem altos padrões de segurança, como bancos por exemplo. A cada erro de autenticação por informar a senha incorreta (evento AuthenticationFailureBadCredentialsEvent) a coluna tentativas_login será incrementada. A cada autenticação com sucesso (evento AuthenticationSuccessEvent) a coluna tentativas_login será zerada. A cada tentativa de login, caso a coluna tentativas_login for igual ou maior que três, a autenticação será bloqueada. Veja na Listagem 8 o listener que atualiza a coluna tentativas_login. Listagem 8. IncorrectPasswordEventListener.java - Listener tentativas_login de acordo com o resultado da autenticação public class IncorrectPasswordEventListener extends JdbcDaoSupport implements ApplicationListener { public void onapplicationevent (ApplicationEvent event) { if (event instanceof AuthenticationFailureBadCredentialsEvent) { AuthenticationFailureBadCredentialsEvent badcredentialsevent = (AuthenticationFailureBadCredentialsEvent) event; que atualiza a coluna

45 String sql = "update Usuario set tentativas_login = tentativas_login + 1 where login =?"; this.executesql(badcredentialsevent, sql); if (event instanceof AuthenticationSuccessEvent) { AuthenticationSuccessEvent successevent = (AuthenticationSuccessEvent) event; String sql = "update Usuario set tentativas_login = 0 where login =?"; this.executesql(successevent, sql); private void executesql(abstractauthenticationevent event, String sql) { getjdbctemplate().update(sql, new Object[] {event.getauthentication().getname()); public class IncorrectPasswordEventListener extends JdbcDaoSupport implements ApplicationListener { public void onapplicationevent(applicationevent event) { if (event instanceof AuthenticationFailureBadCredentialsEvent) { AuthenticationFailureBadCredentialsEvent badcredentialsevent = (AuthenticationFailureBadCredentialsEvent) event; String sql = "update Usuario set tentativas_login = tentativas_login + 1 where login =?"; this.executesql(badcredentialsevent, sql); if (event instanceof AuthenticationSuccessEvent) { AuthenticationSuccessEvent successevent = (AuthenticationSuccessEvent) event; String sql = "update Usuario set tentativas_login = 0 where login =?"; this.executesql(successevent, sql); private void executesql (AbstractAuthenticationEvent event, String sql) { getjdbctemplate().update(sql, new Object[]{event.getAuthentication().getName()); Para completar o exemplo ainda é necessário bloquear o login caso a coluna seja maior ou igual a três. Para isso iremos explorar um ponto de extensão comumente utilizado no Spring Security, a interface UserDetailsService. Essa interface possui o método loaduserbyusername() que recupera os dados de um usuário dado seu username. Veja a Listagem 9. Listagem 9. Interface implementado UserDetailsService e o método loaduserbyusername() public class CustomUserDetailsService implements UserDetailsService { public UserDetails loaduserbyusername(string username) throws UsernameNotFoundException, DataAccessException { //retorna um objeto representado o usuário a ser autenticado a ser

46 return null; Uma implementação dessa interface substitui as tags (usuários em XML ou arquivo de propriedades) ou (usuários em banco de dados) que vimos até agora. Sendo assim, através dessa implementação, o usuário do framework tem liberdade para buscar as informações de onde necessitar e da forma que quiser. Entretanto, o motivo mais comum para implementar a interface não é a escolha de uma nova fonte de dados e sim, a personalização do objeto UserDetails de retorno. A interface UserDetails é implementada por objetos que representam o usuário no seu modelo de domínio. Ela possui métodos para retornar o username, o password, as authorities e quatro booleans representando diferentes motivos para bloqueio do login: enabled, accountnonlocked, accountnonexpired e credentialsnonexpired. Sendo assim, criamos uma classe Usuario para implementar a interface, veja a Listagem 10. Listagem 10. Usuario.java - Objeto do modelo de domínio que implementa a interface UserDetails public class Usuario implements UserDetails { private String login; private String senha; private String ; private boolean ativo; private Integer tentativaslogin; private GrantedAuthority[] authorities; public String getusername() { return this.login; public String getpassword() { return this.senha; public GrantedAuthority[] getauthorities() { return this.authorities; public boolean isenabled() { return this.ativo; public boolean isaccountnonlocked() { return this.tentativaslogin < 3;

47 public boolean isaccountnonexpired() { return true; public boolean iscredentialsnonexpired() { return true; // --- restante dos getters and setters omitidos -- Caso qualquer um dos métodos que retornam boolean retornar false o login será bloqueado e uma mensagem adequada será apresentada. Nesse caso não iremos utilizar as propriedades de conta ou senha expirada, então retornarmos sempre true nos métodos isaccountnonexpired() e iscredentialsnonexpired(). Para o método isenable() utilizamos o valor da coluna ativo no banco de dados e para o método isaccountnonlocked() utilizamos nossa regra de negócios: bloquear o login caso três ou mais tentativas de login tenham sido feitas com a senha incorreta. Para conectar as implementações precisamos de uma classe que implemente a interface UserDetailsService. Entretanto, queremos continuar utilizando um banco de dados para armazenar os usuários e apenas retornar um objeto Usuario com informações adicionais, as colunas e tentativas_login. Para não duplicarmos código sem necessidade, iremos estender uma classe do Spring Security que já nos oferece um ponto de extensão justamente para estes casos. A classe JdbcDaoImpl é a classe por trás da tag. Essa classe já implementa o método loaduserbyusername() e nos deixa uma extensão valiosa, o método createuserdetails(). Esse método é um gancho para retornar um UserDetails customizado. Veja a Listagem 11. Listagem 11. CustomUserDetailsService.java - Estende a classe JdbcDaoImpl para modificar o UserDetails de retorno public class CustomUserDetailsService extends JdbcDaoImpl { protected UserDetails createuserdetails (String username, UserDetails userfromuserquery, GrantedAuthority[] combinedauthorities) { Usuario usuario = new Usuario(); usuario.setlogin (userfromuserquery.getusername()); usuario.setsenha (userfromuserquery.getpassword()); usuario.setativo (userfromuserquery.isenabled()); usuario.setauthorities (combinedauthorities); this.carregarinformacoesadicionais (usuario); return usuario; private void carregarinformacoesadicionais (final Usuario usuario) { String sql = "select , tentativas_login from Usuario where login =?"; getjdbctemplate().query(sql, new Object[] {usuario.getusername(), new RowMapper() { public Object maprow(resultset rs, int rownum)

48 throws SQLException { usuario.set (rs.getstring(" ")); usuario.settentativaslogin(rs.getint ("tentativas_login")); return null; ); O método createuserdetails() apenas copia propriedades que já estão disponíveis e chama o método carregarinformacoesadicionais() que faz uma query para preencher as propriedades restantes: e tentativas_login. A implementação do caso de uso está completa. A classe CustomUserDetailsService é utilizada para buscar as informações de um usuário e retornar um UserDetails do nosso domínio. Após a execução do método loaduserbyusername() as propriedades booleanas do Usuario são testadas. Nesse caso, o getter da propriedade accountnonlocked testa se a coluna tentativas_login é igual ou maior que três. Por fim, para controlar o incremento da coluna, os eventos de sucesso e falha na autenticação são tratados pela classe IncorrectPasswordEventListener. O novo spring-security-config.xml é demonstrado na Listagem 12. Listagem 12. spring-security-config.xml - Versão final do XML de configuração refletindo o exemplo de bloqueio de login <beans:beans (...) > <http auto-config="true" access-denied-page="/accessdenied.jsp"> <intercept-url pattern="/usuarios/**" access="role_usuario,role_admin" /> <intercept-url pattern="/admin/**" access="role_admin" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp? login_error=true" default-target-url="/index.jsp" /> </http> <authentication-provider user-service-ref="customuserservice"> <password-encoder hash="md5" /> </authentication-provider> <beans:bean id="customuserservice" class="br.com.jm.security. CustomUserDetailsService"> <beans:property name="datasource" ref="datasource" /> <beans:property name="usersbyusernamequery" value="select login as username, senha as password, ativo as enabled from usuario where login =?" /> <beans:property name= "authoritiesbyusernamequery" value="select u.login as username, p.descricao as authority from usuario u join usuario_perfil up on u. login = up.login join perfil p on up.id_perfil = p.id_perfil where u.login =?" /> </beans:bean> <beans:bean id="datasource" class="org.springframework.jdbc. datasource.drivermanagerdatasource"> <beans:property name="url" value="jdbc:hsqldb:hsql://localhost" /> <beans:property name="driverclassname" value="org.hsqldb.jdbcdriver" />

49 <beans:property name= "username" value="sa" /> <beans:property name= "password" value="" /> </beans:bean> <beans:bean class="br.com.jm.security. IncorrectPasswordEventListener"> <beans:property name="datasource" ref="datasource" /> </beans:bean> <beans:bean class= "org.springframework.security. event.authorization.loggerlistener" /> <beans:bean class= "org.springframework.security. event.authentication.loggerlistener" /> </beans:beans> A principal diferença do novo XML é a tag. Retiramos o e fizemos uma referência para o bean customuserservice. Como a classe CustomUserServiceDetails estende JdbcDaoImpl as propriedades das queries continuam existindo. Sendo assim, copiamos as propriedades da antiga para o novo bean. Outra diferença importante é a adição do IncorrectPasswordEventListener no final do arquivo. Integração com a API de servlets O filtro do Spring Security substitui a implementação original da interface ServletRequest por um wrapper (extensão da classe ServletRequestWrapper). Este wrapper implementa os métodos relacionados a segurança na interface ServletRequest: getremoteuser(), isuserinrole() e getuserprincipal(). Dessa forma, é possível utilizar os métodos tradicionais do Java EE como de costume, sem diferenças. Por exemplo, veja o trecho de código a seguir: String role = request.getremoteuser(); System.out.println("Role: " + role); System.out.println (request.isuserinrole ("ROLE_USUARIO")); System.out.println (request.isuserinrole ("ROLE_ADMIN")); Este código funciona perfeitamente com o Spring Security. Se o usuário admin (com perfil de administrador) estiver logado, então a seqüência a ser impressa no console será: Role: admin false true O método getuserprincipal() retorna um objeto que implementa a interface org.springframework. security.authentication. Através desse objeto é possível retornar o usuário logado, como a seguir: public Usuario getusuariologado(httpservletrequest request) { Authentication authentication = (Authentication) request.getuserprincipal(); if (authentication == null) return null; return (Usuario) authentication.getprincipal(); Outra forma de se obter o usuário logado, porém sem necessitar do HttpServletRequest, é através da classe SecurityContextHolder. Essa classe mantém o objeto Authentication em uma variável thread-local. O método a seguir pode ser implementado em uma classe de utilidade e pode ser chamado em qualquer ponto da aplicação: public static Usuario getusuariologado() { Authentication authentication = (Authentication) SecurityContextHolder.getContext().getAuthentication();

50 if (authentication instanceof Usuario) { return (Usuario) authentication.getprincipal(); return null; Utilizando as taglibs O Spring Security fornece duas tags úteis para codificação de JSPs: e. Ambas podem ser importadas com a declaração a seguir: taglib prefix="sec" uri="http://www.spring framework.org/security/tags" %> A tag <authorize> é utilizada para mostrar/esconder informações de acordo com as permissões (roles) do usuário. Veja o código a seguir: <sec:authorize ifallgranted="role_admin"> <p>você é um administrador href="../admin/index.jsp">página</a>.<p> </sec:authorize> e também pode acessar esta <a A tag possui três atributos exclusivos: ifallgranted, ifanygranted e ifnotgranted. Todos os atributos suportam um ou mais roles separados por vírgula. O atributo ifallgranted informa que o usuário tem que <Authentication>permite acessar as propriedades do objeto Authentication do usuário logado no JSP. Por exemplo, o trecho de código a seguir, codificado no index.jsp, irá exibir as informações do usuário utilizando a tag <Authentication>: <sec:authorize ifanygranted="role_admin,role_usuario"> <b>informações do usuário logado:</b><br> Login: <sec:authentication property="principal.login" /><br> Senha: <sec:authentication property="principal.senha" /><br> <sec:authentication property="principal. " /><br> <a href="j_spring_security_logout">logout</a><br> </sec:authorize> O vídeo Spring Security apresenta como realizar o controle de sessões, trabalhar com HTTPS e autenticação através de certificados digitais. Conclusões Com os exemplos demonstrados podemos ver alguns dos principais casos de uso de segurança em uma aplicação web. O Spring Security centraliza as configurações em apenas um arquivo que será empacotado juntamente com o war da aplicação, dispensando configurações externas do container. A aplicação não fica apenas mais enxuta, como também mais extensível, como vimos através da interface UserDetailsService e dos eventos de autenticação e autorização. Dessa forma é possível implementar casos complexos de gerenciamento de usuários, de forma desacoplada do domínio de negócios da aplicação. Alguns assuntos não foram abordados no artigo por motivo de espaço, porém o leitor pode consultar a documentação no site do framework. Algumas funcionalidades oferecidas pelo Spring Security e não apresentadas são: segurança a nível de métodos (utilizando anotações e AOP), suporte a HTTPS, controle de sessões concorrentes e diferentes formas de autenticação, como certificados X509, LDAP, etc. Para mais informações sobre single sign on consulte o quadro Single sign on com CAS e OpenID. Single sign on com CAS e OpenID Autenticação single sign on significa logar-se em uma aplicação e permanecer logado ao acessar outra aplicação do mesmo grupo. Essa funcionalidade é comumente oferecida por containers para as aplicações as quais ele gerencia. O Spring Security oferece suporte a single sign on para aplicações intranet através do Central Authentication Service (CAS) e aplicações internet através do OpenID. O CAS é uma aplicação web (arquivo WAR) que é responsável por apresentar as telas de login das aplicações do mesmo grupo. Basicamente, todas as aplicações do grupo irão redirecionar o browser para a aplicação central na hora da autenticação, e após o login, o CAS irá retornar a URL para a aplicação que

51 solicitou o login. Dessa forma, as configurações de autenticação ficam no WAR do CAS e nos demais WARs o Spring Security é usado para realizar a integração. Uma vantagem do CAS é o fato de existirem clientes para diversas linguagens como Java,.Net, PHP, Perl, etc. permitindo integração entre aplicações heterogêneas. O OpenID, por sua vez, elimina a necessidade de ter vários logins em diferentes sites na internet. Ao criar um login em um dos providers de OpenID (veja Links) é possível utilizar o username e senha para acessar todos os sites que o suportam, sem necessitar logar-se múltiplas vezes. Grandes empresas já suportam o padrão como Sun, Google, IBM, Microsoft, etc. O Spring Security facilita o processo de habilitar sua aplicação para suportar logins provenientes de providers OpenID. Nota Devman - Wrapper Um objeto wrapper é uma implementação do padrão de projeto Decorator. O objetivo deste desing pattern é adicionar ou substituir o comportamento de classes existentes de forma dinâmica. Isto é feito criando uma classe base, normalmente com o sufixo Wrapper ou Decorator, que implementa a interface a ser decorada e também recebe como parâmetro no construtor um objeto da mesma interface. Em seguida, todos os métodos da classe são implementados delegando para o objeto recebido no construtor. Por fim, quando se deseja adicionar ou mudar o comportamento da interface, basta estender o Wrapper e sobre-escrever os métodos desejados. Links Portal do Spring Framework e sub-projetos static.springframework.org/spring-security/site/index.html Acesso direto à home page do Spring Security springide.org/blog Download do Spring IDE (plugin para o Eclipse) Homepage do projeto CAS openid.net Homepage do OpenID Provider de logins OpenID md5-hash-online.waraxe.us Gerador online de hash md5 Saiba Mais Curso Online - Trabalhando com Struts 2 em conjunto com Sitemesh, Spring e JPA Curso Online - Java Web: Saiba como Desenvolver Aplicações utilizando Spring, Hibernate e JSF na Prática Java Magazine 40 - Começando com Spring Java Magazine 45 - Indo além com Spring Java Magazine 46 - Integrando Spring com JSF e JDBC Java Magazine 50 - Spring com Struts e JPA Java Magazine 53 - Spring Remoting

52 Java Magazine 60 - Enviando s com Spring 2.5 Java Magazine 65 - Spring e Java EE 6 estão na mesma direção? Java Magazine 65 - Criando uma aplicação web com Spring Framework

53 JavaFX Script Osvaldo Pinali Doederlein é Mestre em Engenharia de Software Orientado a Objetos e Arquiteto de Tecnologia da Visionnaire Informática, trabalhando em projetos de software e prospecção tecnológica. De que se trata o artigo: Apresentamos uma referência da linguagem JavaFX Script, que faz parte da plataforma JavaFX. Para que serve: JavaFX é a nova plataforma RIA da Sun, compatível com Java SE e Java ME, já apresentadas em artigos anteriores desta série. Alguns leitores podem encarar a exigência de aprender uma nova linguagem de programação como um obstáculo, mas este aprendizado é facilitado pela semelhança entre JavaFX Script e Java - tiramos proveito desta semelhança para explicar a nova linguagem de forma concisa. Mesmo para quem já aprendeu JavaFX Script, o artigo serve como uma referência bem organizada e pragmática (ao contrário da referência oficial, que tem uma estrutura mais formal, certamente mais detalhada, mas não adequada à facilidade de consulta e sem pretensões didáticas). Em que situação o tema é útil: A linguagem JavaFX Script é um pré-requisito para desenvolver para a plataforma JavaFX, a qual promete grande produtividade, mas (com qualquer plataforma) somente após vencer uma curva inicial de aprendizado. Mesmo para quem não tiver grande interesse na JavaFX, o artigo apresenta muitas inovações da JavaFX Script que são um aprendizado valioso para qualquer interessado em linguagens de programação. Na Edição 67 apresentamos a plataforma JavaFX, introduzindo-a de forma conceitual e dando alguns aperitivos das suas funcionalidades e programação. Na Edição anterior (68), seguimos com um primeiro tutorial de programação JavaFX, ensinando o básico da linguagem e framework de uma forma prática, mas bastante informal. Agora, encerrando esta cobertura inicial da JavaFX, vamos nos focar apenas na linguagem JavaFX Script, cobrindo-a de uma forma mais formal e abrangente. (Para o leitor ainda pouco motivado a aprender JavaFX Script, seria boa idéia começar pelo quadro Por que uma nova linguagem?.) Não é meu objetivo repetir o documento de Referência da Linguagem de Programação JavaFX Script que está disponível em openjfx.dev.java.net/langref. Ao invés disso, a idéia é explicar a linguagem de uma forma concisa e pragmática, tendo como alvo não alguém que vai escrever um compilador ou outra ferramenta que exige conhecimento formal da linguagem, mas um desenvolvedor que deseja vencer a curva de aprendizado da sua sintaxe ou então ter uma referência de fácil consulta. Ainda mais especificamente, escrevo pensando no programador que já conhece bem a linguagem Java, o que permitirá resumir ou omitir explicações dos pontos onde ambas as linguagens forem iguais ou muito parecidas (e são muitos pontos). Assim, podemos concentrar nosso tempo e neurônios nas partes que são diferentes. O artigo é organizado como uma referência da linguagem, agrupando suas funcionalidades em seções como Valores, Operadores, Classes etc., de forma similar a uma referência formal. No entanto, fiz este agrupamento de uma forma relaxada segundo critérios conceituais e não de gramática formal. Por exemplo, a seção de Operadores não possui todos os operadores, pois alguns deles são cobertos em outras seções (ex.: os diversos operadores específicos para sequences são mostrados na seção

54 Sequences). Também não me preocupei em documentar minimamente alguns aspectos mais elementares da linguagem que são exatamente idênticos a Java, por exemplo a sintaxe para números literais. A intenção é ter um texto o mais compacto e didático possível, mas ainda assim, suficientemente organizado e formal para servir como referência da linguagem. No decorrer do artigo, uso o termo JavaFX no lugar de JavaFX Script, por simplicidade. Tipos e Valores O sistema de tipos da JavaFX é inspirado no Java, mas com melhorias importantes. Na Tabela 1, classifiquei os tipos da JavaFX em cinco categorias e comparei-os aos tipos equivalentes em Java. Vamos comentar apenas as novidades desta tabela. Tabela 1: Classificações de tipos da JavaFX, comparativamente com Java. Valores A maior novidade é que o typesystem de JavaFX é OO-puro: não existem tipos primitivos. Por outro lado, existem tipos de valor, que são aqueles cuja igualdade de referência é equivalente à igualdade de valor (em outras palavras: x == y se e somente se x.equals(y)). Os tipos primitivos do Java, como int, são tipos de valor, por isso não há dois valores 17 distintos, por exemplo. O mesmo vale para o Integer da JavaFX. Além disso, os valores são imutáveis, e não admitem null. A diferença entre esses tipos da JavaFX e os tipos primitivos do Java é que os tipos de valor são objetos. Em JavaFX, todos os tipos, sem exceção, são derivados de Object. Em termos de implementação, os valores de JavaFX são equivalentes aos primitivos de Java, evitando o custo de desempenho de usar objetos. Por exemplo, se você olhar o arquivo.class gerado pelo javafxc para uma função que recebe um parâmetro Integer, verá que o bytecode compilado irá conter um método que recebe um int primitivo. Somente quando um valor é utilizado em alguma operação que

55 exige sua faceta OO, a JavaFX faz uma conversão automática para um objeto. Você pode considerar isso uma versão melhorada do autoboxing de Java 5. As melhorias incluem a simplificação (não há tipos paralelos como int/integer) e desempenho (o compilador, runtime e frameworks usam várias técnicas para representar valores na forma primitiva, e reduzir ao mínimo as conversões de/para a forma OO). Strings Menção honrosa vai para o tipo String da JavaFX Script, que ao contrário de Java, é definido como um value type. Além disso, carrega um lote de funcionalidades extra: O valor default de uma String não inicializada é "" (string vazia). É impossível ter uma string null; se você fizer esta atribuição, fica com "". Nunca acontecerá uma NullPointerException envolvendo strings (ou qualquer value type); O operador == equivale a equals(), não há distinção entre igualdade e identidade (novamente, como todos value types); Pode-se mesclar strings com expressões, por exemplo: "Alô, {nome!" será expandido conforme o valor dinâmico da variável nome. Ou então, "Temperatura: {%2.2f temp", a variável temp será formatada no estilo de System.printf() (ex.: %2.2f ,25); Pode ser delimitada por aspas simples ou duplas, ex.: String com "aspas duplas" dentro; Internacionalização é simples: def msg = ##"ERRO" irá atribuir a msg o valor da string associada à chave ERRO no resource bundle da aplicação; se não existir este resource, o valor da string será "ERRO" mesmo. Para separar a chave do valor default, use ##[ERRO]"Deu zebra!"; É o único tipo de JavaFX Script para manipular caracteres. Não existe um tipo específico para um caractere único, como o char do Java. Conversões automáticas são feitas ao invocar classes/apis de Java que utilizam char; ex.: "Osvaldo".charAt(0) = "O". Duration O tipo de valor Duration representa uma quantidade de tempo. Exemplos de literais: 15ms (15 milissegundos), 2.3s (2.3 segundos), 55m (55 minutos), 10h (10 horas), 10h + 5m (10 horas e 5 minutos). Este tipo não passa de um açúcar sintático para um long contendo o tempo normalizado para milissegundos, mas ao usar o framework de animação da JavaFX, você verá que é muito conveniente ter uma sintaxe especial para isso. Void O Void do Java FX significa o mesmo que o do Java, mas é mais útil, ver seção Controle. Referência Os reference types da JavaFX também são familiares. Ver seções sobre funções e sequences. Funções JavaFX Script possui funções de primeira ordem. Exemplo: var validador: function (o:object): Boolean O tipo da variável validador é uma função que possui um parâmetro do tipo Object e retorna um Boolean. Portanto, funções podem ser atribuídas a variáveis, passadas como parâmetro, etc. como quaisquer outros tipos. A linguagem Java possui uma aproximação desta facilidade, combinando interfaces com inner classes - mas o resultado é uma sintaxe confusa. Com a versão muito melhorada de JavaFX, podemos escrever por exemplo um tratador de eventos assim: Stage { onclose: function() { FX.exit() Funções suportam os seguintes modificadores (antes do function): Visibilidade (public, protected, package, e por default script-private); abstract, igual a Java; override, igual do Java 5 (mas é mandatório); bound, que examinaremos em Binding;

56 Não há nada equivalente ao final dos métodos Java. Sequences As sequences da JavaFX Script possuem sintaxe similar, mas significado e capacidades diferentes dos arrays do Java. Em comum com os arrays, as sequences são coleções de objetos de um tipo homogêneo e com tamanho fixo, indexadas a partir da base 0. As diferenças começam com algumas sintaxes facilitadas (syntax sugar), mas vão além. A Tabela 2 exemplifica todas as capacidades e sintaxes específicas para sequences. Algumas coisas são simples - por exemplo, o operador sizeof equivale ao pseudo-atributo length dos arrays do Java; e com o.. você pode especificar ranges (intervalos), que podem ser usados tanto para determinar quais elementos da sequence serão manipulados (como em delete dias[1.. 2]), quanto para criar uma sequence contendo todos os números inteiros do range (como em [ ]).

57 Tabela 2: Sintaxes de uso de sequences. Uma característica importante das sequences é que elas não admitem aninhamento; qualquer tentativa de colocar uma sequence dentro de outra irá gerar uma sequence única com todos os elementos. Por exemplo, o resultado de [ dias, ["Qua, "Qui"] ] não é [ "Dom", "Seg", "Ter", ["Qua, "Qui"] ], e sim [ "Dom", "Seg", "Ter", "Qua, "Qui" ]. Esta transformação é conhecida como flattening (achatamento), e embora possa parecer uma limitação, é uma característica importante do estilo de programação da linguagem. Este estilo incentiva o uso de expressões fluentes - onde o output de cada expressão é usado como input da seguinte, algo similar ao uso de pipes em shell scripts. Para isso funcionar, é preciso que todas as operações utilizem uma estrutura de dados padronizada; no Unix essa estrutura é texto ASCII, em Java FX Script (e outras linguagens) é a lista ou sequence. O leitor expert em outras linguagens que fazem uso pesado de listas/sequences, como as da família LISP,

58 sabe que tais linguagens permitem o uso de estruturas aninhadas. Mas JavaFX Script não pretende ser uma linguagem de programação funcional sofisticada, para quem curte técnicas do tipo map/reduce ; ao invés disso, foi feita a opção por sequences com flattening automático, o que simplifica os cenários de uso mais importantes para JavaFX, por exemplo a inicialização de estruturas complexas como o Scene Graph. Observe a tentativa da JavaFX Script de usar uma sintaxe SQL-like para a manipulação de dados: sintaxes como insert..into, delete..from, o in e o where do for. Num detalhe importante, o leitor pode estar confuso com minha afirmação que as sequences são imutáveis, seguida por uma tabela que indica várias sintaxes para sua alteração. Explico: todas essas sintaxes criam uma nova sequence. Por exemplo: var dias = [ "Dom", "Seg", "Ter" ]; var diasuteis = dias; delete "Dom" from diasuteis; println(diasuteis); // ["Seg", "Ter" ] println(dias); // [ "Dom", "Seg", "Ter" ] No exemplo acima, após a atribuição diasuteis = dias, ambas variáveis apontam para a mesma sequence. Mas em seguida, o delete cria uma nova sequence e a atribui à variável diasuteis; a sequence original continua existindo pois ainda é referenciada por dias. Este truque sintático - operadores como delete e insert, que executam uma atribuição escondida - mantêm a sintaxe familiar para quem não está acostumado ao estilo funcional (no qual nunca, ou raramente, se altera o valor de variáveis preexistentes). Para mais detalhes, veja o quadro Imperativo ou Funcional?. Declarações Nesta seção veremos como JavaFX Script permite declarar variáveis e funções. Na Tabela 3, podemos ver que as variáveis de JavaFX podem ser declaradas com var ou def. A diferença é que o def é usado para constantes (similar às variáveis final do Java), enquanto var indica variáveis propriamente ditas (i.e., cujo valor pode variar).

59 Tabela 3: Declarações de variáveis e funções. As declarações estáticas de tipo são opcionais, mas isso não significa que JavaFX Script seja uma linguagem dinamicamente tipada. Ao contrário, JavaFX é tão estaticamente tipada quanto Java; a diferença é que contamos com inferência de tipos, ou seja, a capacidade do compilador de determinar automaticamente o tipo. No exemplo var x = 5, o tipo de x é estabelecido como Integer, pois este é o tipo do valor 5 com o qual a variável é inicializada. No caso específico das declarações def, como o valor inicial é mandatório, a declaração de tipo jamais é necessária. Também salta aos olhos que JavaFX Script utiliza o estilo Pascal de declarações de tipos, ou seja nome :

60 Tipo ao invés de Tipo nome como em Java. Apesar de parecer uma diferença gratuita e desagradável de Java, você se acostumará e verá que existem bons motivos para isso (o mesmo vale para Scala, que não coincidentemente - também usa inferência de tipos). A mesma sintaxe de declarações pode ser utilizada em três escopos distintos: var x = 5; function x1 () { return x; // Retorna 5 class Y { var x = 6; function x2 () { return x; // Retorna 6 function z () { var x = 7; def f = function x3 () { return x; // Retorna 7 JavaFX suporta variáveis e funções locais, de instância, e globais. Esta última opção parece ser uma novidade, mas de fato não é, pois ocupa o lugar dos static do Java. Se num arquivo Y.fx você tiver um elemento global x, este será acessível externamente com a sintaxe Y.x, ou seja, igual às statics. Em termos de compilação e desempenho, a equivalência também permanece: variáveis e funções globais são transformadas pelo javafxc em variáveis e métodos static. A inferência de tipos também funciona para funções, especialmente o tipo de retorno: raramente é preciso especificá-lo explicitamente, pois ao encontrar por exemplo uma operação return a + b no corpo da função, o javafxc determina que o tipo desta expressão é o tipo estático de retorno a função. Mas alguns programadores podem preferir especificar o tipo de retorno, para ter certeza que este será um tipo específico (neste caso, um return e onde e não possui exatamente o mesmo tipo declarado para retorno, sofrerá uma conversão implícita se possível). O compilador javafxc irá transformar as funções em métodos idênticos aos do Java, com uma assinatura no bytecode que inclui os tipos dos parâmetros e do retorno, sendo que esta assinatura influi na compilação e na compatibilidade binária de outras classes compiladas com invocações ao método (função) em questão. Assim, as funções de JavaFX Script podem ser também invocadas a partir de classes Java, de maneira direta e tipicamente sem nenhum overhead. Os tipos dos parâmetros, surpreendentemente, também podem ser inferidos. Isso é possível se houver pelo menos uma invocação à função no mesmo script, ou em atribuições ou inicializações para uma propriedade tipada como função: function teste (a, b) { a + b println(teste(10, 15)); class A { var b : function (a:string); A { b: function (x) { println(x.charat(0)) No primeiro exemplo, o compilador determina que os parâmetros a e b de teste() são do tipo Number, devido à presença da invocação teste(10, 15). No segundo exemplo, ao compilar a última linha onde instanciamos um objeto do tipo A, a function (x) {... não exige declarar que x é uma String pois esta função está sendo atribuída à propriedade A.b, e para esta atribuição ser válida, a função no lado direito deve ter a mesma assinatura da propriedade no lado esquerdo. Visibilidade JavaFX suporta um conjunto completo de modificadores de visibilidade, de fato, mais completo que Java. Veja a relação completa na Tabela 4. Mais explicações (sobre a necessidade dos novos níveis) na próxima seção. Mas antes de chegar lá, podemos destacar um fato interessante: JavaFX não possui um nível de visibilidade private. Você logo entenderá o motivo.

61 Propriedades JavaFX Script utiliza o termo propriedade ao invés de atributo. Propriedades são atributos de classes, mas com alguns recursos adicionais em comparação com os atributos do Java. Tabela 4: Níveis de visibilidade. A Tabela 5 resume a sintaxe, que complementamos com as seguintes explicações: Não se usa getters ou setters. Propriedades são declaradas com visibilidade pública. Para propriedades que você não deseja que possam ser modificadas arbitrariamente, basta usar os níveis public-init (equivalente a um atributo do Java que só pode ser inicializado por um construtor) ou publicread (equivalente a um atributo do Java que possui getter, mas não setter); Não há construtores. Objetos são instanciados com uma sintaxe de objetos literais; Triggers. As propriedades podem possuir triggers, que são funções invocadas automaticamente quando o valor da função for modificado. Isso substitui a necessidade de setters para alterações não-triviais de propriedades; Binding. O recurso de binding (ver seção Binding) permite manter diversas propriedades associadas entre si de forma automática. Para quem vem de uma linguagem OO tradicional como C++ ou Java, poderão parecer heréticas idéias como não encapsular atributos com getters e setters, ou não dispor de um nível de visibilidade private. Mas analisando a linguagem como um todo, podemos entender seu design. A soma de recursos como visibilidade mais refinada (especialmente public-init e public-read), instanciação estilo JSON, triggers e binding, substitui 99% das necessidades de getters, setters e construtores. Ou seja, seus atributos (opa, propriedades!) continuarão tão bem encapsulados quanto antes, só que com um código bem mais simples - e, de quebra, algumas novas facilidades. Quanto à visibilidade private, esta não existe de fato nem em Java - um membro private de uma classe pode ser acessado por suas classes aninhadas ou inner classes. Classes aninhadas/inner costumam ser fortemente acopladas à sua enclosing class, justificando o acesso privilegiado. Em JavaFX a lógica é igual: todo o código contido por um script.fx é fortemente acoplado (se não for, divida-o em vários scripts). JavaFX só torna explícito e homogêneo um design que, em Java, é acidental e imperfeito. Acidental, pois não era assim no Java mudou no 1.1 quando as classes aninhadas/inner foram criadas. Imperfeito, pois Java permite definir várias classes no mesmo arquivo.java (desde que só uma seja pública), mas não há privilégios de acesso a membros privados entre estas classes - embora o mesmo argumento de alto acoplamento seja válido. Ilustrando de forma mais aplicada as sintaxes de propriedades e construção de objetos, apresento novamente o Alô Mundo da JavaFX:

62 Stage { title: "Aplicação Alô Mundo" width: 250 height: 80 scene: Scene { content: Text { font: Font { size: 24 x: 10, y: 30 content: "Alô, JavaFX!" onclose: function() { FX.exit() O código acima constrói a aplicação completa (ok, faltando só as declarações package e import). Este código instancia (e retorna - ver seção Controle) um objeto Stage. Este objeto é inicializado com o valor 250 para a propriedade width, etc. No caso da propriedade scene, seu valor é um objeto Scene que é inicializado da mesma forma, idem para a propriedade content de Scene. Finalmente, a propriedade onclose tem o tipo function (): Void, sendo inicializada com uma função deste tipo. Teoricamente, você poderia fazer o mesmo em Java, com expressões new aninhadas. Mas há três problemas. Primeiro, os construtores do Java são rígidos - se um objeto com os atributos a, b, ca,b), inicializar apenas a exige passar explicitamente o valor default de b, e inicializar c exige invocar setc() após a construção (saindo além da inicialização hierárquica). O segundo problema é que os frameworks Java não costumam trabalhar com atributos funcionais como onclose, preferindo design patterns como Template Method (um método onclose() que pode ser redefinido) ou Observer (um método como addcloselistener()); ambos suportam uma expressão única de inicialização, mas ao custo de código bem mais confuso devido à horrível sintaxe das inner classes. Terceiro, a invocação de construtores não indica o nome dos argumentos, de forma que expressões de construção longas e/ou aninhadas tendem a ficar difíceis de ler se você não souber de cor qual argumento que vai em cada posição (ou se isso não for evidente pelos valores passados). Alguns frameworks Java modernos adotam o pattern de APIs fluentes no qual métodos terminam com um return this, o que permite encadear expressões como: new X(a).setB(b).setC(c), etc. Um método addxxxlistener() também poderia seguir este design. Mas o resultado, mais uma vez, é bem pouco elegante. Na minha opinião, é uma tentativa pobre de imitar a linguagem Smalltak, na qual o estilo fluente é natural devido à sua sintaxe de mensagens (não há parâmetros posicionais) e ao fato de todos os métodos retornarem this por default (não existe o tipo void). E como, na definição do Java SE 7, os conservadores venceram a briga e ficaremos sem closures, o Java continua condenado a gambiarras pavorosas (ainda que sejam melhor-que-nada) como APIs fluentes. Por que tudo isso é importante - não é muito oba-oba em cima de uma economia de algumas linhas de código para inicializar objetos complexos? Acontece que esta facilidade sintática possui outros efeitos colaterais positivos. Por exemplo, você pode usar a sintaxe de notação de objetos literais do JavaFX para muitas tarefas onde tipicamente usaria XML, resultando num código que é mais enxuto e legível, fácil de emitir e interpretar (como sabe qualquer programador JavaScript que prefere JSON a XML). Um exemplo concreto disso é o formato gráfico FXD (ver Edição 67), nada mais que código JavaFX com inicializações de classes gráficas. Outro exemplo é a construção da árvore de componentes e eventos da GUI, ilustrada acima: este código, além de enxuto e legível, é ideal para manipulação de ferramentas. Por tudo isso, JavaFX dispensa a necessidade de linguagens de descrição de GUI como XAML (Silverlight), MXML (Flex), XUL (Mozilla), layouts do Android, etc. A falta de algo equivalente (uma DSL para GUI & gráficos) não é uma lacuna de JavaFX, pelo contrário, sua presença em plataformas competidoras revela inadequações das linguagens de programação principais destas plataformas. Na JavaFX, o FXD é inclusive bom o suficiente para substituir o formato

63 SVG de gráficos vetoriais. Binding Binding é uma das características mais famosas de JavaFX Script, pois além de ser um poderoso recurso de programação em geral, é uma peça essencial para os frameworks e o estilo de programação da plataforma JavaFX. Se você (como eu) começou aprendendo sobre binding examinando os fontes de diversos demos que só utilizam as duas variantes mais simples deste recurso (bind x = y e criação de objetos com binding igualmente simples em propriedades), poderá se surpreender com a Tabela 6, que mostra uma sofisticação extraordinária. Vamos demonstrar esta capacidade com um exemplo que explora uma das sintaxes complexas, combinado com triggers para logar o que acontece: var dias = [ "Dom", "Seg", "Ter" ] on replace d[i..j] = nd { println("{d[i..j] = {nd") def iniciaisdias = bind for (d in dias) d.charat(0); dias[1..2] = [ "TER", "QUA" ]; Executando o código acima, o output será o seguinte: -> DomSegTer -> DST SegTer -> TERQUA DST -> DTT DTT -> DTQ As duas primeiras linhas são efeito das atribuições dos valores iniciais a dias, e por conseqüência do binding, a iniciaisdias - pois a trigger é disparada inclusive para a atribuição inicial. (Note que ao exibir sequences com o recurso de mesclagem de strings, os elementos são concatenados.) Na terceira linha, que é o que mais nos interessa, SegTer -> TERQUA vemos que o binding de iniciaisdias foi acionado pela atribuição a dias; sendo que esta atribuição modificou apenas dois dos seus elementos. Na quarta e quinta linhas, vemos que o for (d in dias) é reexecutado somente para estes elementos (dias[1..2]), e as alterações de iniciaisdias também são feitas de maneira incremental: repare que são geradas duas alterações independentes para os elementos de índice 1 ("S" "T") e 2 ("T" "Q"), ao invés de uma alteração única que causaria um log "DST -> DTQ". Podemos concluir várias coisas. Primeiro, como já disse, o binding do Java vai bem além daqueles casos simplórios que você viu em javafx.com/samples; é um recurso que pode ser explorado de inúmeras formas. Segundo, as capacidades das sequences do Java são ainda mais incrementadas pelo tratamento especial de outros recursos da linguagem, como triggers e binding - de uma forma geral, a linguagem tenta otimizar o esforço destas operações tornando-as o mais incrementais possíveis (se você tem uma sequence de 1000 elementos e altera apenas um elemento, isso não irá gerar execuções de triggers ou bindings considerando todos os 1000 elementos). Como nada é perfeito, um alerta: binding é pesado, especialmente devido às capacidades de avaliação incremental de sequences e expressões complexas. Para cada variável sujeita a binding e cada expressão bind, o runtime é obrigado a manter na memória estruturas de dados relativamente grandes. É por isso que você pode encontrar na internet algumas pessoas comentando que ficaram horrorizadas ao ver que uma variável Boolean ocupava 100 bytes ou mais. Use este recurso apenas quando necessário (especialmente na JavaFX Mobile). Operadores Já apresentamos alguns operadores da JavaFX especializados em sequences; veremos agora os operadores mais convencionais para manipulação de valores em geral. A Tabela 7 revela algumas das minhas poucas discordâncias do design de JavaFX Script. Alguns operadores desviam de Java, a meu ver gratuitamente: por que, por exemplo, and ao invés de &&? O argumento é que operadores nomeados são mais simples que símbolos misteriosos como &&, mas não

64 engulo isso, lembrando que linguagens RIA competidoras, como JavaScript e ActionScript, utilizam os operadores simbólicos tradicionais da família C. Os operadores simbólicos são mais legíveis pois se destacam de nomes de variáveis e funções; ao ler um código como aa bb && cc, a distinção entre operadores/operandos é imediatamente clara, o que não ocorre para aa or bb and cc - que exige um parsing mental para reconhecer or e and como operadores e as demais palavras como identificadores de variáveis. Pior que isso, vejo algumas inconsistências: a exclamação! foi substituída por not como operador de negação, mas no operador diferente-de!=, continuamos vendo a exclamação indicando negação. Mais: o de [a a > 5] e o where de for (a in b where a > 5) têm exatamente o mesmo significado... nada é perfeito, e na minha opinião, a sintaxe de operadores não-simbólicos é um lugar onde o design de JavaFX Script derrapou. Outras divergências me parecem OK. O operador de typecast as é mais elegante que o do Java, pois sendo posfixado, é coerente com a ordem de avaliação, ex.: dvar * 2.0 as Integer, temos primeiro uma multiplicação entre variáveis Double, depois sua conversão para Integer, e observe também que não precisamos usar parênteses - (dvar * 2.0) as Integer - pois a precedência do as é mais fraca (i.e., o typecast é avaliado depois da maioria dos outros operadores). E o sizeof é um conceito bastante interessante, coerente com o design orientado a expressões de JavaFX Script. JavaFX não possui operadores de manipulação de bits, como, &, ^, ~, <<, >> e >>> do Java. O veterano de C/C++/Java dentro de mim também não gostou disso à primeira vista, mas acabei entendendo, pois estes operadores são de uso muito raro na enorme maioria das aplicações, e JavaFX Script é uma linguagem dedicada à camada de aplicação - não se supõe que alguém vá usá-la para escovações de bits como algoritmos de compressão ou criptografia. Principalmente lembrando que JavaFX é uma linguagem parceira de Java: é trivial invocar métodos de casses Java a partir de JavaFX e vice-versa, misturar ambas classes no mesmo projeto/ide etc. Além disso, JavaFX reserva os tokens << e >> para outro propósito: escape de literais externas. Por exemplo, se você tiver que invocar um método bind() de uma classe Java, pode fazê-lo com obj.<>(argumentos). Sem o escape isso seria ilegal por que bind é uma palavra-chave em JavaFX. Java 7 também terá um mecanismo de escape similar.

65 Controle JavaFX Script, como qualquer linguagem de programação, precisa de estruturas de controle como decisões e loops. Você poderia imaginar que pelo menos nesta área, a linguagem seria praticamente igual a Java. Engano, também aqui JavaFX apresenta inovações poderosas, muito embora mantenha uma boa similaridade sintática com Java. Veja a Tabela 8. Tabela 5: Estruturas de controle.

66 Começaremos pela novidade conceitual: JavaFX Script é uma linguagem orientada a expressões. Não existe a dualidade entre statements (que não geram nenhum valor, como o if do Java) e expressões (que retornam um valor, como x + y). Porém, nos casos onde não há nenhum valor que faça sentido associar a determinada expressão, seu tipo é definido como Void. Isso pode parecer malandragem, qual é a diferença entre um statement e uma expressão Void? A maior diferença é técnica: a gramática da linguagem fica mais simples e unificada, o único efeito do Void é não permitir o uso de determinada expressão no lado direito de lugares que exijam um valor, como uma atribuição. Porém, podemos ver que a linguagem faz um grande esforço para que quase tudo seja uma expressão normal (não-void). Notavelmente, as estruturas de controle if e for são expressões que retornam valores. Vemos também que num bloco de código, o return é geralmente desnecessário para retornos com valor - basta terminar o bloco com um valor, como: def function par (n : Number) { n mod 2 == 0 O bloco { em si é uma expressão que possui valor, o qual pode ter tipo Void (se termina por um return sem valor ou outra expressão de tipo Void) ou outro tipo qualquer. E não, a Tabela 8 não está incompleta: Veja o quadro Cadê o switch?. Cadê o switch? Se o leitor viu a Tabela 8 com as estruturas de controle de JavaFX e estiver perguntando onde está o switch?, a resposta simples é: não tem. Mas a resposta mais longa é... tem algo parecido, ou poderá ter logo. Muitos designers de linguagens OO apontam que a estrutura de controle switch é anti-oo pois muitas vezes pode ser substituída por polimorfismo ou outras técnicas. Em JavaFX, tiveram a coragem de deixar o switch de fora. Isso significa que você tem que usar ou polirmorfismo, ou cascatas de ifs, onde normalmente usaria um switch. Mas esta parte do design da linguagem me parece incipiente pois, para realmente não sentirmos falta do switch, precisamos de outros mecanismos (o polimorfismo nem sempre é adequado). JavaFX já possui parte da solução (funções de primeira ordem) - é melhor ilustrar com um exemplo prático: [ function() function() function() function() ][valor](); { { { { println("case println("case println("case println("case 0"); 1"); 2"); 3"); Ao invés de case, usamos uma sequence contendo uma função com o código correspondente para o case do seu índice. Ao invés de switch(valor), usamos o valor para indexar a sequence, obtendo e executando a função que contém o código deste caso. Note que os casos poderiam ter parâmetros e retornar valores (desde que todos tenham a mesma assinatura: isso será verificado pelo compilador!), o que já tornaria esta técnica mais poderosa que o switch/case do Java. Observe mais uma vez a inferência de tipos de JavaFX: no exemplo, o tipo da sequence é function() [].Digamos que você edite apenas um dos casos e coloque um parâmetro Integer na função; então o tipo inferido será o tipo mais elementar compatível com todos os casos - no caso, um tipo Function genérico (herdado por todos os tipos de função). Mas se você utilizar a sequence como no exemplo, indexando-a e executando a invocação com (), o compilador exige que todas as funções possuam assinatura compatível com a da invocação - no caso, nenhum parâmetro - e reclamará de qualquer caso que seja diferente disso. O maior problema é que nem todos os switch/case possuem um domínio de valores como 0, 1, 2..., que se prestem ao mapeamento para índices de sequence. O ideal seria então usar mapas (sequences associativas), o que permitiria criar uma estrutura como [ "Ouros": function() { println("ouros" ], etc.; isso também permitiria o uso de objetos arbitrários, não só números, como chave. Infelizmente JavaFX ainda não possui nenhum suporte nativo a estruturas de dado deste tipo - pode-se usar as do Java como java.util.hashmap, mas isso não teria facilidades como uma sintaxe especializada de inicialização e indexação. Uma versão futura da linguagem possuirá este suporte a mapas, provavelmente a JavaFX 2.0 (ver JFXC642 no JIRA). Mas também seria bom permitir a declaração de funções triviais ainda mais simples (sem o

67 function()), e mesmo assim, faltaria o default. Há linguagens, como Smalltalk, que sempre se viraram muito bem sem o switch. Na pior hipótese você pode simplesmente usar ifs em cascata, o que em JavaFX talvez não seja ruim, lembrando que if é uma expressão e você pode escrever código como: def sobrenome = if (nome == "Osvaldo") "Doederlein" else if (nome == "Eduardo") "Spínola" else "Silva"; que é mais enxuto que, com um switch, ter que fazer uma atribuição separada para sobrenome em o cada case. (Para um exemplo tão trivial o Java permitiria usar o ternário?:, mas não se os cases tivessem que executar algum statement antes do valor retornado.) Mas esta solução ainda incomoda um pouco: esteticamente, o primeiro caso (if) não tem um cabeçalho idêntico aos demais (else if); e a repetição de "nome ==" também me incomoda um pouco, ainda que seja mais legível e genérica que os cases. Eficiência não é um problema pois o compilador poderia reconhecer uma cascata de ifs com estrutura similar a um switch, e gerar código idêntico (com bytecodes tableswitch ou lookupswitch). Generators Uma vantagem do design orientado a expressões de JavaFX, e seu uso de tipos de dados de alto nível como sequences e estruturas de controle avançadas como generators (for), é que o javafxc tem oportunidade para fazer otimizações importantes. Por exemplo, ao conhecer o for da JavaFX Script, você talvez tenha se horrorizado ao imaginar que este sempre irá gerar uma sequence com os valores produzidos por cada iteração do loop. Mas não é exatamente assim; o compilador só faz isso se necessário. Assim, no código def x = [1, 2, 3] def y = for (n in x) n * 2 a sequence será de fato gerada, no caso [2, 4, 6], e atribuída a y. Porém, neste outro código: def x = [1, 2, 3] for (n in x) n * 2 for só irá avaliar a expressão n * 2 para cada n in x, mas nenhuma sequence será criada, pois o valor o de retorno do for não está sendo utilizado de qualquer forma (como termo de outra expressão, ladodireito de atribuição, etc.). Classes JavaFX é uma linguagem OO baseada em classes, com sintaxe básica parecida com Java, mas com pelo menos um grande desvio do design de Java. Como JavaFX faz isso? Se você observar os arquivos gerados pelo javafxc, verá que uma classe C da JavaFX gera um par de.class, que se você descompilar gerando arquivos.java (ou examinar com o javap), verá que correspondem a uma interface C.Intf e uma classe C que implementa esta interface. Junto com alguns outros truques de compilação, isso permite integrar o paradigma de herança múltipla generalizada da JavaFX Script ao modelo OO do bytecode / JVM, que suporta herança múltipla apenas para interfaces com métodos abstratos. Para saber mais sobre a linguagem acesse a Apresentação JavaFX Script - Referência Rápida. A Tabela 9 resume a sintaxe das classes de JavaFX. Não existem interfaces, apenas classes, e a herança múltipla é suportada para tudo (funções abstratas e concretas, e até mesmo propriedades). Classes da JavaFX podem inclusive herdar qualquer coisa de Java (tanto classes quanto interfaces). Ou seja, JavaFX Script unifica nossas class e interface numa única entidade, também não exigindo distinguir entre extends e implements.

68 Tabela 6: Classes Por que uma nova linguagem? Ao serem apresentados à JavaFX, muitos desenvolvedores têm a seguinte reação: aprovam as funcionalidades, o framework, mas... isso precisava de uma nova linguagem? Não daria para suportar todos os recursos da JavaFX com APIs orientadas à linguagem Java, ou talvez, uma sintaxe Java estendida (mantendo compatibilidade retroativa) ao invés de inventar outra linguagem separada? A resposta curta: Sim, seria possível fazer tudo com Java ou com uma extensão de Java... porém, não seria uma boa idéia. Vamos explicar os porquês - a resposta longa. Produtividade Competitiva Todas as plataformas RIA competidoras utilizam alguma linguagem de programação considerada de alta produtividade - pelo menos segundo alguns critérios, como alta densidade de código (mais funcionalidade com menos linhas de código) e facilidade de prototipação. As competidoras incluem

69 JavaScript, ActionScript, e linguagens XML como XAML e MXML (para estas últimas, a vantagem é o uso de ferramentas visuais). JavaFX Script possui diversas características de alta produtividade, como: inferência de tipos, binding, sequences, inicialização declarativa de estruturas hierárquicas de objetos, sintaxes de alto nível para diversas necessidades de programação geral (desde o simples relaxamento na pontuação até o for turbinado ), e sintaxes especiais para algumas APIs. Agilidade Quando se fala em evolução da linguagem Java, não podemos nos esquecer que a Sun não é dona do Java. A especificação da linguagem, bem como de todas APIs formais, é controlada pelo Java Community Process (JCP). Embora a Sun mantenha certas prerrogativas e um alto grau de influência no JCP, isso não inclui carta branca para fazer o que quiser com a plataforma. Em especial, a evolução de especificações preexistentes é sempre torturante pois precisa levar em conta os interesses de diversos players com voz no JCP, e possivelmente grande investimento na tecnologia em questão. A quebra de compatibilidade retroativa é virtualmente impossível. A Sun chegou atrasada à briga do RIA. Se fosse seguir o caminho de estender a linguagem Java (mesmo que isso fosse tecnicamente uma boa idéia), ou criar a JavaFX sob os auspícios do JCP, o lançamento da JavaFX 1.0 levaria pelo menos o dobro do tempo, e a sua evolução até a JavaFX 2.0 levaria 3-4 anos ao invés de um ano. Isso liquidaria qualquer chance da JavaFX de competir. Órgãos de padrões como o JCP são excelentes para tecnologias já razoavelmente maduras, mas são quase sempre péssimos para criar coisas completamente novas - a inovação raramente acontece em comitês. Imperativo ou Funcional? Na minha mania de aprender novas linguagens mexendo em código dos outros, cheguei ao seguinte trecho de um demo (javafx.com/samples/smokeparticles/): var parts: Particle[]; function update() : Void { insert Particle { x : 84 y : 164 timer : 100 acc : bind acc vx : 0.3 * random.nextgaussian() vy : 0.3 * random.nextgaussian() - 1 into parts; var i = sizeof parts - 1; while( i >= 0 ) { parts[i].update(); if( parts[i].isdead()) delete parts[i.intvalue()]; i--; Seu funcionamento é o seguinte: primeiro um novo objeto Particle é criado e inserido ao final da sequence parts; depois, um loop varre todos os elementos que já estavam na sequence, invocando os métodos update() e isdead(), e deletando da sequence aqueles que estão mortos. Mas achei esse código feio, confuso, então resolvi reescrevê-lo: function update() : Void { parts = [ for (p in parts where not p.update()) p Particle { x : 84 y : 164 timer : 100 acc : bind acc vx : 0.3 * random.nextgaussian() vy : 0.3 * random.nextgaussian() - 1

70 ] Esta nova versão faz uma substituição única da sequence antiga pela nova, a qual é criada da seguinte forma: primeiro temos um forisdead() a update()), e depois temos a nova Particle. O [...] mais externo serve concatena a sequence gerada pelo for com o objeto final, sendo que graças ao flattening automático, o resultado será uma sequence simples com todos estes elementos. A nova versão é característica do estilo funcional, evitando alterações repetitivas como insert e delete. Sobrou uma alteração de variável (parts =...), mas é uma só, e mesmo esta atribuição só restou por que eu não quis reescrever o programa todo. É um código bem mais limpo, menor (10 linhas ao invés de 14) e mais simples (sua complexidade ciclomática - quantidade e aninhamento de estruturas de controle - é menor.) Mais importante, a versão funcional é idêntica a uma descrição formal / matemática do algoritmo, que podemos enunciar como: o novo conjunto de partículas é formado pelas partículas preexistentes que após o update() continuem vivas, mais uma partícula nova. É por isso que tanta gente gosta de programação funcional: é o estilo de programação que permite traduzir, de forma direta, algoritmos especificados de forma matematicamente rigorosa (que é quase sempre a descrição mais enxuta e elegante possível). Bem, agora as más notícias. Testando meu novo código, este funcionou, mas com um desempenho muito pior. O problema é que a sequence parts é amarrada, via binding, ao scene graph da animação do programa; porém, o binding de sequences não é otimizado para o cenário de substituição total de uma sequence (com uma atribuição explícita), apesar de ser otimizado para manipulações pontuais como insert e delete A otimização em questão evita que o scene graph inteiro seja reconstruído em cada frame da animação, o que resulta em péssimo desempenho. Ou seja, não se trata de um bug/limitação de desempenho das sequences propriamente ditas, mas somente da combinação entre sequences e binding, ou talvez, do runtime do scene graph. Registrei um novo bug descrevendo o problema (javafxjira.kenai.com/browse/jfxc-2911). É o tipo de coisa que, infelizmente, podemos esperar de um software complexo como a JavaFX que ainda é praticamente recém-lançado no momento em que escrevo. Mas não tira o mérito do estilo de programação funcional ou do design de sequences (o JIRA da JavaFX registra uma grande quantidade de bugs similares, a maioria corrigidos antes mesmo do release mas o trabalho obviamente ainda não terminou). Conclusões Este artigo encerra uma primeira trilogia de JavaFX, na qual cobrimos os aspectos principais desta nova plataforma: tecnologia RIA, mobilidade, linguagem de programação, pontos principais do framework. A partir deste ponto, minha expectativa é que um leitor que sabe programar Java e tem interesse pela plataforma JavaFX possa andar com seus próprios pés, chegando ao ponto de desenvolver aplicações RIA sofisticadas para desktop e dispositivos móveis. Há duas partes da JavaFX que cobrimos de forma superficial: os recursos de mídia (ver Edição 67) e as APIs javafx.* (ver Edição 68). Estes temas renderiam, seguramente, pelo menos mais dois capítulos da série. Mesmo na linguagem JavaFX Script, coberta neste artigo, existem tópicos específicos que poderíamos explorar, como a integração com Java, ou o desempenho. Mas preferi parar por aqui, por três motivos. Primeiro, a plataforma JavaFX ainda é muito recente e ainda é difícil avaliar o interesse dos leitores por uma cobertura tão contínua e abrangente. Segundo, o mundo não parou por causa da JavaFX, e há outros temas que pretendo cobrir nas próximas edições. Terceiro, a JavaFX ainda está em rápida evolução: no caso específico dos frameworks, não vou gastar nosso tempo (meu e dos leitores) com um artigão sobre os frameworks da JavaFX 1.1, quando sei que já em junho deste ano (quando nossa próxima Edição já estaria nas bancas) a Sun terá lançado a JavaFX 1.5, com muitas novidades especialmente nas APIs. Resumindo, espero que o leitor tenha apreciado estes primeiros artigos, tanto quanto eu apreciei escrevê-los... chegou a hora de fazer uma pausa, mas com planos de voltar à JavaFX daqui a algumas edições, com as baterias recarregadas.

71 Saiba Mais Java Magazine 67 - JavaFX: RIA a todo vapor Java Magazine 68 - JavaFX: Tutorial

72 Novos tempos: javax.time Daniel Cicero Amadei Bacharel em Sistemas de Informação pelo Mackenzie e pós-graduado pela Fundação Vanzolini. Trabalha com Java desde 1999 e possui as certificações SCJP, SCWCD, SCBCD, SCDJWS, SCEA, BEA Certified Developer: Integration Solutions e BEA Certified SOA Architect. Já atuou como Desenvolvedor, Analista e Arquiteto de Sistemas e atualmente é Consultor em Arquitetura Oracle BEA. Blog: Michael Nascimento Santos É um dos spec-leads da JSR-310 e expert em outras cinco JSRs. Ganhou um JavaOne Rock Star Speaker Award pela sua palestra sobre a JSR-310 em 2008 no JavaOne. Atua como Senior Technical Consultant na Summa Technologies do Brasil. De que se trata o artigo: O artigo aborda o resultado da JSR-310, a JSR que está definindo a nova API de data e hora que será incorporada na plataforma Java. A arquitetura e as principais classes e interfaces da API são discutidas e exemplificadas. Além disso, são abordadas as lacunas presentes nas classes atuais (Date e Calendar) e como a javax.time endereça tais problemas. Para que serve: Apresentar a nova API de datas e horas que será incorporada na plataforma Java, provendo discussões sobre a sua arquitetura e exemplos de uso da API, além de comparações com as classes atuais. Em que situação o tema é útil: O tema é importante para qualquer um que deseje estar atualizado sobre as novas tendências da plataforma Java. A manipulação de datas e horas é peça-chave em qualquer implementação e a criação de uma nova API tende a facilitar muito a vida do desenvolvedor. Novos tempos: javax.time: O artigo aborda a nova API para representação de datas e horas da plataforma Java e como ela facilita a vida do desenvolvedor Java, corrigindo bugs e endereçando problemas das classes atuais Date e Calendar. A nova API possui representações distintas para datas que serão utilizadas para cálculos computacionais e datas que serão utilizadas por seres humanos. Além disso, temos representações padrão para tipos de dados que atualmente precisamos criar como durações, períodos e intervalos. Neste artigo conheceremos a nova API de data e hora que está sendo elaborada para a plataforma Java SE 7. O foco da nova API é resolver vários problemas que afetam os desenvolvedores Java há anos, presentes nas classes java.util.date e java.util.calendar.

73 Por que uma nova API? A arquitetura elaborada para as classes Date e Calendar, ambas do pacote java.util é bastante questionável. Veremos algumas dessas decisões arquiteturais dúbias, além de bugs da API atual, no decorrer do artigo. Outro grande problema é a falta de tipos para representar unidades comuns no dia-a-dia de qualquer desenvolvedor como, por exemplo, períodos, instantes, durações, entre outros. Sem classes que representem essas unidades do mundo real, é necessária a criação de soluções paliativas por conta e risco dos desenvolvedores. Isso resulta em mais codificação e código legado para manutenção. Esses pontos claramente abrem espaço a uma nova abordagem para o tratamento de datas e horas dentro da plataforma Java. Alguns dos problemas apresentados por Date e Calendar Um dos principais problemas das classes atuais é a inconsistência. A classe java.util.date não representa uma data, mas sim um instante na linha do tempo. Desta forma, não temos como representar somente uma data ou somente o tempo. Outro exemplo de inconsistência é o fato da classe Date utilizar anos com base em 1900, enquanto a Calendar requerer os anos completos, incluindo o século. O código apresentado a seguir, apesar do uso de um construtor descontinuado (deprecated), ilustra a criação de uma data cujo ano será 3909, ao contrário do que parece ao ler o código. Date date = new Date(2009, 2, 1); O início dos meses em 0 (Zero) na classe Calendar também é algo que tem atrapalhado a vida dos desenvolvedores Java de forma considerável. Por exemplo, para criar uma instância de Calendar que represente a data 01/01/2009, temos que escrever o seguinte código: Calendar calendar = new GregorianCalendar(2009, 0, 1); Além disso, temos uma série de outros problemas arquiteturais ou de implementação: Os objetos são mutáveis, inseguros em ambiente multi-thread, requerendo sincronização; Não há como formatar uma instância de Calendar usando as classes do pacote java.text; Não existe opção para representar períodos ou durações de forma padronizada; As APIs atuais exigem muito código para tarefas rotineiras de manipulação de datas e horas. Sem mencionar ainda que muitas dessas tarefas rotineiras constituem casos de uso comuns e poderiam ser implementados pelas próprias APIs. Esses são apenas alguns dos problemas que a JSR 310 irá resolver. Os já velhos conhecidos problemas devido às alterações no horário de verão também estão sendo endereçados. Além de tudo isso, você verá que a API é muito mais intuitiva e irá lhe poupar muitas e muitas linhas de codificação. Princípios de Design da JSR 310 A JSR 310 tem sido elaborada com alguns princípios para facilitar seu uso e entendimento e tornar seu código mais robusto e de fácil leitura. Baseada em padrões A nova API está sendo construída totalmente alinhada com o ISO-8601, um padrão internacional para representação de datas e horas. Imutável Os principais objetos da nova API serão imutáveis. Não será possível alterá-los após a construção. Também serão thread-safe, podendo até mesmo ser singletons. A seguir, um primeiro exemplo, da criação de uma data (sem a hora!): LocalDate date = LocalDate.date(2009, 1, 1); Nesse caso, criamos uma data com a classe javax.time.calendar.localdate. Essa classe representa uma data sem fuso horário (time zone) no padrão ISO-8601, resultando em Caso desejemos

74 alterar o ano dessa data, por exemplo, para 2010 não iremos utilizar um método set(). Neste caso, devemos utilizar um método with(), que cria uma nova instância da classe com o ano desejado. O código ficaria conforme apresentado a seguir: date = date.withyear(2010); Repare na atribuição ao objeto date com o resultado da invocação do método. Isso é necessário, pois é criado um novo objeto, mantendo o original inalterado, pois os objetos envolvidos são imutáveis. Interfaces Fluentes As classes e interfaces seguem o padrão de fluência para permitir uma melhor legibilidade do código. Isso transforma as invocações a mais do que um método em sentenças de fácil leitura. O código apresentado a seguir, além do ano, altera o mês e o dia. date = date.withyear(2010). withmonthofyear(3).withdayofmonth(2); Clareza Os métodos são bem definidos e indicam claramente seu propósito. Por exemplo, para subtrair dois anos de uma data qualquer, utilizamos o seguinte código: date = date.withyear(2010). withmonthofyear(3). withdayofmonth(2); date = date.minusyears(2); Isso irá resultar na data Muito mais claro do que o método roll(int field, int amount) da classe Calendar. Extensível Através de pontos de extensão, utilizando conceitos do design pattern Strategy, é possível controlar e customizar como a API se comporta em relação às datas e horas. Mesmo assim, não é necessário ser um especialista para usar a API. São fornecidas implementações padrão para a maioria dos cenários. Um exemplo desses ganchos para extensibilidade é a interface javax.time.calendar.dateadjuster, capaz de realizar ajustes em uma data de forma padronizada. Você simplesmente implementa essa interface e a utiliza para ajustar suas datas de forma padronizada e bem definida. Além disso, a javax.time traz consigo uma classe utilitária, a javax.time.calendar.dateadjusters, contendo implementações dos casos de uso mais comuns para o ajuste de datas. Essas implementações devem satisfazer a maioria das necessidades de desenvolvimento. O código apresentado a seguir ilustra o ajuste sendo realizado em uma data: LocalDate date = Clock.systemDefaultZone().today(); date = date.with(dateadjusters. next(dayofweek.monday)); O código que apresentamos, além do ajuste da data, apresenta uma nova classe: javax.time.calendar.clock. Essa classe é um façade para o acesso à data e hora correntes. O método today(), que invocamos na classe Clock, retorna a data corrente como uma instância de LocalDate. Voltando a falar sobre o ajuste da data, ele ocorre na invocação ao método with(). Informamos DateAdjusters.next(DayOfWeek.MONDAY) como parâmetro do método. O objeto retornado pelo método next() é responsável por ajustar a data para a segunda-feira subsequente à data informada. Avaliando as datas, caso executemos tal código no dia 05/02/2009, após o ajuste, a nova data (lembre-se da imutabilidade!) será dia 09/02/2009.

75 Ainda no âmbito dos Adjusters, outro exemplo muito interessante de sua aplicabilidade seria o ajuste das datas para dias úteis. Você pode, ainda, implementar seu próprio adjuster - digamos, para saltar feriados obtidos de um cadastro de feriados do seu sistema. Duas escalas para lidar com tempo A javax.time apresenta duas formas distintas para lidar com o tempo. Uma escala voltada para máquinas, denominada Continuous e a outra com foco em datas para seres humanos, denominada Human. Continuous Essa abordagem da javax.time é voltada para máquinas e representa o tempo na forma de um número incremental, sem muito significado para seres humanos, porém com grande valor para uso em processamentos que requerem cálculos envolvendo timestamps. Instant A classe javax.time.instant representa um ponto instantâneo na linha do tempo, um instante de tempo, conhecido também como timestamp. Possui precisão de nanossegundos e 96 bits para armazenamento. Através dessa abordagem, é possível armazenar até algumas centenas de vezes uma data equivalente ao tempo de existência do universo. (Para os curiosos, o universo tem em torno de 13,8 bilhões de anos.) A seguir, um exemplo onde validamos se um instante é superior a outro utilizando o método isafter(). Instant instante1 = Clock.systemDefaultZone().instant(); //qualquer código aqui Instant instante2 = Clock.systemDefaultZone().instant(); boolean avaliacao = instante1.isafter(instante2); Duration A classe javax.time.duration representa uma duração de tempo. Dentro da javax.time, ela representa a duração entre dois instantes. O instante inicial que forma uma instância de Duration é inclusivo e o final é exclusivo. Apesar de armazenar dados provenientes de lá, a classe Duration é desconectada e independente da linha do tempo. O código apresentado a seguir ilustra o uso da classe Duration: Instant agora = Clock.systemDefaultZone().instant(); Instant umminutomais = agora.plusseconds(60); Duration duration = Duration.durationBetween(agora, umminutomais); System.out.println(duration); No trecho de código apresentado, vemos primeiramente a criação de dois instantes. O primeiro representa o momento exato da execução, enquanto que o segundo derivamos a partir do primeiro com a soma de 60 segundos. Repare no método plusseconds(). Ele é conciso, bem definido e indica exatamente seu propósito e a unidade manipulada. Após a criação dos instantes, criamos uma duração entre eles, que deverá conter exatamente 60 segundos. Ao imprimir a duração no console, temos a impressão da duração utilizando o padrão ISO InstantInterval A classe javax.time.instantinterval representa um intervalo de instantes na linha do tempo. A classe pode possuir intervalos inclusivos, exclusivos ou algum dos intervalos pode não estar associado, isso quer dizer que podemos criar o intervalo com apenas o instante de início e posteriormente associar o instante final. O código apresentado a seguir ilustra a criação de um intervalo a partir de dois instantes e a posterior verificação se um terceiro intervalo está contido entre eles:

76 Instant agora = Clock.systemDefaultZone().instant(); Instant umminutomais = agora.plusseconds(60); InstantInterval intervalo = InstantInterval. intervalbetween(agora, umminutomais); boolean contido = intervalo.contains (Clock.systemDefaultZone().instant()); No exemplo, por utilizarmos o método padrão, o intervalo inicial é inclusivo e o final é exclusivo. Existe outro método que recebe valores booleanos indicando se desejamos que cada um dos intervalos seja inclusivo (true) ou exclusivo (false). Além disso, podemos construir a instância de InstantInterval a partir dos métodos builder : intervalfrom() e intervalto(). Human Essa abordagem da javax.time é voltada para seres humanos. Ela representa os valores de datas e horas utilizando campos com classes específicas para representar cada um dos dados do calendário: ano, mês, dia, hora, minuto e segundo. Além desses campos mais comuns, temos algumas outras classes ou enumerações para representar, por exemplo, o dia do ano, a semana do ano, os nanossegundos de cada segundo, entre outras. Através da abordagem para seres humanos, temos formas (classes!) para representar datas e horas, datas sem hora, horas sem data, offsets e time zones. Datas e Horas locais (sem time zone ou offset) Os tipos mais simples presentes dentro da javax.time são os tipos chamados de locais. Esses tipos podem representar data ou hora de forma isolada ou as duas em conjunto. São chamadas de locais por não estarem associados a um offset ou time zone. LocalDate A primeira classe que mereceria nossa atenção seria a javax.time. calendar.localdate. Como já estamos cansados de ver exemplos envolvendo essa classe, pois é a que estamos acompanhando no decorrer do artigo, veremos algo a mais. A representação dos campos de datas e horas dentro das classes é efetuada através de classes com este propósito. Com isso, essas classes contém métodos implementando ações comuns, requeridas de cada um desses campos que compõem nossas datas e horas. A javax.time utiliza como padrão os métodos get() retornando valores numéricos para tais campos, por exemplo, getyear() retorna o ano como um inteiro e os métodos to() retornam as classes específicas, no caso do ano, seria a classe javax.time.calendar.field.year. O exemplo apresentado a seguir ilustra o uso do método toyear(). LocalDate hoje = Clock.systemDefaultZone().today(); Year ano = hoje.toyear(); boolean bissexto = ano.isleap(); No exemplo, obtemos o ano e, a partir do objeto criado, verificamos se ele é bissexto. Repare como isso seria trabalhoso caso o ano fosse representado somente pelo tipo primitivo (int). Teríamos que fazer esse cálculo manualmente, cada um em seu projeto, testar esse código e mantê-lo. No exemplo apresentado a seguir, temos a obtenção do mês, representado pela enumeração javax.time.calendar.field.monthofyear e, a partir dela, obtemos o último dia do mês representado pela classe javax.time.calendar.field.dayofmonth.

77 LocalDate hoje = Clock.systemDefaultZone().today(); MonthOfYear mes = hoje.tomonthofyear(); DayOfMonth ultimodiames = mes.getlastdayofmonth(hoje.toyear()); Vemos aqui também, com a obtenção do último dia do mês, o grande valor no uso de classes específicas em comparação com tipos primitivos. O cálculo do último dia do mês é resolvido automaticamente pela API, poupando você, desenvolvedor, desse (grande) trabalho. LocalTime A classe javax.time.calendar.localtime representa uma hora sem time zone ou offset. O trecho de código apresentado a seguir imprime a hora corrente e, posteriormente, subtrai uma hora e imprime o valor atualizado. LocalTime agora = Clock.systemDefaultZone().currentTime(); System.out.println(agora); agora = agora.minushours(1); System.out.println(agora); LocalDateTime A classe javax.time.calendar.localdatetime representa uma data e hora sem time zone ou offset. O trecho de exemplo apresentado a seguir imprime a hora corrente e posteriormente subtrai 36 horas e imprime o valor atualizado. LocalDateTime agora = Clock.systemDefaultZone().currentDateTime(); System.out.println(agora); agora = agora.minushours(36); System.out.println(agora); No exemplo, caso a primeira data e hora fosse representada por T11:50:08.093, após a subtração de 36 horas, teríamos T23:50: Repare que o cálculo ocorreu corretamente e alterou até mesmo a data. Datas e Horas com offset As datas e horas com offset representam um valor relativo ao UTC (Coordinated Universal Time ou Tempo Universal Coordenado). Esses valores relativos, ou offsets, estão geralmente casados com as áreas de fuso horário (time zones), porém a javax.time separa os dois conceitos: offsets e time zones em classes distintas. O objetivo dessa separação é tratar trocas de offset por uma mesma time zone devido a horários de inverno ou verão. OffsetDate A classe javax.time.calendar.offsetdate representa uma data com um offset em relação ao UTC. Por exemplo, ao criar um objeto OffsetDate aqui no Brasil, na região que segue o horário de Brasília, temos como offset o valor -03h00min, ou seja, se em Brasília são 16h, o horário UTC estará marcando 13h. O trecho de código apresentado a seguir ilustra a obtenção da data atual considerando o offset: OffsetDate hoje = Clock.systemDefaultZone().offsetDateTime().toOffsetDate(); Caso esteja sob o offset de Brasília, ao imprimir o objeto, a string :00 teria sido impressa no console, seguindo o padrão ISO-8601 para datas e horas com offset.

78 Nota Devman - Thread-safe Thread-safe ou, melhor dizendo, thread-safety é o conceito que usamos para nomear a situação em que o acesso de múltiplas threads a um elemento no mesmo momento não apresenta resultados inconsistentes, sem que uma thread tenha interferência sobre os dados manipulados por outra thread. A classe javax.time.calendar.offsettime representa um horário com um offset em relação ao UTC, seguindo o mesmo padrão da classe OffsetDate. O trecho de código apresentado a seguir ilustra a obtenção do horário atual considerando o offset. Após isso, a criação de uma nova instância de OffsetTime contendo o mesmo horário, porém com o offset encontrado no Japão, que é +09h00min. Após isso, fazemos uma comparação dos dois horários com o intuito de ilustrar que a comparação levará em conta o offset. OffsetTime hojebrasil = Clock.systemDefaultZone().offsetDateTime().toOffsetTime(); OffsetTime hojejapao = hojebrasil.withoffset(zoneoffset.zoneoffset(9)); boolean horariojapaoposterior = hojejapao.isafter(hojebrasil); Após a execução do código apresentado, a variável horariojapaoposterior irá armazenar o valor true indicando que a hora no Japão é posterior. OffsetDateTime A classe javax.time.calendar.offsetdatetime representa uma data e um horário com um offset em relação ao UTC, seguindo o padrão dos dois exemplos vistos até o momento. O código a seguir ilustra a obtenção de uma OffsetDateTime. OffsetDateTime hojebrasil = Clock.systemDefaultZone().offsetDateTime(); Ao imprimir essa variável no console, temos uma string representando a data, horário e o offset seguindo o padrão ISO: T23:20: :00. Time Zones Além de objetos capazes de armazenar o offset, temos a classe javax.time.calendar.zoneddatetime que armazena também o time zone. O time zone é representado pela classe javax.time.calendar.timezone que tem o propósito de tratar regras e exceções das alterações nos offsets das regiões mundiais. Essas alterações geralmente se devem a mudanças no horário de verão ou inverno. Dentro da javax.time, é possível instanciar a classe TimeZone a partir de um identificador da base de time zones zoneinfo ou a partir do offset em relação à UTC. O código apresentado a seguir ilustra a obtenção de duas instâncias de ZonedDateTime, a primeira com o time zone padrão da JVM, configurado como América/Sao_Paulo e o segundo forçando o uso do time zone de Paris. ZonedDateTime agora = Clock.systemDefaultZone(). zoneddatetime(); System.out.println(agora); TimeZone timezone = TimeZone.timeZone ("Europe/Paris"); agora = Clock.system(timeZone). zoneddatetime(); System.out.println(agora); Ao executar o código apresentado, as datas e horas correspondentes ao time zone informado são impressas no console:

79 T23:37: :00 UTC-03: T03:37: :00 Europe/Paris Repare que a primeira string impressa apresenta o time zone como UTC-03:00, isso por que não há um identificador correspondente para este time zone, ao contrário do que ocorreu com o time zone de Paris, que criamos a partir do identificador, que é apresentado na impressão do objeto. Uma forma equivalente de obter a instância de ZonedDateTime à que utilizamos é a apresentada a seguir, uma vez que o time zone de Paris corresponde ao offset de uma hora em relação ao UTC: ZonedDateTime agora = Clock. systemdefaultzone().zoneddatetime(); System.out.println(agora); TimeZone timezone = TimeZone. timezone(zoneoffset.zoneoffset(1)); agora = Clock.system(timeZone). zoneddatetime(); System.out.println(agora); Matchers e Resolvers Como já dissemos, a javax.time recorre a conceitos do design pattern Strategy para que você possa customizar pontos de seu comportamento. Um exemplo pelo qual já passamos foi o dos Adjusters que permitem a realização de ajustes em datas e horas de forma bastante flexível. Além dos Adjusters, a javax.time nos provê o conceito de Matchers e Resolvers, que veremos agora. Matchers Os Matchers possuem a responsabilidade de realizar consultas em datas e horas de forma muito simples e flexível. Eles reduzem drasticamente a quantidade de código e a lógica empregada neste tipo de operação. O código apresentado a seguir ilustra a consulta à data (e hora) atual. Nesse caso consultamos se o ano é 2009, valorizando uma variável booleana denominada ano2009. Como estamos realmente em 2009, essa variável será valorizada com true. LocalDateTime agora = Clock.systemDefaultZone().dateTime(); boolean ano2009 = agora.matches(year.isoyear(2009)); A consulta envolvendo o horário é praticamente idêntica, conforme pode ser visto a seguir: LocalDateTime agora = Clock.systemDefaultZone().dateTime(); boolean vinteumahoras = agora.matches(hourofday.hourofday(21)); É possível realizar tais operações, pois cada uma dessas classes (Year, HourOfDay e as outras classes representando os elementos do calendário) implementa as interfaces necessárias para executar o método matches(). A interface que representa o Matcher para a consulta em datas é a javax.time.calendar.datematcher, que possui um único método boolean matchesdate(localdate input). Já a interface para a consulta em horários é a javax.time.calendar.timematcher e ela segue o mesmo padrão da outra que vimos, possuindo um único método boolean matchestime(localtime time). A Listagem 1 apresenta um exemplo de implementação de DateMatcher para verificar se a data possui um dia ímpar ou não. Listagem 1. Exemplo do uso de um DateMatcher customizado para realizar a consulta de dias ímpares package br.com.jm.javax.time.human.matchers;

80 //imports... public class ExemploMatcherDiaImpar { public static void main(string[] args) throws Exception { LocalDateTime agora = Clock.systemDefaultZone().dateTime(); boolean diaimpar = agora.matches(new DiaImparMatcher()); System.out.println(diaImpar); class DiaImparMatcher implements DateMatcher public boolean matchesdate(localdate data) { if (data.getdayofmonth() % 2 == 0) { return false; else { return true; A classe javax.time.calendar.datematchers possui alguns matchers pré-configurados para você utilizar. Entre os matchers que já vêm por padrão temos, por exemplo, um para verificar se estamos durante a semana ou em um final de semana, se é o primeiro ou último dia do mês, além de alguns outros. O código apresentado a seguir ilustra o uso da classe DateMatchers para a verificação se a data corrente é um final de semana. LocalDateTime agora = Clock.systemDefaultZone().dateTime(); boolean finaldesemana = agora.matches(datematchers.weekendday()); Como visto, a classe DateMatcher pode nos auxiliar com a verificação de datas e nos auxiliar muito em tarefas do mundo real como, por exemplo, verificar se determinada data está dentro do domingo de páscoa ou na sexta-feira santa. Resolvers Assim como os matchers, os Resolvers são pontos de extensibilidade disponíveis na javax.time. Através deles você pode indicar como deseja que uma data inválida seja tratada, por exemplo, ao criar uma data no dia 29 de fevereiro em um ano que não seja bissexto. A classe javax.time.calendar.dateresolvers possui algumas implementações dos casos de uso mais comuns onde possa vir a ser necessário o uso de um Resolver.

81 O exemplo apresentado a seguir ilustra a criação de uma data utilizando um resolver provido pela classe DateResolvers que resolve uma data inválida como a próxima data válida. LocalDate data = DateResolvers.nextValid().resolveDate(Year.isoYear(2009), MonthOfYear.monthOfYear(2),DayOfMonth.dayOfMonth(29)); Ao imprimir tal data no console, temos como data apresentada Caso você tenha achado o código verboso demais, é possível utilizar o recurso de static imports para reduzir a verbosidade. A Listagem 2 apresenta tal opção. Listagem 2. Uso de static imports para minimizar a verbosidade do código no uso de Resolvers package br.com.jm.javax.time.human.resolvers; import static javax.time.calendar.field.dayofmonth.dayofmonth; import static javax.time.calendar.field.monthofyear.monthofyear; import static javax.time.calendar.field.year.isoyear; import javax.time.calendar.dateresolvers; import javax.time.calendar.localdate; public class ExemploResolverSI { public static void main (String[] args) throws Exception { LocalDate data = DateResolvers.nextValid(). resolvedate(isoyear(2009), monthofyear(2), dayofmonth(29)); System.out.println(data); Períodos Os períodos, dentro da javax.time, são cidadãos de primeira-classe. Isso quer dizer que existem classes capazes de representá-los, ao contrário do que você encontra nas APIs atuais, onde não há forma padrão para representar períodos. Através da representação dos períodos, podemos expressar durações de tempo da maneira tratada pelos seres humanos como, por exemplo, a duração de uma reunião ou de suas férias. Como dito, existe uma classe para cada parte do período: javax.time.period.field.days javax.time.period.field.hours javax.time.period.field.minutes

82 javax.time.period.field.months javax.time.period.field.seconds javax.time.period.field.weeks javax.time.period.field.years E uma classe para representar o período como um todo: javax.time.period.period. O código apresentado a seguir representa a criação de um período de duas horas: Period period = Period.hours(2); A partir desse momento, o objeto representa o determinado período para o qual foi criado. Ao imprimir tal período no console, é impressa sua representação de acordo com o padrão ISO Essa representação para o período de duas horas é PT2H. Uma das grandes vantagens no uso de objetos especializados para os períodos é permitir que você execute operações nesse objeto. Isso resultará na criação de outro objeto para representar o novo período resultante da operação. O objeto que representa o período também é imutável. A seguir, uma subtração de quarenta minutos de nosso período de duas horas: period = period.minusminutes(40); Ao executar tal operação, o período ainda permanece com duas horas e menos quarenta minutos e necessita ser normalizado para representar o período real, que seria de uma hora e vinte minutos. Normalização O método normalize() retorna uma cópia do período normalizado para os limites padrão dos campos de data e hora, levando em conta as seguintes regras: 12 meses em um ano; 60 minutos em uma hora; 60 segundos em um minuto; de nanossegundos em um segundo. Por exemplo, um período de 13 meses é normalizado para um ano e um mês e a criação de um período de 5000 minutos com o código Period.minutes(5000) resulta em um período normalizado de 83 horas e 20 minutos. Caso você necessite ainda realizar a normalização por dias, quebrando cada 24 horas em um dia, você deve utilizar o método normalizedwith24hourdays(), que neste nosso exemplo resultaria em um período de três dias, onze horas e vinte minutos. Para revisar o que foi visto e por em prática o conteúdo apresentado, veja a Apresentação Javax.time.

83 Conclusão Você conheceu um pouco sobre a nova especificação para representar datas e horas dentro da plataforma Java. Essa nova API tenta trazer várias facilidades e corrigir problemas conhecidos das opções atuais, buscando transformar seu código em algo mais legível e simples. Passamos por todos os pontos mais importantes da nova API, fornecendo exemplos pontuais e focados, tentando ambientar você com os novos conceitos. A JSR 310, que está definindo a nova API, é aberta e você pode contribuir para seu desenvolvimento. Acesse o site da JSR (veja seção de Links) e faça parte da definição do futuro da linguagem. O código apresentado neste artigo está disponível para download no site da revista, contando com um JAR da javax.time compilado durante a escrita do artigo. Como a API ainda está sendo concebida, é possível que quando o artigo chegar a você, leitor, algo possa ter sido alterado. Devido a isso, deixamos aqui a sugestão de baixar os fontes da última versão da API e adequar os exemplos às possíveis alterações. Acesse também a lista de discussões para entender o rumo que está sendo dado à API. Links jsr-310.dev.java.net Site de desenvolvimento da JSR 310, onde você pode obter acesso a todos os artefatos relacionados à nova API, além de participar de seu desenvolvimento, cadastrando-se nas listas de discussão. jcp.org/en/jsr/detail?id=310 Site oficial da JSR 310, parte do JCP. joda-time.sourceforge.net Site da Joda Time, API que está servindo de base para o desenvolvimento da JSR 310.

84 Java ME Platform SDK 3 Ernandes Mourão Júnior é Bacharel em Informática pela Universidade de Fortaleza e desenvolvedor certificado Java (SCWCD, SCBCD e SCMAD). Atualmente exerce o cargo de Analista de Sistemas e Líder Técnico Java ME no Instituto Atlântico. De que se trata o artigo: Apresentação da nova ferramenta da Sun para a plataforma Java ME: o Java ME Platform SDK, o sucessor do Wireless Toolkit. Neste artigo, as principais novidades trazidas por esta ferramenta são apresentadas de uma forma clara e objetiva para o leitor. Para que serve: Proporcionar uma apresentação objetiva das principais funcionalidades da nova ferramenta de desenvolvimento da plataforma Java ME. Esta apresentação concede ao leitor uma visão geral, mas completa, do que de novo ele pode vir a utilizar daqui para frente no desenvolvimento de suas aplicações. Em que situação o tema é útil: No momento em que uma ferramenta que usamos com frequência surge com uma versão nova, é sempre válido dar uma olhada nas principais novidades que ela vem trazendo. Estas novidades, geralmente, vêm para melhorar nossa produtividade, além de nos proporcionar mais subsídios, a fim de desenvolvermos aplicações ainda melhores. Java ME Platform SDK 3: Assim como os seres vivos, os softwares de computador também evoluem a partir do momento em que se inicia um novo ciclo. No caso da principal ferramenta de desenvolvimento da plataforma Java ME, o Wireless Toolkit, este seu novo ciclo trouxe-lhe evoluções bastante expressivas. Mudanças que vão desde o nome, passando pelo novo conceito da ferramenta, até chegar às suas novas funcionalidades. A ferramenta que antes era considerada um simples toolkit (caixa de ferramenta), agora passa a ser um completo SDK, contando com um ambiente integrado de desenvolvimento. Editor de código, emuladores, nova máquina virtual e APIs são somente algumas das muitas novidades trazidas por esta nova ferramenta. Sem falar que até o seu nome é novidade, pois agora a ferramenta é chamada de Java ME Platform SDK 3. Com todas essas novidades é possível constatar o grande passo que a plataforma Java ME dá em direção a uma maior popularização da plataforma. Pois com o ambiente de desenvolvimento integrado baseado no NetBeans, novos desenvolvedores terão mais facilidades de criar as suas primeiras aplicações, o que garante uma maior chance de crescimento da comunidade Java ME. Segundo a Biologia, o processo permanente de mudança que vem transformando a vida na Terra, desde o seu princípio mais simples até a sua atual diversidade, é conhecido como Evolução. A evolução ocorre quando um ser vivo se reproduz, e pequenas mudanças aleatórias nos seus genes fazem com que o seu descendente seja diferente dele próprio. Essas mudanças, se benéficas, fazem com que o indivíduo sobreviva o tempo necessário para se reproduzir, dando início a um novo ciclo de transformações, o que resulta no surgimento de novas espécies. Num paralelo entre o processo de evolução dos seres vivos com o de um software de computador, verificamos como ambos são parecidos. O software, geralmente, inicia o seu clico de vida de forma bem simples, com poucas funcionalidades, somente com o intuito de atender certa demanda do momento. À medida que vai sendo utilizado, o software, se for bom, acaba aguçando a criatividade dos usuários, que solicitam novas versões mais aperfeiçoadas e com mais funcionalidades. Estas solicitações induzem o software a entrar no clico de evoluções, resultando em novos releases.

85 Neste artigo, falaremos sobre como este processo evolutivo dos softwares atingiu o Wireless Toolkit (WTK). Apresentaremos algumas das principais novidades que a Sun Microsystems preparou, justificando a mudança do seu nome para Java ME Platform SDK 3. De Toolkit para SDK O fato de a Sun ter mudando o nome do WTK não deve causar muito espanto aos desenvolvedores, tendo em vista que esta não é a primeira vez. Desde o surgimento da plataforma Java ME, por volta de 1999, esta já é a segunda vez que a Sun muda o nome da ferramenta. O nome original, Java 2 Platform Micro Edition Wireless Toolkit, foi substituído em 2007, devido à nova versão 1.5 (ou 5) da plataforma Java. Desde então, a Sun retirou o famigerado 2 de todos os nomes de suas plataformas e ferramentas. Com isto, o que era J2ME virou Java ME, o que também acabou refletindo na primeira mudança de nome do WTK para Sun Java Wireless Toolkit. A mudança do nome na nova versão, que agora insere o termo SDK (Standard Development Kit), se deve ao fato da ferramenta proporcionar um ambiente de desenvolvimento completo, e não somente os emuladores, ferramentas de monitoração (e.g. monitor de memória), códigos de exemplo, documentação, etc. O pacote agora também vem com editor de código com assistência de codificação (veja a seção Netbeans Lite ). Além disso, a plataforma Java ME é suportada de forma muito mais completa (o antigo WTK suportava apenas a configuração CLDC, exigindo toolkits separados para CDC e outras variantes). Um arsenal completo que eleva a categoria da ferramenta, justificando o acréscimo do termo SDK. O nome original, Java 2 Platform Micro Edition Wireless Toolkit, foi substituído em 2007, devido à nova versão 1.5 (ou 5) da plataforma Java. Desde então, a Sun retirou o famigerado 2 de todos os nomes de suas plataformas e ferramentas. Com isto, o que era J2ME virou Java ME, o que também acabou refletindo na primeira mudança de nome do WTK para Sun Java Wireless Toolkit. A mudança do nome na nova versão, que agora insere o termo SDK (Standard Development Kit), se deve ao fato da ferramenta proporcionar um ambiente de desenvolvimento completo, e não somente os emuladores, ferramentas de monitoração (e.g. monitor de memória), códigos de exemplo, documentação, etc. O pacote agora também vem com editor de código com assistência de codificação (veja a seção Netbeans Lite ). Além disso, a plataforma Java ME é suportada de forma muito mais completa (o antigo WTK suportava apenas a configuração CLDC, exigindo toolkits separados para CDC e outras variantes). Um arsenal completo que eleva a categoria da ferramenta, justificando o acréscimo do termo SDK. NetBeans Lite De longe a mais importante e impactante novidade do Java ME Platform SDK 3 é o ambiente de desenvolvimento integrado (veja Figura 1), baseado na plataforma NetBeans. Nas versões anteriores da ferramenta, todo o desenvolvimento das aplicações (e.g. escrita de código) tinha que ser feito numa ferramenta (IDE) à parte, como por exemplo, Eclipse, NetBeans, VistaMax, etc. O trabalho do WTK era executar os emuladores, alterar configurações de ambiente da plataforma, monitoramento de memória, dentre outras funcionalidades auxiliares. IDEs como Eclipse e NetBeans, por exemplo, permitiam que o WTK pudesse ser integrado, possibilitando ao desenvolvedor uma transparência do seu uso. As principais ferramentas deste ambiente de desenvolvimento integrado são o editor de código, gerenciador de projetos e arquivos, integração com o Ant, configurações do projeto (e.g. propriedades do arquivo JAD), ofuscador de código, além de outras de cunho mais geral, encontradas em qualquer distribuição do NetBeans. Quem já trabalha com o Netbeans Mobility Pack vai se sentir em casa neste novo ambiente, pois ambos são praticamente o mesmo. Além disso, aqueles que, porventura, decidirem migrar para o NetBeans Mobility Pack futuramente, já que este dispõe de mais funcionalidades, não encontrarão barreiras. Pois o arquivo de projeto do Java ME Platform SDK 3 é totalmente compatível com o Mobility Pack, o que facilita muito a migração entre as ferramentas.

86 Figura 1: Ambiente integrado de desenvolvimento do Java ME Platform SDK 3 baseado no NetBeans. A KVM se Despede Após quase dez anos desde sua chegada, a máquina virtual da Java ME, a Kilo Virtual Machine (KVM), finalmente encerra o seu ciclo de vida. Este fim já era esperado, já que há alguns anos, a KVM já não estava mais presente nos dispositivos móveis disponíveis no mercado, sendo esta substituída pela CLDC HotSpot Virtual Machine. Um projeto mais moderno e robusto, que já conseguia atender melhor as atuais demandas por desempenho. O que prolongou um pouco mais a vida da KVM foi o fato da Sun continuar utilizando-a em seus emuladores. Até a última versão do WTK, a 2.5.2, todos os emuladores ainda eram baseados na KVM. No entanto, com a chegada do Java ME Platform SDK 3 a Sun finalmente aposentou a KVM, trazendo de uma vez por todas, a CLDC HotSpot Virtual Machine também para os seus emuladores, inclusive para a configuração CDC. Com esta mudança, o comportamento das aplicações no emulador ficou mais parecido ao encontrado nos dispositivos reais. Dentre as principais vantagens da CLDC HotSpot Virtual Machine, comparada à KVM, estão a compilação dinâmica das instruções de bytecode em instruções nativas (veja o quadro Compilação Just-in-time (JIT) ), menor consumo e fragmentação de memória, maior economia da bateria, dentre outras. Em termos de números, a execução de uma instrução compilada dinamicamente, chega a ser cinquenta vezes mais rápida do que uma instrução interpretada. Para conhecer um pouco mais sobre a CLDC HotSpot Virtual Machine e a sua chegada aos dispositivos móveis, veja a seção Links, além do artigo Java: Uma perspectiva, da Edição 65. Descobrindo as Diferenças Existe na Internet uma iniciativa chamada de Wireless Universal Resource File (WURFL), aonde desenvolvedores e entusiastas vêm tentando catalogar todos os dispositivos móveis disponíveis no mercado, assim como suas características. O objetivo é fornecer uma base de dados centralizada para os desenvolvedores. Neste caso, um arquivo XML, afim de que eles possam conhecer, antecipadamente, as principais diferenças que existem de um dispositivo para outro, além de ter uma idéia da fatia de

87 mercado que suas aplicações estão abrangendo. Com o objetivo de facilitar o acesso às informações providas pelo WURFL (para saber mais sobre esta iniciativa, veja a seção Links), a Sun desenvolveu uma nova funcionalidade, no Java ME Platform SDK 3, chamada Device Database Search, que acessa essa base de dados de uma forma fácil e rápida. O usuário pode tanto solicitar para ver a lista completa de todos os dispositivos disponíveis, como ele também pode aplicar alguns filtros (e.g. fabricante, modelo, JSRs suportadas, tamanho de tela, etc.), a fim de facilitar a busca pelo dispositivo desejado. O resultado é apresentado numa lista, onde modelo e fabricante são identificados. Para ver os detalhes de um determinado dispositivo, basta selecioná-lo na lista, que todas as suas informações serão exibidas numa outra lista ao lado (veja Figura 2). LWUIT Ganha Força A equipe do projeto Lightweight User Interface Toolkit (LWUIT) deve estar orgulhosa com esta conquista. Tendo em vista a grande popularização deste projeto entre os desenvolvedores Java ME, a Sun não perdeu tempo em tentar transformar este projeto numa espécie de padrão dentro da comunidade de desenvolvedores. Os engenheiros da Sun devem ter percebido a quantidade de projetos que existem na Internet, que visam melhorar a vida dos desenvolvedores, no tocante do desenvolvimento de interfaces gráficas mais sofisticadas. Com isso, a Sun não hesitou e incorporou o LWUIT como uma de suas bibliotecas padrão, disponibilizou uma aplicação exemplo e integrou uma de suas ferramentas utilitárias, o Resource Manager, dentro do Java ME Platform SDK 3. Alavancando de vez o nome LWUIT dentro da comunidade Java ME. Figura 2: Ferramenta Device Database Search retornando todos os dispositivos da Nokia que suportam MIDP 2.0. O LWUIT, para quem ainda não conhece, é um framework de componentes gráficos inspirado no Swing da plataforma Java Standard Edition (Java SE), especificamente modelado e construído para ambientes

88 restritos em poder de processamento e memória, como o dos dispositivos móveis. O LWUIT traz para o mundo móvel, algumas das funcionalidades para o desenvolvimento de interfaces gráficas já conhecidas no desktop e que são bem características do Swing, como por exemplo, layouts (e.g. FlowLayout), renders (componentes que especificam a forma como um objeto é desenhado na tela), manipuladores de evento (e.g. ActionListener), etc. Com toda esta integração, para um desenvolvedor acrescentar o suporte ao LWUIT à sua aplicação dentro do Java ME Platform SDK 3, basta somente alguns passos: acessar as propriedades do projeto, selecionar Libraries & Resources, clicar no botão Add Library e selecionar a biblioteca LWUIT, que já aparece na lista, junto com as demais bibliotecas disponíveis na ferramenta. Além disso, a aplicação exemplo é bem completa, o que serve como uma boa referência inicial para os desenvolvedores que estão começando no LWUIT (para saber mais sobre LWUIT, veja a Edição 60 e a seção Links). Ela apresenta diversos exemplos de várias partes do framework. Encontrando o Gargalo Como se os problema de lógica não fossem o bastante, os problemas de desempenho também tem sido uma constante nas aplicações atuais, principalmente nas móveis, devido às exigentes demandas por mais funcionalidades, sem falar das restrições de processamento, inerentes aos dispositivos móveis. A fim de também facilitar mais esta tarefa dos desenvolvedores, já que por muito tempo esta também foi executada com o auxilio de APIs como System.out.println() e System.currentTimeMillis(), foram criados os monitores de processamento (profiler). São ferramentas que monitoram toda a execução da aplicação, registrando os tempos de execução e a quantidade de vezes que cada método foi executado. Informações muito valiosas quando se está à procura do gargalo de um determinado processo. No Java ME Platform SDK 3, esta ferramenta de monitoração é a mesma encontrada em outras distribuições do NetBeans, também usada para testes em aplicações Java SE e Java EE. Para ativar o profiler para determinada aplicação no Java ME Platform SDK 3, basta habilitar a opção Enable profiler nas propriedades do emulador utilizado. Durante a execução, o profiler registra num arquivo (e.g. data.prof), todas as informações sobre o código que está sendo executado. Ao final da execução, é preciso informar ao SDK, através da opção Profile>Import Java ME SDK Snapshot, o caminho do arquivo gerado pelo profiler, a fim de que a informação coletada seja apresentada. Nesta nova tela que é mostrada (veja Figura 3), o desenvolvedor pode ver o tempo gasto para executar cada método e a quantidade de vezes em que ele foi executado, além de ainda poder agrupar todas estas informações por classe ou por pacote. Dando uma visão mais macro dos tempos de execução de cada componente da aplicação. Figura 3: Tela do profiler que mostra os tempos de execução dos métodos da aplicação.

89 E mais JSRs A cada dia novas APIs são finalmente especificadas, tornando-se aptas a serem implementadas por algum fabricante, que suporte a plataforma Java ME em seus dispositivos móveis. O que normalmente acontece é a implementação dessas APIs chegarem primeiro às ferramentas de desenvolvimento, tendo em vista uma maior facilidade de implementá-las em plataformas Windows ou Linux, por exemplo, para depois chegarem aos dispositivos. No Java ME Platform SDK 3, três novas APIs estão finalmente disponíveis para os desenvolvedores: Mobile Sensor API (JSR 256) (veja o artigo da Edição 55), XML API for Java ME (JSR 280) e a Java Binding for the OpenGL ES API (JSR 239). A primeira é responsável por fornecer acesso a alguns sensores (e.g. acelerômetro) disponíveis em certos dispositivos móveis (veja o quadro Trabalhando com Sensores no Emulador ). A JSR 280, por sua vez, define uma API exclusiva para manipular arquivos XML com parsers SAX2 e DOM. A idéia é acabar com a fragmentação que existe atualmente, onde cada API que precisa manipular XML define o seu próprio mecanismo para desempenhar este trabalho (e.g. Web Services Specification (JSR 172)). E finalmente, a JSR 239 vem para prover o suporte ao desenvolvimento de gráficos 3D através da biblioteca OpenGL ES, a qual é um subconjunto da OpenGL 1.3. Para fechar o pacote das novas API, o Java ME Platform SDK 3 também disponibiliza aplicações exemplo para cada nova API suportada, inclusive as que já eram suportadas. Um ótimo pontapé inicial para quem está começando a trabalhar com as APIs mais recentes. Quanto mais Emuladores, Melhor É inquestionável a qualidade dos emuladores disponibilizados pelo Java ME Platform SDK 3, assim como os de suas versões anteriores. Todos eles seguem à risca cada ponto das especificações das APIs, dando maior segurança ao desenvolvedor sobre a corretude do seu código. Se nenhuma exceção for lançada, alertando sobre alguma operação indevida, é porque ele está no caminho certo. No entanto, por mais que as especificações sirvam para definir uma base comum, além de diminuir as chances de incompatibilidade entre as diferentes implementações, no mundo real as coisas não são tão perfeitas assim. É comum encontrar problemas de incompatibilidade entre uma implementação feita para o Windows, que não funciona no Linux, e vice-versa. No mundo móvel então, é ainda pior. Aplicações feitas para rodar num dispositivo da Nokia podem precisar de ajustes para rodar perfeitamente num Motorola ou Sony Ericsson, por exemplo. Por mais que sigam a risca o que está na especificação, sempre é possível ter algo na implementação (inclusive bugs) que gera um comportamento diferente. A complexidade e as restrições dessas plataformas móveis potencializam ainda mais este problema. Tendo em vista essas possíveis diferenças, os testes em outras plataformas se tornam muito importantes para uma aplicação Java ME, que deseja rodar em dispositivos de mais de um fabricante. Nesta versão do Java ME Platform SDK 3 é possível importar outros emuladores desenvolvidos, por exemplo, pela Nokia, Samsung, Motorola, Sony Ericsson, dentre outros, para dentro da ferramenta e usá-los para testar suas aplicações. Uma funcionalidade já encontrada no NetBeans Mobility Pack. Para importar novos emuladores, é preciso informar o caminho do SDK do fabricante, o qual os emuladores pertencem. Para isto, deve-se acessar Tools>Java Platforms, selecionar o tipo de plataforma J2ME, clicar em Add Plaform, selecionar Custom Java ME MIDP Platform Emulador e informar os caminhos solicitados pelo restante do wizard. Após ter configurado a nova plataforma, basta acessar as propriedades do projeto e selecionar a nova plataforma e o emulador a ser utilizado. Testes em emuladores é realmente uma mão na roda, pois facilitam muito o desenvolvimento, tendo em vista a rapidez que é por em execução a aplicação no emulador. Entretanto, eles nunca vão substituir o teste no dispositivo real, pois, se de um emulador para outro já existem diferenças, imagine do emulador para o hardware. Suporte Oficial Com exceção do sistema operacional Symbian, outros sistemas como Palm OS e Windows Mobile, também bem populares no mercado, nunca foram referência pelo seu suporte à plataforma Java ME, pelo contrário. Esta questão, acredito, deve-se ao fato que ambos possuem, desde muito cedo, suas próprias plataformas nativas (baseadas em C) de desenvolvimento de aplicações. Ambas muito bem difundidas e poderosas, e que acabou gerando uma comunidade de desenvolvedores duradoura.

90 Com relação ao Palm OS, a Sun até que se esforçou na época do lançamento da primeira versão do Wireless Toolkit (ainda MIDP 1.0), disponibilizando uma máquina virtual que podia ser instalada nos dispositivos da empresa Palm. No entanto, a investida não vingou, talvez pelo desinteresse da própria Palm, e o projeto ficou pelo caminho. A IBM também tentou, lançando uma máquina virtual chamada Websphere Everyplace Micro Environment (WME), com suporte ao MIDP 2.0. A Palm dessa vez até esboçou um incentivo, publicando a VM da IBM no seu site como um produto homologado. Porém, em 2008, o incentivo acabou e a Palm retirou o apoio. Hoje este projeto está parado no tempo, assim como o próprio Palm OS, que vem sumindo do mercado aos poucos. A história da plataforma Java ME no sistema operacional da Microsoft não é muito diferente da vivida pela Palm. Esta também é marcada pela dificuldade de encontrar uma máquina virtual robusta e sólida, o que ajudaria a difundir melhor a Java ME nos populares PDAs da empresa de Bill Gates. No entanto, por mais que o suporte seja fraco, o Windows Mobile chega ainda a ser melhor que o Palm OS, com relação a Java ME. Nas versões para smartphones do Windows Mobile, por exemplo, até existe uma máquina virtual que já acompanha o dispositivo. Por mais que seja restrito em recursos, ainda serve para rodar aplicações mais simples. A IBM também investiu na Java ME para o Windows Mobile, disponibilizando uma versão paga da sua máquina virtual, WME, voltada para versões anteriores deste sistema. Mas agora, as coisas parecem que vão melhorar para os desenvolvedores Java ME que querem rodar suas aplicações no Windows Mobile. A Sun está disponibilizando, no Java ME Platform SDK 3, uma máquina virtual para o Windows Mobile 6, que pode tanto ser instalado em um emulador do próprio sistema operacional no PC, quanto num dispositivo real. Tudo o que o desenvolvedor precisa fazer é instalar a maquina virtual (veja Figura 4), através do arquivo sun-java-cldc-emu.cab, que se encontra disponível no SDK na pasta JavaMESdkHome\ondevice\winmobile-arm, no emulador ou no dispositivo. Além de executar as aplicações, o desenvolvedor ainda tem a possibilidade de depurar suas aplicações tanto no emulador quanto no dispositivo real. Com mais esta plataforma dando suporte à Java ME, agora com a assinatura da Sun, a plataforma Java dá mais um passo muito importante na consolidação do seu nome nas principais plataformas móveis do mercado. Conclusão A Sun, com certeza, acertou com o Java ME Platform SDK, pois a falta do ambiente de codificação do Wireless Toolkit atrapalhava, de certa forma, os novos desenvolvedores. O problema era que estes não conseguiam, rapidamente, codificar um Hello, World!. Haja vista que precisavam usar um editor de código externo, importar o projeto para o toolkit, etc. Com o Java ME Platform SDK tudo ficou mais integrado. A facilidade de criar um projeto, codificar, escolher o emulador e colocar para executar são características muito importantes, que todo iniciante, em qualquer plataforma, gosta de ter. Entretanto, o Java ME Platform SDK é indicado somente para aplicações de teste ou pequenas, pois algumas funcionalidades importantes no desenvolvimento de aplicações mais complexas, como depuração e controle de versão, não estão disponíveis. Nesses casos, o recomendado mesmo é o NetBeans Mobility Pack, que oferece o ambiente completo do NetBeans mais uma série de ferramentas específicas para Java ME QUADRO INFORMATIVO Compilação Just-in-time (JIT) A característica da plataforma Java que permite que suas aplicações sejam possíveis de serem executadas em diferentes plataformas (e.g. Windows e Linux), sem necessidade de recompilação, é o fato do seu código-fonte ser compilado para uma representação intermediária, conhecida como bytecode. Mas sua execução depende de outra aplicação, esta sim dependente de plataforma: a máquina virtual, que interpreta o bytecode. Os ganhos em portabilidade com este código intermediário, por outro lado, gera problemas de

91 desempenho, pois a interpretação é bem menos eficiente que a execução de código nativo. Entretanto, o problema pode ser resolvido com ajuda da técnica de compilação Just-in-time (JIT), que consiste na compilação do bytecode para código nativo durante a execução da aplicação. No momento em que um método vai ser executado, este é convertido numa representação de código de máquina. Por isso o termo Just-in-time que, em português, significa no momento exato. Este código compilado fica salvo na memória, pronto para execuções futuras. Além da plataforma Java, a.net também utiliza esta técnica. Neste caso, o código intermediário convertido pela máquina virtual.net é o Microsoft Intermediate Language (MIL). Para saber mais sobre a JIT, veja a seção Links. Trabalhando com Sensores no Emulador Existem algumas APIs Java ME que interagem com alguns tipos de hardware ou serviço, que vem integrado a algumas linhas de dispositivos móveis. Por exemplo, a Mobile Sensor API (JSR 256), que interage com sensores (e.g. acelerômetro); a Location API (JSR 179), que captura os dados de um GPS; e a Payment API (JSR 229), que fornece serviço de pagamentos em geral. Imaginar como se testa uma aplicação desenvolvida com estas APIs, no dispositivo real, não é difícil. Pois neste caso, o hardware ou serviço está presente no dispositivo e a API vai acessá-lo para poder retornar suas informações. Mas o que acontece quando não se tem o dispositivo real em mãos, para testar a aplicação? A resposta é simples: para cada API que interage com um hardware ou serviço, os emuladores do Java ME Platform SDK executam tais papéis, simulando-os. No caso da JSR 256, para a qual a emulação de sensores é mais uma novidade do Java ME Platform SDK, o desenvolvedor pode alterar as informações que o acelerômetro retorna. Desta forma, o desenvolvedor pode informar novos valores para as coordenadas x, y e z, que representam a leitura tridimensional deste tipo de hardware. Para acessar as ferramentas de simulação dos emuladores, o desenvolvedor precisa acessar a opção View>External Events Generator, disponível no próprio emulador. Depois disto, uma nova tela será apresentada, com uma série abas nela. Cada aba, por sua vez, representa um tipo de hardware ou serviço que pode ser simulado. No caso do acelerômetro, a aba Sensors é a que fornece os meios para simulá-lo. Nesta mesma aba, o Java ME Platform SDK ainda fornece a simulação de um sensor de temperatura. Links Página de download do Java ME Platform SDK 3 CLDC HotSpot Implementation Virtual Machine WURFL: Wireless Universal Resource File https://lwuit.dev.java.net/ LWUIT: Lightweight User Interface Toolkit JIT: Just-in-time Saiba Mais Auditório Virtual DevMedia - Empreendedorismo na era dos Celulares Curso Online - Introdução ao desenvolvimento para celulares com Java ME Curso Online - Introdução ao uso de Web Services em Java ME

92 Curso Online - Criação de Interfaces Gráficas em Java ME Curso Online - Java ME e Banco de Dados Curso Online - Trabalhando com SMS e MMS em JavaME Curso Online - Conectividade em Java ME Curso Online - Desenvolvendo um Software Acadêmico para Celular Java Magazine 44 - A Plataforma Java ME: Parte 1 Java Magazine 45 - Mini-curso: programação Java ME: Parte 2 Java Magazine 46 - Programação Java ME: Parte 3 Java Magazine 47 - Programação Java ME: Parte 4 Java Magazine 48 - Programação Java ME: Parte 5 Java Magazine 49 - Mini-curso de java ME: Parte 6 Java Magazine 56 - Opinião: Android versus Java ME Java Magazine 56 - JSR 257: Contactless Communication API Java Magazine 57 - Web Feed Reader ME Java Magazine 60 - LWUIT: Swing para Java ME Java Magazine 64 - Google Maps em aplicações móvies WebMobile 11 - JavaME usando GPS WebMobile 15 - J2ME Polish - Desenvolvendo interfaces gráficas para aplicações JavaME webmobile 17 - Desenvolvimento ponta-a-ponta: cliente JavaME com servidor JavaEE WebMobile 17 - Criando jogos de ação em 2D com a API de jogos em JavaME WebMobile 18 - Desenvolvimento ponta-a-ponta: Cliente JavaME com servidor JavaEE WebMobile 20 - Escrevendo Jogos para Celular em JavaME

93 WebMobile 22 - Construindo Interfaces Gráficas na Prática Vídeo - Introdução do Desenvolvimento de Jogos em Java ME - Parte 1 Vídeo - Introdução do Desenvolvimento de Jogos em Java ME - Parte 2 Vídeo - Introdução do Desenvolvimento de Jogos em Java ME - Parte 3

94 Estratégias de Integração de Aplicações Java EE Marco Aurélio de Souza Mendes É consultor independente de Arquitetura de Software e Engenharia de Software com mais de 16 anos de experiência em projetos de TI. É também professor de pós-graduação dos cursos de Estratégias de Arquitetura de Sistemas do IGTI e Engenharia de Software do IEC/PUC-Minas. Ele mantém artigos diversos sobre Arquitetura, Java e Engenharia de Software no seu blog De que se trata o artigo: O artigo apresenta técnicas e práticas provadas de integração de aplicações Java com outras aplicações, sistemas e bancos de dados. Projetos de integração apresentam muitas complexidades técnicas e muitas possibilidades técnicas em Java tais como JMS, JCA, JDBC, RMI, HTTP e SOAP. O artigo mostra como escolher estas tecnologias e como utilizá-las adequadamente através de padrões de integração de aplicações (EIP). Para que serve: O artigo é útil para que desenvolvedores possam conhecer os riscos associados à integração de sistemas Java com outros sistemas e aplicar as melhores práticas de mercado e padrões de integração para mitigar e eliminar estes riscos. Projetos com riscos técnicos reduzidos possuem maior garantia de sucesso, maior qualidade, estabilidade e manutenções mais simples e facilitadas. Em que situação o tema é útil: Em projetos de TI que requerem integrações de todo tipo, como bancos de dados relacionais, bases de dados em outros formatos, sistemas de filas de mensagens, aplicações legadas em plataformas baixas e altas ou aplicativos como CRM (Customer Relationship Management) e ERP (Enteprise Resource Planning). Estratégias de Integração de Aplicações Java EE: Integrar aplicações Java com outros sistemas não é uma tarefa trivial. Para reduzir riscos e manter projetos sob controle, devemos usar práticas provadas de integração de sistemas. As melhores práticas de integração são denominadas padrões EAI (EAI Patterns) e foram popularizadas por Gregor Hohpe através do seu livro Enterprise Integration Patterns. Estas práticas permitem que um arquiteto ou desenvolvedor escolha as estratégias mais eficientes de integração de sistemas Java com outros sistemas e produza soluções mais perenes e econômicas. Estas práticas de integração também são fundamentais para empresas que estejam buscando iniciativas SOA e BPM, pois permitem gerir adequadamente a criação e evolução de serviços (ativos) em repositórios de serviços (ESB). Um processo simples para que você possa aprender a integrar sistemas em projetos envolve os seguintes passos: (1) Coletar os requisitos arquiteturais de interoperabilidade; (2) Desenvolver soluções independentes de tecnologia para cada requisito arquitetural coletado; (3) Estudar os exemplos disponibilizados na referência [1]; (4) Estudar as tecnologias Java mais adequadas para cada requisito (ex: WebServices ou RMI); (5) Implementar os cenários com as tecnologias Java escolhidas; (6) Testar as soluções em ambiente de homologação. Em alguma empresa do Brasil, uma história comum... Integrar aplicações não é uma tarefa trivial. Protocolos diversos, APIs exóticas, tecnologias e ambientes complexos e cronogramas agressivos são alguns aspectos que desafiam diariamente analistas desenvolvedores Java EE.

95 Conto aqui uma história que resume estes desafios. Uma equipe necessitava enviar s de sua aplicação Java. Uma tarefa aparentemente trivial, que muitos desenvolvedores vivem todos os dias. A equipe não possuía experiência com a API JavaMail, mas com a ajuda de um recurso externo a equipe se capacitou e desenvolveu o código necessário para suportar a integração, que neste caso ocorreria com o servidor Microsoft Exchange. Código implementado, testes internos realizados com sucesso e aprovação gerencial. Aparentemente o problema foi resolvido. A vida real, entretanto, guarda surpresas. Na véspera da semana de implementação, o código foi implantado na empresa do cliente (vamos chamá-la de empresa ACME), mas os casos de uso que requeriam a integração com o Microsoft Exchange não funcionavam. Todos os olhos e atenções (e culpas) foram lançados para o servidor de da Microsoft. Após a descoberta que o servidor de do cliente (v2007) estava em uma diferente versão do ambiente interno da desenvolvedora (v2003), modificações no ambiente de desenvolvimento foram realizadas para adequar o servidor. Nenhum resultado positivo foi alcançado. O pânico se instalou! Mais investigações foram realizadas e a equipe descobriu que o servidor de de produção não residia na mesma rede do servidor de aplicação do cliente, mas em um distante local remoto (em outra cidade) em um provedor com um acesso controlado por um firewall. O analista de infra-estrutura do cliente não foi questionado o bastante para informar este fato. Para encurtar a história, a equipe descobriu que o envio de s neste ambiente requeria o uso de certificados e protocolos com garantia de transporte seguro (SMTP sobre SSL). Noites mal-dormidas, um atraso de algumas semanas no cronograma, um cliente relativamente estressado e o desafio foi finalmente vencido. Que lições podemos aprender com esta história? Enumero algumas abaixo: Certificar que as versões dos ambientes a serem integrados sejam exatamente iguais; Analisar cuidadosamente a topologia, isto é, a organização física do ambiente de produção do cliente. Diagramas UML de implantação são uma ferramenta útil neste aspecto; Analisar os protocolos e requisitos não-funcionais que possam interferir na interoperabilidade; Antecipar testes realizados na plataforma real do cliente. O leitor mais experiente pode questionar as lições aprendidas neste exemplo. Estas lições são óbvias. Mas devemos lembrar que senso comum não é prática comum. Dica: Seja um Indiana Jones de aplicações Java na sua empresa. Faça uma arqueologia de software nas aplicações Java da sua empresa e colete os erros e lições aprendidas. Os erros do passado são uma excelente fonte de aprendizado para projetos futuros. O objetivo deste artigo é mostrar a você como tornar senso comum em prática comum, isto é, evitar erros comuns de integrações de sistemas em projetos e evitar estresses desnecessários. Vamos abordar estratégias e técnicas para organizar o seu trabalho, organizados da seguinte forma nas seções seguintes deste artigo: Estilos, Níveis e Topologias de Integração. Iremos conhecer aqui fundamentos da integração de sistemas; Tecnologias para Interoperabilidade Java. Aqui iremos citar as principais tecnologias e padrões Java para a integração de aplicações; Padrões de Integração (EIP). Iremos conhecer aqui as melhores práticas de mercado para integrar aplicações; Processo para Integrar Aplicações. Vamos abordar aqui as principais tarefas necessárias durante um projeto para garantir uma boa interoperabilidade de suas aplicações Java. Estilos, Níveis e Topologias de Integração Se você se conhece, mas não o inimigo, para cada vitória sofrerá uma derrota, Sun Tzu, A Arte da Guerra. Como conhecer o inimigo? Primeiramente devemos compreender que interoperabilidade é um mecanismo arquitetural, ou seja, uma preocupação importante de um projeto e que, portanto, requer a atenção técnica ainda no começo do projeto. Devemos investigar as interoperabilidades requeridas no nosso projeto através do estilo, nível e topologia associados, pois para cada um haverá uma abordagem técnica diferenciada e tecnologias distintas em Java.

96 Dica: Colete os requisitos arquiteturais diretamente com representantes do seu cliente em reuniões conjuntas com o analista de requisitos. Normalmente analistas de requisitos têm dificuldade de capturar e expressar informações técnicas, o que implica em informações truncadas e novas descobertas indesejadas no final do projeto. A interoperabilidade de aplicações pode se apresentar em quatro estilos, conforme Gregor Hohpe [1] O primeiro estilo é a transferência de arquivos, onde duas aplicações compartilham as informações através de um arquivo texto ou binário. O protocolo FTP é um exemplo popular de tecnologia que suporta este estilo; O segundo estilo, talvez o mais popular, é através de dados compartilhados em bancos de dados; O próximo estilo é através de procedimentos remotos (RPC), onde um programa cliente invoca uma funcionalidade em outra máquina. As tecnologias de WebServices são exemplos normalmente associados a RPC; O último estilo é através de passagem de mensagens. Programas com suporte a filas de mensagens, como a especificação Java JMS, são exemplo deste estilo. Pare um minuto e responda: Qual o estilo requerido no exemplo citado de interoperabilidade com o Microsoft Exchange? (Resposta no final deste artigo). Além dos estilos, podemos classificar a interoperabilidade em níveis, listados a seguir: Nível de dados. Como integrar fontes de dados relacionais ou em outros formatos e como reduzir a sua redundância? A integração em nível de dados foca na movimentação de dados entre aplicações com o objetivo de compartilhar o mesmo dado entre aplicações diferentes; Nível de Interfaces de Aplicação (API). Como integrar APIs de aplicação em outras tecnologias que não sejam Java? A integração via APIs passa pela chamada de funções através de protocolos síncronos (RPC) ou assíncronos (mensagens); Nível de Processos de Negócio. Domínio do mundo BPM/SOA, a integração em nível de processos de negócio foca no desenvolvimento de componentes de alto nível que irão fornecer interfaces de alto nível que podem ser considerados serviços; Nível de Apresentação. Popularmente conhecidos como mash-ups, integram aplicações através de um conjunto de vários portlets (janelas visuais independentes) que residem em um determinado portal. A Figura 1 mostra um exemplo de integração neste nível. Figura 1: Mashup do internet google Nota Devman - Requisitos Funcionais e Requisitos Não-Funcionais Requisitos funcionais expressam os desejos dos interessados do projeto na perspectiva da funcionalidade. Exemplos incluem cadastros, relatórios e fluxos de trabalho. Requisitos não-funcionais expressam atributos de qualidade de um sistema tais como desempenho, usabilidade, disponibilidade ou

97 portabilidade. Requisitos funcionais e não-funcionais importantes para o negócio (prioritários) e complexos formam o conjunto de requisitos arquiteturais que devem ser foco inicial de qualquer projeto de TI. Requisitos funcionais e não-funcionais coletados podem responder a perguntas sobre escolhas de estratégias e tecnologias sobre interoperabilidade. Por exemplo, restrições sobre desempenho podem eventualmente influenciar na escolha de uma integração com soquetes ao invés de XML e Web Services. Um novo teste: Qual o nível associado ao exemplo citado de interoperabilidade com o Microsoft Exchange? (Resposta no final deste artigo). Finalmente, devemos considerar também a questão da topologia da aplicação. Dois modelos clássicos existem: Comunicação Ponto a Ponto. A integração ponto a ponto é também chamada de integração oportunista e ocorre diretamente entre dois sistemas que queiram conversar. Quando conectamos uma TV diretamente a um DVD, usamos intuitivamente esta topologia de integração; Comunicação Hub and Spoke. Topologia popularizada pelos ESB (um tipo particular de Hub and Spoke), esta topologia usa um mediador central para comunicar cada aplicação (Spoke) que deseje conversar. Nenhuma aplicação conversa diretamente com outra aplicação. Isto pode parecer confuso e complexo, mas considere (na sua sala de TV dos sonhos) como você poderia integrar adequadamente uma televisão digital, um computador, um sistema de som 7.1, um DVD, um vídeo-cassete (para as fitas de formatura da sua família), um projetor e um vídeo-game de última geração. É claro neste exemplo que usar um aparelho central para gerir todas as conexões é mais vantajoso. O Home-Theater é um hub na sua sala de TV dos sonhos e pode ligar todos os fios dos aparelhos (Figura 2). Figura 2: A topologia de comunicação ponto a ponto liga duas aplicações diretamente. A topologia Hub and Spoke usa um barramento central (Hub) para ligar múltiplos clientes. Mais um desafio: Qual a topologia associada ao exemplo citado de interoperabilidade com o Microsoft Exchange? (Resposta no final deste artigo). Dica: Colete os requisitos arquiteturais de interoperabilidade na sua aplicação. Para cada requisito arquitetural, defina o estilo, nível e topologia associada. Tecnologias de Interoperabilidade Java Um chefe deve empregar táticas variadas de acordo com os tipos de terreno, Sun Tzu. A plataforma Java foi desenhada e evoluída nos últimos anos com um grande suporte para

98 interoperabilidade. Considere como exemplo simples a especificação JDBC. Projetada de forma elegante para suportar a portabilidade de sistemas operacionais e bancos de dados, ela é um exemplo que suporta a integração do estilo (ver Tabela 1) banco de dados compartilhados, em nível (ver Tabela 2) de dados. Diversas outras tecnologias foram projetadas para suportar outros estilos e níveis. Apresentamos alguns exemplos nas Tabelas 1, 2 e 3, sem nos ater aos detalhes da API, que podem ser encontrados em artigos anteriores da revista Java Magazine. As Tabelas 1, 2 e 3 mostram que é fundamental escolher adequadamente a tática (tecnologia) conforme o tipo de terreno (estilo, nível ou topologia). Tabela 1: Tecnologias Java para suportar estilos de interoperabilidade Tabela 2: Tecnologias Java para suportar níveis de interoperabilidade Tabela 3: Tecnologias Java para suportar topologias de interoperabilidade Dica: Não use as tecnologias Java no primeiro combate a um problema de interoperabilidade. A tecnologia é secundária e deve ser considerada apenas após a correta coleta e desenvolvimento dos requisitos arquiteturais e definição dos estilos, níveis e topologia. Padrões de Integração de Aplicações (EIP) Um soberano iluminado estuda deliberadamente a situação e um bom general lida cuidadosamente com ela. Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada., Sun Tzu. Conhecemos o inimigo. Conhecemos as ferramentas. Entretanto, a grande chave na interoperabilidade de aplicações é saber como aplicar as tecnologias Java a nosso favor. Neste aspecto, introduzimos o conceito de um padrão de integração de aplicações. Um padrão EIP é uma solução provada aplicável ao contexto de integração de aplicações corporativas. O livro Enterprise Integration Patterns [1] apresenta 65 padrões de integração de sistemas. Cada padrão resolve um problema particular no contexto de integração de aplicações corporativas e pode ser usado junto com outros padrões EIP para solucionar um problema do mundo real.

99 Consideremos, para ilustrar o conceito, um problema similar ao citado no começo deste artigo. Poderíamos formalizar os requisitos arquiteturais da seguinte forma: R1. A aplicação ACME deve interoperar com o servidor Microsoft Exchange 2007 através de protocolos SMTP para envio de s. R2. O transporte para interoperabilidade com o servidor de s deve garantir confidencialidade e integridade das informações enviadas através do uso do protocolo SMTP sobre SSL. Ao lermos o livro EAI Patterns, capturamos alguns padrões candidatos para o problema acima. Estes padrões são documentados na Tabela 4. Tabela 4: Padrões EAI usados para resolver a interoperabilidade com o Microsoft Exchange O primeiro padrão da Tabela 4 nos diz que a solução provavelmente será resolvida com um mecanismo assíncrono. Dadas as restrições de protocolos no requisito R1, vemos que a especificação Java nos sugere a especificação JavaMail. O segundo e terceiro padrões nos diz que teremos um canal para o envio e recebimento de informações e este canal deve se conectar a um sistema de como o Microsoft Exchange. Ao examinarmos a classe Transport, da API do JavaMail, veremos que ela possui esta função. Naturalmente, um Message Endpoint requer uma implementação da especificação JavaMail. Assumamos neste exemplo que usamos o JBoss AS para esta solução.

100 O quarto padrão nos diz que devemos enviar um documento textual. Ao observamos novamente a classe Transport, notamos que ela possui um método send() que espera como argumento um objeto do tipo Message, que modela um Document Message. O quinto padrão endereça os requisitos de segurança. Um enriquecedor de conteúdo permite adicionar à mensagem original informações adicionais. No nosso caso, estas informações adicionais serão de segurança, que nos permite que a mensagem seja entregue em servidores que operem sobre protocolo SSL. Ao examinarmos a hierarquia da classe Transport, vemos a classe SMTPSSLTransport. Esta classe fornece a funcionalidade de envio de s sobre canal seguro (confidencialidade e integridade). O último padrão está fora do escopo Java, mas ele indica que alguém deve configurar o servidor Exchange para não aceitar mensagens SMTP, mas somente mensagens SMTP sobre SSL. O padrão Consumidor Seletivo representa este mecanismo. Se conectarmos os padrões EIP teremos o desenho da nossa solução apresentado na Figura 3. Figura 3: Esquema da solução de integração com o MS Exchange Server Nota Devman - Diagramas de Casos de Uso Diagramas de casos de uso são visualizações de negócio usadas por analistas de requisitos para o auxílio na coleta e entendimento de requisitos. Estes diagramas possuem atualmente grande popularidade na comunidade de analistas e podem ser ferramentas poderosas para a coleta de interoperabilidades. No nosso exemplo, poderíamos representar a interoperabilidade do envio do com o seguinte diagrama. Note que neste diagrama o Microsoft Exchange suporta a operação de envio de e por isso é chamado de Ator Secundário. O trecho de código abaixo mostra estas peças conectadas. Listagem 1. Fragmento de Código para Envio de . Security.addProvider(new com. sun.net.ssl.internal.ssl.provider()); Properties props = new Properties(); props.put("mail.smtp.host", SMTP_HOST_NAME); // Servidor de props.put("mail.smtp.auth", "true"); // Requer autenticacao props.put("mail.debug", "true"); props.put("mail.smtp.port", SMTP_PORT); // Porto do servidor de props.put("mail.smtp.socketfactory.port", SMTP_PORT); props.put("mail.smtp.socketfactory.class", // Enriquecedor da mensagem com SSL "javax.net.ssl.sslsocketfactory" );

101 props.put("mail.smtp.socketfactory. fallback", "false"); Session session = Session.getDefaultInstance (props, new javax.mail.authenticator() { protected PasswordAuthentication getpasswordauthentication() { return new PasswordAuthentication ("username", "password"); ); Message message = new MimeMessage(session); InternetAddress addressfrom = new InternetAddress(from); message.setfrom(addressfrom); message.setsubject( OLÁ EIP ); message.settext( Padrões EIP organizam e comunicam as soluções Java! ); Transport.send(message);... Este fragmento de código pode ser entendido como a realização do esquemático da Figura 3. Para um problema simples, naturalmente, podemos até ir intuitivamente para uma tecnologia ou um código, mas isso é como começar a correr uma maratona sem preparação física adequada. Os padrões representam esta preparação física. Eles permitem que você pense nos aspectos da solução sem se ater aos detalhes da tecnologia. Ao escolheremos uma tecnologia Java determinada, ela será a conseqüência dos padrões, que naturalmente devem suportar os requisitos arquiteturais especificados. Para problemas complexos de integração do mundo real, entretanto, devemos conhecer e aplicar os padrões EIP. Outra excelente fonte de padrões é o livro POSA [2], que contém mais de uma centena de padrões arquiteturais, entre eles diversos padrões EIP. Como exemplo de padrões EIP usados para modelar aplicações com integração complexa, dita aplicações EAI, poderíamos citar os padrões descritos na Tabela 5. Tabela 5: Padrões EAI tipicamente usados em aplicações BPM/SOA/ESB.. Um Processo para Interoperar Aplicativos Se um general sabe o lugar e a hora de uma batalha, ele pode conduzir as suas tropas para até mil milhas, mesmo para uma batalha decisiva. Se ele não sabe nem o lugar nem a hora de uma batalha, então o seu lado esquerdo não pode ajudar a sua direita e a ala direita não pode salvar a esquerda; a tropa da frente não pode auxiliar a tropa da retaguarda, nem a tropa da retaguarda pode ajudar a tropa da frente., Sun Tzu

Aula 1 - Introdução e configuração de ambiente de desenvolvimento

Aula 1 - Introdução e configuração de ambiente de desenvolvimento Aula 1 - Introdução e configuração de ambiente de desenvolvimento Olá, seja bem-vindo à primeira aula do curso para desenvolvedor de Android, neste curso você irá aprender a criar aplicativos para dispositivos

Leia mais

ENTERPRISE JAVABEANS 3. Msc. Daniele Carvalho Oliveira

ENTERPRISE JAVABEANS 3. Msc. Daniele Carvalho Oliveira ENTERPRISE JAVABEANS 3 Msc. Daniele Carvalho Oliveira Apostila Servlets e JSP www.argonavis.com.br/cursos/java/j550/index.html INTRODUÇÃO Introdução Enterprise JavaBeans é um padrão de modelo de componentes

Leia mais

CURSO DE PROGRAMAÇÃO EM JAVA

CURSO DE PROGRAMAÇÃO EM JAVA CURSO DE PROGRAMAÇÃO EM JAVA Introdução para Iniciantes Prof. M.Sc. Daniel Calife Índice 1 - A programação e a Linguagem Java. 1.1 1.2 1.3 1.4 Linguagens de Programação Java JDK IDE 2 - Criando o primeiro

Leia mais

Linguagem de Programação Visual

Linguagem de Programação Visual Linguagem de Programação Visual Unidade 1 Ambiente de desenvolvimento Curso Técnico em Informática SUMÁRIO INTRODUÇÃO... 3 SOBRE O JAVA... 3 AMBIENTE DE DESENVOLVIMENTO... 5 RECURSOS DA FERRAMENTA NETBEANS...

Leia mais

Prof. M.Sc. Fábio Procópio Prof. M.Sc. João Maria Criação: Fev/2010

Prof. M.Sc. Fábio Procópio Prof. M.Sc. João Maria Criação: Fev/2010 Prof. M.Sc. Fábio Procópio Prof. M.Sc. João Maria Criação: Fev/2010 Primeira Dica Afirmação O que é Java? Características do Java Como Java Funciona Plataforma Java Edições Java Java SE Java EE Java ME

Leia mais

Java e Banco de Dados: JDBC, Hibernate e JPA

Java e Banco de Dados: JDBC, Hibernate e JPA Java e Banco de Dados: JDBC, Hibernate e JPA 1 Objetivos Apresentar de forma progressiva as diversas alternativas de persistência de dados que foram evoluindo na tecnologia Java, desde o JDBC, passando

Leia mais

Integrando Eclipse e Websphere Application Server Community Edition

Integrando Eclipse e Websphere Application Server Community Edition 1 Integrando Eclipse e Websphere Application Server Community Edition Sobre o Autor Carlos Eduardo G. Tosin (carlos@tosin.com.br) é formado em Ciência da Computação pela PUC-PR, pós-graduado em Desenvolvimento

Leia mais

Prof. Esp. Adriano Carvalho

Prof. Esp. Adriano Carvalho Prof. Esp. Adriano Carvalho Um arquivo contendo uma sequência de comandos em uma linguagem de programação especifica Esses comandosrespeitam regras de como serem escritos e quais são as palavras que podem

Leia mais

Nome N Série: Ferramentas

Nome N Série: Ferramentas Nome N Série: Ferramentas Competências: Identificar e utilizar técnicas de modelagem de dados; Habilidades: Utilizar ferramentas de apoio ao desenvolvimento de software; Bases Tecnológicas: Metodologias

Leia mais

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse Como criar um EJB Criando um projeto EJB com um cliente WEB no Eclipse Gabriel Novais Amorim Abril/2014 Este tutorial apresenta o passo a passo para se criar um projeto EJB no Eclipse com um cliente web

Leia mais

Linguagem de Programação JAVA. Professora Michelle Nery Nomeclaturas

Linguagem de Programação JAVA. Professora Michelle Nery Nomeclaturas Linguagem de Programação JAVA Professora Michelle Nery Nomeclaturas Conteúdo Programático Nomeclaturas JDK JRE JEE JSE JME JVM Toolkits Swing AWT/SWT JDBC EJB JNI JSP Conteúdo Programático Nomenclatures

Leia mais

Tecnologia Java. Daniel Destro do Carmo Softech Network Informática daniel@danieldestro.com.br

Tecnologia Java. Daniel Destro do Carmo Softech Network Informática daniel@danieldestro.com.br Tecnologia Java Daniel Destro do Carmo Softech Network Informática daniel@danieldestro.com.br Origem da Tecnologia Java Projeto inicial: Oak (liderado por James Gosling) Lançada em 1995 (Java) Tecnologia

Leia mais

Introdução ao IDE Netbeans (Programação Java)

Introdução ao IDE Netbeans (Programação Java) Universidade Federal do ABC (UFABC) Disciplina: Processamento da Informação (BC-0505) Assunto: Java e Netbeans Introdução ao IDE Netbeans (Programação Java) Conteúdo 1. Introdução... 1 1.1. Programas necessários...

Leia mais

Manual de Utilização

Manual de Utilização Se ainda tiver dúvidas entre em contato com a equipe de atendimento: Por telefone: 0800 642 3090 Por e-mail atendimento@oisolucoespraempresas.com.br Introdução... 3 1. O que é o programa Oi Backup Empresarial?...

Leia mais

Procedimentos para Configuração do Ambiente J2EE e J2SE em Ambiente Windows

Procedimentos para Configuração do Ambiente J2EE e J2SE em Ambiente Windows Procedimentos para Configuração do Ambiente J2EE e J2SE em Ambiente Windows 1 - Configuração do J2SDKSE (Java 2 SDK Standard Edition) Deve-se obter o arquivo j2sdk-1_4_2_03-windows-i586-p.exe ou mais recente

Leia mais

Este livro é dedicado a minha esposa Edna e a todos os desenvolvedores que fizeram do software livre um meio profissional levado a sério.

Este livro é dedicado a minha esposa Edna e a todos os desenvolvedores que fizeram do software livre um meio profissional levado a sério. EDSON GONÇALVES Este livro é dedicado a minha esposa Edna e a todos os desenvolvedores que fizeram do software livre um meio profissional levado a sério. AGRADECIMENTOS Primeiramente gostaria de agradecer

Leia mais

Java Laboratório Aula 1. Divisões da Plataforma. Introdução a Plataforma Java. Visão geral da arquitetura da

Java Laboratório Aula 1. Divisões da Plataforma. Introdução a Plataforma Java. Visão geral da arquitetura da Java Laboratório Aula 1 Programação orientada a objetos Profa. Renata e Cristiane Introdução a Plataforma Java O que é Java? Tecnologia Linguagem de Programação Ambiente de Execução (JVM) Tudo isso é a

Leia mais

Grails: o que isso quer dizer? Gilliard Cordeiro http://gilliard.eti.br

Grails: o que isso quer dizer? Gilliard Cordeiro http://gilliard.eti.br Grails: o que isso quer dizer? Gilliard Cordeiro http://gilliard.eti.br Sobre mim Formado em análise de sistemas pela UFMS Trabalho há 5 anos com desenvolvimento Web Minha principal área de atuação é P&D

Leia mais

Java II. Sérgio Luiz Ruivace Cerqueira sergioruivace@gmail.com

Java II. Sérgio Luiz Ruivace Cerqueira sergioruivace@gmail.com Java II Sérgio Luiz Ruivace Cerqueira sergioruivace@gmail.com Java Web Arquitetura Aplicações web são basicamente constituídas de: Requisições Respostas Model View Controller (MVC) O que é MVC? Padrão

Leia mais

Introdução. à Linguagem JAVA. Prof. Dr. Jesus, Edison O. Instituto de Matemática e Computação. Laboratório de Visão Computacional

Introdução. à Linguagem JAVA. Prof. Dr. Jesus, Edison O. Instituto de Matemática e Computação. Laboratório de Visão Computacional Introdução à Linguagem JAVA Prof. Dr. Jesus, Edison O. Instituto de Matemática e Computação Laboratório de Visão Computacional Vantagens do Java Independência de plataforma; Sintaxe semelhante às linguagens

Leia mais

TDC2012. EJB simples e descomplicado, na prática. Slide 1

TDC2012. EJB simples e descomplicado, na prática. Slide 1 TDC2012 EJB simples e descomplicado, na prática Slide 1 Palestrantes Kleber Xavier Arquiteto Senior / Globalcode kleber@globalcode.com.br Vinicius Senger Arquiteto Senior / Globalcode vinicius@globalcode.com.br

Leia mais

Fatos e Mitos do Java EE. Fernando Lozano Consultor 4Linux lozano@4linux.com.br

Fatos e Mitos do Java EE. Fernando Lozano Consultor 4Linux lozano@4linux.com.br Fatos e Mitos do Java EE Fernando Lozano Consultor 4Linux lozano@4linux.com.br O Que É o Java EE? É um padrão de bibliotecas e componentes (APIs) para a criação de aplicações corporativas Também é um padrão

Leia mais

Conhecendo o Visual FoxPro 8.0 Parte 3

Conhecendo o Visual FoxPro 8.0 Parte 3 AULA Conhecendo o Visual FoxPro 8.0 Parte 3 Continuando nossa saga pelas ferramentas do Visual FoxPro 8.0, hoje vamos conhecer mais algumas. A Ferramenta Class Designer A Class Designer é a ferramenta

Leia mais

Lógica de Programação

Lógica de Programação Lógica de Programação Unidade 4 Ambiente de desenvolvimento Java QI ESCOLAS E FACULDADES Curso Técnico em Informática SUMÁRIO A LINGUAGEM JAVA... 3 JVM, JRE, JDK... 3 BYTECODE... 3 PREPARANDO O AMBIENTE

Leia mais

CA Nimsoft Monitor Snap

CA Nimsoft Monitor Snap CA Nimsoft Monitor Snap Guia de Configuração do Monitoramento do Jboss do Nimsoft jboss série 1.3 Aviso de copyright do CA Nimsoft Monitor Snap Este sistema de ajuda online (o Sistema ) destina-se somente

Leia mais

Manual de Instalação PIMSConnector em Windows

Manual de Instalação PIMSConnector em Windows Manual de Instalação PIMSConnector em Windows Julho/2015 Sumário 1. Contexto de negócio (Introdução)... 3 2. Pré-requisitos instalação/implantação/utilização... 4 3. JBOSS... 6 3.1. Instalação... 6 3.2.

Leia mais

Microsoft Visual Studio Express 2012 for Windows Desktop

Microsoft Visual Studio Express 2012 for Windows Desktop Microsoft Visual Studio Express 2012 for Windows Desktop Apresentação da ferramenta Professor: Danilo Giacobo Página pessoal: www.danilogiacobo.eti.br E-mail: danilogiacobo@gmail.com 1 Introdução Visual

Leia mais

Definições. Parte 02. Java Conceitos e. Desenvolvimento de Programação Orientada a Objetos. Prof. Pedro Neto

Definições. Parte 02. Java Conceitos e. Desenvolvimento de Programação Orientada a Objetos. Prof. Pedro Neto Java Conceitos e Definições Parte 02 Prof. Pedro Neto Aracaju Sergipe - 2011 Conteúdo 2 O que é Java i. Java ii. Máquina Virtual iii. Java lento? Hotspot e JIT iv. Versões do Java e a confusão do Java2

Leia mais

Fundamentos de Java. Prof. Marcelo Cohen. 1. Histórico

Fundamentos de Java. Prof. Marcelo Cohen. 1. Histórico Fundamentos de Java Prof. Marcelo Cohen 1. Histórico 1990 linguagem Oak; desenvolvimento de software embutido para eletrodomésticos S.O. para o controle de uma rede de eletrodomésticos o surgimento da

Leia mais

Receita de bolo para instalar MinGW-GCC e Netbeans em Windows

Receita de bolo para instalar MinGW-GCC e Netbeans em Windows Receita de bolo para instalar MinGW-GCC e Netbeans em Windows Hae Yong Kim 13/08/2014 Este documento explica como fiz para instalar compilador MinGW-GCC e ambiente de desenvolvimento Netbeans em Windows.

Leia mais

Instalando o IIS 7 no Windows Server 2008

Instalando o IIS 7 no Windows Server 2008 Goiânia, 16/09/2013 Aluno: Rafael Vitor Prof. Kelly Instalando o IIS 7 no Windows Server 2008 Objetivo Esse tutorial tem como objetivo demonstrar como instalar e configurar o IIS 7.0 no Windows Server

Leia mais

Instalando o IIS 7 no Windows Server 2008

Instalando o IIS 7 no Windows Server 2008 Goiânia, 16/09/2013 Aluno: Rafael Vitor Prof. Kelly Instalando o IIS 7 no Windows Server 2008 Objetivo Esse tutorial tem como objetivo demonstrar como instalar e configurar o IIS 7.0 no Windows Server

Leia mais

UFG - Instituto de Informática

UFG - Instituto de Informática UFG - Instituto de Informática Especialização em Desenvolvimento de Aplicações Web com Interfaces Ricas EJB 3.0 Prof.: Fabrízzio A A M N Soares professor.fabrizzio@gmail.com Aula 5 Servidores de Aplicação

Leia mais

Dominando Action Script 3

Dominando Action Script 3 Dominando Action Script 3 Segunda Edição (2014) Daniel Schmitz Esse livro está à venda em http://leanpub.com/dominandoactionscript3 Essa versão foi publicada em 2014-05-02 This is a Leanpub book. Leanpub

Leia mais

Spring: Um suite de novas opções para Java EE

Spring: Um suite de novas opções para Java EE Spring: Um suite de novas opções para Java EE Alberto J Lemos (Dr. Spock) Instrutor Globalcode Ricardo Jun Taniguchi Instrutor Globalcode 1 Agenda > Sobre o Spring Framework > Escopo de integração com

Leia mais

INTRODUÇÃO AO DESENVOLVIMENTO DE JOGOS COM LIBGDX. Vinícius Barreto de Sousa Neto

INTRODUÇÃO AO DESENVOLVIMENTO DE JOGOS COM LIBGDX. Vinícius Barreto de Sousa Neto INTRODUÇÃO AO DESENVOLVIMENTO DE JOGOS COM LIBGDX Vinícius Barreto de Sousa Neto Libgdx é um framework multi plataforma de visualização e desenvolvimento de jogos. Atualmente ele suporta Windows, Linux,

Leia mais

Tutorial de instalação do Java 7 no Windows 7.

Tutorial de instalação do Java 7 no Windows 7. Tutorial de instalação do Java 7 no Windows 7. Neste tutorial vamos instalar um ambiente de desenvolvimento Java JDK 7 no Windows 7. Quando falamos em ambiente Java, estamos nos referindo ao conjunto de

Leia mais

Prática em Laboratório N.02 Criando um serviço Web via NetBeans

Prática em Laboratório N.02 Criando um serviço Web via NetBeans Prática em Laboratório N.02 Criando um serviço Web via NetBeans O objetivo deste exercício é criar um projeto apropriado para desenvolver um contêiner que você resolva utilizar. Uma vez criado o projeto,

Leia mais

Frameworks - Grails. Aécio Costa

Frameworks - Grails. Aécio Costa Aécio Costa Abstração que une códigos comuns entre vários projetos de software provendo uma funcionalidade genérica. Framework é um conjunto de classes que colaboram para realizar uma responsabilidade

Leia mais

BlackBerry Messenger SDK

BlackBerry Messenger SDK BlackBerry Messenger SDK Versão: 1.2 Getting Started Guide Publicado: 2011-10-11 SWD-1391821-1011103456-012 Conteúdo 1 Requisitos do sistema... 2 2 Dependências de versão do BlackBerry Messenger... 3 3

Leia mais

EJB ainda tem vez no Java EE 6? Fernando Lozano Consultor 4Linux lozano@4linux.com.br

EJB ainda tem vez no Java EE 6? Fernando Lozano Consultor 4Linux lozano@4linux.com.br EJB ainda tem vez no Java EE 6? Fernando Lozano Consultor 4Linux lozano@4linux.com.br Você Gosta do EJB? O EJB esteve por muito tempo na berlinda do mundo Java É pesado... É complicado... Código muito

Leia mais

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE ALAGOAS CURSO TECNICO EM INFORMATICA DISCIPLINA:

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE ALAGOAS CURSO TECNICO EM INFORMATICA DISCIPLINA: INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DE ALAGOAS CURSO TECNICO EM INFORMATICA DISCIPLINA: PROGRAMAÇÃO ORIENTADA A OBJETOS PROFESSOR: REINALDO GOMES ASSUNTO: REVISÃO DA INTRODUÇÃO A ORIENTAÇÃO

Leia mais

NOVIDADES DO JAVA PARA PROGRAMADORES C

NOVIDADES DO JAVA PARA PROGRAMADORES C PROGRAMAÇÃO SERVIDOR EM SISTEMAS WEB NOVIDADES DO JAVA PARA PROGRAMADORES C Prof. Dr. Daniel Caetano 2012-1 Objetivos Apresentar o Conceito de Classes e Objetos Capacitar para a criação de objetos simples

Leia mais

Java Como Programar, 8/E

Java Como Programar, 8/E Capítulo 2 Introdução aos aplicativos Java Java Como Programar, 8/E (C) 2010 Pearson Education, Inc. Todos os 2.1 Introdução Programação de aplicativo Java. Utilize as ferramentas do JDK para compilar

Leia mais

UFG - Instituto de Informática

UFG - Instituto de Informática UFG - Instituto de Informática Especialização em Desenvolvimento de Aplicações Web com Interfaces Ricas EJB 3.0 Prof.: Fabrízzio A A M N Soares professor.fabrizzio@gmail.com Aula 10 Persistência de Dados

Leia mais

Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva

Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva 1. O que são Serviços Web (Web Services)? Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva A ideia central dos Web Services parte da antiga necessidade

Leia mais

DESENVOLVIMENTO COM JAVA EE E SUAS ESPECIFICAÇÕES

DESENVOLVIMENTO COM JAVA EE E SUAS ESPECIFICAÇÕES DESENVOLVIMENTO COM JAVA EE E SUAS ESPECIFICAÇÕES Hugo Henrique Rodrigues Correa¹, Jaime Willian Dias 1 Universidade Paranaense (Unipar) Paranavaí PR Brasil hugohrcorrea@gmail.com, jaime@unipar.br Resumo.

Leia mais

1 REQUISITOS BÁSICOS PARA INSTALAR O SMS PC REMOTO

1 REQUISITOS BÁSICOS PARA INSTALAR O SMS PC REMOTO 1 ÍNDICE 1 REQUISITOS BÁSICOS PARA INSTALAR O SMS PC REMOTO... 3 1.1 REQUISITOS BASICOS DE SOFTWARE... 3 1.2 REQUISITOS BASICOS DE HARDWARE... 3 2 EXECUTANDO O INSTALADOR... 3 2.1 PASSO 01... 3 2.2 PASSO

Leia mais

Arquivos de Instalação... 4. Instalação JDK... 7. Instalação Apache Tomcat... 8. Configurando Tomcat... 9

Arquivos de Instalação... 4. Instalação JDK... 7. Instalação Apache Tomcat... 8. Configurando Tomcat... 9 Instalando e Atualizando a Solução... 3 Arquivos de Instalação... 4 Instalação do Servidor de Aplicação... 7 Instalação JDK... 7 Instalação Apache Tomcat... 8 Configurando Tomcat... 9 Configurando Banco

Leia mais

Relatório do GPES. Descrição dos Programas e Plugins Utilizados. Programas Utilizados:

Relatório do GPES. Descrição dos Programas e Plugins Utilizados. Programas Utilizados: Relatório do GPES Relatório referente à instalação dos programas e plugins que estarão sendo utilizados durante o desenvolvimento dos exemplos e exercícios, sendo esses demonstrados nos próximos relatórios.

Leia mais

Introdução ao BPEL utilizando o Oracle SOA Suíte 10g

Introdução ao BPEL utilizando o Oracle SOA Suíte 10g Introdução ao BPEL utilizando o Oracle SOA Suíte 10g 1. Introdução Neste artigo serão apresentados alguns conceitos inerentes a SOA Service Oriented Architecture e um exemplo prático de construção de processo

Leia mais

Lidando de Forma Eficiente com Validações Locais de Objetos

Lidando de Forma Eficiente com Validações Locais de Objetos Lidando de Forma Eficiente com Validações Locais de Objetos Aprenda a construir um mini-framework para validar objetos locais sem afetar a complexidade do código. Autor Paulo César M. N. A. Coutinho (pcmnac@gmail.com):

Leia mais

Instalando o J2SE 5.0 JDK no Windows 2000/XP

Instalando o J2SE 5.0 JDK no Windows 2000/XP Instalando o J2SE 5.0 JDK no Windows 2000/XP Fabricio Leonard Leopoldino Descreve o processo de download, instalação e configuração do J2SE 5.0 JDK, no Windows 2000 e no Windows XP. 1 - Introdução Para

Leia mais

Programação Orientada a Objetos Prof. Rone Ilídio UFSJ/CAP

Programação Orientada a Objetos Prof. Rone Ilídio UFSJ/CAP Programação Orientada a Objetos Prof. Rone Ilídio UFSJ/CAP 1) Introdução Programação Orientada a Objetos é um paradigma de programação bastante antigo. Entretanto somente nos últimos anos foi aceito realmente

Leia mais

Manual de Instalação PIMSConnector em Linux

Manual de Instalação PIMSConnector em Linux Manual de Instalação PIMSConnector em Linux Julho/2015 Sumário 1. Contexto de negócio (Introdução)... 3 2. Pré-requisitos instalação/implantação/utilização... 4 3. JBOSS... 6 3.1. Instalação... 6 3.2.

Leia mais

Google Web Toolkit* Clério Damasceno Soares, Daniel da Silva Filgueiras e Fábio Figueiredo da Silva

Google Web Toolkit* Clério Damasceno Soares, Daniel da Silva Filgueiras e Fábio Figueiredo da Silva Google Web Toolkit* Clério Damasceno Soares, Daniel da Silva Filgueiras e Fábio Figueiredo da Silva Universidade Federal de Juiz de Fora UFJF-MG Campo Universitário Bairro Marmelos Juiz de Fora MG Brasil

Leia mais

Prova Específica Cargo Desenvolvimento

Prova Específica Cargo Desenvolvimento UNIVERSIDADE FEDERAL DO PIAUÍ Centro de Educação Aberta e a Distância CEAD/UFPI Rua Olavo Bilac 1148 - Centro CEP 64.280-001 Teresina PI Brasil Fones (86) 3215-4101/ 3221-6227 ; Internet: www.uapi.edu.br

Leia mais

Tecnólogo em Análise e Desenvolvimento de Sistemas

Tecnólogo em Análise e Desenvolvimento de Sistemas Tecnólogo em Análise e Desenvolvimento de Sistemas O conteúdo deste documento tem como objetivos geral introduzir conceitos mínimos sobre sistemas operacionais e máquinas virtuais para posteriormente utilizar

Leia mais

Como sobreviver com Java 2? Saulo Arruda

Como sobreviver com Java 2? Saulo Arruda Como sobreviver com Java 2? Saulo Arruda Agenda Apresentação Contexto do mercado Soluções para Java 5+ Soluções para Java 2 Conclusões Apresentação Saulo Arruda (http://sauloarruda.eti.br) Trabalha com

Leia mais

ORDEM DE SERVIÇO OS 003/DINFO/2013 16/09/2013

ORDEM DE SERVIÇO OS 003/DINFO/2013 16/09/2013 A DIRETORIA DE INFORMÁTICA DINFO DA UNIVERSIDADE DO ESTADO DO RIO DE JANEIRO -UERJ, no uso de suas atribuições legais, estabelece: Art. 1º: Para fins de normatização do Desenvolvimento Tecnológico na UERJ

Leia mais

Criando uma agenda simples com NetBeans 6.5

Criando uma agenda simples com NetBeans 6.5 Criando uma agenda simples com NetBeans 6.5 (Swing application framework e Beansbinding) Já faz algum tempo que escrevi uma agenda simples usando o Eclipse com o Visual Class Editor. Demorei em torno de

Leia mais

Tutorial Eclipse (IDE)

Tutorial Eclipse (IDE) www.dejavuxteam.wordpress.com Tutorial Eclipse (IDE) (Start) Sumário Introdução O que é o Eclipse? Característica e Ferramentas Download Preparando Ambiente de Trabalho Iniciando o Eclipse Criando um Projeto

Leia mais

Desenvolvendo Aplicações Web com NetBeans

Desenvolvendo Aplicações Web com NetBeans Desenvolvendo Aplicações Web com NetBeans Aula 3 Cap. 4 Trabalhando com Banco de Dados Prof.: Marcelo Ferreira Ortega Introdução O trabalho com banco de dados utilizando o NetBeans se desenvolveu ao longo

Leia mais

Em uma linguagem de programação como C e Pascal, temos a seguinte situação quando vamos compor um programa:

Em uma linguagem de programação como C e Pascal, temos a seguinte situação quando vamos compor um programa: 1 1. Introdução Este manual se propõe a dar uma visão inicial do Java e apresentar os primeiros passos para sua instalação, configuração e usabilidade pelo prompt de comando do Windows. O ideal é que este

Leia mais

Algoritmos em Javascript

Algoritmos em Javascript Algoritmos em Javascript Sumário Algoritmos 1 O que é um programa? 1 Entrada e Saída de Dados 3 Programando 4 O que é necessário para programar 4 em JavaScript? Variáveis 5 Tipos de Variáveis 6 Arrays

Leia mais

CA Nimsoft Unified Reporter

CA Nimsoft Unified Reporter CA Nimsoft Unified Reporter Guia de Instalação 7.5 Histórico de revisões do documento Versão do documento Data Alterações 1.0 Março de 2014 Versão inicial do UR 7.5. Avisos legais Este sistema de ajuda

Leia mais

Web-Services com JAX-WS. Capítulo. Introdução aos Web-Services via JAX-WS. - Um breve histórico sobre Web-Services. - SOAP x REST. Provendo um Serviço

Web-Services com JAX-WS. Capítulo. Introdução aos Web-Services via JAX-WS. - Um breve histórico sobre Web-Services. - SOAP x REST. Provendo um Serviço A1Provendo e Consumindo Web-Services com JAX-WS Capítulo 22 Introdução aos Web-Services via JAX-WS - Um breve histórico sobre Web-Services Os Web-Services são uma tecnologia popular para apoiar iniciativas

Leia mais

Seu manual do usuário XEROX 6279 http://pt.yourpdfguides.com/dref/5579951

Seu manual do usuário XEROX 6279 http://pt.yourpdfguides.com/dref/5579951 Você pode ler as recomendações contidas no guia do usuário, no guia de técnico ou no guia de instalação para XEROX 6279. Você vai encontrar as respostas a todas suas perguntas sobre a XEROX 6279 no manual

Leia mais

Orientação a Objetos com Java

Orientação a Objetos com Java Orientação a Objetos com Java Julio Cesar Nardi julionardi@yahoo.com.br 2011/2 Aula 01: Começando com Java Objetivos: Compreender o que é Java, OO e suas vantagens; Entender os procedimentos para criação

Leia mais

Java & OpenJDK. Thiago S. Gonzaga. Sun Campus Ambassador thiago.gonzaga@sun.com

Java & OpenJDK. Thiago S. Gonzaga. Sun Campus Ambassador thiago.gonzaga@sun.com Java & OpenJDK Thiago S. Gonzaga Sun Campus Ambassador thiago.gonzaga@sun.com Tópicos Sobre a Sun Microsystems Algumas tecnologias da Sun Linguagem de Programação Ciclo de Desenvolvimento O que é Java?

Leia mais

ARQUITETURA DO SISTEMA ERP PEGASUS

ARQUITETURA DO SISTEMA ERP PEGASUS ARQUITETURA DO SISTEMA ERP PEGASUS Elaborado por: Bruno Duarte Nogueira Arquiteto de Software Data: 05/03/2012 1 Sumário 1. Introdução... 3 2. Tecnologias... 3 2.1. Web Tier... 3 2.1.1. Facelets 1.1.14...

Leia mais

Dicas para usar melhor o Word 2007

Dicas para usar melhor o Word 2007 Dicas para usar melhor o Word 2007 Quem está acostumado (ou não) a trabalhar com o Word, não costuma ter todo o tempo do mundo disponível para descobrir as funcionalidades de versões recentemente lançadas.

Leia mais

Manual de Instalação do Agente Citsmart

Manual de Instalação do Agente Citsmart 16/08/2013 Manual de Instalação do Agente Citsmart Fornece orientações necessárias para efetuar a instalação do Agente Citsmart. Versão 1.9 21/11/2014 Visão Resumida Data Criação 21/11/2014 Versão Documento

Leia mais

Curso de Extensão Programação Orientada a Objetos com Java. Última atualização: 25/05/2010

Curso de Extensão Programação Orientada a Objetos com Java. Última atualização: 25/05/2010 Curso de Extensão Programação Orientada a Objetos com Java Última atualização: 25/05/2010 1 Objetivos do Curso Este curso fornece a você conhecimento e habilidades para: Programar e executar aplicações

Leia mais

DESENVOLVIMENTO DE APLICATIVOS PARA CELULAR JAVA 2 MICRO EDITION

DESENVOLVIMENTO DE APLICATIVOS PARA CELULAR JAVA 2 MICRO EDITION DESENVOLVIMENTO DE APLICATIVOS PARA CELULAR JAVA 2 MICRO EDITION Robison Cris Brito Centro Federal de Educação Tecnológica do Paraná Unidade de Pato Branco robison@pb.cefetpr.br RESUMO Engana-se quem acha

Leia mais

marcio@dsc.ufcg.edu.br priscillakmv@gmail.com

marcio@dsc.ufcg.edu.br priscillakmv@gmail.com DSC/CEEI/UFCG marcio@dsc.ufcg.edu.br priscillakmv@gmail.com 1 Realiza atividades com ênfase em Ensino, Pesquisa e Extensão (Ensino) 2 Configurando o projeto Adicionando código ao arquivo com o código-fonte

Leia mais

Java EE 6. A revolução do. Um overview sobre as novidades da JSR 316. a r t i g o

Java EE 6. A revolução do. Um overview sobre as novidades da JSR 316. a r t i g o a r t i g o Pedro Henrique S. Mariano (pedro.mariano@caelum.com.br) técnologo em Análise e Desenvolvimento de Sofware pela FIAP, possui as certificações SCJP 6 e SCRUM master.trabalha como consultor e

Leia mais

Moodle FTEC Versão 2.0 Manual do Usuário Acesse a área de LOGIN do site da FTEC www.ftec.com.br

Moodle FTEC Versão 2.0 Manual do Usuário Acesse a área de LOGIN do site da FTEC www.ftec.com.br Moodle FTEC Versão 2.0 Manual do Usuário Acesse a área de LOGIN do site da FTEC www.ftec.com.br Índice Como acessar o Moodle Editando seu PERFIL Editando o curso / disciplina no Moodle Incluindo Recursos

Leia mais

GEPLANES GESTÃO DE PLANEJAMENTO ESTRATÉGICO MANUAL DE INSTALAÇÃO DO GEPLANES EM UM AMBIENTE WINDOWS

GEPLANES GESTÃO DE PLANEJAMENTO ESTRATÉGICO MANUAL DE INSTALAÇÃO DO GEPLANES EM UM AMBIENTE WINDOWS GEPLANES GESTÃO DE PLANEJAMENTO ESTRATÉGICO MANUAL DE INSTALAÇÃO DO GEPLANES EM UM AMBIENTE WINDOWS JANEIRO 2015 1 Sumário 1. Introdução...3 2. Pré-Requisitos...4 2.1. Instalação do Java Development Kit

Leia mais

SCC-0263. Técnicas de Programação para WEB. Rodrigo Fernandes de Mello http://www.icmc.usp.br/~mello mello@icmc.usp.br

SCC-0263. Técnicas de Programação para WEB. Rodrigo Fernandes de Mello http://www.icmc.usp.br/~mello mello@icmc.usp.br SCC-0263 Técnicas de Programação para WEB Rodrigo Fernandes de Mello http://www.icmc.usp.br/~mello mello@icmc.usp.br 1 Cronograma Fundamentos sobre servidores e clientes Linguagens Server e Client side

Leia mais

Evolução do Design através de Testes e o TDD

Evolução do Design através de Testes e o TDD c a p a Lucas Souza (lucas.souza@caelum.com.br): é bacharel em Engenharia da Computação pela Universidade de Ribeirão Preto, possui a certificação SCJP e trabalha com Java há 4 anos. Atualmente é desenvolvedor

Leia mais

Guia de Instalação e Inicialização. Para WebReporter 2012

Guia de Instalação e Inicialização. Para WebReporter 2012 Para WebReporter 2012 Última revisão: 09/13/2012 Índice Instalando componentes de pré-requisito... 1 Visão geral... 1 Etapa 1: Ative os Serviços de Informações da Internet... 1 Etapa 2: Execute o Setup.exe

Leia mais

Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans.

Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans. 1 - Criando uma classe em Java Para desenvolver a atividade a atividade desta aula utilizaremos o ambiente de desenvolvimento integrado NetBeans. Antes de criarmos a(s) classe(s) é necessário criar o projeto

Leia mais

CURSO DESENVOLVEDOR JAVA Edição 2009

CURSO DESENVOLVEDOR JAVA Edição 2009 CURSO DESENVOLVEDOR JAVA Edição 2009 O curso foi especialmente planejado para os profissionais que desejam trabalhar com desenvolvimento de sistemas seguindo o paradigma Orientado a Objetos e com o uso

Leia mais

Documento de Instalação e Configuração do InfoGrid

Documento de Instalação e Configuração do InfoGrid Documento de Instalação e Configuração do InfoGrid Tecgraf/PUC Rio infogrid@tecgraf.puc rio.br 1.Introdução O objetivo deste documento é podermos registrar em um único local todas as informações necessárias

Leia mais

1. Instalando o Java 7 JavaFX e o Netbeans

1. Instalando o Java 7 JavaFX e o Netbeans 1. Instalando o Java 7 JavaFX e o Netbeans Faça o download do Java 7 que inclui JavaFX no site do Oracle: http://www.oracle.com/technetwork/java/javase /downloads/index.html. Clique no License Agreement

Leia mais

Desenvolvimento Web com Framework Demoiselle versão 1.0

Desenvolvimento Web com Framework Demoiselle versão 1.0 Desenvolvimento Web com Framework Demoiselle versão 1.0 Módulo 07: Outros Componentes Autor: Rodrigo Hjort Serpro / Coordenação Estratégica de Tecnologia / Curitiba www.frameworkdemoiselle.org.br Modificado

Leia mais

UNIDADE IV ENTERPRISE JAVABEANS

UNIDADE IV ENTERPRISE JAVABEANS UNIDADE IV ENTERPRISE JAVABEANS MODELO J2EE COMPONENTES DE Camada de Negócios NEGÓCIOS JAVA SERVLET, JSP E EJB Nos capítulos anteriores, foi mostrado como desenvolver e distribuir aplicações servlet e

Leia mais

CURSO DESENVOLVEDOR JAVA WEB E FLEX Setembro de 2010 à Janeiro de 2011

CURSO DESENVOLVEDOR JAVA WEB E FLEX Setembro de 2010 à Janeiro de 2011 CURSO DESENVOLVEDOR JAVA WEB E FLEX Setembro de 2010 à Janeiro de 2011 O curso foi especialmente planejado para os profissionais que desejam trabalhar com desenvolvimento de sistemas seguindo o paradigma

Leia mais

Laboratório I Aula 2

Laboratório I Aula 2 Laboratório I Aula 2 Prof. Msc. Anderson da Cruz Fases da Programação Implementação de Linguagens de Programação Compilação geração de código executável dependente da plataforma de execução tradução lenta

Leia mais

Linguagens de. Aula 02. Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br

Linguagens de. Aula 02. Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br Linguagens de Programação III Aula 02 Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br Linguagens de Programação Técnica de comunicação padronizada para enviar instruções a um computador. Assim

Leia mais

Desenvolvendo aplicações desktop em Java: presente e futuro

Desenvolvendo aplicações desktop em Java: presente e futuro Desenvolvendo aplicações desktop em Java: presente e futuro Michael Nascimento Santos Conexão Java 2006 Michael Nascimento Santos 7 anos de experiência com Java Expert nas JSRs 207, 250, 270 (Java 6),

Leia mais

4.0 SP2 (4.0.2.0) maio 2015 708P90911. Xerox FreeFlow Core Guia de Instalação: Windows 8.1 Update

4.0 SP2 (4.0.2.0) maio 2015 708P90911. Xerox FreeFlow Core Guia de Instalação: Windows 8.1 Update 4.0 SP2 (4.0.2.0) maio 2015 708P90911 2015 Xerox Corporation. Todos os direitos reservados. Xerox, Xerox com a marca figurativa e FreeFlow são marcas da Xerox Corporation nos Estados Unidos e/ou em outros

Leia mais

Objetivos: Sun recomenda que utilize o nome de domínio da Internet da empresa, para garantir um nome de pacote único

Objetivos: Sun recomenda que utilize o nome de domínio da Internet da empresa, para garantir um nome de pacote único Pacotes e Encapsulamento Prof. Bruno Gomes bruno.gomes@ifrn.edu.br Programação Orientada a Objetos Introdução Permite o agrupamento de classes em uma coleção chamada pacote Um pacote é uma coleção de classes

Leia mais

Introdução à Linguagem Java

Introdução à Linguagem Java Introdução à Linguagem Java Histórico: Início da década de 90. Pequeno grupo de projetos da Sun Microsystems, denominado Green. Criar uma nova geração de computadores portáveis, capazes de se comunicar

Leia mais

Instalação do IBM SPSS Modeler Server Adapter

Instalação do IBM SPSS Modeler Server Adapter Instalação do IBM SPSS Modeler Server Adapter Índice Instalação do IBM SPSS Modeler Server Adapter............... 1 Sobre a Instalação do IBM SPSS Modeler Server Adapter................ 1 Requisitos de

Leia mais

Linguagem de Programação JAVA

Linguagem de Programação JAVA Linguagem de Programação JAVA Curso Técnico em Informática Modalida Integrado Instituto Federal do Sul de Minas, Câmpus Pouso Alegre Professora: Michelle Nery Agenda JAVA Histórico Aplicações Pós e Contras

Leia mais

FACULDADE DE TECNOLOGIA SENAC GOIÁS CONTROLE DE ACESSO USANDO O FRAMEWORK RICHFACES. 5º PERÍODO Gestão da Tecnologia da Informação

FACULDADE DE TECNOLOGIA SENAC GOIÁS CONTROLE DE ACESSO USANDO O FRAMEWORK RICHFACES. 5º PERÍODO Gestão da Tecnologia da Informação FACULDADE DE TECNOLOGIA SENAC GOIÁS CONTROLE DE ACESSO USANDO O FRAMEWORK RICHFACES 5º PERÍODO Gestão da Tecnologia da Informação Alunos: Alessandro Aparecido André Alexandre Bruno Santiago Thiago Castilho

Leia mais

Manual de Atualização de Versão

Manual de Atualização de Versão Este documento fornece as orientações necessárias para efetuar a atualização da versão da Plataforma Citsmart. Versão 2.0 05/03/2014 Visão Resumida Data Criação 05/03/2014 Versão Documento 2.0 Projeto

Leia mais

2. O AMBIENTE DE PROGRAMAÇÃO EM C

2. O AMBIENTE DE PROGRAMAÇÃO EM C 2. O AMBIENTE DE PROGRAMAÇÃO EM C Este capítulo trata de colocar a linguagem C para funcionar em um ambiente de programação, concentrando-se no compilador GNU Compiler Collection (gcc). Mas qualquer outro

Leia mais