编译 Java 代码

JDT 插件包含增量式和批处理 Java 编译器,用以根据源代码来构建 Java 的 .class 文件。编译器没有提供直接 API。在 Java 项目上,它是作为构建器来安装的。编译是使用标准平台构建机制触发的。

增量项目构建器详细描述了平台构建机制。

编译代码

可以使用构建 API 来使用程序编译项目中的 Java 源文件。

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

对于 Java 项目,这将调用 Java 增量项目构建器(以及已经添加至项目的构建规范中的任何其它增量项目构建器)。生成的 .class 文件被写入到指定的输出文件夹中。附加资源文件也复制到输出文件夹中。 

在完全批处理构建的情况下,输出文件夹中的所有 .class 文件都可能“已清理”,以确保找不到任何陈旧过时的文件。这是使用“JDT 核心构建器选项”(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER)控制的。此选项的缺省值将清除输出文件夹。除非重新设置此选项,否则必须确保将所有 .class 文件(您没有这些文件的相应源文件)放置在类路径中的单独类文件文件夹中,而不是放置在输出文件夹中。

可以使用其它用于控制将哪些资源复制到输出文件夹的选项来配置增量和批处理构建器。以下样本显示如何设置资源过滤器,以便不将以“.ignore”结尾的文件和名为“META-INF”的文件夹复制到输出文件夹:  

   Hashtable options = JavaCore.getOptions();
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   JavaCore.setOptions(options);

如果文件名与所提供的模式之一相匹配,则会过滤掉这些文件名。如果整个文件夹的名称与所提供的文件夹名之一(以路径分隔符结尾)相匹配,则会过滤掉整个文件夹。

还可以将增量和批处理构建器配置为在 .classpath 文件具有错误时只生成单个错误。缺省情况下将设置此选项,它将消除大量的错误。参见 JDT 核心构建器选项以获取与构建器相关的选项及其缺省值的完整列表。

还可以使用 JavaCore 选项来配置编译器。例如,可以定义应当用于在编译期间发现的不同类型的问题的严重性。参见 JDT 核心编译器选项以获取与编译器相关的选项及其缺省值的完整列表。

当使用程序来配置构建器或编译器的选项时,应确定选项的作用域。例如,设置资源过滤器可能只适用于特定的项目。以下示例设置前面显示的那个资源过滤器,但是只设置个别的项目。  

   
   Hashtable options = myProject.getOptions(false);  // get only the options set up in this project
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

使用 ant javac 适配器

可以通过使用 javac 适配器在 Ant 脚本内使用 Eclipse 编译器。要使用 Eclipse 编译器,只需在脚本中定义 build.compiler 属性。以下是一个简单示例。
<?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>
可以在 Ant javac 任务文档中找到用于 javac Ant 任务的语法。当前适配器支持 Javac Ant 任务 1.4.1。当发布了 Ant 1.5 时,将可以使用版本 1.5。

问题确定

“JDT 核心”定义了一个专用标记(标记类型“org.eclipse.jdt.core.problem”)来指示编译问题。要使用程序发现由编译器检测到的问题,应该使用标准的平台标记协议。有关使用标记的概述,参见资源标记

以下代码片段查找编译单元中的所有 Java 问题标记。

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

Java 问题标记是由 Java 项目构建器来维护的,在问题得到解决以及重新编译 Java 源代码之后,就会自动除去这些标记。

问题标识值是由 IProblem 中的其中一个常量设置的。问题标识是可靠的,但是消息是本地化的,因此可以根据缺省语言环境来更改消息。在 IProblem 中定义的常量是自我描述的。

应该定义 IProblemRequestor 的实现,以便收集在 Java 操作期间发现的问题。如果已经为创建工作副本提供了 IProblemRequestor,则可以使工作副本与问题检测相协调。为此,可以使用 reconcile 方法。以下是一个示例:

  ICompilationUnit unit = ..; // get some compilation unit
			
  // create requestor for accumulating discovered problems
  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; } // will detect problems if active
  };
    
  // use working copy to hold source with error
  IWorkingCopy workingCopy = (IWorkingCopy)unit.getWorkingCopy(null, null, problemRequestor);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // trigger reconciliation			
  workingCopy.reconcile(true, null);
可以对 acceptProblem(IProblem) 方法中报告的问题添加一种操作。在此示例中,报告的问题将是无法解析 Zork,或者它是无效超类,并且它的标识为 IProblem.SuperclassNotFound

Copyright IBM Corporation and others 2000, 2003. All Rights Reserved.