Java EE 6: A Community Update
Reza Rahman
Autor, EJB 3 in Action
Expert Group Member, Java EE 6 e EJB 3.1
Fundador, Cognicellence
Java EE 6: Expandindo
Horizontes
>
Java EE 5
>
Facilidade de uso, annotations, liberdade do XML, expansão da API
>
EJB 3.0, JPA 1.0, JSF 1.0, JAX-WS 2.0
>
A queda dos EJB 2.x Entity Beans
>
Java EE 6
>
Podando: Uma maturidade saudável
>
Profiles: Um tamanho não serve para tudo
>
Estensibilidade: Facilitando para soluções não padronizadas
>
Inovação: Novas APIs, novas features, mais facilidade de uso
>
WebBeans, JSF 2.0, EJB 3.1, JPA 2.0, Bean Validation, Servlet 3.0,
JAX-RS
>
Participação do SpringSource em alguns grupos JSR, incluindo Java EE 6
(JSR 317), do qual Rod Johnson é um membro
Podando
>
Um primeiro passo importante no ciclo de vida de um
plataforma madura
>
A meta é “deprecar” APIs que estão obsoletas ou que
sofreram substituição
>
Candidatos à poda:
>
JAX-RPC: Substituída pela popular API JAX-WS
>
EJB 2.x Entity Beans CMP: Descartada em favor da JPA
>
APIs serão consideradas opcionais, e posteriormente
removidas
Profiles
>
Sub-conjuntos específicos das APIs Java EE direcionados
para ambientes específicos
>
Cada Profile é completamente integrado, simplesmente
funciona, sem customizações, embora integração com recursos
adicionais seja possível
>
Facilita a criação de servidores de aplicação modulares e
lightweight compatíveis com Java EE
>
Apenas um Profile, o “Web Profile” foi inicialmente planejado
>
Porém, já existe amplo suporte a dois Profiles direcionados
para desenvolvimento web, um “minimal” e um “intermediate”
>
É necessário seu feedback sobre como estes profiles
Profiles Sugeridos
JavaMail 1.4 JMS 1.1 JPA 2.0 JAX-RS 1.0 JAX-WS 2.2 JTA 1.1 EJB 3.1 WebBeans 1.0 JSF 2.0 EL 1.2 JSTL 1.2 JSP 2.2 Servlet 3.0 Full Profile Intermediate Profile Minimal Profile APIExtensibility
>
Se encontra em um estágio muito preliminar
>
Extensibility e Profiles funcionam integrados
>
Profiles, particularmente o Web Profile, tornam possível estender a
plataforma pela integração de APIs não padronizadas sem um risco sério de
perda de compatibilidade, ou de fragmentação
>
Injeção de dependência transparente e anexação de interceptadores,
ajustadas com fornecedores terceiros, podem facilitar a integração de
tecnologias não padronizadas sem complicar para os desenvolvedores
>
Pode ser implementada de forma tão simples quanto acrescentar um JAR e
aplicar annotations em classes/interfaces
>
APIs de provedores de serviços Java EE (SPIs) são um mecanismo de
extensão existente, que pode ser impulsionado também
Exemplo de
Java EE Extensibility
@Statelesspublic class PlaceBidBean implements PlaceBid {
@SqlMapClientBuilder(configuration=“sql-map-config.xml”) private SqlMapClient sqlMapClient;
public void placeBid(Bid bid) {
sqlMapClient.insert("insertBid", bid); }
}
@Local
public interface PlaceBid {
public void placeBid (Bid bid); }
Maiores Mudanças
na API Java EE 6
>
WebBeans 1.0
>
Integração JSF/EJB 3/JPA
>
Java Server Faces (JSF) 2.0
>
Facilidade de uso, adoção da tecnologia, novas features
>
Enterprise Java Beans (EJB) 3.1
>
Facilidade de uso, novas features
>
Java Persistence API (JPA) 2.0
>
Novas features
>
Bean Validation
>
Definição unificada de constraints de dados por aplicação
>
Servlet 3.0
>
Facilidade de uso, novas features
>
Java API for RESTful Web Services (JAX-RS) 1.0
>
API para desenvolvimento de web services REST, em adição ao
suporte a SOAP do JAX-WS
WebBeans 1.0 (JSR 299)
>
Unifica modelos de programação JSF, JPA e EJB 3
>
desenvolvimento web stateful, contextual
>
Conversações
>
Injeção de dependência robusta, type-safe
>
Melhorias no modelo de interceptadores
JSF Page com WebBeans
<h:form> <table> <tr> <td>Bidder</td> <td><h:inputText value="#{bid.bidder}"/></td> </tr> <tr> <td>Item</td> <td><h:inputText value="#{bid.item}"/></td> </tr> <tr> <td>Bid Amount</td> <td><h:inputText value="#{bid.bidPrice}"/></td> </tr> </table><h:commandButton type="submit" value="Add Bid" action="#{placeBid.addBid}"/>
JPA Entity WebBeans
Component
@Entity @Component @Named("bid") @Table(name=“BIDS”) public class Bid {@Id
@GeneratedValue
@Column(name=“BID_ID”) public Long bidId;
public String bidder; public String item;
@Column(name=“BID_PRICE”) public Double bidPrice; }
EJB 3.1 Session Bean
WebBeans Component
@Stateful @RequestScoped @Component @Named("placeBid")public class PlaceBidBean { @PersistenceContext
private EntityManager entityManager;
@Current
private Bid bid;
public void addBid() {
entityManager.persist(bid); }
Java Server Faces 2.0
(JSR 314)
>
Componentes customizados simplificados
>
Ótimo suporte a Facelets
>
Ótimo suporte a Ajax
>
Configurações por Annotations
>
Convenção sobre configuração
>
faces-config.xml opcional
>
Estágios de desenvolvimento estilo RAILS_ENV
>
Resources
>
Data Validation (JSR 303)
JSF Project Stages
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> javax.faces.application.ProjectStage • Production • Development • UnitTest • SystemTest • ExtensionJSF Resources
Resource path:
[/META-INF]/resources/
[localePrefix/][libraryName/][libraryVersion/] resourceName[/resourceVersion]
Resource resource = FacesContext.getApplication() .getResourceHandler()
.createResource(resourceName[,libraryName]);
#{resource['<libraryName>:<resourceName>']}
@ResourceDependency(name="style.css",library=“actionbazaar") public class HeaderTabs extends UIComponentBase {
... }
Enterprise Java Beans 3.1
(JSR 318)
>
Interfaces opcionais para Session Bean
>
Singleton Beans com controle de concorrência
>
Timers declarativos e progrmáticos, estilo Cron
>
Invocações Assíncronas
>
Empacotamento WAR simplificado
>
Suporte Java SE
>
Nomes Globais JNDI Global JNDI padronizados
Timers Declarativos
Estilo Cron
@Stateless
public class NewsLetterGeneratorBean { @Resource
private Session mailSession;
@Schedule(second="0", minute="0", hour="0",
dayOfMonth="1", month="*", year="*") public void generateMonthlyNewsLetter() {
... }
Session Bean Assíncrono
@Statelesspublic class OrderBillingBean { ...
@Asynchronous
public Future<BillingStatus> billOrder(Order order) {
try {
bill(order);
return new AsyncResult<BillingStatus>( BillingStatus.COMPLETE);
} catch (BillingException be) {
return new AsyncResult<BilllingStatus>( BillingStatus.BILLING_FAILED);
} }
... }
Invocação Cliente
Assíncrona
@EJB
private OrderBillingBean orderBilling; ...
Order order = new Order(); ...
Future<BillingStatus> future = orderBilling.billOrder(order); ...
BillingStatus status = future.get(); ...
if (status == BillingStatus.COMPLETE) { notifyBillingSuccess(order);
} else if (status == BillingStatus.BILLING_FAILED) { notifyBillingFailure(order);
Java Persistence API 2.0
(JSR 317)
>
Melhorias no mapeamento Objeto-Relacional
>
Collections, maps e listas ordenadas
>
Mapeamento one-to-many unidirecional
>
Tabelas de junção para one-to-one, many-to-one
>
Criteria API
>
Bean validation (JSR 303)
>
Adições na API EntityManager e na API de Query
>
Locking, loading Entity, clearing Entity, max results, first
result
>
Cache de segundo nível
>
Mais propriedades e hints padronizados
Mapeando Collections
@Entity@Table(name=“USERS”) public class User {
@Id
@GeneratedValue
@Column(name=“USER_ID”) public long userId;
public String userName; @Column(name=“BIRTH_DATE”) public Date birthDate;
...
@ElementCollection
@CollectionTable(name=”ALIASES”) @Column(name=”ALIAS”)
Relacionamento
One-to-Many Unidirecional
@Entitypublic class User {
@Id @GeneratedValue public long id;
public String userName; ...
@OneToMany
@JoinColumn(name=”USER_ID”) public Set<Phone> phones; }
@Entity
public class Phone { @Id @GeneratedValue public long id;
public String type; public String number; ...
Bean Validation (JSR 303)
>
Especifique constraints apenas uma vez através das camadas
de aplicação
>
Constraint
>
Restrição em um bean, campo ou propriedade
>
Not null, between 10 and 45, email válido, etc
>
Avaliadas automaticamente por um framework
>
Útil em outras APIs Java SE/Java EE
>
JSF 2.0
>
JPA 2.0
JPA Entity
with Bean Validation
@Entity @Table(name=“BIDS”) public class Bid {@Id @GeneratedValue @Column(name=“BID_ID”) public Long bidId;
@NotNull
@Length(max=30)
public String bidder;
@NotNull
@Length(max=200) public String item;
@Column(name=“BID_PRICE”) @NotNull
@Min(value=0.0, message=“price negative”) public Double bidPrice;
Servlet 3.0 (JSR 315)
>
Annotations desde o começo
>
web.xml opcional
>
Defaults inteligentes
>
Fragmentos web.xml modulares em jars
>
Adição programática de Servlets, Filters and
Listeners através do ServletContext
>
Suporte a processamento assíncrono em Servlets
Exemplo
Servlet Annotations
@Servlet(name=“PlaceBidServlet”
urlMapping={“/bid”, “/place-bid”}) public class PlaceBidServlet {
@EJB
private PlaceBid placeBid;
@GET
public void onGet(HttpServletRequest request, HttpServletResponse response) {
Bid bid = new Bid(); ...
placeBid.placeBid(bid); ...
} }
Adição Programática
de Servlet
@ServletContextListener
public class ActionBazaarListener { public void contextInitialized(
ServletContextEvent event) {
ServletContext context = event.getServletContext(); context.addServlet(
“PlaceBidServlet", “Place bid servlet",
“actionBazaar.PlaceBidServlet", null, -1); context.addServletMapping( “PlaceBidServlet", new String[]{"/place-bid"}); } }
Java API para RESTful
Web Services (JSR 311)
>
Web services via REST, em vez de SOAP
>
Contrapartida REST do JAX-WS
>
Liberação da codificação de baixo nível – você pode
se focar na lógica central
>
Annotations desde o começo
Session Bean com JAX-RS
@Stateless@Path("/webservices")
public class PlaceBidBean { @PersistenceContext
private EntityManager entityManager;
@PUT
@Path("/bid/{bidder}") public void placeBid(
@PathParam(“bidder") String bidder, @QueryParam(“item") String item, @QueryParam(“bid_price") Double bidPrice) { entityManager.persist(