Palestra realizada na Semana de Tecnologia da Unip 2016.
Conhecendo boas práticas e como esta poderosa ferramenta do Java 8 pode auxiliar no desenvolvimento de aplicativos Java.
4. Plugin para o javac 8
0101010101011111000000000101001110001
1100011100000001111010101010110001110
1001001010000101001010101011010110111
5. • Por quê, para quê, desenvolver
plugins para o compilador do
Java?
– Adicionar checagem extras em tempo
de compilação
– Adicionar transformações de código
– Customizar análise do código fonte
6. Este código compila?
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
7. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
10. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
Inner
12. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
ex
14. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
VAR
16. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
vazio
18. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
Muitos
parâmetros
19. Jogo dos 5 erros(!?)
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
VAR
ex
Inner
vazio
Muitos
parâmetros
20. Compilar ou não compilar
Teste.java
package br.unip.sicc;
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0;
System.out.println("UNIP");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
21. Alterando o
comportamento do javac
1. Usar Java 8 (tools.jar no CLASSPATH)
2. Implementar Plugin
3. Implementar TaskListener
4. Implementar a lógica desejada
– (TreePathScanner, TreeScanner, TreeVisitor)
– Ex: Não aceitar bloco catch vazio
5. Gerar o jar do Plugin
– META-INF/services/
• com.sun.source.util.Plugin
– NomeTotalmenteQualificadoDoPlugin
6. Compilar usando o plugin
– javac -processorpath CodeCheckPlugin.jar -
Xplugin:CodeCheckPlugin Teste.java
22. Alterando o
comportamento do javac
1. Usar Java 8 (tools.jar no CLASSPATH)
2. Implementar Plugin
3. Implementar TaskListener
4. Implementar a lógica desejada
– (TreePathScanner, TreeScanner, TreeVisitor)
– Ex: Não aceitar bloco catch vazio
5. Gerar o jar do Plugin
– META-INF/services/
• com.sun.source.util.Plugin
– NomeTotalmenteQualificadoDoPlugin
6. Compilar usando o plugin
– javac -processorpath CodeCheckPlugin.jar -
Xplugin:CodeCheckPlugin Teste.java
25. interfaces
com.sun.source.util
• Plugin
– permite definir um plugin para o
compilador
• SourcePositions
– fornece métodos para obter a
posição corrente da compilação
• TaskListener
– fornece um listener para monitorar
atividades do javac
26. interface Plugin
public class CodeCheckPlugin implements Plugin {
@Override
public String getName() {
return "CodeCheckPlugin";
}
@Override
public void init(JavacTask task, String... strings) {
System.out.println("Iniciando plugin!");
task.setTaskListener(new CheckTaskListener(task));
}
}
27. interface TaskListener
public class CheckTaskListener implements TaskListener{
@Override
public void started(TaskEvent taskEvent) {
if(taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) {
CompilationUnitTree compUnit =
taskEvent.getCompilationUnit();
TreePathScanner emptyCacthVisitor =
new EmptyCacthVisitor(task);
emptyCacthVisitor.scan(compUnit, null);
}
}
@Override
public void finished(TaskEvent te) {
}
}
28. interface TaskListener
public class CheckTaskListener implements TaskListener{
@Override
public void started(TaskEvent taskEvent) {
if(taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) {
CompilationUnitTree compUnit =
taskEvent.getCompilationUnit();
TreePathScanner emptyCacthVisitor =
new EmptyCacthVisitor(task);
emptyCacthVisitor.scan(compUnit, null);
}
}
@Override
public void finished(TaskEvent te) {
}
}
31. Classes (Syntax Trees)
com.sun.source.util
com.sun.source.tree
• public abstract class Trees
• public abstract class DocTrees extends Trees
• public interface Tree
• public enum Tree.Kind
• public interface CompilationUnitTree extends Tree
• public interface MethodTree extends Tree
• public interface BlockTree extends Tree
• public interface CatchTree extends Tree
• public interface StatementTree extends Tree
• public interface ModifiersTree extends Tree
• public interface VariableTree extends Tree
• public interface PrimitiveTypeTree extends Tree
• + um montão de Tree
32. Abstract Syntax Trees
Exemplo da Gramática da Linguagem Java
normalClassDeclaration
: 'class' Identifier typeParameters?
('extends' type)?
('implements' typeList)?
classBody
public class Teste
extends TesteBase{
}
class TesteBase{}
Abstract
Syntax Tree
33. SHOW ME THE CODE
0101010101011111000000000101001110001
1100011100000001111010101010110001110
1001001010000101001010101011010110111
34. Referências
• OpenJDK 8 http://openjdk.java.net/
• API Specification, The Java Programming Language Compiler
http://docs.oracle.com/javase/8/docs/jdk/api/javac/tree/index.html
• Sun Microsystems, Java Code Conventions, 1997
• Compiler Grammar http://openjdk.java.net/projects/compiler-grammar/
• Effective Java by Joshua Block, 2008
• Hacking the Java Compiler for Fun and Profit By Raoul-Gabriel Urma
• “Java Compiler Plugins”, Oracle Java Magazine January/February 2013,
Raoul-Gabriel Urma& Jonathan Gibbons http://www.oraclejavamagazine-
digital.com/javamagazine/20130102?sub_id=jFwJyABK25xj#pg56