Novo Treinamento FJ-16: Laboratório Java com Swing, XML e Testes

Por Sérgio Lopes em 14/08/08

FJ-16 Laboratório SwingDepois de aprender bem o Java, uma pergunta comum de alunos e de usuários do GUJ é: como adquirir experiência e boas práticas? Com esse intuito criamos um novo treinamento, onde desenvolvemos uma aplicação desktop com Swing, que faz análise técnica da bolsa de valores, através de gráficos, usando como fonte uma base XML. É o FJ-16: Laboratório Java com Swing, XML e Testes.

FJ16

O mais interessante é que, durante o desenvolvimento da aplicação, aprendemos a aplicar diversos design patterns (como o Decorator entre indicadores), utilizamos testes unitários com JUnit, conhecemos as ferramentas Ant e Maven, aplicamos reflection e anotações, além de sempre estar refatorando o código inúmeras vezes.

Nesse treinamento, são colocados em prática também diversos conceitos da linguagem que usamos no dia-a-dia, como manipulação de datas, de XML, classes anônimas, classes internas, uso do log4J, entre outros.

Veja a ementa completa na página do treinamento. Temos turmas agendadas para final de agosto e começo de setembro. Entre em contato conosco para mais informações.

Novidades do EJB 3.1 do futuro Java EE 6

Por Nico Steppat em 24/03/08

A especificação EJB 3.0 já está no mercado há quase 2 anos e simplificou bastante o desenvolvimento. O uso de anotações (XML opcional) e POJOs/POJIs são as características principais. EJB 3.0 faz parte da Java EE 5.

Ainda esse ano deve sair o Java EE 6 e, com ele, também uma atualização da especificação do EJB. Vamos ver quais são as novidades/melhorias propostas atualmente no rascunho do EJB 3.1:


Facilidades no desenvolvimento

1) Interfaces locais são opcionais.

Um session bean local pode ficar simples assim:


@Stateless
public class PedidoDAO {

  public void cadastra(Pedido pedido) {
    //código para cadastrar um pedido
  }
}

Não precisa mais da interface e da anotação @Local.

2) EJB’s dentro do war

Será possivel colocar um EJB3 num war, facilitando o packaging. Não é preciso criar um jar e ear separado, tudo pode ser dentro de um unico war. As classes ficam na pasta WEB-INF/classes, e se for usado um ejb-jar.xml, se encontra na pasta WEB-INF.


Novidades

1) Singleton Beans

A ideia é que você pode criar session beans que só existem uma única vez na sua aplicação. Assim é possível criar objetos como o ServletContext na aplicação web. Por exemplo:


@Singleton @ReadOnly
public class ApplicationContextBean implements ApplicationContext {

  @PostConstruct
  public void init() {
    //initializa o contexto da aplicação
  }

  //métodos, por exemplo getAttribute(String chave)
}

Repare a anotação @ReadOnly, declarando o EJB imutável. Também vai existir uma anotação @ReadWrite para singletons beans que podem ser alterados.

O método init() será executado quando o container inicializa a aplicação. Singleton components também serão EJBs e podem ser injetados, o que é uma grande vantagem em relação a ter de ficar preso ao método estático de lookup de um singleton, e uma boa prática de inversão de controle.

2) EJB Timer

Terá uma nova anotação @Schedule referente ao EJB timer para facilitar o agendamento. Por exemplo:



@Schedule(hour=”13”, dayOfMonth=”1”)
public void geraRelatorio() {/* …. */}

executa cada primeiro dia no mes as 13 horas. É um modelo bem superior aos atuais timers do EJB, porém ainda não tão completo quanto aos frameworks open source existentes, como o Quartz.

3) Chamadas assíncronas

Parecidos com Web Services, métodos num session beans também podem ser chamados assincronamente. Para isto serve a anotação @Asynchronous:


@Stateless @Remote(PedidoFacade.class)
public class PedidoFacadeBean implements PedidoFacade{

  @Asynchronous
  public void cadastra(Pedido pedido) {
    //código para cadastrar um pedido
  }

  @Asynchronous
  public Future autoriza(Pedido pedido) {
    //autoriza demora …..
  }
}

O segundo método devolve um object do tipo java.util.concurrent.Future que fornece métodos para verificar se o resultado já chegou.

O lançamento da versão 3.1, que teoricamente ocorrerá até o fim deste ano, deve acelerar ainda mais a adoção da plataforma Java EE 5/6 em relação ao uso das versões antigas J2EE.

Os 7 hábitos dos desenvolvedores de WebServices altamente eficazes

Por Paulo Silveira em 18/02/08

Esta semana tive o prazer de palestrar no Café Com Tapioca, evento do CeJUG realizado em Fortaleza. Estavam presentes dois conhecidos evangelistas da Sun: Reggie Hutcherson e Simon Ritter.


DSC01766 DSC01773
DSC01770 DSC01763

O agradecimento fica ao Rafael Carneiro, do PortalJava e do CeJUG, pela organização geral do evento. Agradeço também à equipe do grupo Fortes pela minha vinda ao Ceará: ao Clavius Tales, Igo Coelho, Antônio Israel, Ronaldo Moreira, Tiago Moraes, Rodrigo Maia e tantos outros. Vale reparar como a comunidade java cearense é ativa nos blogs! Nesse sábado também ministrei umworkshop sobre Arquitetura e Design Java aqui em Fortaleza.

Durante esses dias aqui, muitas pessoas perguntaram bastante sobre webservices: em especial JSON e Rest. Compilei alguns dos pontos que foram recorrentes nas discussões e considerados como boas práticas:

Cuidado com a granularidade - a granularidade do seu serviço não pode ser muito fina, caso contrário seus seviços sofrerão dos mesmos problemas que o EntityBean do EJB2 exposto remotamente: uma enorme quantidade de requisições serão disparadas para executar pequenas tarefas, como getters! Seus serviços devem realizar uma quantidade significativa de tarefas, para evitar um número alto de roundtrips!

Exponha serviços, não dados - é comum ouvir a frase “Vou criar webservices para expor os meus dados“. O grande perigo aqui é deixar toda a lógica de negócio na mão do cliente, o que descentralizará seu serviço e forçará o cliente a realizar muitas requisições ao servidor. Devemos expor serviços, e não dados em sua forma mais crua.

Nunca parsear WSDL/SOAP manualmente - antes das ferramentas que trabalham com webservices terem atingido sua maturidade, era muito comum ver por aí as pessoas gerando o SOAP manualmente, através de bibliotecas XML ou às vezes até mesmo concatenando String com o uso de StringBuffer! O SOAP é o protocolo de comunicação, e assim como quando você usa RMI/CORBA e você não enxerga absolutamente nada do JRMP/IIOP, você nunca deveria ter contato direto com o protocolo de comunicação! O SOAP e o WSDL devem ser utilizados por ferramentas, e não pela sua própria aplicação. Hoje em dia qualquer ferramenta como o Apache Axis, Apache CXF, ou mesmo o wsimport, que já vem no JDK 6, auxilia nossa tarefa de gerar Stubs que sabem trabalhar com o SOAP, sem que você nem mesmo precise ve-lo um dia. Se você está usando um servidor de aplicação, esta tarefa é ainda mais fácil, até mesmo para fazer o deploy do serviço.

Não enviar XML dentro de XML - outra prática comumente encontrada em aplicações antigas que usam Webservices: dentro do SOAP é enviado um outro XML como um dos parâmetros, então mesmo usando ferramentas para gerar os stubs você fica com uma String que dentro dela há um XML e este precisa ser parseado por sua própria aplicação. Isto é uma má interpretação do conceito que “Webservices é comunicação via XML“. Concordo que em alguns raros casos isso possa fazer sentido, como por exemplo se o valor do que você quer realmente é um outro XML, mas no geral isto é feito sem necessidade nenhuma, como é o famoso caso do WebService MS Office dos Correios do Brasil.

Considerar protocolo binário - são muitas as reclamações de que o SOAP acaba sendo um XML grande e pesado para ser transportado. Hoje em dia há muitas formas de contornar isso, como o uso do padrão Fast InfoSet para compressão do XML. Uma outra forma seria o uso de protocolos proprietários, como o AMF da Adobe, que é uma opção comum no uso do Flex.

Considerar não usar WSDL/SOAP - pelas diversas críticas a burocracia exagerada do WSDL/SOAP, muitas pessoas estão optando por usar algo mais simples, como o bom e velho XML (POX), JSON ou até mesmo uma forma qualquer de estruturar dados. Caso você precise de simplicidade e velocidade no desenvolvimento com outras plataformas, essa é uma boa opção. Cuidado: muita gente está considerando qualquer webservice que não use WSDL/SOAP como sendo REST. Os webservices do flickr e da Amazon são um bom exemplo: tudo é via GET (as vezes POST) e não há recurso identificado pela URI. Na verdade ele usa apenas um esquema HTTP+XML (POX), considerado apenas em parte como RESTful. Você pode ver que esses webservices são muito diferentes do modelo RESTful do Atom Publishing Protocol. Criar um protocolo realmente REST como este não é fácil: porém teremos esse trabalho bastante simplificado com a JAX-RS (JSR 311), e já podemos ver isso através do Glassfish Jersey.

Considerar usar JSON - JSON é um formato que tem ganho muita popularidade. Não é a toa: além de ser um simples para debugar, parsear e gerar, com javascript basta fazer um eval em um resultado JSON que ele já estará pronto para usar. É uma excelente opção para o consumo via AJAX e criação de mashups. JSON tem ganho bastante força na comunidade Flex, tornando-o uma ótima opção como ponte entre Flex e Java. A escolha por JSON abre portas para muitos tipos diferentes de clientes, e em especial o browser, que é nossa plataforma global.

Java 6, as APIs de XML, Webservices e classloaders

Por Paulo Silveira em 17/12/07

A Sun vem há muito tempo fazendo esforços para facilitar a manipulação de XML e de webservices na plataforma. São tantos projetos, subprojetos e especificações que podemos facilmente nos encontrar perdidos no meio de tantas siglas. Elas são:

JAXP (pacote java.xml no geral) - Processamento geral de XML, com os já antigos SAX e DOM, além de transformadores (XLST) e XPath.

JAXB (pacote javax.xml.bind) - Assocaição/mapeamento de classes java para XML.

JAX-WS (pacote javax.xml.ws) - Criação e consumo de webservices. Aliada a especificação de metadados para webservices (pacote javax.jws), previamente já vista aqui no blog, a JAX-WS tornasse poderosa e fácil de usar.

JAXR (pacote javax.xml.registry) - para acesso aos registros de serviços XMLs, como UDDI.

JAX-RPC (pacote javax.xml.rpc) - era o nome antigo do atual JAX-WS. O JAX-WS mudou de nome e já apareceu como 2.0, essa mundaça foi justificada pelo fato dessa API passar a trabalhar bem mais próxima da API do JAXB, além do óbvio marketing.

E a Sun não para por aí, temos mais especificações: a duvidosa JSR 267 que possibilita um JSP acessar diretamente um webservice (!) através de taglibs e a esperada JSR 311 para trabalhar com serviços de maneira RESTful, oferecendo simples anotações para expor métodos Java através de URI + métodos HTTP.

Não são todos subprojetos de manipulação de xml com java que viraram especificações, e as que viraram nem todas estão no Java SE. A Fast Infoset é uma especificação ISO para representação binária do padrão XML (economizando assim espaço e banda, além de melhorar performance do parsing) possui uma implementação Java, utilizada dentro do Metro, projeto que fornece os recursos de webservices do Glassfish.

Muitas dessas APIs, juntamente com implementações de referência (RIs), agora estão presentes no java SE 6.0, que antes eram opcionais. Qual é o problema disso? Até então diversos servidores de aplicação e frameworks traziam embutido implementações do JAXB, JAX-WS, etc. Ao rodar essas aplicações com o Java 6 o sistema de classloading da plataforma vai primeiro carregar as classes da api padrão, mesmo que você tenha implementações dessas APIS de XML no classpath. O ruim aqui é que muitos servidores de aplicação acabam se amarrando a detalhes de sua própria implementação e versão, como é esse caso do JBoss com o JAX-WS. Quando rodado com o Java 6, temos a seguinte exception quando você tenta acessar um webservice que está implantando no servidor:

java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage
at javax.xml.soap.SOAPMessage.setProperty(SOAPMessage.java:424)

Enfrentamos esse problema recentemente, e para resolve-lo usamos o sistema de endosso de jars (endorsed jars) do Java: determinados diretórios podem ser configurados para que alguns pacotes específicos possam ser carregados destes antes do Classloader tentar chegar ao rt.jar.

Um outro problema comum é com o JAXB: o Java 6 vem com a versão 2.0, se você precisar usar a 1.1 ou a 2.1, vai ter problemas. O interessante é que a JAXB do Java SE já foi projetada para ela mesma detectar se o classloading foi correto, ou se partiu de uma versão posterior/anterior a ela, mostrando uma mensagem de erro amigável. Para outras bibliotecas esse problema pode ser muito sutil: o classloader pode acabar carregando parte da biblioteca de uma versão recente, já que algumas classes novas só existem nesse jar, e o restante de uma outra antiga, resultando exceptions como NoSuchMethodError, que não mostram claramente que o problema é a existência de dois jars de versões diferentes no classpath daquela aplicação.

Podemos ver que mesmo seguindos boas práticas, isolando bibliotecas e não usando a terrível variável de ambiente CLASSPATH, acabamos sempre enfrentando o classloader hell.