Arquivo da categoria: Java

Entenda os MVCs e os frameworks Action e Component Based

É muito comum encontrar desenvolvedores que aprendem componentes do JSF como o Primefaces e o Richfaces e gostariam de usá-las em seus projetos que utilizam frameworks web como o Spring MVC, Struts e VRaptor, porém, isso não é possível. Por que? Entenda os diferentes funcionamentos do MVC, aprenda como funcionam os frameworks e tire para sempre essa e outras dúvidas!

Um @Controller do SpringMVC

Quando trabalhamos com o SpringMVC, tratamos as requisições enviadas pelos usuários dentro de classes conhecidas como Controller. É uma classe simples, anotada com @Controller onde implementamos métodos que tratam a requisição para uma determinada URL, indicada através da anotação @RequestMapping.

@Controller
public class ProdutosController {
   @RequestMapping("adicionaProduto")
   public void adiciona(Produto p, HttpServletRequest req) {
      // pega o produto recebido no request e grava no banco de dados
   }
}

Quando a requisição é submetida para o endereço adicionaProduto e envia os parâmetros adequados para preencher o objeto Produto, ele é gravado no banco. Porém, precisamos devolver uma resposta para o usuário, que deverá conter o nome do produto adicionado, então podemos disponibilizar um atributo ao JSP através do request que recebemos no nosso método.

@RequestMapping("adicionaProduto")
public void adiciona(Produto p, HttpServletRequest req) {
   // pega o produto recebido no request e grava no banco de dados
   req.setAttribute("nome", p.getNome());
}

Então logo após a execução da ação, indicamos para o SpringMVC que o produto-adicionado.jspdeve ser mostrado. Para isso, basta fazermos nosso método retornar uma String com o nome do JSP.

@RequestMapping("adicionaProduto")
public String adiciona(Produto p) {
   // pega o produto recebido no request e grava no banco de dados
   req.setAttribute("nome", p.getNome());
   return "produto-adicionado";
}

Dessa forma, após a execução, o JSP será exibido para o usuário.

<h2>Produto ${nome} adicionado com sucesso</h2>

Onde está o MVC aí?

O mais importante nisso tudo, é notar que existe uma separação clara entre as responsabilidades no tratamento da requisição.

Quando um usuário submete uma requisição para o endereçohttp://localhost:8080/projeto/adicionaProduto, o SpringMVC a recebe e descobre, de alguma maneira, qual é o @Controller e qual método deve ser responsável por tratá-la. Nesse caso, o SpringMVC está fazendo o papel do Front Controller, que delega a responsabilidade para umController secundário, no caso a classe ProdutosController e o método adiciona. Chamamos o responsável por esse trabalho de Controlador.

Os passos do controlador

O próximo passo é a execução das regras de negócio, que podem envolver a execução da persistência das informações, validações e outras tarefas que dizem respeito aos requisitos funcionais da aplicação. Chamamos as classes que fazem esse trabalho de Modelo.

@Controller invoca o Modelo para realizar as regras de negócio

Após a execução do Modelo e de todas as as regras de negócio, o JSP contendo a resposta adequada deve ser exibido para o usuário. Nesse ponto, temos as regras de visualização implementadas, como por exemplo, exibir as informações em vermelho, dada alguma característica. Essas regras ficam todas centralizadas no JSP, que nesse caso, faz um papel que chamamos de Visão, ou seja, é o responsável pelo que o usuário irá visualizar como resultado.

@Controller indica qual visão será devolvida para o usuário

Juntando tudo o que vimos, temos o MVC – Modelo, Visão e Controlador, cujo objetivo é separar as responsabilidades da aplicação, fazendo com que tenhamos um código mais fácil de ser mantido.

Os frameworks Action Based e o MVC Push

….

Saiba mais em: http://blog.caelum.com.br/entenda-os-mvcs-e-os-frameworks-action-e-component-based/

Fonte: Adriano Almeida / Caelum

Conhecendo o Play Framework

Quem já experimentou frameworks como Django e Rails sabe bem que o desenvolvimento de aplicações web pode perfeitamente ser produtivo e até divertido. Isso estava fora da realidade do mundo Java antes do surgimento do Play Framework!.

O Play é um framework full stack, stateless, focado em produtividade, bastante parecido com Django e Rails. É construído sobre uma arquitetura assíncrona baseada em eventos, sendo muito simples de escalar. Possui suporte a módulos, gerenciamento de dependências e configuração baseada em arquivos properties. Não é necessário compilar e realizar deploy em um servidor de aplicações, o Play vem com um servidor embutido, e durante o desenvolvimento basta alterar o código, salvar e recarregar o browser. O próprio framework compila e recarrega a aplicação, como em linguagens interpretadas. E se houverem erros, eles serão exibidos no próprio browser, de forma intuitiva.

O Play vem com um conjunto de ferramentas em modo console para várias tarefas, como criar novos projetos, iniciar a aplicação com o servidor embutido, executar testes, configurar dependências, gerar um pacote WAR, etc, o que o torna bastante produtivo tanto para novos projetos quanto para dar manutenção em um projeto já existente. É possível desenvolver em Java ou Scala (sim, Scala!).

Vamos enumerar alguma das caracteristicas do framework:

  • Limpo, Rápido e Dinâmico
  • Produtivo, Poderoso e Divertido!
  • Puro Java (Permite a importação e uso de qualquer biblioteca Java)
  • Utiliza o sistema de template Groovy(Groovy trabalha de forma transparente com todos os objetos e bibliotecas Java existentes e compila diretamente para Java bytecode tanto no desenvolvimento de aplicações como no modo script.)
  • Utiliza sistemas de tradução de Rotas
  • Facilidade na resolução de erro
  • Padrão MVC
  • Assíncrono (I/O não bloqueante)
  • Stateless
  • Arquitetura RESTful ( REST (ou Representational State Transfer) é um estilo de desenvolvimento para sistemas distribuídos que privilegia a trasferência de estado sem envolver camadas de mapeamento (como o SOAP faz). Assim, os verbos GET, POST, PUT e DELETE mapeam quase que diretamente para ações READ, UPDATE, CREATE e DELETE (CRUD).
  • Persistência com JPA (JPA é uma especificação de Persistência da plataforma Java, para persistir as classes java em bancos de dados relacionais. )
  • Extensível (Através de Módulos / Bibliotecas Java)
  • TDD – Test Development Drive (Test Driven Development (TDD) ou em português Desenvolvimento dirigido por testes )

 

Como iniciar uma aplicação no Play?

É facil, basta usar o comando no consolhe (Terminal no Linux e Prompt de comando no Windows, lembrando que você terá que estar dentro da pasta do framework no windows e no linux ter adicionado o caminho da pasta ao PATH para executar o comando play):

play new nomedaaplicacao

Toda a estrutura do projeto será criada, incluindo arquivos de configuração e o roteamento inicial da aplicação. Se você deseja abrir o projeto no Eclipse ou no Netbeans, o Play! cria o projeto para você. Basta fazer assim:

play eclipsify nomedaaplicacao

Ou se preferir o Netbeans:

play netbeansify nomedaaplicacao

Dessa forma, você poderá importar o projeto de sua IDE e todas as configurações estarão realizadas. Outro comando importante é a gerador de war (deploy).

 play war nomeDoProjeto -o nomeDoProjeto.war

Pronto, feito isto basta começar a programar no projeto usando Java ou Scala 🙂 !

Slide da apresentação feita na SWX: play-framework-apresentaçao

Código de uma pequena aplicação de uma agenda feita na SWX:

No diretório /conf no arquivo application.conf , caso use mysql, basta localizar e modificar o padrão para seu usuário e senha do mysql e o nome do banco (No exemplo a seguir está sem senha).

# To connect to a local MySQL5 database, use:
db=mysql:acson@minha_agenda
// acson -> usuário do banco,  minha_agenda -> banco

No diretório /app/controllers , modifique o Application.java (ou crie se não existir)  para:

package controllers;
import play.*;
import play.mvc.*;
import play.data.validation.*;
import java.util.*;
import models.*;
public class Application extends Controller {
public static void index() {
 List<Contato> contatos = Contato.find("order by nome asc").fetch();
 render(contatos);
 }
public static void inserir() {
 render();
 }

 public static void visualizar(String email) {
 Contato contato = Contato.find("email", email).first();
 render(contato);
 }

 public static void editar(String email) {
 Contato contato = Contato.find("email", email).first();
 render(contato);
 }

 public static void excluir(String email) {
 Contato contato = Contato.find("email", email).first();
 contato.delete();
 index();
 }

 public static void cadastrar_contato(@Required String nome, @Required String email, String telefone, String twitter, String skype) {
 Contato contato = new Contato(nome, email, telefone, twitter, skype);
 if (validation.hasErrors()) {
 render("Application/inserir.html", contato);
 }

 contato.save();
 index();
 }

 public static void editar_contato(long id) {
 validation.required(request.params.get("nome"));
 validation.required(request.params.get("email"));

 Contato contato = Contato.find("id", id).first();

 if (validation.hasErrors()) {
 render("Application/editar.html", contato);
 }

 contato.nome = request.params.get("nome");
 contato.telefone = request.params.get("telefone");
 contato.email = request.params.get("email");
 contato.twitter = request.params.get("twitter");
 contato.skype = request.params.get("skype");

 contato.save();
 index();
 }
}

 

No diretório /app/models  , crie a classe Contato (Contato.java) com o seguinte código:

package models;
import play.*;
import play.db.jpa.*;
import javax.persistence.*;
import java.util.*;
@Entity
public class Contato extends Model {

 public String nome;
 public String email;

 public String telefone;
 public String twitter;
 public String skype;

 public Contato(String nome, String email, String telefone, String twitter, String skype) {
 this.nome = nome;
 this.email = email;
 this.telefone = telefone;
 this.twitter = twitter;
 this.skype = skype;
 }

}

No diretório /app/views  , crie o arquivo application.html com o seguinte código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>.: Agenda de Contatos - #{get 'title' /}</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/principal.css'}">
 #{get 'moreStyles' /}
 <script src="@{'/public/javascripts/jquery-1.4.2.min.js'}" type="text/javascript" charset="utf-8"></script>
 #{get 'moreScripts' /}
</head>
<body id="page1">
 <div id="geral">

 <div id="conteudo">
 <div id="logo"></div>
 <div class="linha">
 <div class="titulo">.: Agenda de Contatos</div>
 #{if request.actionMethod != "inserir" && request.actionMethod != "editar"}
 <div class="text"><a href="@{Application.inserir()}" class="button">+ Incluir Contato</a></div>
 #{/if}
 </div>
 <div class="linha"></div>
 #{doLayout /}
 </div>
 </div>
 </div>
</body>
</html>

No diretório /app/views/Application  , crie o arquivo inserir.html com o seguinte código:

#{extends 'application.html' /}
#{set title:'Inclusão' /}
#{form @Application.cadastrar_contato()}
 #{ifErrors}
 <div class="linha"><p style="color:red;"><strong>ATENÇÃO: </strong>Preencha todos os campos obrigatórios.</p></div>
 <div class="linha"></div>
 #{/ifErrors}
<div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="nome">Nome:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="nome" id="nome" value="${params.nome}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="telefone">Telefone:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="telefone" id="telefone" value="${params.telefone}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="email">Email:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="email" id="email" value="${params.email}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="twitter">Twitter:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="twitter" id="twitter" value="${params.twitter}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="skype">Skype:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="skype" id="skype" value="${params.skype}" /></p>
 </div>
 </div>
 </div>
 <div class="btn-submit">
 <p><input type="submit" value="Cadastrar o Contato" /></p>
 </div>

#{/form}

No diretório /app/views/Application  , crie o arquivo visualizar.html com o seguinte código:

#{extends 'application.html' /}
#{set title:'Visualiza‹o' /}
<div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="nome">Nome:</label></p>
 </div>
 <div class="dir">
 <p>${contato.nome}</p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="telefone">Telefone:</label></p>
 </div>
 <div class="dir">
 <p>${contato.telefone}</p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="email">Email:</label></p>
 </div>
 <div class="dir">
 <p>${contato.email}</p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="twitter">Twitter:</label></p>
 </div>
 <div class="dir">
 <p>${contato.twitter}</p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="skype">Skype:</label></p>
 </div>
 <div class="dir">
 <p>${contato.skype}</p>
 </div>
 </div>
 </div>
 <div class="btn-submit">
 <p>
 <a href="@{Application.index()}">Cancelar</a>
 <a href="@{Application.editar(contato.email)}">Editar</a>
 <a href="@{Application.excluir(contato.email)}" onClick="if(!confirm('Deseja excluir este contato?')){return false;}">Excluir</a>
 </p>
 </div>

No diretório /app/views/Application  , crie o arquivo editar.html com o seguinte código:

#{extends 'application.html' /}
#{set title:'Edição' /}
#{form @Application.editar_contato(contato.id)}
 #{ifErrors}
 <div class="linha"><p style="color:red;"><strong>ATENÇÃO: </strong>Preencha todos os campos obrigatórios.</p></div>
 <div class="linha"></div>
 #{/ifErrors}
<div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="nome">Nome:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="nome" id="nome" value="${contato.nome}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="telefone">Telefone:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="telefone" id="telefone" value="${contato.telefone}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="email">Email:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="email" id="email" value="${contato.email}" /></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="twitter">Twitter:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="twitter" id="twitter" value="${contato.twitter}"/></p>
 </div>
 </div>
 </div>
 <div class="linha">
 <div class="duas-colunas">
 <div class="esq">
 <p><label for="skype">Skype:</label></p>
 </div>
 <div class="dir">
 <p><input type="text" name="skype" id="skype" value="${contato.skype}" /></p>
 </div>
 </div>
 </div>
 <div class="btn-submit">
 <p><input type="submit" value="Editar o Contato" /></p>
 </div>

#{/form}

No diretório /app/views/Application  , crie o arquivo index.html com o seguinte código:

#{extends 'application.html' /}
#{set title:'Listagem' /}
#{if contatos.size() == 0}
 <div class="linha">
 <p>Nenhum contato cadastrado.</p>
 </div>
#{/if}
#{else}
 #{list items:contatos, as:'contato'}
 <div class="linha">
 <p><a href="@{Application.visualizar(contato.email)}">&raquo; ${contato.nome} - ${contato.email}</a></p>
 </div>
 #{/list}
#{/else}

E para ficar mais agradável e padronizado, vamos mudar o arquivo de rotas que fica em  /conf , o arquivo é o routes

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / Application.index
GET /cadastrar Application.inserir
GET /visualizar/{email} Application.visualizar
GET /editar/{email} Application.editar
GET /excluir/{email} Application.excluir
# Map static resources from the /app/public folder to the /public path
GET /public/ staticDir:public
# Catch all
* /{controller}/{action} {controller}.{action}

Quando o usuário chamar o método de inserir que está no Application.java, no browser aparecerá dominio/cadastrar, e assim por diante.
Terminando isso o aplicativo está pronto para uso.
Abaixo algumas telas de uma pequena aplicação que fizemos, uma agenda de contados:

Site oficial do Play Framework: http://www.playframework.org/

Github do Play Framework:  https://github.com/playframework/play

Algumas fontes consultadas: Imasters, Bragil.net

Oracle atualiza Java SE e corrige falhas críticas de segurança

Com informações de Under-Linux

Fonte: IMasters


A Oracle Corporation anunciou a correção de 14 falhas de segurança no Java Standard Edition (Java SE) através de um Critical Patch Update.

As vulnerabilidades permitem que os atacantes utilizem aplicativos ou serviços da web para instalar código malicioso em computadores que executam versões imperfeitas do Java.

A Oracle afirma que essas falhas nas versões são particularmente suscetíveis de existir em computadores com Windows, pois os usuários desse sistema operacional tendem a ter privilégios de administrador. Segundo a empresa, o risco é bem menor em sistemas operacionais como Linux e Solaris.

As falhas, das quais cinco são classificadas como vulnerabilidades de risco máximo, afetam JDK (JavaDevelopment Kit) e JRE (Java Runtime Environment) 7 Update 2, JDK e JRE 6 Update 30, JDK e JRE 5.0 Update 33, e SDK e JRE Releases 1.4.2:35, e anteriores a essas citadas. Versões mais antigas do que o JavaFX 2.0.2 também são afetadas pelo problema.

Nova API JSON padrão para Java será desenvolvida

Uma nova interface Java para processamento de dados no formato JSON foi aprovada pela Java Community Process (JCP) como uma Java Specification Request (JSR).

Com 10 votos a favor e 6 abstenções, o comitê executivo votou a favor do JSR 353, que, primeiramente, tem como objetivo ser a base para o desenvolvimento padronizado para futuras APIs JSON e vai permitir que aplicativos sejam menores e mais portáveis por não terem o pacote existente nas bibliotecas JSON.

A proposta planeja capacitar a produção e o consumo do texto JSON, em um estilo semelhante ao da API StAX usada para XML. Além disso, ela está focada na produção de um modelo de objeto e de uma API para texto JSON, em um estilo semelhante ao da API DOM para XML.

O pedido aponta especificamente que ligar o texto JSON a objetos Java, e vice-versa, não é a meta da especificação. Os desenvolvedores afirmaram que pretendem integrar o JSR 353 no Java EE 7, assim como oferecer uma variante independente para o for Java SE 6 e superior.

O SouJava, grupo de usuários brasileiros, votou a favor do JSR e comentou favoravelmente a respeito do trabalho da especificação, liderado por Jitendra Kotamraju, que, segundo eles, já demonstrou sua habilidade em envolver desenvolvedores a partir da comunidade mais ampla. A IBM também se manifestou e afirmou que seu voto a favor do JSR foi exclusivamente baseado nos méritos técnicos do JSR 353.

Com informações de The H

Fonte: IMasters

Java 8 e módulos: o estado atual do projeto Jigsaw

Mark Reinhold, arquiteto-chefe da plataforma Java na Oracle, publicou uma nota detalhando a situação atual do projeto Jigsaw e apontando novidades nessa área para o Java 8. O projeto Jigsaw tem como objetivo permitir a criação de módulos de sistemas (coleções de classes e interfaces) dentro da Plataforma Java.

Para obter a modularidade foram seguidos alguns princípios:

  • A linguagem Java em si precisa ter suporte à criação de módulos;
  • Os módulos devem controlar quais classes podem ser acessadas externamente a eles;
  • Deve haver uma identificação de versão, caso ocorra a necessidade de os módulos serem adicionados ou removidos durante a execução do programa.

A seguir, são mostrados exemplos de como será o uso de módulos.

O exemplo abaixo cria um módulo, informando a sua versão, e define qual o pacote de classes públicas será compartilhado com outros módulos:

module br.infoq.foo @ 1.0 {
/* Permite que os outros módulos tenham acesso às classes públicas deste pacote. */
exports br.infoq;
}

O exemplo a seguir cria um módulo que possui uma dependência com outro módulo (podendo ser especificada a versão):

module zoo {
requires br.infoq.foo @ 1.0;
}

Note que é informada uma dependência do módulo br.infoq.foo na versão 1.0. Pode-se também especificar uma condição, por exemplo @ >= 2.0, que nesse caso informa a necessidade de uma versão maior ou igual à versão 2.0 do módulo.

O exemplo a seguir cria um módulo que possui uma dependência e aproveita para compartilhar essa dependência com outros módulos. Também demonstra como definir quais módulos podem acessar o módulo em questão:

module bar {
/* Permite que os módulos dependentes de bar, também acessem o módulo zoo. */
requires public zoo;
/* Somente o módulo baz pode acessar este módulo. */
permits baz;
}

Mark Reinhold também descreveu tarefas pendentes, além de revisões que serão realizadas no projeto, e futuras implementações que ocorrerão na parte de compilação, empacotamento, bibliotecas, repositórios, API de modularização de sistemas e modularização do JDK. No site do Jigsaw há mais informações sobre o histórico do projeto, além de sua documentação.

Fonte: Rafael Sakurai/InfoQ

NetBeans 7.1 é liberado

A versão 7.1 do NetBeans foi lançada, e a principal funcionalidade do IDE baseado em Java é a introdução do suporte para JavaFX 2.0, incluindo compilação, depuração e definição de perfil dos aplicativos, e seu desenvolvimento para o desktop como um applet ou via JNLP.

O suporte para NetBeans JavaFX requer o JavaFX 2.0 SDK – downloads para Windows e Mac OS X apenas -, que foi construído com o mais recente Java 7 SDK. Melhorias no Swing GUI Builder, CSS3, e no suporte e nas ferramentas para depuração das interfaces de usuário do Swing e do JavaFX também foram incorporadas.

Além disso, o suporte para Git foi totalmente integrado ao NetBeans 7.1, e criar versões no IDE ficou mais fácil de gerenciar com a adição de uma barra de histórico na janela de edição do arquivo. Outra melhoria é a chegada da funcionalidade “Inspect and Refactor”, que permite que refatorações protegidas sejam aplicadas ao código.

Desenvolvedores do Java EE encontrarão mais opções de implementação suportadas pelo Glassfish, suítes de componentes JSF e melhorias para Java Persistence, Web Services e EJB. Desenvolvedores do PHP verão que o NetBeans 7.1 tem um depurador melhor, suporte para PHPUnit e templates Smarty. E desenvolvedores do NetBeans Platform agora são capazes de usar as novas APIs do Window System.

Mais detalhes sobre o NetBeans 7.1 podem ser encontrados no site do projeto, nas notas de lançamento e em tutoriais.

Com informações de The H

Fonte: IMasters

Canonical vai remover Java do sistema de usuários

A Canonical anunciou na semana passada que vai remover sistematicamente o Java do Ubuntu, deixando espaço para alternativas livres. A decisão tem base nos problemas de segurança encontrados nos pacotes JDK do Java, usados também em navegadores. Várias das vulnerabilidades foram descobertas em outubro e até hoje permanecem sem solução, oferecendo risco aos usuários. Dessa forma a Canonical achou mais fácil desabilitar o plugin e cortar o mal pela raíz.

As primeiras versões do Ubuntu a serem afetadas serão a 10.04 LTS, 10.10 e 11.04. A ideia envolve substituir os pacotes disponíveis atualmente no repositório de Parceiros com pacotes vazios. Assim, ao fazer a atualização, o próprio Ubuntu removeria todos os arquivos do sistema.

A Canonical já está alertando aos usuários para que migrem para OpenJDK e desinstalem o JDK da Oracle (caso eles o tenham baixado e instalado manualmente), ou eles poderão “experimentar falhas após a atualização dos pacotes”.

Marc Deslauriers, da Canonical, disse que eles podiam remover os pacotes dos repositórios e deixar os pacotes inseguros nos sistemas dos usuários, ou remover tanto dos repositórios, quanto dos sistemas, de forma remota. “Não há uma forma perfeita de lidar com isso”, ele disse, “mas infelizmente essa é melhor maneira de lidar com o problema e garantir que nossos usuários permaneçam seguros, ao custo de quebrar algumas instalações”.

Portanto, se você ainda não usa o OpenJDK ou o icedtea, é bom começar a se preparar, ou muito em breve terá problemas para acessar páginas que tenham código Java.

Por Paulo Graveheart

Fonte: IMasters

Java 8: O estado atual do lambda

Brian Goetz publicou uma atualização do “estado do lambda“, dando informações da situação do plano de adicionar lambdas na linguagem Java, que também pode ser acompanhado pela JSR 335 e pela proposta de melhoria do Java número 126.

O plano para trazer os lambdas para a linguagem Java cobre tanto as sintaxes para funções anônimas, como planos para estender o conjunto de classes Java existentes (tal como as de Collections), com métodos que aceitem lambdas também. O objetivo é adicionar funções como map e filter, para que coleções possam ser processadas de forma mais funcional.

De modo a fornecer este comportamento nas interfaces existentes (e não somente nas classes básicas do Java), um novo tipo de método foi adicionado às interfaces, chamado método default (antes chamado método defender).

Isto efetivamente permite que interfaces tenham implementações de métodos, de forma bem parecida com as traits do Scala ou classes abstratas do Java. Quando um método é invocado através de uma referência de interface, o compilador inicialmente delega a chamada do método para uma instância; mas se nenhuma implementação do método for encontrada, o método default declarado na interface é invocado.

Diferentemente do que acontecia em versões anteriores da especificação, em vez de se definir um apontador para um método estático existente, a nova especificação permite métodos (mas não atributos) de interface com corpos válidos, identificados com a palavra-chave default. O seguinte exemplo adiciona o método skip() a todos os iterators:

interface Iterator<E> {
boolean hasNext();
E next();
void remove();
 
void skip(int i) default {
for (; i > 0 && hasNext(); i--) next();
}
}

Como a mudança efetivamente adiciona a implementação de herança múltipla à linguagem Java, no caso de colisões (quando o mesmo método default é herdado por dois caminhos separados), o método precisa ser redefinido na classe. Ou então um dos métodos default deve ser explicitamente chamado através do construtor: new Iterator.super.skip().

Outra recente mudança é a sugestão de alterar a sintaxe das referências a métodos, de Person#compare, inspirada no JavaDoc, para uma sintaxe mais inspirada no C++ como Person::compare. Qualquer que seja a sintaxe adotada, as referências de métodos fornecem um atalho tipado para um método que recebe um lambda.

Embora as expressões atuais do lambda não tenham sofrido muitas alterações, algumas partes da sintaxe e da terminologia vêm sendo revisadas. Por exemplo, a decisão anterior era de usar =>, adotado em C# e Scala, como sintaxe para introduzir uma expressão lambda; agora a sintaxe foi alterada para ->. Assim, uma função que retorna a negação dela mesma, pode ser escrita como int a -> -a. (Se o tipo de a puder ser inferido, ele é usado como alternativa; no caso de expressões em que o compilador não consegue identificar o tipo como byte, short, int ou long, será preciso fazer a distinção explicitamente ).

Outra mudança em terminologia ocorre para classes como Runnable e Action. Estas são interfaces com um único método abstrato, antes chamadas tipos SAM (Single Abstract Method). Para estimular o seu uso mais amplo no Java, agora são chamadas de interfaces funcionais.

A mudança visa encorajar o uso desses tipos como sendo conversíveis para um tipo mais geral, partindo de uma referência a um método. Dessa forma, onde um código Java existente tem métodos que esperam instâncias de Comparator, pode-se passar agora uma expressão lambda ou um handle do método com a mesma assinatura do método compareTo() do Comparator. Embora tecnicamente o Comparator tenha dois métodos abstratos (compareTo() e equals()), ainda é visto como uma interface funcional, pois equals() já é disponibilizado em Object.

Embora as funções tipadas tenham sido consideradas (estão disponíveis em um rascunho inicial da especificação), foram rejeitadas, pelo menos por agora. Isso porque apagar uma função tipada causa problemas na versão atual da JVM. Embora não esteja descartada a inclusão das funções tipadas no futuro, há a expectativa de que interfaces funcionais baseadas em tipos sejam mais úteis em Java do que um novo tipo funcional.

Os lambdas continuam tendo uma vantagem na qual o tipo do argumento pode ser inferido sem ter que se definir explicitamente o tipo (a menos que haja necessidade de distingui-lo, como mencionado). Lambdas podem também ser recursivos e capturar estados de escopos externos (lambdas que capturam escopos externos são conhecidos como closures). A captura acontece somente para variáveis com modificador final. No entanto, a adoção de um “final efetivo”, significa que o final pode ser inferido em muitos locais e não precisa ser explicitamente mencionado.

A adição de lambdas à linguagem Java, juntamente com referências a métodos, irá reduzir significativamente a quantidade de código repetitivo necessário para operações comuns. Por exemplo, para ordenar um array de strings diferenciando maiúsculas e minúsculas, poderá ser escrito:

Arrays.sort(names, String::compareToIgnoreCase)

Juntamente com os métodos default, que permitem que interfaces cresçam (como os traits do Scala) sem afetar os códigos existentes, essas mudanças deixarão o código Java muito mais conciso. Não teremos um completo híbrido objeto-funcional, mas veremos um crescimento no número de bibliotecas com estilo funcional a partir do JDK8.

O código compilado com lambdas e métodos default não rodará em versões anteriores ao JDK8, mas será possível compilá-lo com versões mais antigas do JDK e usá-lo de maneira funcional. O processo será parecido com o que foi utilizado para trazer os tipos genéricos gradualmente para a linguagem Java.

Fonte: Alex Blewitt , traduzido por Rafael Sakurai/InfoQ

Conhecendo o F#

Como você sabe, existem algumas linguagens OOP por aí. Você provavelmente conhece VB.Net, C# e Java, mas eu vou falar de uma relativamente nova.

Gostaria de falar um pouco sobre F#.

Similar ao C# e ao VB.Net, o F# também é direcionado para o Framework .Net e também é orientado a objeto.

A principal diferença no F# não é sua sintaxe única, mas sim o novo ponto de vista e o estado de espírito que traz para a programação orientada a objeto.

O F# usa inferência de tipos – o que significa que o programador não precisa se preocupar com a declaração de tipo e pode apenas utilizar a palavra reservada “let” (que é similar a “var”). A declaração do tipo de dados será deduzida pelo compilador durante a compilação (o F# também permite a declaração explícita de tipos de dados).

Depois dessa pequena introdução ao F# (bem pequena), gostaria de começar a parte prática. E este artigo será sobre Listas no F#.

Vamos fazer um pequeno experimento:

Crie uma lista de ints no C#

List<int> newList = new List<int>();

Adicione os seguintes valores a essa lista:

newList.Add(5);
newList.Add(2);
newList.Add(-3);
newList.Add(1);

Agora por favor tente classificá-la usando valor absoluto.

Você provavelmente descobrirá que se você tentou fazer isso, você usou a funcionalidade da programação.

No F#, é quase o mesmo, e fica o mais fácil possível, uma vez que você chega neste ponto:

[5; 2; -3; 1] |> List.sortBy(fun intElem -> abs intElem)

Vamos testar nossas habilidades no C# mais uma vez mapeando a lista de ints (cada número será aumentado em 3).

Mais uma vez, a maioria de vocês que se saiu bem usando LINQ ou outra programação funcional que o C# permite, é assim que funcional no F#:

[5; 2; -3; 1] |> List.map(fun x-> x * x * x)

Outro teste para o poder do nosso C# (ou Java) será tentar filtrar essa lista para ints que retornam 0 quando divididas por 2. No F#, é fácil assim:

[5; 2; -3; 1] |> List.filter(fun x -> x % 2 = 0)

Esses foram apenas alguns exemplos sobre o F# e sua usabilidade. Espero que ajude você a compreender a sintaxe, e mais importante – que ajude você a pensar em programação funcional.

Falando nisso, como podemos esquecer o imortal primeiro programa: “Hello World!” ?

printfn "Hello World!"

Texto original disponível em http://www.devaffair.com/2011/01/first-steps-in-f-sharp.html

Fonte: IMasters

IcedTea, Harmony, IKVM e mais: altos e baixos do Java Open Source

Este artigo traz um panorama de projetos open source relacionados com o coração da plataforma Java, e em que tem havido extremos de altos e baixos. Em outubro, o IcedTea liberou sua versão 2.0, baseada no OpenJDK 7, que já está disponível como o Java 7 oficial do Fedora e do Ubuntu Linux; em novembro a Apache anunciou que o Harmony estava sendo rebaixado para o “sótão” da Fundação. São dois exemplos (e dois extremos) de projetos trazendo novidades que poderão afetar o futuro da tecnologia Java, mesmo sem o apoio de gigantes como Oracle e IBM.

IcedTea

Quando a Sun liberou em 2007 os fontes da sua JVM e sua biblioteca de classes, criando o projeto OpenJDK, atual implementação de referência do Java 7, o resultado não era imediatamente usável pela comunidade open source, pois alguns componentes licenciados de terceiros não puderam ser abertos naquele momento. Exemplos de APIs que não foram incluídas no código inicial do OpenJDK são as de gerência de fontes tipográficas e de interação com dispositivos de som. Sem falar de complementos indispensáveis para algumas aplicações, como o plugin web para Applets e o Java Web Start, que embora sejam parte do produto da Sun e Oracle há tempos, cobrem funcionalidades não-padronizadas como parte do Java SE.

Para remediar esses problemas, a comunidade open source criou, com patrocínio da Red Hat, o projeto IcedTea. O objetivo era substituir os componentes proprietários necessários para compilação e execução do OpenJDK, pelos equivalentes em outros projetos open source, especialmente o projeto GNU Classpath.

Na verdade, já havia conversas entre membros importantes da comunidade open source e da Sun bem antes do lançamento do OpenJDK, e não foi acidente a opção da Sun pela licença GPL, em vez das licenças usadas no Glassfish e no extinto Open Solaris. O objetivo era permitir a mistura de código com o ecossistema do GNU Classpath, baseado na GPL.

Já há alguns anos, as distribuições do Linux incluem binários certificados do IcedTea, mas que são distribuídos usando o nome OpenJDK como parte de um acordo com a Sun para acesso ao TCK, o kit de testes de compatibilidade do Java.

Algumas distribuições ofereciam como alternativa o Java proprietário da Sun, empacotado nos repositórios “não-livres”, usando a licença DLJ (Operating System Distribution License for Java). Mas a DLJ foi descontinuada pela Oracle com a liberação do Java 7, não apenas para o novo Java mas também para as versões anteriores. Por isso o IcedTea se tornou o único Java certificado a ser fornecido como parte dos sistemas Fedora, Ubuntu e Debian, além de se tornar também o preferencial para uso em distribuições comerciais com RHEL e SuSE.

O escopo do projeto IcedTea aumentou desde a sua criação. Ele implementou melhorias sobre o OpenJDK, para melhor compatibilidade com o Linux, por exemplo o suporte ao PulseAudio para multimídia; e evoluiu para uso de JVMs alternativas, como a JamVM, entrando no lugar do HotSpot do OpenJDK original.

Ampliando o alcance do OpenJDK

A maior contribuição do IcedTea para o OpenJDK provavelmente foi os projetos Zero e Shark. O Zero é um interpretador genérico de alta performance, que torna o OpenJDK viável em várias plataformas embarcadas, em que o custo de memória e bateria de um compilador JIT seria proibitivo.

Já o Shark utiliza a infraestrutura do LLVM para criar um compilador JIT portável para múltiplas arquiteturas de CPU, evitando a necessidade de se escrever um novo JIT para cada arquitetura de processador. Graças a estes projetos o OpenJDK vem se tornando a implementação do Java preferencial em algumas CPUs populares em plataformas voltadas para a computação embarcadas, como ARM e MIPS.

Note que o IcedTea não é um fork do OpenJDK. Alguns dos seus contribuidores estão no Community Board do OpenJDK e vários dos patches do projeto migraram para o OpenJDK e se tornaram parte do Java 7 oficial.

Outra contribuição importante do IcedTea é um processo de compilação mais simples para o OpenJDK, reduzindo a barreira de entrada para potenciais contribuidores. O projeto OpenJDK não fornece binários para nenhuma plataforma, somente fontes. O JDK fornecido pela Oracle à partir dos fontes do OpenJDK usa uma licença proprietária. Mas, graças ao processo simplificado do IcedTea hoje é possível baixar, sob uma licença open source, binários para Windows no site do Open SCG, que é o mesmo grupo responsável pelo porte nativo do PostgreSQL para Windows.

A certificação do Java SE é realizada sobre binários, não sobre fontes, e os binários do IcedTea inclusos no Ubuntu, Fedora e derivados (como RHEL e CentOS) são certificados desde 2009. Mas os binários do OpenJDK 7/IcedTea 2 inclusos nas distribuições do Linux não são certificados ainda, e nem os fornecidos pelo OpenSCG para Windows. Ambas as comunidades estão trabalhando no processo, e estão em busca de patrocinadores.

Ainda há espaço para outras JVMs open source?

A criação do projeto OpenJDK diminuiu o incentivo a continuidade de vários projetos de JVMs open source. O SableVM foi uma das vítimas. O desenvolvimento do GNU Classpath, que fornecia a biblioteca de classes do Java SE para a maioria destes projetos, ficou congelado no Java SE 5, e o venerável Kaffe apenas recentemente voltou a ter atividade, sendo transferido para o Github.

Poderia ser argumentado que não há mais necessidade de outros projetos de JVMs open source, uma vez que a Sun abriu sua implementação, e ainda mais agora que a Oracle oficializou o OpenJDK como a implementação de referência (RI) para o Java 7. A competição trazida por estes projetos foi benéfica porque estimulou a evolução e a abertura do JDK pela Sun, mas qual seu papel no futuro do Java?

Na época o Classpath estava chegando perto do 100% do Java SE 5 e se tornaria certificável. Com dois Javas open source plenamente funcionais (GCJ+Classpath e Apache Harmony) ficaria complicado manter restrições ao TCK do Java SE, e mais importante, o fluxo de caixa originado pelo licensiamento do JDK da Sun para fabricantes de plataformas móveis e embarcadas. A criação do OpenJDK sob licença GPL permitiu unir esforços à comunidade open source, sem abrir o TCK para projetos externos.

Por outro lado, sem projetos open source independentes, deixa-se de explorar alternativas de design para a JVM, que poderiam atender a nichos específicos ou se tornarem importantes em plataformas futuras. O fato de smartphones e tablets atuais em sua maioria ignorarem a plataforma Java SE (e também a Java ME) mostra que essas alternativas podem estar fazendo falta.

Por exemplo, o GCJ, que é parte da suite de compiladores GCC, tem a opção de gerar código nativo (que não necessita de uma JVM para executar). Era uma opção interessante para aplicações desktop e sistemas embarcados, tanto que foi utilizado pelo RHEL e pela comunidade Fedora para suportar o Eclipse e o Tomcat, antes da criação do OpenJDK. Sem falar na ampla cobertura de arquiteturas de CPU e SOs do GCC, muito superior à suportada pelo Java “oficial” na época.

As releases recentes do GCC continuam suportando o GCJ, e ele continua sendo incluído nas principais distribuições do Linux; mas, infelizmente não parece haver planos para atualizar seu suporte à linguagem Java, nem para completar o GNU Classpath ou atualizá-lo para além do Java 5.

JVMs alternativas ao OpenJDK

O OpenJDK, no entanto, não parece ter diminuído o ritmo do JikesRVM, que tem o diferencial de ser escrito quase que inteiramente em Java. Infelizmente ele não tem a pretenção de ser uma JVM para “uso real”, seu objetivo é ser uma plataforma de testes para novos algoritmos internos à JVM para projetos acadêmicos.

Dois dos projetos baseados no GNU Claspath, o JamVM e o Cacao continuam vivos. Eles colaboram com o projeto IcedTea e hoje podem utilizar a biblioteca de classes do OpenJDK em lugar do GNU Classpath, voltando assim a acompanhar a evolução da plataforma oficial. Apesar de os seus releases mais recentes terem mais de um ano, existe grande atividade nos repositórios de código do JamVM e do Cacao, e espera-se para breve novos releases que finalmente atualizarão suas respectivas JVMs para compatibilidade com as novas versões do Java.

Ambos o JamVM e o Cacao são focados em plataformas embarcadas, explorando diferentes designs para componentes da JVM, como o coletor de lixo, o interpretador de bytecodes e o compilador JIT. A comunidade do JamVM afirma, por exemplo, que é possível gerar um executável da sua JVM ocupando menos de 100 Kb.


Java no .NET

Outro projeto de JVM open source que continua vivo e pode ser interessante para alguns nichos é o IKVM, que roda dentro do CLR do .NET ou do Mono, e permite convivência “sem costuras” entre código escrito em Java e código escrito em C#, VB.Net ou outras linguagens que rodam sob o CLR.

O IKVM também permite empacotar aplicações Java como assemblies nativas do .NET. O projeto ganhou certa popularidade entre desenvolvedores que gostariam de continuar tendo acesso a bibliotecas Java em um projeto .NET. É também o projeto mais atualizado em relação aos padrões do Java, pois já oferece um release candidate com suporte ao Java 7.

Com o fim do Harmony, como fica o Android?

A DalvikVM, que é a base das aplicações Android, é baseada na biblioteca de classes do Java SE fornecida como parte do Apache Harmony. Originalmente este projeto tinha apoio da IBM, que contribuiu com a maior parte do código para a biblioteca de classes, mas quando a IBM decidiu focar seus esforços no OpenJDK, o Harmony ficou “órfão”. O projeto Harmony foi oficialmente descontinuado pela Apache Software Foundation em novembro deste ano. Ao contrário do que muitos esperavam, o Google não assumiu o projeto, mantendo o desenvolvimento do Dalvik como um fork separado, provavelmente devido ao processo aberto pela Oracle por violação de patentes.

O Dalvik não é exatamente uma JVM, pois roda seu próprio bytecode, e usa uma arquitetura interna bem diferente da usada no OpenJDK, embora semelhante ao JamVM e ao CacaoVM. O desenvolvimento das aplicações para o Dalvik é feito na linguagem Java, e os bytecodes Java são convertidos em bytecodes Dalvik. Está disponível apenas um subconjunto da API do Java SE, embora maior do que o incluso no Java ME, mas o Dalvilk não traz nada do Java oficial para celulares, sendo incompatível com MIDP ou CDC. Recursos que seriam parte do Java ME são fornecidos por APIs proprietárias para o Android, ou por acesso a serviços do Google.

A omissão do Google quanto ao Harmony dá margem a dúvidas sobre qual será o futuro do “Java” no Android:

  • O Google vai continuar evoluindo o Dalvik usando ideias do Java, de modo similar feito pela Microsoft com o .NET?
  • Ou será o HTML 5 quem poderá provocar um futuro abandono do DalvikVM e Java no Android?

Qualquer que seja o futuro do Dalvilk, ele representa uma linha que poderia ter sido incorporada ao Java oficial e que garantiria a popularidade do Java na computação móvel. A disputa entre Google e Oracle não atende aos interesses da comunidade Java, e a recente ênfase no HTML 5 mostra bem como o mercado ainda carece de uma solução para desenvolvimento interoperável entre smartphones e tablets de diferentes fornecedores.

Serviços nativos do Linux

O exemplo do Dalvik mostra que, apesar da necessidade de funcionalidades independentes de plataforma, há também necessidade de se incorporar suporte a recursos nativos. O Java 7 já foi uma evolução nessa direção, com a nova API de filesystem do NIO2 e se pode argumentar que o Eclipse deve grande parte do seu sucesso ao toolkit gráfico SWT, também baseado no acesso a recursos nativos de Windows, Unix e Mac.

Novamente vemos que a comunidade open source traz novidades neste sentido, dentro do ramo da computação embarcada. Por exemplo, o BUG System e o OpenEmbedded fazem uso de APIs Java para acesso ao desktop Gnome e o D-Bus – efetivamente colocando o Java em pé de igualdade com o código nativo, no acesso aos recursos do SO e Desktop do Linux.

Em vez de criar todo um “universo paralelo”, como feito pelo Android, estes projetos buscam maximizar a utilidade de recursos já conhecidos dos desenvolvedores em plataformas embarcadas, e abrem espaço para a plataforma Java como “linguagem de sistema” para o Linux, viabilizando o desenvolvimento de aplicações de gerência de hardware sem recorrer diretamente a código nativo.

Conclusões

Podemos ver que, apesar do foco de grandes empresas no projeto OpenJDK, ainda há vários outros projetos open source com potencial de contribuir para a evolução da plataforma, especialmente em nichos ainda negligenciados pela plataforma oficial, como o de dispositivos embarcados. Vale a pena acompanhar o amadurecimento destes projetos, pois de um deles pode sair o diferencial competitivo para os produtos da sua empresa, ou surgirem evoluções importantes para a plataforma oficial do Java.

Fonte: Fernando Lozano/InfoQ

Restfuse 1.0.0: uma biblioteca para facilitar testes de integração REST/HTTP

A EclipseSource lançou a primeira versão estável de uma extensão open souce do JUnit para automação de testes de serviços REST/HTTP. O Restfuse é um conjunto de anotações para JUnit que oferece asserções para respostas de requisições HTTP. Tanto chamadas síncronas como assíncronas são suportadas.

O Restfuse já está disponível no Maven Central, então para usá-lo não é necessário nenhum repositório especial:

<dependency>
<groupId>com.restfuse</groupId>
<artifactId>com.eclipsesource.restfuse</artifactId>
<version>1.0.0</version>
</dependency>

Usar a biblioteca para chamadas síncronas é simples e direto:

@RunWith(HttpJUnitRunner.class)
public class RestFuseTest {
@Rule
public Destination destination = new Destination("http://example.com" );

@Context
private Response response; // será injetado depois de cada chamada
@HttpTest(method = Method.GET, path = "/reloadLocalConfiguration" )
public void checkRestfuseOnlineStatus() {
assertOk(response );
String answerBody = response.getBody(String.class);
assertEquals("Expected correct response","done",answerBody);
}
}

O teste acima chama um endereço HTTP de maneira síncrona e então valida se há uma resposta textual (text/plain) contendo a string “done”. Note que a primeira asserção, assertOk, é do Restfuse; ela verifica se o status da resposta HTTP foi 200 OK. A segunda asserção, assertEquals, verifica a igualdade como no JUnit. Embora esteja se supondo que o endereço HTTP vai retornar um texto puro, poderia também ser processado conteúdo em JSON/XML ou de outro tipo, e executar os asserts de maneira estruturada.

O Restfuse também suporta chamadas assíncronas. Uma aplicação clássica disso se dá em operações de longa duração (como o upload de um arquivo extenso), em que o cliente monitora continuamente o servidor para identificar o status atual. No exemplo abaixo, é considerado um endereço do lado servidor que retorna um número entre 0 e 100 e mostra o progresso de alguma operação:

@RunWith( HttpJUnitRunner.class )
public class PollTest1 {

@Rule
public Destination destination = new Destination( "http://example.com" );

@Context
private Response response;

@Context
private PollState pollState;

@HttpTest( method = Method.GET, path = "/progressStatus" )
@Poll( times = 5, interval = 500 )
public void testAsynchronousService() {
if(pollState.getTimes() == 5)
{
String answerBody = response.getBody(String.class);
assertEquals("Expected last response","100",answerBody);
}
}
}

O teste acima chama o mesmo endereço cinco vezes (com um intervalo definido), mas somente a última chamada verifica a resposta HTTP.

Uma característica interessante da interface PollState é a manutenção das respostas anteriores. Isto permite aos asserts sejam feitos sobre o histórico das chamadas:

@RunWith( HttpJUnitRunner.class )
public class PollTest2 {

@Rule
public Destination destination = new Destination( "http://example.com" );

@Context
private Response response;

@Context
private PollState pollState;

@HttpTest( method = Method.GET, path = "/progressStatus" )
@Poll( times = 5, interval = 500 )
public void testAsynchronousService() {
int currentRun = pollState.getTimes();
if(currentRun > 1)
{
String previousProgress = pollState.getResponse(currentRun - 1).getBody(String.class);
String presentProgress = response.getBody(String.class);
assertTrue("Expected some progress",Integer.parseInt(presentProgress) > Integer.parseInt(presentProgress)); //Just for illustration purposes
}
}
}
}

O teste acima verifica se cada resposta tem número superior à resposta anterior. O Restfuse tem uma dependência com o servidor HTTP Jetty e suporta serviços assíncronos que seguem o modelo de Web Hooks. Ao invés de enviar várias requisições ao servidor para verificar o estado de um processo, o cliente cliente faz uma chamada uma única vez e então aguarda por uma resposta iniciada pelo servidor em uma conexão diferente. Aqui está um exemplo usando Restfuse:

 
@RunWith( HttpJUnitRunner.class )
public class RestfuseCalbackTest {

@Rule
public Destination destination = new Destination( "http://example.com" );

@Context
private Response response;

private class TestCallbackResource extends DefaultCallbackResource {

@Override
public Response post( Request request ) {
assertTrue("Expected a quote response", request.getBody(String.class).startsWith("quote:") );
return super.post( request );
}
}

@HttpTest( method = Method.GET, path = "/requestQuote" )
@Callback( port = 9090, path = "/asynchron", resource = TestCallbackResource.class, timeout = 10000 )
public void testMethod() {
assertAccepted( response );
}
}

Este último exemplo conecta-se ao requestQuote e monitora a porta 9090 do cliente. Durante até dez segundos, ele espera uma resposta textual, começando com “quote:”

Para mais informações sobre o Restfuse, visite a wiki do projeto e seu Javadocs. O código-fonte esta hospedado no GitHub.

Fonte: Kostis Kapelonis , traduzido por Jefferson Prestes /InfoQ

Google App Engine 1.6.0: Graduação oficial e mais novidades

Após três anos e meio do lançamento da plataforma, o Google AppEngine deixa de ser um produto ‘preview’ e passa a ser completamente suportado pelo Google. O crescimento da plataforma neste tempo foi excepcional. Estatísticas atuais dão conta de mais de 100 bilhões de requisições por mês, 300 mil aplicações em execução e acima de 100 mil novos desenvolvedores adicionados mensalmente. Ficam claros, portanto, o sucesso e a necessidade de investimentos a longo prazo no GAE.

Com a nova versão 1.6.0, oficialmente será adotado o novo modelo de cobrança, conforme anunciado em maio; também foram publicados os documentos termos de serviço e política de uso, e há uma SLA de 99.95%.

E a nova versão traz um conjunto de novas funcionalidades:

  • Min Idle Instances: Agora você pode ajustar o número mínimo de instâncias da sua aplicação que ficarão em execução(de 1 a 100).
  • Max Pending Latency: Aplicações que necessitam de menor latência no acesso, agora podem configurar por quanto tempo uma requisição irá aguardar para ser atendida antes de iniciar uma nova instância da aplicação.
  • Python 2.7: Agora o SDK suporta também esta versão do Python; assim se pode testar aplicações localmente contra a versão 2.7, antes de publicá-las em produção.
  • Map Reduce (Python): Foi liberada uma versão experimental de um framework de Map Reduce, que inclui as fases Map, Shuffle e Reduce
  • Memcache API (Java): A API de memcache agora suporta chamadas assíncronas também para a plataforma Java.
  • Datastore Callback (Java): Pode-se agora especificar ações a serem executadas antes e depois das operações de put e delete no Datastore.
  • Blobstore API: Não será mais necessário habilitar a cobrança de sua aplicação para utilizar a API do Blobstore

Todas as funcionalidades e correções podem ser acompanhadas para ambas as plataformas nas notas da versão, para Python e Java.

Fonte: Rafael Nunes/InfoQ