【问题标题】:working with java source and class files programatically以编程方式处理 java 源文件和类文件
【发布时间】:2013-01-14 17:02:33
【问题描述】:

为了尽可能简洁,我将把它分成两个问题。前段时间我开始制作一个用于教育目的的文本编辑器,并一直在这里和那里添加。在此过程中,我决定希望它编译和运行 java 程序。我使用JavaCompiler 类进行编译,并使用一个简单的exec() 方法来执行命令以在控制台中运行程序。源代码变得一团糟,可能是因为它是用无组织的随机代码块编写的,所以我最近决定重写它。在重写程序时,我在文本区域下方添加了一个控制台窗口,以显示编译器的控制台输出以及运行时引发的任何异常等。

在编写代码以显示来自JavaCompiler 的输出或通过BufferedInputStream 显示控制台输出时,我意识到我正在做这两件事,我一直认为它们以非常不同的方式相似。我的第一个问题主要是问你的意见,我不知道 Java 中有一个类会像简单的 IDE 一样运行 java 程序,所以执行控制台命令是我知道的唯一方法,同样可能是完成使用 javac 命令编译代码,我很好奇使用 JavaCompiler 类是否有任何优势?

最后,我一直在为这个东西添加一些简洁的功能。我希望能够跟踪和组织 java 项目,因为我正在编译和运行 java 程序。我希望能够分辨任何给定文件属于哪个项目,以及能够分辨项目中的包和目录之间的区别,以便我可以查看包文件夹以编译源文件并执行正确的运行命令从二进制文件夹中运行它,Java 是否提供了一种方法来执行此操作,还是我将不得不做一些事情,例如创建从文件继承但具有附加字段来确定文件类型(目录或包)的自定义类?还是有更好的方法来实现这一点?

感谢您的宝贵时间。

【问题讨论】:

  • 对于你的最后一个问题,现代 IDE 通过让开发人员指定哪个目录是源的根目录来解决这个问题,例如 srcsrc/main/java
  • 嗯,这很尴尬,我不确定我输入的时候在想什么……我的意思是询问存储目录和文件的位置,包括会话之间的位置。我知道它必须是某种属性文件,可能是 XML?我从未见过这样的属性文件,而且我建议的每个项目的 XML 文件似乎都可能会变得混乱,如果不小心的话,可能会弄乱用户文件系统的一部分。如果用户打开保存的文件,我希望将整个项目加载到屏幕左侧的 JList 或 JTree 中以具体说明。最好的方法是什么?
  • 我已经发布了一些建议和想法的答案。

标签: java compilation system-console


【解决方案1】:

您提出的两个问题是齐头并进的。让我们从元数据开始。弄清楚如何跟踪 IDE 的项目元数据的最佳方法是查看已建立的项目如何尝试执行此操作。

Eclipse 和 Netbeans 都使用在项目根目录中创建的项目文件夹来保存元数据(Eclipse 中的.settings,Netbeans 中的.nbproject)。源文件夹、编译器目标目录、源级别等元数据保存在元数据文件中,主要是 XML。

您可能希望遵循类似的内容,然后考虑添加常见的项目原型,例如 /src/classes/src/main/java/target。这导致您的问题的第二部分,编译。

Netbeans 本身并不直接使用编译器。 Eclipse 可以,但这是因为 Eclipse 有自己的内部编译器实现来提供默认编译器中不可用的额外警告和配置。对于您的 IDE,我将看看 Netbeans 如何管理其项目并对其进行编译。 Netbeans 没有调用javac,而是使用Ant 和一个内部build.xml 文件。如果您不熟悉 Ant,它只是一个工具,允许您在 XML 中设置由 Ant 解释和运行的任务。例如,您可以使用 Ant 编译 Java 源代码、生成文档和创建分发 JAR。这是一个非常强大的工具,可让您将整个构建过程作为一种脚本自动化。

你可以遵循同样的想法。您的 IDE 中的新项目将有一个默认的 build.xml 文件,该文件将使用一些默认的 Ant 目标构建他们的项目。您也可以从build.xml 访问属性文件,因此您可以将有关源目录的信息以及您想在构建脚本中使用的任何其他可定制信息存储在属性文件中,并将它们导入构建脚本中。这是一个示例设置。

文件结构:

| Project root/
|   .myideproject/
|     build.xml
|     project.properties
|     ui.properties
|   classes/
|     <compiled .class files>
|   doc/
|     <generated javadoc files>
|   lib/
|     <3rd-party .jar files needed for compilation>
|   src/
|     <user .java files>

build.xml 文件是 IDE 用来编译的文件。您可以要求用户安装 Ant(一个快速而轻松的过程),也可以像 Netbeans 那样捆绑它(为您做更多的工作)。无论哪种情况,如果您将build.xml 嵌套在.myideproject 目录中,您的构建文件将如下所示:

<project name="<User's project name>" default="compile" basedir="..">
    <!-- ... -->
</project>

注意两件事:

  1. “用户的项目名称”由用户在创建项目时提供。
  2. “默认”属性将指向构建文件中的目标。
  3. “basedir”属性将使构建过程变基,使其指向项目根目录中的目录,而不是.myideproject中的目录。

接下来您需要导入您的project.properties 文件(ui.properties 用于保存与 UI 相关的数据,而不用于构建脚本,project.properties 包含构建脚本正常运行所需的所有内容)。这是您将属性导入 Ant 项目的方式:

<project ... >
    <import file=".myideproject/project.properties" />
    <!-- ... -->
</project>

这将使用指令${propname} 使project.properties 中的所有属性可用。现在,srcclassesproject.properties 文件中的可配置目录,我们可以在compile 目标中使用它们,如下所示:

<target name="compile">
    <javac srcdir="${src}"
        destdir="${target}"
        classpath="${classpath}"
        source="${src.jdk}"
        target="${target.jdk}"
        debug="on"
        debugLevel="lines,vars,source" />
</target>

对于上述目标,属性文件可能如下所示:

# delimits source directories containing .java files using ':'
src=src1:src2
# only 1 directory, it's where the .class files go
target=classes
# ':'-delimited list of jars or globs which are needed for compilation
classpath=lib/*
# Determines the -source value on the javac process
src.jdk=1.6
# Determines the -target value on the javac process
target.jdk=1.6

为了清楚起见,cmets 就在那里。此属性文件将使用用户输入从您的 IDE 的 UI 构建,因此如果他们添加或删除源文件夹,属性文件中的 src 值会自动更改,然后他们可以重建该过程。

这应该足以让您入门。需要考虑的一些事项:

  • 您将需要一个 run 目标,它使用 java 任务以及 IDE 设置的属性来告诉它哪个类用于 main 方法。
  • 您可能还需要考虑支持 Maven 项目,这有助于用户自动解决依赖关系。这对你来说会做更多的工作,你可能应该等到你完成 Ant 支持
  • 您需要将标准输出/错误/输入从 Ant 进程重定向到用户可以与之交互的东西。您不必支持标准输入,但您至少应该支持标准输出/错误

根据您的评论的最后一句话:您需要使用带有扩展 DefaultMutableTreeNode 的自定义节点类的 JTree 来创建视图,但它不必是文件结构的视图,因此只是项目的一个视图,所以也许它可能是这样的:

+ Project 1 Name
| + Source Folder 1
|     <.java files>
| + Source Folder 2
|     <.java files>
| + Source Folder 3
|     <.java files>
+ Project 2 Name
| + Source Folder 1
|     <.java files>
| + Source Folder 2
|     <.java files>
| + Source Folder 3
|     <.java files>

结构可以基于文件系统,但只显示用户需要的信息,比如他的源目录。你可以从那里扩展这个想法。

祝你好运,听起来是个有趣的项目。希望我的建议有一定的意义,可以帮助你。如果有任何需要澄清的地方,请告诉我。

【讨论】:

  • 谢谢,首先我要研究 Ant。我知道它,但我从未使用过它。我还必须决定使用一个库来创建和读取 XML 文件。如果我有任何问题,我一定会告诉你的。谢谢,这非常有用:-)。
  • 对于 XML 文件,有很多选项。我通常编写一个 XSD 文件,然后将 XSD 与 XJC 和 JAXB 一起使用来编组/解组 XML。你可以start here,网上有很多资源可以用来学习如何使用它。很高兴我能帮上忙。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2016-01-03
  • 1970-01-01
  • 2010-10-27
  • 2015-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多