Java EE 6 para quem está com pressa

Eu sempre achei legal aprender linguagens de programação, novas maneiras de expressar ideias em código. E linguagens são relativamente fáceis de testar: digitar ou copiar um trecho de código e mandar compilar/rodar. Se tiver um REPL (uma linha de comando interativa), é melhor ainda.

Já coisas mais “enterprise” (cof, cof) eu sempre achei um saco. Java, Java EE e a infinita disponibilidade de frameworks para Java eram os grandes culpados. Às vezes realmente eram tecnologias pouco importantes mesmo, que cairiam no esquecimento afogados na própria complexidade, mas outras vezes surgem coisas bem legais mas que ainda assim não são tão acessíveis: de qualquer jeito, só para começar, a pessoa tem que instalar um ambiente com editor, compilador, interpretador/VM, um servidor web, um banco de dados, ferramenta de construção (Ant ou Maven, se não quiser ficar preso ao Eclipse, NetBeans, JDeveloper, etc.), JARs de algumas bibliotecas e frameworks extras, caso não esteja usando o Maven para baixá-los… Faz lembrar este vídeo: Java vs Ruby On Rails (não que eu conheça Rails, mas a parte Java é bem realista). Nem todas essas coisas são obrigatórias, mas a maior parte acaba sendo.

Mas como eu ia dizendo, às vezes tem coisas legais, depois de transpor a barreira inicial. E o Java EE 6 não é mais aquele inferno de XMLs de configuração que fazem qualquer um esquecer o objetivo do programa/tutorial que está construindo/seguindo enquanto configura coisas irrelevantes. Às vezes era fácil até de esquecer o que realmente é o Java EE: Java EE é o mesmo que EJB? JSP também é Java EE? E no que isso tudo me ajuda?

Então, para dar uma visão geral e ter condições de posteriormente ler algo mais aprofundado sem se perder, aqui vai um resumão:

Servlet: classe que responde a requisições HTTP. Declarada com @WebServlet ou no web.xml. Servlets são instanciados uma vez e acessados simultaneamente por todas as requisições (cuidado com variáveis de instância, elas serão compartilhadas por todos os clientes!). A partir de um servlet você pode despachar a requisição para um JSP (que também é um servlet) ou gerar dinamicamente toda resposta, seja HTML ou outra coisa (por exemplo, até mesmo gerando uma imagem para um captcha).

Filter: classe que é executada “ao redor” de uma requisição HTTP (ao redor de um servlet). Declarado com @WebFilter ou no web.xml.

web.xml: arquivo de configuração que fica dentro da pasta WEB-INF, que fica dentro de um arquivo war. Nele você configura servlets, filters e qualquer coisa em geral que construa sobre essa fundação. Tornou-se opcional por causa das novas anotações @WebServlet e @WebFilter, mas ainda tem bastante utilidade (por exemplo, escolher a ordem dos filters)

Os três itens acima são a base (mas não tudo) da parte web do Java EE. Se você já ouviu falar dos frameworks para construir sistemas web em Java, é [quase] certo que esses frameworks são ou contêm alguns servlets e/ou filters que dão um jeitão novo para o desenvolvimento. Esse “jeitão” que eu digo pode ser a troca dos JSPs por outra linguagem de marcação, ou um arquivo de configurações diferente, ou funcionalidades extras pré-empacotadas, etc.

JSP: página HTML com umas tags especiais para integração com o Java. No fim é compilado para um servlet por baixo dos panos. Então, cuidado ao usar variáveis declaradas entre <%! … %>, porque serão compartilhadas por todos os clientes — variáveis entre <% … %> e guardadas nos escopos “page” e “request” não têm esse problema. Algumas das tags especiais são as tags do JSTL. Possui também uma minilinguagem chamada EL (Expression Language) para fazer coisas como ${objeto.propriedade} no meio de uma página ou atributo de tag.

JSF: uma tentativa de fazer que sites se comportem como programas desktop, usando componentes e tentando de certa forma abstrair a existência das requisições HTTP. Não gosto muito, porque complica coisas simples (e complica coisas complicadas também — o ciclo de vida de uma requisição é um saco de entender). As páginas podem ser escritas em JSP ou Facelets (um Facelet é basicamente um XHTML com algumas coisas a mais) e costumam usar a EL na forma #{objeto.propriedade}.

JAX-RS: uma maneira diferente de atender requisições HTTP com algumas facilidades para fazer web services do tipo RESTful (REST significa simplesmente “HTTP do jeito que seu criador tinha realmente imaginado”), retornando JSON, XML ou outros formatos. Declarado com @Path na classe ou método. A configuração global do JAX-RS fica numa classe que herda de Application e é anotada com @ApplicationPath. A URL gerada será a concatenação do @ApplicationPath + @Path da classe + @Path do método (se houver).

JAX-WS: outro jeito de fazer web services, só que com mais XML (formato SOAP). Usa a anotação @WebService, entre outras.

CDI: você declara uma classe com @RequestScoped, ou @SessionScoped, ou @ApplicationScoped, ou o default @Dependent e em [quase] qualquer outro lugar do programa você declara um objeto dessa classe com @Inject em cima. E magicamente você obtém uma instância no escopo correto sem se preocupar como nem quando esse objeto foi criado (na verdade você obtém um objeto proxy que acessa o objeto verdadeiro no escopo correto). O objeto que recebe outros objetos por injeção deve ser instanciado pelo contêinter (servlet, EJB, managed bean do JSF, outro bean CDI, etc.), ou seja, o @Inject não funciona para objetos instanciados com new (a construção de objetos normais do Java não muda). Possui também outros recursos como eventos e interceptors. É necessário ter um arquivo beans.xml (mesmo vazio) no WEB-INF ou META-INF do seu pacote (war, jar) para usar os recursos do CDI no Java EE 6.

EJB: classe anotada com @Stateless, @Stateful ou @Singleton que é capaz de iniciar e terminar (com commit ou rollback) transações automaticamente entre outros recursos. As transações incluem bancos de dados (com JDBC ou JPA), serviço de envio mensagens (JMS) e timers. EJBs eram famosos por serem complicados antigamente, mas agora estão bem fáceis de usar, basta a anotação, e têm uns recursos novos como chamadas assíncronas. Assim como objetos do CDI, podem ter interceptors. Ao contrário de servlets, EJBs @Stateless não são acessados simultaneamente, o servidor contêiner faz um pool deles para atender as chamadas e por isso o código não precisa se preocupar com reentrância. Já os EJBs @Singleton, naturalmente, só são instanciados uma vez (por nodo num cluster), e têm suas próprias @anotações para controle concorrência.

JPA: você cria classes com @Entity e usa elas para representar linhas do banco de dados. A manipulação dessas @Entity‘s é feita com um EntityManager que pode ser obtido com @PersistenceContext. Com EJBs, tudo fica integrado e o contexto é automaticamente propagado, de modo que não é necessário ficar passando o EntityManager de um lado para o outro. Um EntityManager foi projetado para ser usado numa só operação (uma só thread, e muitas vezes apenas uma transação, embora também exista a opção EXTENDED para deixá-lo aberto para outra transação, que eu nunca usei). A configuração fica no META-INF/persistence.xml de um jar ou WEB-INF/classes/META-INF/persistence.xml de um war (achou estranho o WEB-INF/classes/META-INF? Eu também achei, mas está lá na especificação).

Interceptor: permite que você execute uma tarefa “ao redor” (@AroundInvoke) de chamadas de métodos (semelhante a um filtro). Essas chamadas têm que ser feitas a objetos obtidos com @Inject (CDI ou EJB), já que é o @Inject que cria o objeto proxy capaz de fazer a “mágica”. Afinal, chamadas de métodos em Java continuam sendo a mesma coisa de sempre.

JMS: permite enviar mensagens assíncronas de um sistema para outro. Não, não são e-mails (tem o JavaMail pra isso). Tem também os EJBs @MessageDriven para ajudar na tarefa.

Arquivo .jar (Java Archive): pacote compactado que contém classes Java. Existe também um tipo especial de jar para EJBs, mas no Java EE 6 os EJBs também podem ficar direto num arquivo war (na pasta WEB-INF/classes ou WEB-INF/lib)

Arquivo .war (Web Archive): pacote que contém JSPs e a pasta WEB-INF, que por sua vez contém o arquivo web.xml e as subpastas classes e lib.

Arquivo .ear (Enterprise Archive): pacote que pode conter pacotes war, jar  e mais algumas configurações.

Fazer deploy: pegar um pacote desses e colocar num servidor para ficar disponível pela web.

Context root: parte do endereço onde ficarão todas as coisas de um arquivo war. Por exemplo em http://example.com/my-web-app/index.jsp o context root é /my-web-app. O context-root pode ser o próprio nome do war ou pode ser configurado no application.xml do ear ou ainda pode ser configurado de uma forma específica ao servidor de aplicação (interface visual de administração, arquivo de configuração proprietário, etc.).

JNDI: um negócio para seu programa pegar coisas globais que o servidor disponibiliza através de caminhos especiais (ex.: java:global/isso/aquilo” ou java:comp/env/isso/aquilo”). Ficou bem menos necessário usar diretamente o JNDI quando surgiram as anotações @Inject e @Resource (ufa, ainda bem).

4 pensamentos sobre “Java EE 6 para quem está com pressa

  1. Simples, objetivo e com propriedade técnica. Até um aluno no primeiro ano de TI entende bem a explicação da plataforma java com este artigo. Parabéns!
    PS: Gostei da sinceridade quanto aos “problemas crônicos” do java. Excelente, abriu o coração!!

  2. Boa, valeu, não preciso mais escrever a minha versão nas coxas desse post: só apontar pra cá! :)

    Não sei se concordo que JSF seja uma tentativa de fazer aplicações Web se comportarem como desktop, porque o ciclo de vida não esconde o HTTP, só bota um monte de tranquera no meio. É certamente uma tentativa de habilitar componentização — que recém está começando a dar fruto — baseada em abstrações vazadas (leaky) e complicada demais, mas acho que o grande problema técnico do JSF é que os componentes estão no lado errado: componentes GUI ficam melhor no cliente, não no servidor.
    Isso é mais claro pra nós hoje do que na época que começaram a desenvolver e especificar a bagaça, mas…
    Enfim, já passei muita raiva de JSF, mas hoje em dia acho que tô mais adaptado — até consigo ver algumas vantagens…

    De qualquer forma, só queria aqui enfatizar uma coisa: REPL’s são a melhor coisa desde pão fatiado!! \o/ \o/

    • Bom, tenho que acrescentar que minha opinião sobre o JSF vem das versões 1.0/1.1, que são amplamente consideradas no mínimo como “tecnologia imatura” (e no máximo como “ruim mesmo”, hahaha). Apesar disso, incluí essa minha opinião no post porque esse “distanciamento” (ou abstração) do HTML e HTTP que o JSF faz através do uso os componentes é uma das suas principais características, então acho que continua valendo a crítica.

      Se a pessoa quer fazer algo específico em HTML e JavaScript que os componentes usados não suportam, vai ter que entender como os componentes e o seu HTML interagem com o ciclo de vida o JSF antes de poder meter a mão na massa! E como você disse: certas abstrações vazam! O pobre programador tem que entender tudo o que está por baixo dos panos, e mais a abstração; quando o certo seria aprender apenas a abstração e deixar de se preocupar com o baixo nível.

      O Java EE 6 tem o JSF 2.0, e o Java EE 7 terá o 2.2, que parecem ser muito melhores: o HTML agora realmente tem cara de HTML, dá pra integrar AJAX, e várias outras coisas.

      Mesmo assim, uma estrutura com ações onde método X corresponde ao endereço HTTP 1, método Y corresponde ao endereço 2 me parece tão mais simples e direto que acabo preferindo.

      • Ah, tenho que concordar que os JSF pre-1.2 não deveriam ter existido. :P Não cheguei a usá-los, na real, só conheço de fama… Quando conheci JSF em 2009, já foi com 1.2 e Facelets, por isso não tive esse problema do HTML ir pra saída antes do componente ser decodificado — nunca precisei do f:verbatim :).

        Mas ainda era chato fazer algumas coisas básicas, e eu também tava mais acostumado com os frameworks PHP/Python/Ruby, com roteamento de URL baseado em ações que também prefiro (Grails é assim também, btw :).

        A coisa ficou bem mais decente na versão 2, especialmente por estar dando mais importância às requisições GET — agora é relativamente trivial fazer Post-Redirect-Get. O suporte a chamada de métodos na EL 2.2 também já tava na hora de virar padrão (antes o negócio era usar a JBoss-EL, copiada do Seam).

        A próxima versão tá prometendo um monte de coisa, e parece que está ficando com dependência do CDI pra alguns features, vamos ver o que vai rolar.

Deixar mensagem para eljunior Cancelar resposta