Compilando o Código Java

Os plug-ins do JDT incluem um compilador Java batch e incremental para construir arquivos Java .class a partir do código fonte. Não há uma API direta fornecida pelo compilador. Ela é instalada como um construtor em projetos Java. A compilação é disparada utilizando mecanismos de construção de plataforma padrão.

Há uma descrição detalhada do mecanismo de construção da plataforma em Construtores de projetos incrementais .

Código de Compilação

É possível de maneira programática, compilar os arquivos fonte Java em um projeto que utilize a API de construção.

   IProject myProject;
IProgressMonitor myProgressMonitor;myProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, myProgressMonitor);

Para um projeto Java, isso chamará o construtor de projeto incremental Java (juntamente com outros construtores de projeto incrementais que tenham sido incluídos na especificação de construção do projeto). Os arquivos.class gerados são gravados na pasta de saída designada. Os arquivos de recurso adicionais também são copiados para a pasta de saída.  

No caso de uma construção em batch completa, todos os arquivos .class na pasta de saída poderão ser 'apagados' para assegurar que nenhum arquivo stale seja encontrado. Isto é controlado através do uso de uma Opção do Construtor de Núcleo do JDT (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER).  O padrão para esta opção é limpar pastas de saída.  A menos que esta opção seja redefinida, certifique-se de colocar todos os arquivos .class, para os quais você não tenha arquivos de origem correspondentes, em uma pasta de arquivos de classe separada no classpath em vez de na pasta de saída.

Os construtores incremental e em batch podem ser configurados com outras opções que controlam quais recursos são copiados para a pasta de saída.   A amostra a seguir mostra como configurar um filtro de recursos para que arquivos que terminam com '.ignore' e pastas chamadas 'META-INF', não sejam copiados para a pasta de saída:

      Opções da tabela de hashing = JavaCore.getOptions();
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   JavaCore.setOptions(options);

Os nomes de arquivos serão filtrados se corresponderem a um dos padrões fornecidos. Pastas inteiras serão filtradas se seus nomes corresponderem a um dos nomes de pasta fornecidos que terminarem em um separador de caminho.

Os construtores incremental e em lote também podem ser configurados para gerar apenas um único erro quando o arquivo .classpath tiver erros. Esta opção é definida por padrão e elimina muitos erros.  Consulte Opções do Construtor de Núcleo do JDT para obter uma lista completa das opções relacionadas ao construtor e seus padrões.

O compilador também pode ser configurado utilizando as opções JavaCore.   Você pode definir, por exemplo, a gravidade a ser utilizada para diferentes tipos de problemas encontrados durante a compilação.   Consulte Opções do Compilador do Núcleo do JDT para obter uma lista completa de opções relacionadas ao compilador e seus padrões.

Ao configurar, através de programação, opções para o construtor ou compilador, é preciso determinar o escopo da opção.  Por exemplo, a configuração de um filtro de recursos pode se aplicar apenas a um projeto específico. O exemplo a seguir configura o mesmo filtro de recursos mostrado anteriormente, mas o define apenas para o projeto específico.

   
   Hashtable options = myProject.getOptions(false);  // obter somente as opções configuradas neste projeto
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

Utilizando o Compilador de Batch

Localizando o Compilador de Batch

A classe do compilador de batch está localizada nas classes internas do plug-in do Núcleo/JDT. Portanto ela está no arquivo jdtcore.jar no diretório plugins/org.eclipse.jdt.core. O nome da classe é org.eclipse.jdt.internal.compiler.batch.Main.

Executando o Compilador de Batch

Quais Opções Estão Disponíveis?

Com o segundo plano laranja, estas são as opções sugeridas.

Name Uso
Opções de caminhos de classes
-bootclasspath <dir 1>;<dir 2>;...;<dir P> Esta é uma lista de diretórios ou arquivos jar utilizada para auto-inicializar os arquivos de classes, utilizados pelo compilador. Por padrão, as bibliotecas do VM em execução são utilizadas. As entradas são separadas pelo separador de caminhos da plataforma.
-cp
-classpath <dir 1>;<dir 2>;...;<dir P>
Esta é uma lista de diretórios ou arquivos jar utilizada para compilar os arquivos de origem. O valor padrão é o valor da propriedade "java.class.path". As entradas são separadas pelo separador de caminhos da plataforma.
-extdirs <dir 1>;<dir 2>;...;<dir P> Esta é uma lista de diretórios, utilizada para especificar o local de arquivos zip/jar de extensão. As entradas são separadas pelo separador de caminhos da plataforma.
-sourcepath <dir 1>;<dir 2>;...;<dir P> Esta é uma lista de diretórios utilizada para especificar os arquivos de origem. As entradas são separadas pelo separador de caminhos da plataforma.
-d <dir 1>|none Isso é utilizado para especificar em qual diretório os arquivos .class gerados devem ser despejados. Se ele for omitido, nenhuma estrutura de diretório do pacote será criada.
Se não desejar gerar os arquivos .class, utilize -d none.
-encoding <nome da codificação> Especifique o formato de codificação da origem padrão (a codificação customizada também pode ser especificada em uma base por arquivo incluindo em cada nome de arquivo/pasta de origem de entrada um sufixo com [encoding <encoding name>]).
Opções de conformidade
-destino 1.1|1.2|1.3|1.4|1.5|5|5.0 Isso especifica a configuração de destino do arquivo .class. O valor possível é:
  • 1.1 (versão principal: 45 secundária: 3)
  • 1.2 (versão principal: 46 secundária: 0)
  • 1.3 (versão principal: 47 secundária: 0)
  • 1.4 (versão principal: 48 secundária: 0)
  • 1.5, 5 ou 5.0 (versão principal: 49 secundária: 0)
Os padrões são:
  • 1.1 no modo -1.3
  • 1.2 no modo -1.4
  • 1.5 no modo -1.5
-1.3 Configure o nível de conformidade como 1.3. -origem 1.3 -destino 1.1 implícitos.
-1.4 Configure o nível de conformidade como 1.4 (padrão). -origem 1.3 -destino 1.2 implícitos.
-1.5 Configure o nível de conformidade como 1.5. -origem 1.5 -target 1.5 implícitos.
-origem 1.3|1.4|1.5|5|5.0 Isso é utilizado para ativar o nível de origem do compilador.
O valor possível é:
  • 1.3
  • 1.4
  • 1.5, 5 ou 5.0
Os padrões são:
  • 1.3 no modo -1.3
  • 1.4 no modo -1.4
  • 1.5 no modo -1.5
Em 1.4, assert é tratado como uma palavra-chave. Em 1.5, enum e assert são tratados como uma palavra-chave.
Opções de aviso
-warn:
allDeprecation
allJavadoc
assertIdentifier
boxing
charConcat
conditionAssign
constructorName
dep-ann
deprecation
emptyBlock
enumSwitch
fieldHiding
finalBound
finally
hiding
incomplete-switch
indirectStatic
intfAnnotation
intfNonInherited
javadoc
localHiding
maskedCatchBlocks
nls
noEffectAssign
null
over-ann
pkgDefaultMethod
semicolon
serial
specialParamHiding
static-access
staticReceiver
suppress
synthetic-access
syntheticAccess
tasks(<task1>|...|<taskN>)
typeHiding
desmarcada,
unnecessaryElse
unqualified-field-access
unqualifiedField
uselessTypeCheck
unused
unusedArgument
unusedImport
unusedLocal
unusedPrivate
unusedThrown
varargsCast
warningToken
Configure o nível de aviso.
Por exemplo, -warn:unusedLocals,deprecation

Em red são as configurações padrão.

    -warn:<warnings separated by ,>    enable exactly the
listed warnings
    -warn:+<warnings separated by ,>   enable additional
warnings
    -warn:-<warnings separated by ,>   disable specific
warnings
allDeprecation substituição mesmo dentro do código substituído
allJavadoc javadoc inválido ou ausente
assertIdentifier ocorrência de assert utilizada como identificador
boxing conversão do autoboxing
charConcat quando uma matriz de caracteres é utilizada em uma concatenação de cadeia sem estar convertida explicitamente para uma cadeia
conditionAssign possível designação do booleano acidental
constructorName método com nome de construtor
dep-ann anotação do @Deprecated ausente
deprecation o uso de tipo ou membro substituído fora do código substituído
emptyBlock bloco vazio não documentado
enumSwitch,
incomplete-switch
comutador enum incompleto
fieldHiding campo ocultando outra variável
finalBound parâmetro type com limite final
finally bloco finally não é concluído de modo normal
hiding macro para fieldHiding, localHiding, typeHiding e maskedCatchBlock
indirectStatic referência indireta para membro estático
intfAnnotation tipo de anotação utilizada como super interface
intfNonInherited compatibilidade de método não-herdado da interface
javadoc javadoc inválido
localHiding variável local ocultando outra variável
maskedCatchBlocks bloco catch oculto
nls literais de cadeia não-nls (falta de tags //$NON-NLS-<n>)
noEffectAssign para designação com nenhum efeito
null verificação nula ausente ou redundante
over-ann anotação @Override ausente
pkgDefaultMethod tentativa de substituir método de pacote padrão
serial serialVersionUID ausente
semicolon semicolon desnecessário ou instrução vazia
specialParamHiding parâmetro construtor ou definidor ocultando outro campo
static-access macro para indirectStatic e staticReceiver
staticReceiver se um receptor não estático for utilizado para obter um campo estático ou chamar um método estático
suppress ativar @SuppressWarnings
syntheticAccess,
acesso-sintético
quando executar acesso sintético para innerclass
Tasks ative suporte para tags de tarefas no código fonte
typeHiding parâmetro type ocultando outro tipo
desmarcada, operação de tipo desmarcada
unnecessaryElse desnecessária cláusula else
acesso ao campo não qualificado,
unqualifiedField
referência não qualificada para campo
unused macro para unusedArgument, unusedImport, unusedLocal, unusedPrivate e unusedThrown
unusedArgument argumento de método não utilizado
unusedImport referência de importação não utilizada
unusedLocal variável local não utilizada
unusedPrivate declaração de membro privado não utilizada
unusedThrown exceção emitida declarada não utilizada
uselessTypeCheck operação de coerção/instância desnecessária
varargsCast argumento varargs precisa de coerção explícita
warningToken token de aviso não tratado em @SuppressWarningsb

-nowarn Nenhum aviso (equivalente a -warn:none)
-deprecation Equivalente a -warn:deprecation.
Debug options
-g[:none|:lines,vars,source] Configure o nível de atributos de depuração
-g Todas as informações sobre depuração (equivalente a -g:lines,vars,source)
-g:none Nenhuma informação sobre depuração
-g:[lines,vars,source] informações de depuração seletiva
-preserveAllLocals Explicitamente peça ao compilador para preservar todas as variáveis locais (para fins de depuração). Se for omitido, o compilador removerá locais não utilizados.
Opções Avançadas
@<arquivo> Mostre os argumentos da linha de comandos a partir do arquivo
-maxProblems <n> Número máximo de problemas por unidade de compilação (100 por padrão)
-log <nome do arquivo> Especifique um arquivo de registros no qual todas as saídas do compilador serão despejadas. Isso será realmente útil se você desejar depurar o compilador de batch ou obter um arquivo que contenha todos os erros e avisos a partir de uma construção de batch. Se a extensão for .xml, o registro gerado será um arquivo xml.
-proceedOnError Mantenha a compilação quando houver erros, arquivos de classes de despejo com métodos do problema ou tipos de problemas. Será recomendável apenas se você puder executar o aplicativo mesmo se tiver erros restantes.
-verbose Imprima unidades de compilação acessadas/processadas no console ou no arquivo de registros, se especificado.
-referenceInfo Compute informações sobre referência. Isso será útil apenas se estiver conectado com o construtor. Caso contrário, as informações sobre referência serão inúteis.
-progress Mostrar progresso (apenas no modo de -log)
-time Exiba informações sobre velocidade
-noExit Não chame o System.exit(n) no final da compilação do (n=0 se não houver erro)
-repeat <n> Repita as vezes do processo de compilação do <n> (análise de desempenho).
-inlineJSR bytecode JSR seqüencial (implícito se for destino >= 1.5)
-enableJavadoc Considere as referências dentro do javadoc
Opções de ajuda
-? -help Exiba a mensagem de ajuda
-v -version Exiba a número de construção do compilador. Isso é muito útil para relatar um erro.
-showversion Exiba o número de construção do compilador e continue. Isso é muito útil para relatar um erro.

Exemplos

d:\temp -classpath rt.jar -time -g -d d:/tmp Ele compila todos os arquivos de origem no d:\temp e suas subpastas. O caminho de classe é simplesmente rt.jar. Ele gera todos os atributos de depuração e todos os arquivos .class são despejados em d:\tmp. A velocidade do compilador será exibida quando o processo de batch for concluído.
d:\temp\Test.java -classpath d:\temp;rt.jar -g:none Ele compila apenas o Test.java e recuperará quaisquer arquivos dependentes do d:\temp. O caminho de classe é rt.jar e d:\temp, que significa que todas as classes necessárias são procuradas primeiro no d:\temp e, em seguida, no rt.jar. Nenhum atributo de depuração é gerado por ele e todos os arquivos .class gerados são despejados em d:\tmp.

Utilizando o Adaptador Ant Javac

O compilador Eclipse pode ser utilizado dentro do script Ant utilizando o adaptador javac. Para utilizar o compilador Eclipse, será necessário apenas definir a propriedade build.compiler em seu script. A seguir, um pequeno exemplo.
<?xml version="1.0" encoding="UTF-8"?>
<project name="compile" default="main" basedir="../.">

	<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>

	<property name="root" value="${basedir}/src"/>

	<property name="destdir" value="d:/temp/bin" />

	<target name="main">
		<javac srcdir="${root}" destdir="${destdir}" debug="on" nowarn="on" extdirs="d:/extdirs" source="1.4">
		    <classpath>
		      <pathelement location="${basedir}/../org.eclipse.jdt.core/bin"/>
		    </classpath>
		</javac>		
	</target>
</project>
A sintaxe utilizada para a tarefa javac Ant pode ser encontrada na documentação da tarefa Ant javac . O adaptador atual suporta a tarefa Javac Ant 1.4.1 até as versões 1.6.5.

Se estiver utilizando uma versão acima de 1.5.0, será possível utilizar o elemento do argumento do compilador aninhado para especificar opções específicas ao compilador.

...
		<javac srcdir="${root}" destdir="${destdir}" debug="on" nowarn="on" extdirs="d:/extdirs" source="1.4">
		    <classpath>
		      <pathelement location="${basedir}/../org.eclipse.jdt.core/bin"/>
		    </classpath>
    <compilerarg
compiler="org.eclipse.jdt.core.JDTCompilerAdapter"
line="-1.5 -warn:+boxing"/>
</javac>		
...

Para evitar a obtenção dos scripts dependentes do compilador, aconselhamos que você utilize o argumento do compilador configurado como org.eclipse.jdt.core.JDTCompilerAdapter. Se isso não estiver configurado, o script poderá ser utilizado apenas com o compilador do Eclipse. Se estiver configurado, o argumento do compilador aninhado será ignorado se o nome for diferente do nome do compilador especificado pela propriedade build.compiler.

Determinação de Problemas

O Núcleo do JDT define um marcador especializado (tipo de marcador "org.eclipse.jdt.core.problem ") para indicar problemas de compilação. Para descobrir os problemas detectados pelo compilador de maneira programática, deve-se utilizar o protocolo de marcador de plataforma padrão. Consulte Marcadores de Recursos para obter uma visão geral da utilização de marcadores.

O seguinte trecho procura todos os marcadores de problemas Java em uma unidade de compilação.

   public IMarker[] findJavaProblemMarkers(ICompilationUnit cu)          throws CoreException {
IResource javaSourceFile = cu.getUnderlyingResource();IMarker[] markers = javaSourceFile.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,true, IResource.DEPTH_INFINITE);   }

Os marcadores de problemas Java são mantidos pelo construtor de projeto Java e são removidos automaticamente à medida que os problemas são resolvidos e a origem Java é recompilada.

O valor do id do problema é definido por uma das constantes em IProblem . O id do problema é confiável, mas a mensagem é localizada e, portanto, pode ser alterada de acordo com o locale padrão. As constantes definidas em IProblem são autodescritivas.

Uma implementação de IProblemRequestor deve ser definida para coletar os problemas descobertos durante uma operação Java. As cópias de trabalho poderão ser reconciliadas com a detecção de problemas se um IProblemRequestor tiver sido fornecido para a criação da cópia de trabalho. Para conseguir isso, você pode utilizar o método reconcile.Por exemplo:

  ICompilationUnit unit = ..; // obter alguma unidade de compilação
			
  // criar solicitante para acumular problemas descobertos
  IProblemRequestor problemRequestor = new IProblemRequestor() {
    public void acceptProblem(IProblem problem) {
      System.out.println(problem.getID() + ": " + problem.getMessage());
    }
    public void beginReporting() {}
    public void endReporting() {}
    public boolean isActive() {	return true; } // detectará problemas se ativo
  };
    
  // utilizar cópia de trabalho para reter origem com erro
  ICompilationUnit workingCopy = unit.getWorkingCopy(new WorkingCopyOwner() {}, problemRequestor, null);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // reconciliação do disparo
  workingCopy.reconcile(NO_AST, true, null, null);
Você pode incluir uma ação sobre os problemas relatados no método acceptProblem(IProblem). Neste exemplo, o problema relatado será que Zork não pode ser resolvido ou não é uma superclasse válida e seu id é IProblem.SuperclassNotFound .