Professional Documents
Culture Documents
05.
11.
15.
22.
29.
33.
36.
38.
42.
49.
51.
InfoQ Brasil
CONTEDO DETALHADO
Onde foi parar o PermGen do Java? . . . . . . . . . . . . . . . . . . . . . 5
1. StampedLock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2. Adicionadores concorrentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3. Ordenao Paralela . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
4. Migrando para nova API de data . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5. Controle de processos do sistema operacional . . . . . . . . . . 13
6. Operaes numricas precisas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
7. Gerao segura de nmeros aleatrios . . . . . . . . . . . . . . . . . . . 13
8. Referncias opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
16
17
18
19
20
21
24
25
25
26
26
26
28
Primeiros anncios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Outras novidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Data final quase definida, com alguns sacrifcios . . . . . . . . . 52
APRESENTAO
InfoQ Brasil
ONDE
FOI
PARAR
O
PERMGEN
DO
JAVA?
por Monica Beckwith, traduzido por Rafael Brito
Com a introduo do JDK8, no existe mais o espao de PermGen. Os metadados que antes eram armazenados no PermGen no desapareceram,
mas foram movidos para a memria nativa, em uma rea conhecida como Metaspace. Conhea neste artigo maiores detalhes desta importante
mudana da plataforma Java.
Adeus PermGen.
Ol Metaspace!
Com o surgimento do JDK8, PermGen no existe mais. As informaes
de metadados no desapareceram, s
que o espao em que eram mantidos
no mais contguo ao heap. Agora, o
metadado foi movido para a memria
nativa, em uma rea conhecida como
Metaspace.
InfoQ Brasil
Otimizao e Metaspace
Como mencionado anteriormente, uma VM Metaspace gerenciar
o crescimento do Metaspace, mas
talvez surgiro cenrios em que se
deseje limitar o crescimento atravs
do uso da configurao explcita do
-XX:MaxMetaspaceSize via linha de
comando. Por padro, o -XX:MaxMetaspaceSize no possui um limite,
jmap -clstats <PID>: exibe as estatsticas de um classloader. (Isto agora assume o lugar do -permstat, que era usado
para exibir estatsticas do classloader de JVMs anteriores ao JDK8). Segue um exemplo de sada no momento de
execuo do benchmark da DaCapo Avrora:
1222734
0
0
0
0
1
1471
116 316053
538 773854
2314112
null
live
<internal>
0x000000074004a708
dead
null
dead
0x00000007400752f8
dead
0x000000074004a760
dead
0x000000074004a708
dead
N/A
alive=1, dead=5
java/util/ResourceBundle$RBClassLoader@0x00000007c0053e20
sun/misc/Launcher$ExtClassLoader@0x00000007c002d248
sun/reflect/DelegatingClassLoader@0x00000007c0009870
sun/misc/Launcher$AppClassLoader@0x00000007c0038190
org/dacapo/harness/DacapoClassLoader@0x00000007c00638b0
N/A
jstat -gc <LVMID>: agora exibe informaes do Metaspace, como demonstra o exemplo a seguir:
$jstat-gc <LVMID>
SOC
SIC
SOU S1U EC
EU
OC
OU
MC
UM
CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 0.0 96.0 6144.0 2456.3 129536.0 2228.3 7296.0 6550.3 896.0 787.0 229 0.211 33 0.347 0.558
Where, MC: Current Metaspace Capacity (KB); UM: Metaspace Utilization (KB)
jcmd <PID> GC.class_stats: Este um novo comando de diagnstico que permite ao usurio final se conectar
JVM em execuo, e obter um histograma detalhado dos metadados das classes Java.
Nota: Com o JDK8 build 13, voc deve iniciar o Java com -XX:+UnlockDiagnosticVMOptions.
$ jcmd <PID> help GC.class_stats
9522:
GC.class_stats
Provide statistics about Java class meta data. Requires -XX:+UnlockDiagnosticVMOptions.
Impact: High: Depends on Java heap size and content.
Syntax : GC.class_stats [options] [<columns>]
Arguments:
columns : [optional] Comma-separated list of all the columns to show. If not specified, the following columns are shown:
InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecodes,MethodAll,ROAll,RWAll,Total (STRING, no default value)
Options: (options must be specified using the <key> or <key>=<value> syntax)
-all : [optional] Show all columns (BOOLEAN, false)
-csv : [optional] Print in CSV (comma-separated values) format for spreadsheets (BOOLEAN, false)
-help : [optional] Show meaning of all the columns (BOOLEAN, false)
InfoQ Brasil
Um exemplo de sada:
$ jcmd <PID> GC.class_stats
7140:
Index Super InstBytes KlassBytes annotations
ROAll
RWAll
Total ClassName
-1
426416
480
24
576
600 [C
-1
290136
480
40
576
616 [Lavro-
576
600 [B
ra.arch.legacy.LegacyInstr;
-1
269840
480
43
137856
648
19248
129
43
136968
624
8760
94
43
75872
1296
560
24
4886
25288
16368
30568
46936 java.lang.Class
4570
33616
12072
32000
44072 java.lang.String
149
1400
880
2680
1480
528
2488
3016 avrora.sim.util.
31
440
280
1536
1816 avrora.
24
576
600 [Ljava.
3560 java.
util.HashMap$Node
836
57408
608
720
69
MulticastFSMProbe
43
55488
504
53712
480
680
sim.FiniteStateMachine$State
-1
10
-1
49424
480
11
-1
49248
480
24
576
600 [I
24
576
600 [Lavrora.sim.pla-
32
576
608 [Ljava.util.HashMa-
1216
432
2080
2512 avrora.sim.AtmelIn-
lang.Object;
tform.ExternalFlash$Page;
12
-1
24400
480
394
21408
520
600
33
19800
672
968
71
1240
664
2472
3136 avrora.arch.legacy.
152
104
1024
1128 sun.util.resources.
p$Node;
13
terpreter$IORegBehavior
14
727
LegacyInstr$MOVW
<snipped>
<snipped>
1299
1300
608
256
608
1744
10
290
1808
1176
3208
4384 sun.util.resources.
616
2184
12
395
2200
1480
3800
5280 sun.util.resources.
LocaleNamesBundle
1300
1098
OpenListResourceBundle
1301
1098
ParallelListResourceBundle
2244312
794288
34.0%
2024 2260976
12.1%
0.0%
12801
34.3%
561882
ROAll
47.6%
28.9%
RWAll
Total ClassName
71.1%
100.0%
Questes Atuais
Como mencionado anteriormente, a VM Metaspace emprega um alocador de segmentos. H mltiplos tamanhos de
segmentos, dependendo do tipo de classloader. Alm disso, os itens de classe por si mesmos no possuem um tamanho
fixo, por isso h chances de que os segmentos livres no sejam do mesmo tamanho que os segmentos necessrios para os
itens de classe. Tudo isso pode gerar uma fragmentao. A VM Metaspace (ainda) no utiliza compactao, consequentemente a fragmentao uma das principais preocupaes neste momento.
Sobre a Autora
Acompanhe Monica no Twitter:
@mon_beck.
Monica Beckwith uma engenheira de desempenho
trabalhando na indstria de hardware por mais de uma
dcada. Seu mais atual ttulo Arquiteta de Desempenho
na Servergy - uma startup que oferece uma nova classe de
servidores Cleantech hiper-eficientes . Antes da Servergy,
Monica trabalhou na Oracle / Sun e AMD otimizando a JVM
para sistemas de classe de servidor. Monica foi eleita uma
palestrante estrela do rock no JavaOne 2013.
10 InfoQ Brasil
8 FUNCIONALIDADES POUCO
CONHECIDAS DO JAVA 8
por Tal Weiss, traduzido por Vitor Puente
Este artigo visa apresentar algumas das novas APIs do Java 8 que no esto sendo to comentadas, mas que tornaram o Java melhor de vrias
maneiras.
1. StampedLock
O cdigo multithreaded tem sido um desafio para os
desenvolvedores. Com o tempo, algumas construes
complexas foram adicionadas s bibliotecas Java visando
auxiliar o desenvolvedor com cdigos multithreaded, e
seu acesso a recursos compartilhados. Um exemplo o
ReadWriteLock, que permite ao desenvolvedor dividir o
cdigo em sees que precisam ser mutuamente exclusivas (writers) e sees que no precisam (readers).
Na teoria parece timo. Porm um problema com ReadWriteLock que a aplicao pode ficar muito lenta, s
vezes at dez vezes mais lenta. O Java 8 introduziu um
novo bloqueio ReadWrite, chamado StampedLock. A boa
notcia que o StampedLock muito rpido. A m notcia
que mais complicado de usar e envolve mais estados. O
StampedLock no reentrante, o que significa que uma
2. Adicionadores concorrentes
3. Ordenao Paralela
Assim como os Adicionadores aceleram os contadores, o Java 8 traz uma maneira concisa de acelerar a
ordenao. E de uma maneira muito simples, em vez
de realizar a ordenao desta maneira:
Array.sort(myArray);
Agora pode utilizar o mtodo pronto para a paralelizao:
Arrays.parallelSort(myArray);
Isso automaticamente dividir a sua coleo em
partes, as quais sero ordenadas atravs de um nmero de cores e ento agrupadas novamente. H
uma ressalva, quando o mtodo de ordenao paralela chamado em ambientes com multi-thread elevado, tal como um web container sobrecarregado, os
benefcios iniciais so reduzidos, at mais de 90%, devido ao aumento de trocas de contexto da CPU.
12 InfoQ Brasil
O nico aspecto negativo disso que a responsabilidade em identificar como o cdigo pode ter problemas com overflow fica por conta de quem est desenvolvendo. No h soluo mgica, porm isso j
melhor que nada.
8. Referncias opcionais
As excees do tipo NullPointerException so bem
antigas. Porm ainda hoje esto presentes no dia-a-dia de uma equipe de desenvolvimento, no importa
quo experiente a equipe seja. Para ajudar com este
Sobre o Autor
Tal Weiss o CEO da Takipi. Weiss vem desenhando aplicaes escalveis, de tempo real em Java e C++ nos ltimos 15 anos. Ele ainda gosta de
analisar um bom bug atravs da instrumentao de cdigo Java. Em seu
tempo livre Weiss toca Jazz na bateria.
14 InfoQ Brasil
Supondo que a classe Connection tenha um mtodo send(File), possvel executar esse mtodo passando como parmetro qualquer uma das duas variveis do tipo File:
connection.send(file);
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
connection.send(encryptedFile);
16 InfoQ Brasil
A intuio por trs dessa limitao que o compilador no tem conhecimento sobre a relao entre
tipos anotados e no anotados ou entre tipos com diferentes anotaes.
Repare que h uma anotao @Encrypted na varivel encryptedFile coincidindo com o parmetro
file na assinatura do mtodo send, mas perceba que
no h nada nesse mtodo que corresponda anotao @Open na varivel connection. Quando feita a
chamada connection.send(...), a varivel connection
conhecida como uma receptora (receiver) do mtodo
(o termo receiver uma analogia clssica troca de
mensagens entre objetos na teoria de Orientao a
Objetos). O Java 8 introduz uma nova sintaxe para as
declaraes de mtodos de forma que anotaes de
tipos possam ser escritas em um receptor no mtodo.
void send(@Open Connection this, @Encrypted File file)
Observe nesse ltimo exemplo a sintaxe para definir o mtodo send. O primeiro parmetro na verdade
faz referncia instncia receptora, por isso o nome
desse parmetro this.
Como citado anteriormente, as anotaes no afetam a execuo do programa. Assim, um mtodo
declarado com a nova sintaxe do parmetro receptor
tem o mesmo comportamento quele utilizando a
sintaxe tradicional. Na prtica, o uso da nova sintaxe
s permite que anotaes de tipos sejam escritas no
tipo do receptor.
Uma explicao completa da sintaxe de anotaes
de tipos, incluindo sintaxe para arrays multi-dimensionais, pode ser encontrada na especificao JSR
(Java Specification Request) 308.
compilado, executado e causar erro durante a execuo. O compilador Java no faz verificaes de anotaes definidas pelo usurio. Apesar disso, a plataforma Java expe duas APIs que auxiliam nessa tarefa,
uma para a criao de plugins para o Compilador e
outra para o processamento de anotaes, de forma
que terceiros possam construir seus prprios mtodos de anlise.
Nos exemplos anteriores, as anotaes tinham a
funo de qualificar os valores que as variveis poderiam conter. Porm, podem ser pensadas outras
formas de qualificar o tipo File: @Open, @Localized,
@NonNull, etc; tambm pode ser pensada na aplicao dessas anotaes qualificando outros tipos, como
por exemplo: @Encrypted String. Devido ao fato das
anotaes serem independentes do sistema de tipos
do Java, os conceitos expressos atravs delas podem
ser reutilizadas de muitas formas.
Mas como essas anotaes poderiam ser automaticamente verificadas? Intuitivamente, algumas anotaes so subtipos de outras anotaes e suas aplicaes podem ser verificadas em relao aos tipos.
Considere a vulnerabilidade ao ataque de Injeo de
SQL, causado pela execuo de sentenas SQL modificadas maliciosamente pelo usurio. Pode-se pensar
em um tipo de dados classificado como @MaybeTainted, indicando que o dado pode ter sido adulterado,
ou @Untainted, indicando que o dado est garantidamente livre de adulterao, pois no foi diretamente
informado pelo usurio.
@MaybeTainted String userInput;
@Untainted String dbQuery;
Nesse exemplo, a primeira linha no contm nenhum problema, pois userInput supe que o valor
atribudo pode ter sido adulterado, mesmo que esse
no seja o caso. Por outro lado, essa tipagem revela
um erro na segunda linha, pois est atribuindo um
valor que pode ter sido adulterado a uma varivel
que contm essa restrio.
O framework Checker
O Checker um framework que faz verificaes de
anotaes em Java. Lanado em 2007, esse framework
um projeto de cdigo aberto encabeado pelo sub-lider da especificao JSR 308, professor Michael Ernst.
O Checker vem com um conjunto padro de anotaes e verificadores de falhas, tais como: NullPointerException, incompatibilidade no uso de unidades de
medidas, vulnerabilidades de segurana, problemas
de concorrncia, entre outros. Por ser um verificador
que utiliza mecanismos formais de verificao de tipagem baseado em lgica, ele capaz de reconhecer
falhas potenciais que verificadores baseados em heursticas no detectam. O framework usa uma API de
compilador que detecta as falhas durante a compilao. Outra caracterstica que ele estensvel, o prprio desenvolvedor pode criar rapidamente os seus
verificadores de anotaes para detectar problemas
especficos da aplicao em questo.
A meta do Checker detectar falhas sem que o
desenvolvedor tenha que escrever muitas anotaes.
Isso feito principalmente atravs de duas funcionalidades apelidadas como: padres mais inteligente e
controle de fluxo sensveis. Por exemplo, durante o
processo de verificao de falhas por ponteiros nulos, o verificador assume que os parmetros de um
mtodo no so nulos por padro. O verificador pode
tambm utilizar condicionais para determinar quando uma atribuio de nulo uma expresso vlida.
void nullSafe(Object nonNullByDefault, @Nullable Object
mightBeNull){
nonNullByDefault.hashCode(); // OK, devido ao padro
mightBeNull.hashCode(); // Falha!
if (mightBeNull != null){
mightBeBull.hashCode(); // OK, devido ao padro
}
}
18 InfoQ Brasil
Na prtica, os padres e o controle de fluxo sensveis significam que o desenvolvedor raramente ter
que escrever anotaes no corpo dos mtodos, pois o
verificador capaz de inferir e verificar as anotaes
automaticamente. Mantendo a semntica das anotaes fora do compilador oficial do Java garante que
ferramentas de terceiros e os prprios desenvolvedores tomem as suas decises. Isso permite que a verificao de erros possa ser personalizada conforme as
necessidades de cada projeto.
A habilidade de definir suas prprias anotaes
tambm permite que seja considerada a verificao
de subtipos especficos do domnio de negcio. Por
exemplo, em um sistema financeiro, as taxas de juros usam frequentemente porcentagens enquanto a
diferena entre taxas utiliza ponto base (1/100 de 1%).
Com um framework de verificao de unidades podem ser definidas as anotaes @Percent e @BasisPoint para garantir que no h confuso no uso dos
dois tipos:
BigDecimal pct = returnsPct(...); // anotado para devolver @Percent
requiresBps(pct); // erro: requer @BasisPoints
No exemplo apresentado, devido ao fato do Checker ser sensvel ao fluxo de controle, sabe-se que
pct um @Percent BigDecimal quando feita a chamada para requiresBps(pct) com base em dois fatos:
returnsPct(...) anotado para devolver um @Percent
BigDecimal e pct no foi novamente atribudo antes
de chamar requireBps(...). Frequentemente, desenvolvedores usam convenes de nomes para tentar prevenir esses tipos de falha. O que o Checker faz dar
ao desenvolvedor a garantia de que essas falhas no
existam, mesmo que o cdigo mude e evolua.
O Checker j foi executado em milhes de linhas
de cdigo, apontando centenas de falhas, mesmo em
cdigo bem testado. Um dos exemplos mais interessante aconteceu ao execut-lo com a biblioteca muito
utilizada Google Collections, agora Google Guava,
que revelou um possvel NullPointerException que
no tinha sido detectado aps vrios testes e nem
aps utilizar ferramentas heursticas de anlise esttica de falhas.
Resultados assim foram obtidos sem fazer muitas
alteraes no cdigo existente. Na prtica, verificar
uma propriedade com o Checker requer somente 2
ou 3 anotaes para uma centena de linhas de cdigo.
Para aqueles que utilizam o Java 6 ou 7, tambm
possvel usar o Checker para melhorar a qualidade
do cdigo. As anotaes podem ser escritas em comentrios, tal como:
POSSUEM SUPORTE
Checker Framework
Eclipse
IntelliJ IDEA
NO POSSUEM SUPORTE
PMD
Coverity
Check Style
Find Bugs
Novamente, as anotaes de tipo do maior controle ao se fazer metraprogramao com AOP. A Injeo de Dependncia uma histria similar. Com o
Spring 4, finalmente possvel usar generics como
qualificador:
@Autowired private Store<Product> s1;
@Autowired private Store<Service> s2;
A estrada frente
Como apresentado, as anotaes de tipo podem
ser usadas tanto para detectar como prevenir erros
em programas e tambm para aumentar a produtividade. Contudo, o potencial real das anotaes de
tipos est em combinar a verificao de erros e a metaprogramao para dar suporte aos novos paradigmas de desenvolvimento.
A ideia bsica construir ambientes de execuo
e bibliotecas que alavanquem a abordagem de criar
programas automaticamente mais eficientes, paralelos ou seguros e que faam com que os desenvolvedores usem as anotaes corretamente.
20 InfoQ Brasil
Concluso
No Java 8, as anotaes podem ser usadas em qualquer tipo, incrementando a capacidade de escrever anotaes em declaraes. As anotaes por s prprias no afetam o comportamento do programa. Contudo, utilizando ferramentas como o Checker, possvel utiliz-las para verificar automaticamente a ausncia de falhas e
aumentar a produtividade com metaprogramao. Enquanto ainda levar algum tempo para que as ferramentas
existentes obtenham total vantagem das anotaes de tipos, agora hora de comear a explorar como as anotaes de tipos podem melhorar tanto a qualidade do software desenvolvido quanto a produtividade.
Sobre o Autor
Todd Schiller diretor da FinLingua, uma companhia de consultoria
e desenvolvimento de software para a rea financeira. A prtica de
consultoria da FinLingua ajuda equipes de desenvolvimento a adotar
uma linguagem especfica de domnio, metraprogramao e tcnicas
de anlise de programas. Todd um membro ativo da comunidade de
pesquisa em engenharia de software; sua pesquisa em especificao e
verificao tem sido apresentada nas principais conferncias internacionais, incluindo ICSE e OOPSLA.
O artigo destaca os pontos principais da palestra Lambdas & Streams que Simon Ritter apresentou no QCon London 2014. Ele explica o que so as
expresses Lambdas, interface funcional, referncia de mtodos, Streams, operaes de agregao e diversos exemplos
22 InfoQ Brasil
petitivo.
Neste problema, queremos encontrar a maior nota em
uma coleo de estudantes. Usamos um idioma comum
de iterao externa para percorrer e comparar cada elemento da coleo.
Mas h algumas desvantagens no cdigo. Em primeiro
lugar, a iterao externa significa que os desenvolvedores
so responsveis pela implementao (programao imperativa), e como usado um nico loop, definimos que
a execuo do cdigo ser de modo sequencial. Se quisermos otimiz-lo, no poderamos facilmente segmentar
em um conjunto de execuo de instrues em paralelo.
Em segundo lugar, a varivel highestScore mutvel
e no thread-safe. Ento, mesmo que quisssemos quebr-lo em mltiplas threads, precisaramos adicionar um
lock (bloqueio) para prevenir race conditions (condies
de concorrncia), que por sua vez podem introduzir problemas de desempenho.
Agora, se quisermos agir de modo mais inteligente,
podemos mudar um pouco mais a implementao em
direo ao estilo funcional utilizando uma classe interna
annima:
Nessa implementao, eliminamos o estado mutvel e passamos o trabalho da interao para a biblioteca. Estamos encadeando uma sequncia de chamadas de mtodos para aplicar a operao em uma
expresso Olhe para todos os meus estudantes e filtre apenas aqueles que se graduaram em 2011.
A classe interna annima implementa a interface
Predicate (ela contm um mtodo, aceita um parmetro e retorna um valor booleano) com o mtodo cha-
mado op, que simplesmente compara o ano de graduao do estudante com 2011 e retorna o resultado.
Enviaremos o resultado (todos os estudantes graduados em 2011) para o mtodo map, que usar outra classe interna annima para chamar um mtodo
da interface de mapeamento com seu nico mtodo
extract para extrair o dado que queremos (chamando o mtodo getScore). Ento passaremos esse resultado, que um conjunto de notas de todos estudantes
graduados em 2011, para o mtodo max, que enfim
entregar o maior valor a partir do conjunto de resultados.
Usando essa abordagem, tratamos toda a interao, filtro e acmulo com o uso da biblioteca, sem
precisar fazer isso de forma explcita. Isso no somente simplifica a implementao, como tambm elimina
o compartilhamento de estado, deixando mais fcil
pedir ao cdigo da biblioteca para decompor a implementao em diversas sub tarefas e aloc-lo em diferentes threads para serem executadas em paralelo.
Em muitos casos, tambm executamos uma avaliao
posterior, economizando ainda mais tempo.
Ento, uma abordagem que usa classe interna
annima rpida e thread-safe, mas atente-se para
as cores do cdigo fonte. Note que a quantidade em
azul maior do que em vermelho, indicando cdigo
repetitivo.
Ento, entram em cena as expresses lambda!
2011.
Note que no h um retorno explicito. Simplesmente dizemos Compare o ano de graduao com
2011 e o compilador deduz que destina-se a interface
Predicate (que tem um nico mtodo que necessita de
uma assinatura com um retorno do tipo booleano).
O mtodo map processado de forma similar, usando uma expresso lambda, passando um estudante S
como parmetro e mapeando (como um tradutor) seu
valor de retorno, que a nota (score) do estudante. O
mtodo map no deve ser confundido com o java.util.
Map que usa pares de chave-valor. O mtodo map da
classe Stream retorna uma nova instncia do Stream
contendo os resultados da operao aplicada para todos os elementos da Stream de entrada, produzindo,
parametrizados.
Ritter ampliou esse conceito apontando que uma
vez que uma lambda uma funo sem uma classe,
ento a palavra-chave this no se refere a prpria
lambda, mas sim a classe na qual foi declarada. Isso
distingue de uma classe interna annima, na qual
this refere-se a prpria classe interna.
til olhar para as decises de implementaes
que os designers da linguagem fizeram para desenvolver os lambdas.
Olhando para o Java como um todo, h muitas interfaces que possuem apenas um mtodo.
Vamos definir uma interface funcional como uma
interface com exatamente um mtodo abstrato, por
exemplo:
interface
interface
interface
interface
interface
Uma expresso Lambda permite definir uma interface funcional (novamente, um mtodo abstrato) que
24 InfoQ Brasil
Referncia de mtodos
A sintaxe da referncia de mtodo outra nova
funcionalidade da expresso lambda. um atalho
que permite reutilizar um mtodo basicamente como
uma expresso Lambda. Podemos fazer coisas como:
FileFilter x = f -> f.canRead();
Essa sintaxe diz para o programa criar um FileFilter que filtra os arquivos com base em uma propriedade comum nesse caso, se o arquivo pode ser lido.
Note que nesse exemplo, nunca mencionamos que f
um arquivo; o compilador infere atravs da assinatura do nico mtodo no FileFilter:
boolean accept(File pathname);
Podendo ser simplificado ainda mais usando a
nova notao do Java 8 ::.
FileFilter x = File::canRead;
Operaes de agregao
Operaes de negcios frequentemente envolvem
agregaes como: encontrar a soma, mximo, ou mdia de um conjunto de dados, ou grupo de alguma
coisa. At agora, tais operaes so normalmente executadas com loops de interao externa, como dissemos, nos restringindo das otimizaes e adicionando
boilerplate ao cdigo fonte.
As Streams do Java SE 8 tem como objetivo resolver estes problemas. Nas palavras de Ritter:
Factory<List<String>> f = ArrayList<String>::new;
como processar uma agregao. Ele no uma estrutura de dados. Na realidade uma maneira de tratar os
dados, mas define uma nova estrutura de dados, e in-
Evoluo da biblioteca
Ento, agora temos a opo de implementar o mtodo stream ou se preferir usar a implementao padro fornecida pelo Java.
Fontes de stream
H diversas formas de obter um Stream. Muitos
mtodos esto sendo adicionados a API de Collection
(usando a extenso de mtodos nas interfaces).
Atravs de uma List, Set, ou Map.Entry possvel
chamar um mtodo de Stream que retorna uma Stream com o contedo da coleo.
Um exemplo o mtodo stream(), ou parallelStream(), que internamente a biblioteca usa o framework
de fork/join para decompor as aes em diversas subtarefas.
H outras maneiras de obter um stream:
Fornecer um array para o mtodo stream() da
classe Arrays;
Chamar o mtodo Stream.of(), um mtodo esttico da classe Stream;
Chamar um dos novos mtodos estticos para
retornar um stream em particular, por exemplo:
IntStream.range(), fornecendo um ndice de
inicio e fim. Por exemplo, IntStream.range(1, 10)
gera um stream de 1 a 9 com incremento de 1
26 InfoQ Brasil
mapToInt(Transaction::getPrice). //Lazy
sum(); //Executa o pipeline
Inteface Iterable
Essa uma velha conhecida dos dias do Java 1.5, exceto que agora tem um mtodo forEach() que aceita
um Consumer, que aceita um simples argumento e
no retorna valor e produz um efeito colateral. Mas
continua sendo uma interao externa e a melhor forma de obter um lambda o mtodo map().
Exemplos:
Ritter conclui a apresentao com alguns exemplos
uteis, que esto listados a seguir com comentrios explicativos. (As linhas em negrito indicam o especial
uso demonstrado em cada exemplo).
mapToInt(String::length).
map(String::toUpperCase).
max().
collect(Collectors.toList());
uma optionalInt)
getAsInt();
lines().
collect(Collectors.toList());
// todas as linhas.
collect(Collectors.toList());
lines().
// Conta os elementos do stream de entrada.
count();
lines().
map(String::toLowerCase).
skip(2).
// letras minsculas.
sorted().
limit(2).
// Concatena as linhas.
collect(Collectors.toList());
collect(Collectors.joining());
Concluso
Simon Ritter conclui a apresentao declarando:
O Java precisa das expresses lambda para facilitar a vida do desenvolvedor. As expresses lambdas eram necessrias para a criao dos Streams e tambm para implementar a ideia de passagem de comportamento como a
passagem de valor. Tambm precisvamos ampliar as interfaces existentes, com o uso das extenses de mtodos do
Java SE 8, e que resolve o problema da retro compatibilidade. Isso permite fornecer a ideia de operaes em lote na
Collections e permite fazer coisas que so mais simples, e de um modo mais legvel. O Java SE 8 est basicamente
evoluindo a linguagem; evoluindo as bibliotecas de classes e tambm as maquinas virtuais ao mesmo tempo.
O Java 8 est disponvel para download e h um bom suporte a lambda em todos as principais IDEs. Sugiro
que todos os desenvolvedores Java faam o download e usem o Projeto Lambda.
Sobre o Autor
Simon Ritter o diretor do Evangelismo da tecnologia Java na
Oracle Corporation. Ritter trabalha com negcios de TI desde 1984
e bacharel de Cincia graduado em Fsica pela universidade de
Brunel no Reino Unido.
28 InfoQ Brasil
Tem sido falado que o Java 8 trouxe a Programao Funcional para o Java. Neste artigo, Ben Evans discute o que significa ser funcional. Olhando
a evoluo do Java em particular o seu sistema de tipos, possvel ver como os novos recursos do Java 8, especialmente as expresses lambda,
mudam o panorama e fornecem alguns benefcios fundamentais para o estilo de programao funcional.
(scan-log-for-http-entries log-file)))
Programao funcional em
linguagens no funcionais
A caracterstica de uma linguagem ser ou no funcional no uma
condio binria ao invs disto, as
linguagens existem em um espectro.
Em um dos extremos desta espectro
esto as linguagens que basicamente
foram a programao funcional, frequentemente proibindo estruturas de
dados mutveis. Clojure um exemplo de linguagem que no permite a
30 InfoQ Brasil
e ao chamar o mtodo
showRefine(barBell), o esperado ser:
showRefine(barBell) Bell
Recursos introduzidos
no Java 6 e 7
O Java 6 foi essencialmente uma
verso para melhoria de desempenho
e de bibliotecas. As nicas mudanas
para o sistema de tipos foi a expanso
do papel das anotaes e o lanamento da capacidade de processamento
de anotao conectvel (pluggable).
Isto no impactou a maioria dos desenvolvedores Java e no disponibilizou um sistema de tipos conectveis
(pluggable type system) no Java 6.
O Java 7 no mudou materialmente
o sistema de tipos. Os nicos novos
recursos, todos de baixa relevncia,
so:
Pequenas melhorias na inferncia de tipos do compilador javac;
Tratamento de assinatura polimrfica - utilizado como um detalhe
de implementao para o recurso chamado method handles - que, por sua
vez, foi utilizado para implementar
expresses lambda no Java 8;
O Multi-catch fornece algumas
caractersitcas de tipos de dados al-
32 InfoQ Brasil
Operador Diamante
O Java muitas vezes criticado por
ser excessivamente verboso. Uma das
reas mais comuns desta queixa est
na atribuio. No Java 6, somos forados a escrever declaraes de atribuio como esta:
Map<String, String>
Manipulador de Mtodos
Os manipuladores de mtodos so
simultaneamente o novo recurso mais
importante do Java 7 e o que menos
provvel de ser usado no dia-a-dia da
34 InfoQ Brasil
invokedynamic
A ltima funcionalidade do Java 7
que abre as portas para o Java 8 ainda mais esotrica que os manipuladores de mtodo. Esse o novo bytecode
invokedynamic - o primeiro bytecode
a ser adicionado plataforma desde o
Java 1.0. Esta funcionalidade quase
impossvel de ser usada por desenvolvedores na verso 7, porque nessa
verso o javac no ir, sob nenhuma
circunstncia, gerar um arquivo class
que contenha isso.
Em vez disso, o bytecode foi projetado ser usado por desenvolvedores
de outras linguagens alm do Java, tal
como JRuby, que requer muito mais
execuo dinmica que o Java. Para
ver como o invokedynamic funciona,
discutiremos como as chamadas de
mtodo Java so compiladas em bytecode.
Uma chamada padro de mtodo
Java ser convertida em um pedao
de bytecode da JVM, que frequentemente referenciado como uma chamada local. Esta chamada composta
de um cdigo de operao de envio
(tal como invokevirtual, para chamadas de mtodo de instncia normal)
e uma constante (um deslocamento
para o Constant Pool da classe) que
indica qual o mtodo a ser chamado.
Os diferentes cdigos de invocao
tm regras diferentes que definem
como a pesquisa de mtodo feita,
mas at Java 7 sempre eram utilizadas
constantes para saber diretamente
qual o mtodo a ser chamado.
O invokedynamic diferente. Ao
invs de fornecer uma constante que
indica diretamente qual mtodo deve
ser chamado, o invokedynamic fornece um mecanismo de indireo que
permite o cdigo do usurio decidir
qual mtodo chamar em tempo de
execuo.
Quando a primeira chamada com
invokedynamic encontrada, o alvo
ainda no conhecido. Ao invs disso, um manipulador de mtodo (chamado mtodo inicial) invocado.
declarao como:
Function<Integer, Integer> fn = x -> x + 2;
Concluso
Obter expresses lambda na plataforma Java sempre foi e vai ser uma tarefa
desafiadora, mas garantindo que o terreno adequado estava no lugar, o Java 7
facilitou consideravelmente esse esforo. O plano B no s forneceu aos desenvolvedores o lanamento antecipado do Java 7, mas tambm permitiu que as
principais tecnologias realizassem testes em produo antes de usarem o Java 8
e especialmente expresses lambda.
Sobre o Autor
Ben Evans o CEO da jClarity, uma startup que fornece ferramentas de
desempenho para auxiliar equipes de desenvolvimento e ops. Ele um organizador no LJC (JUG Londres) e membro do comit executivo do JCP, ajudando a definir padres para os ecossistemas Java. Ele um Java Champion; JavaOne Rockstar; coautor do The Well-Grounded Java Developer
e um palestrante pblico na plataforma Java, desempenho, concorrncia
e tpicos relatados.
Q&A:
NOVIDADES
DO
JAVA
8
por Matt Raible, traduo de Diogo Carleto
O Java 8 uma das atualizaes de linguagem de programao mais esperadas dos ltimos anos. O novo release contm a API de datas, API de
stream e os lambdas, remove o permgen e traz um longo conjunto de melhorias. Para aprender mais sobre este lanamento, conversamos com
Georges Saab, vice-presidente de desenvolvimento de software do Java Platform Group na Oracle.
InfoQ: Para os que no tm seguido o projeto Lambda de perto, poderia
nos dar uma ideia do que foi envolvido nesta implementao? Talvez seja
a primeira vez que tanto a linguagem
como a VM e as bibliotecas evoluram
juntas de maneira coordenada.
A maioria das grandes funcionalidades
em verses anteriores foi feita de maneira que somente uma dessas trs reas foi
afetada; ou as mudanas em cada rea foram introduzidas ao longo de uma srie de
grandes releases. Com o projeto Lambda
no Java 8, fizemos um mudanas coordenadas, envolvendo a linguagem, as bibliotecas e a JVM. Ao longo do desenvolvimento,
cada rea influenciou e fortaleceu o design
e a implementao das demais.
Experimentamos, por exemplo, com implementaes alternativas do Lambda na
JVM e descobrimos que poderamos utilizar o InvokeDynamic. Ao faz-lo, encontramos pontos que poderiam ser melhorados
no prprio InvokeDynamic. O desejo de
utilizar Lambdas de forma natural com as
Collections nos levou ao design da Streams
API e depois aos mtodos de extenso os
quais exigiram suporte da linguagem.
Tem sido um processo evolutivo ao longo de vrios anos, com bastante feedback
da comunidade.
36 InfoQ Brasil
DO
GROOVY
AO
JAVA
8
por Dan Woods, traduzido por Daniel Sousa
Este artigo focar nas semelhanas entre o Groovy e o Java 8, e vai demonstrar o quo familiar os conceitos do Groovy se traduzem para Java 8.
38 InfoQ Brasil
def closure = {
called
}
assert closure instanceof java.util.concurrent.Callable
assert closure() == called
return getAttribute(key);
}
default Map getScope() {
return scopeMap;
}
}
static final WebFlowScope scope =
R calc(T t);
scopeMap[key] = val
getAttribute(key)
if (!cache.containsKey(t)) {
cache.put(t, calc(t));
scopeMap
return (R)cache.get(t);
edited_${scope[name]}
if (n == 0 || n == 1) return n;
};
return this;
}
}
// Encapsula a chamada do TrampolineFunction para evitar um
StackOverflowError
static
TrampolineFunction<Integer,
Object>
fibTrampoline
(Integer...objs) -> {
Integer n = objs[0];
list.add(3); list.add(4);
List<Integer> newList =
if (n == 0) return a;
toList());
};
println item
}
emails.add(danielpwoods@gmail.com);
emails.add(nemnesic@gmail.com);
emails.add(daniel.woods@objectpartners.com);
emails.add(nemnesic@nemnesic.com);
List<String> gmails = emails.stream().filter( (String email) ->
email.endsWith(@gmail.com) ).collect(Collectors.toList());
assert gmails.get(0) == danielpwoods@gmail.com && gmails.get(1) ==
nemnesic@gmail.com;
40 InfoQ Brasil
list.add(2); list.add(3);
strings.add(item3);
list.add(4); list.add(1);
strings = strings.stream().map(Helpers::modifier).collect(Collectors.
list = list.stream().sorted().collect(Collectors.toList());
toList());
assert edited_item1.equals(strings.get(0));
assert edited_item2.equals(strings.get(1));
Integer.valueOf(a-b).compareTo(b)).collect(Collectors.toList());
assert edited_item3.equals(strings.get(2));
list.collect(this.&modifier)
==
[edited_item1,
edited_
item2, edited_item3]
Desenvolvedores no Java 8 dispem da mesma flexibilidade atravs do
uso do operador :: para obter uma referncia do mtodo.
List<String> strings = new ArrayList<>();
strings.add(item1);
strings.add(item2);
Sobre o Autor
Daniel pode ser contatado atravs do email
danielpwoods@gmail.com ou pelo Twitter
@danveloper.
Daniel Woods consultor snior na Object Partners, Inc. Ele especialista
em Arquitetura de Aplicaes com Groovy e Grails, mantendo forte interesse em Java e outras linguagens baseadas na JVM.
eMag | Java: Presente e Futuro 41
42 InfoQ Brasil
Shell scripts
linha de comando usando o comando jjs. Pode executa-
44 InfoQ Brasil
}
});
var th = new MyThread();
th.start();
th.join();
Linguagem funcional
simpleBindings.put(globalValue, valueIn);
nashorn.eval(print (globalValue), simpleBindings);
list.forEach(new Consumer() {
@Override
assert(result == 3);
}
});
jsArray.forEach(function(el) { print(el) } );
print(running...\n);
46 InfoQ Brasil
}
});
Avatar.js
Vimos que com o Nashorn temos um bom motor
de JavaScript embarcado no Java. Tambm vimos que
o Nashorn pode acessar as classes do Java. O Avatar.js
vai um passo alm e traz o modelo de programao
do Node, APIs e os mdulos do ecossistema para a
plataforma Java. Para entender o que isso significa
e porque excitante, primeiro vamos entender o que
o Node.
O Node basicamente uma extrao do motor de
JavaScript V8 do Chrome que pode ser executado
atravs de linhas de comando, sem precisar de
um navegador. Isso permite que o JavaScript seja
executado no apenas no navegador, mas tambm no
lado servidor. Para executar o JavaScript no servidor
de uma forma significativa, ser necessrio acessar
pelo menos o sistema de arquivos e a rede. Para fazer
isso, o Node possui uma biblioteca chamada libuv
que faz isso de maneira assncrona. Na prtica, isso
significa que as chamadas ao sistema operacional no
ficam bloqueadas mesmo que demorem algum tempo
para responder. Ao invs de bloquear, fornecida
uma funo de callback que ser acionada uma vez
que a chamada terminar, entregando os resultados,
se houver algum.
H diversas empresas que usam o Node para
aplicaes srias, como o Walmart e o Paypal.
Vejamos um pequeno exemplo de JavaScript que
foi adaptado do site do Node:
// carrega o mdulo http (isso bloqueante)
para tratar requisies http.
var http = require(http);
// quando h uma requisio, retornamos Hello, World\n.
function handleRequest(req, res) {
res.writeHead(200, {Content-Type: text/plain});
res.end(Hello, World\n);
}
// Vamos escutar a porta 1337 do localhost
// e dar um handleRequest quando a chamada voltar.
// Veja aqui a forma sem bloqueio / assncrona.
http.createServer(handleRequest).listen(1337, 127.0.0.1);
// registramos no console para garantir
que a aplicao foi inicializada.
console.log(Get your hello at http://127.0.0.1:1337/);
return result.toPlainString();
}
Apenas precisamos substituir a funo handleRequest do Node, como no exemplo anterior, para completarmos o cdigo. Como esse:
// Carrega o mdulo utilitrio url para converter a url.
var url = require(url);
function handleRequest(req, res) {
// /calculate o caminho do web service.
if (url.parse(req.url).pathname === /calculate) {
var query = url.parse(req.url, true).query;
// Quantia e percentual so passados como
48 InfoQ Brasil
Sobre o Autor
Oliver Zeigermann consultor de arquitetura e desenvolvimento de software, e Coach em Hamburg, Alemanha. Atualmente tem se concentrado em usar JavaScript em aplicaes corporativas.
InfoQ.com: E quanto s formas de type erasure em interfaces, com perda de informao, como em sobrecargas?
List<String> e List<Map<String, Integer>> seriam tipos
distintos no Java 10?
Goetz: List<String> e List<Integer> sempre foram tipos diferentes, mas esses dois tipos so representados pela mesma classe em
tempo de execuo. A remoo de informao de tipos (erasure)
impede que se descubra se um tipo List foi definido como List<String> ou um List<Integer> antes de a informao ser removida.
Uma traduo heterognea completa de tipos genricos, como
a usada nos templates do C++, mapearia cada um desses tipos para
Rose: O Java tem 20 anos de idade e ouvem-se reclamaes sobre arrays desde a primeira verso. Estamos convergindo para uma
API que permita atingir dados unidimensionais (flat data). Estamos
chegando perto de iniciar prottipos que o objetivo do Projeto
Panama. A IBM foi envolvida desde o incio; h uma lista de discusso especial de que os engenheiros da VM da empresa podem participar. So necessrias mudanas na linguagem, por exemplo os
value types e mudanas em algumas premissas.
Sobre os Participantes
Brian Goetz desenvolvedor profissional h mais
de 20 anos e autor do popular livro Java Concurrency in Practice. Escreveu mais de 75 artigos sobre
desenvolvimento em Java e foi lder da especificao que trouxe os lambdas para a linguagem (JSR
335). Goetz o Arquiteto da Linguage Java na Oracle.
John Rose lder do projeto Da Vinci no OpenJDK.
Liderou a JSR 292, que introduziu no Java o suporte
a invocaes dinmicas e profiling de tipos. Antes
disso, participou da criao dos inner cla
50 InfoQ Brasil
NOVOS
HORIZONTES
DO
JAVA
por Ben Evans, Victor Grazi e Abraham Marn Prez.
Primeiros anncios
evoluo do Java 9, adaptando vrias notcias e artigos do
InfoQ, Conhea o que est a caminho!
O Java 9 teve incio em agosto de 2014, quandi a Oracle
anunciou o primeiro grupo de JEPs para o Java 9 (JEP
= Java Enhancement Proposal Proposta de Aperfeioamento).
Os JEPs fazem parte de um novo processo que permite
funcionalidades da linguagem e VM do Java para ser exploradas sem a necessidade de um processo de especificao completo como o atual JSR. Isso permite que o escopo
dos JEPs seja menor e mais focado e que tratem so especficos implementao OpenJDK. JEPs bem sucedidas podem ento ser convertidas em pedidos de padronizao
no JSR ou includas em padres existentes.
Trs novas APIs foram anunciadas inicialmente:
Process API Updates para interao com processos
de sistema operacional no baseados em Java;
Um novo HTTP Client que inclui suporte a HTTP/2;
Uma nova API leve para JSON, que deve ser construda com base no suporte a JSON (JSR 353).
H tambm trs novidades voltadas ao desempenho:
Outras novidades
Foi um primeiro passo na direo da modularidade completa, ainda que os mdulos no estivessem visveis ao
desenvolvedor em tempo de execuo.
Em novembro de 2014, a Oracle anunciou outras funcionalidades do Java 9, com destaque para a modularidade da plataforma. Veja outras mudanas anunciadas:
Logging unificado na JVM uma grande reviso
no mecanismo interno de notificao de eventos na
JVM, permitindo substituir o atual sistema de logging por um sistema comum e unificado, possibilitando que diversos componentes compartilhem o
mecanismo de logging;
Remoo de combinaes de GC obsoletas a remoo das combinaes: DefNew + CMS, ParNew
+ SerialOld e Incremental CMS. Estas haviam sido
marcadas como obsoletas no Java 8;
Mais controle sobre o compilador melhoria no
controle sobre o compilador Hotspot JIT, permitindo adicionar opes para cada mtodo a ser compilado e alterar as opces em runtime. Por exemplo,
adicionar diretivas para habilitar ou desabilitar
uma otimizao especfica para determinado mtodo, remover a opo de o mtodo ser inline ou at
mesmo instalar uma diretiva durante a execuo e
verificar seu resultado;
Project Coin atualizado Ajustes em alguns detalhes originados no Java 7 (Project Coin) que trouxe
mudanas na linguagem. Sero permitidos @SafeVargs em mtodos privados, o operador diamond
com inner classes, entre outras mudanas.
Novidades incluem tambm o trmino do projeto
de remoo de warnings e uma limpeza no gerenciador
de importao. Ao importar classes obsoletas, no sero
mais disparados alertas. Alm disso, alguns problemas
antigos na resoluo de tipos no javac sero corrigidos.
O suporte a algumas tecnologias modernas tambm
52 InfoQ Brasil
foi anunciado, incluindo o Datagram Transport Layer Security (DTLS), e uma atualizao da ferramenta Javadoc
para gerao de HTML5.
As JEPs tambm indicam que a especializao de tipos
primitivos em tipos genricos (para permitir estruturas
como List<int>) no est mais planejada para o JDK9, mas
sim para o JDK10.